I'm trying my best to make a command that bans people inside and outside a server. Is this possible?
#client.command(aliases=["banmember", "banuser"])
async def ban(ctx, member: discord.Member, *, reason=None):
await ctx.message.delete()
if reason is None:
reason = ""
if reason is not None:
reason = reason
try:
await member.ban(reason=reason)
except:
user = await commands.converter.UserConverter().convert(ctx, user)
banneduser = await client.fetch_user(user.id)
await ctx.guild.ban(banneduser, reason=reason)
It does not look possible, as if i used UserConverter it wouldn't ban members inside the server, if i used Members it wouldn't ban people outside the server. How can I do both?
You can use use typing-union which allows for the command to take in any of the specific types instead of a singular type..
Here is a simple example to send the name to verify it is working for both.
import typing
#bot.command()
async def union(ctx, member: typing.Union[discord.Member, discord.User]):
await ctx.send(member.name)
Related
I want to make i discord bot that can move a member to a specified channel without having to mention them.
import discord
from discord.ext import commands
token = '<token>'
bot = commands.Bot(command_prefix='#')
#bot.command()
async def m(ctx, member : discord.Member, channel : discord.VoiceChannel):
await member.move_to(channel)
#bot.event
async def on_ready():
print('Ready')
bot.run(token)
The command would be: #m #user General
This works great but i need the command to be easier to type by not having to mention a user and simply just moving the author of the message. How do I do that?
You can use ctx.author and make the member argument optional.
Now we just move around the member argument to be last (because a channel is required), and set the default value to None to make it optional.
#bot.command()
#commands.guild_only()
async def m(ctx, channel: discord.VoiceChannel, member: discord.Member = None):
member_to_move = member or ctx.author # if `member` is None, it will be the author instead.
await member_to_move.move_to(channel)
Edit: added #commands.guild_only decorator. This is to ensure that the command can only be used within a guild (and will raise an error if invoked, lets say, in DMs).
You can use ctx.author to get the author of the message:
#bot.command()
#commands.guild_only()
async def m(ctx, channel : discord.VoiceChannel):
await ctx.author.move_to(channel)
So, you can use the command like this: #m General.
Also I added #commands.guild_only() check to be sure that the command is invoked in the guild channel.
This kick command worked, but after adding an embed it doesn't. Any idea why?
#KICK COMMAND
#bot.command()
#commands.has_permissions(administrator=True)
async def kick(ctx, user : discord.Member,*,reason):
kickbed = discord.Embed(title="Kick Log",description=f"Kicked by {ctx.author}.", color=23457535)
kickbed.add_field(name="User Kicked:", value=f'{user}',inline=False)
kickbed.add_field(name="Reason:", value=f'{Reason}',inline=False)
await user.kick(reason=reason)
await ctx.send(embed=kickbed)
First, you used variable reason, but then in:
kickbed.add_field(name="Reason:", value=f'{Reason}',inline=False)
You used the variable Reason (uppercase first letter), which is not defined. You just have to change it to reason.
Then you used 23457535 as a color, which is incorrect because the value you pass to the color= should be less than or equal to 16777215.
discord.Colour in docs
As stated by #NikkieDev:
It could be because you're trying to mention a user that is not in the server.
When I tested it works (mentioning while a user is not on the server), but if you want you could send the message first and then kick the user:
await ctx.send(embed=kickbed) # changed the order of last 2 lines
await user.kick(reason=reason)
It could be because you're trying to mention a user that is not in the server. Therefore it cannot mention the user.
Try this instead:
from discord.ext import commands
import discord
#commands.has_permissions(administrator=True)
async def kick(self, ctx, member: discord.Member, reason="No reason given"):
kickDM=discord.Embed(title='Kicked', description=(f"You've been kicked from {member.guild.name} for {reason} by {ctx.author}"))
kickMSG=discord.Embed(title='Kicked', description=(f"{member} has been kicked from {member.guild.name} for {reason} by {ctx.author}"))
await member.send(embed=kickDM)
await ctx.send(embed=kickMSG)
await member.kick(reason=reason)
bot.add_command(kick)
I have tried different options, and this one was the one that I desired the most, but I cannot seem to get it working. Could I get some help? (Sorry I am very new to coding)
This is my code:
import discord
from discord.ext import commands
client = discord.Client()
bot = commands.Bot(command_prefix='-')
#bot.command()
async def speak(ctx, *, text):
if ctx.message.author.id == ID here:
message = ctx.message
await message.delete()
await ctx.send(f"{text}")
else:
await ctx.send('I need text!')
Thanks
Your else statement makes little sense here. It is best to set up the condition differently, that you want text once and if that does not happen, then there is an else argument.
I don't know if this is relevant either, but apparently it looks like you want only one person to be able to execute this command. For the owner there would be:
#commands.is_owner()
But if you want to make it refer to another person use:
#bot.command()
#commands.is_owner() # If you want to set this condition
async def say(ctx, *, text: str = None):
if ctx.message.author is not ID_You_Want:
await ctx.send("You are not allowed to use the command.")
return # Do not proceed
if text is None: # If just say is passed with no text
await ctx.send("Please insert a text.")
else:
await ctx.send(text) # Send the text
Optional: You can also delete the command that was send with ctx.message.delete()
Your command is not executing because you defined client and bot.
Simply remove client = discord.Client() and you will be fine.
I'm trying to get my bot to check if a member is on the server or not.
I'm only asking this because I tried this answer and it always returns None, no matter what.
Here's my code so far:
#bot.command()
async def membercheck(ctx, member:discord.Member):
guild = bot.get_guild(my_server_id)
if guild.get_member(member) is not None:
await ctx.send("he on server")
else:
await ctx.send("he not on server")
Ideally my code should work so that you input a User ID and the bot checks if the user is on the server.
Thanks in advance for your help!
It's returning None always cause you're passing a discord.Member object to Guild.get_member instead of an int.
#bot.command()
async def membercheck(ctx, member: discord.User):
guild = bot.get_guild(some_id)
member = guild.get_member(member.id)
if member is None:
await ctx.send('Member is not in the server')
else:
await ctx.send('Member is in the server')
Also it's better if you use UserConverter as MemberConverter is going to raise MemberNotFound error when it can't get the member
EDIT
#bot.command()
async def membercheck(ctx, id: int):
guild = bot.get_guild(some_id)
member = guild.get_member(id)
if member is None:
await ctx.send('Member is not in the server')
else:
await ctx.send('Member is in the server')
Okay so I'm trying to make a command that is only available for specific guilds.
Here's The code.
If I add multiple guild IDs then every guild can use this command.
async def is_guild(ctx):
return ctx.guild.id == someguildidhere, someguildidhere
#client.command()
#commands.check(is_guild)
async def checkispremium(ctx):
await ctx.send("Guild owns lifetime premium.")
#checkispremium.error
async def checkispremium(ctx, error):
if isinstance(error, commands.CheckFailure):
await ctx.send("Guild doesn't owns premium ")
However when I add only one guild ID then everything works fine. Only the specific guild can use the command and others will get error.
async def is_guild(ctx):
return ctx.guild.id == someguildidhere
#client.command()
#commands.check(is_guild)
async def checkispremium(ctx):
await ctx.send("Guild owns lifetime premium.")
#checkispremium.error
async def checkispremium(ctx, error):
if isinstance(error, commands.CheckFailure):
await ctx.send("Guild doesn't owns premium")
Anyone know how can I have multiple guild IDs, I tried looking at discordpy-rewrite docs, but looks like nothing is there.
Use
async def is_guild(ctx):
return ctx.guild.id in [someguildidhere, someguildidhere, ...]