Reputation: 13
So I'm trying to make my discord.py bot only accept command execution from certain users for certain commands. I know now that ctx.author.id
means bot author ID. I've heard message.author.id
is supposed to work but using message.author.id
throws a traceback, the infamous NameError error. Why and how do I fix it?
@bot.command(description="Restarts The Bot's source file, use if bot freezes etc, [OWNER]")
async def shutdown(ctx):
if ctx.author.id == 436646726204653589 or 525334420467744768 or 218142353674731520:
embed = discord.Embed(color = 0xff0000)
embed.add_field(name="Shutdown Command Sent, Bot Rebooting in 3 seconds", value = str, inline = False)
await ctx.send(embed=embed)
await asyncio.sleep(3)
await bot.close()
os.execl(sys.executable, sys.executable, * sys.argv)
os.system("py -3 theBot.py")
bot.run(TOKEN)
Upvotes: 1
Views: 3344
Reputation: 5157
If you're using the commands extension and shutdown
is a command, ctx
is a Context
object.
Context.author
is the author of the command message and is shorthand for Message.author
.
Both are User
objects from which you can use User.id
.
I'm not sure what exactly you mean by "bot author ID", but if you want to get the user ID of the bot's owner, you can use Bot.owner_id
, or Bot.owner_ids
if the bot application is team based, instead.
Otherwise, you can use Bot.user
to get the ClientUser
that represents the bot and then ClientUser.id
to get its ID.
The "Not Defined error" should actually be a NameError
telling you that the variable is not defined, and exactly as it's saying, message
is undefined and you need to define it before you use it.
You can use Context.message
to get the Message
that triggered the command being executed.
Note, if ctx.author.id == 436646726204653589 or 525334420467744768 or 218142353674731520:
will always enter the if statement as
ctx.author.id == 436646726204653589 or 525334420467744768 or 218142353674731520
will always be True
. or
has a lower precedence than ==
. This means that this equivalently evaluates as
(ctx.author.id == 436646726204653589) or 525334420467744768 or 218142353674731520
, and the integer, 525334420467744768
, as well as 218142353674731520
, will always evaluate as True
.
Instead, you want to check for equality with each ID. This can be done by checking for membership in a tuple or set, e.g.
ctx.author.id in (436646726204653589, 525334420467744768, 218142353674731520)
or ctx.author.id in {436646726204653589, 525334420467744768, 218142353674731520}
, respectively.
See this How to test multiple variables against a value? question for more information.
Also, if you do not redefine str
anywhere (which you should not do, as it's a built-in class), you're passing the class itself as the embed value and the output will be cast to a string and display as <class 'str'>
.
Additionally, I'm not sure why you're attempting to execute the Python executable with itself with os.execl(sys.executable, sys.executable, * sys.argv)
, but os.execl
immediately replaces the current process, so the next line will never be run.
Upvotes: 1