Discord bot check if user is admin - python

Hi i'm new to python coding with discord and I have tried to make a command that tells the user if they are a admin or not but well... its not working in the slightest
#client.command(name="whoami",description="who are you?")
async def whoami():
if message.author == client.user:
return
if context.message.author.mention == discord.Permissions.administrator:
msg = "You're an admin {0.author.mention}".format(message)
await client.send_message(message.channel, msg)
else:
msg = "You're an average joe {0.author.mention}".format(message)
await client.send_message(message.channel, msg)
I then get this when I try to type whoami
Ignoring exception in command whoami
Traceback (most recent call last):
File "/home/python/.local/lib/python3.6/site-packages/discord/ext/commands/core.py", line 50, in wrapped
ret = yield from coro(*args, **kwargs)
File "<stdin>", line 3, in whoami
NameError: name 'message' is not defined
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/python/.local/lib/python3.6/site-packages/discord/ext/commands/bot.py", line 846, in process_commands
yield from command.invoke(ctx)
File "/home/python/.local/lib/python3.6/site-packages/discord/ext/commands/core.py", line 374, in invoke
yield from injected(*ctx.args, **ctx.kwargs)
File "/home/python/.local/lib/python3.6/site-packages/discord/ext/commands/core.py", line 54, in wrapped
raise CommandInvokeError(e) from e
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: NameError: name 'message' is not defined

If message.author.server_permissions.administrator doesn't work.
Change it to message.author.guild_permissions.administrator
Or try message.author.top_role.permissions.administrator, this will return you a bool.
One thing is, normally the server owner sets the administrator to the server top role, so this will work most of the time. But if they don't, the third sol won't work.

You can use the has_permissions check to see if a user has the administrator privilege.
We can then handle the error that failing that check will throw in order to send a failure message.
from discord.ext.commands import Bot, has_permissions, CheckFailure
client = Bot("!")
#client.command(pass_context=True)
#has_permissions(administrator=True)
async def whoami(ctx):
msg = "You're an admin {}".format(ctx.message.author.mention)
await ctx.send(msg)
#whoami.error
async def whoami_error(ctx, error):
if isinstance(error, CheckFailure):
msg = "You're an average joe {}".format(ctx.message.author.mention)
await ctx.send(msg)

Change
#client.command(name="whoami",description="who are you?")
async def whoami():
to
#client.command(pass_context=True)
async def whoami(ctx):
Then you can use ctx to get all kinds of stuff like the user that wrote it, the message contents and so on
To see if a User is an administrator do
if ctx.message.author.server_permissions.administrator: which should return True if the user is an an Administator
Your code should look like this:
import discord
import asyncio
from discord.ext.commands import Bot
client = Bot(description="My Cool Bot", command_prefix="!", pm_help = False, )
#client.event
async def on_ready():
print("Bot is ready!")
return await client.change_presence(game=discord.Game(name='My bot'))
#client.command(pass_context = True)
async def whoami(ctx):
if ctx.message.author.server_permissions.administrator:
msg = "You're an admin {0.author.mention}".format(ctx.message)
await client.send_message(ctx.message.channel, msg)
else:
msg = "You're an average joe {0.author.mention}".format(ctx.message)
await client.send_message(ctx.message.channel, msg)
client.run('Your_Bot_Token')

Related

error with discord.py NoneType object has no attribute 'id'

Ok, so I try to make a command with on_message, I put await bot.process_commands(message). But it always raises the 'NoneType' object has no attribute 'id'.
import os
import random
import discord
from discord.ext import commands
from dotenv import load_dotenv
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
intents = discord.Intents.default()
intents.message_content = True
activity = discord.Activity(name='null, dying, trying to fix me', type=discord.ActivityType.watching)
client = discord.Client(intents=intents, activity = activity)
bot = commands.Bot(intents=intents,command_prefix='!')
#client.event
async def on_ready():
print(f'{client.user.name} has connected to Discord!')
channel = client.get_channel(956302622170701946)
await channel.send(f'connected successfully as {client.user.name}#{client.user.discriminator}')
#client.event
async def on_message(message):
await bot.process_commands(message)
if message.author == client.user:
return
if message.content.startswith('hello'):
await message.channel.send("hello stopid")
elif message.content.startswith('die'):
await message.channel.send('ok :sob: i ded now')
await client.close()
#bot.command
async def a(ctx):
await ctx.send("a")
client.run(TOKEN)
this is the entire error:
2022-12-08 18:15:54 ERROR discord.client Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\xxxxx\source\repos\DBot\DiscordBot\lib\site-packages\discord\client.py", line 409, in _run_event
await coro(*args, **kwargs)
File "c:\Users\xxxxx\source\repos\DBot\discordbot.py", line 25, in on_message
await bot.process_commands(message)
File "C:\Users\xxxxx\source\repos\DBot\DiscordBot\lib\site-packages\discord\ext\commands\bot.py", line 1389, in process_commands
ctx = await self.get_context(message)
File "C:\Users\xxxxx\source\repos\DBot\DiscordBot\lib\site-packages\discord\ext\commands\bot.py", line 1285, in get_context
if origin.author.id == self.user.id: # type: ignore
AttributeError: 'NoneType' object has no attribute 'id'
i just want a command with the prefix '$' and sends back the args sent by the user
i probably did something stupid but still thanks.
You only need the bot instance, client is unnecessary. CommandsBot is just upgraded discord.Client and also includes the #bot.event decorator
remove client.close() and move bot.process_commands(message) to the bottom of your on_message function
*Note you should not be doing anything else than prints in on_ready since that fires multiple times

How can I ignore the ctx argument from discord.py?

Here is the full script:
from discord.ext.commands import Bot
import tracemalloc
tracemalloc.start()
client = Bot(command_prefix='$')
TOKEN = ''
#client.event
async def on_ready():
print(f'Bot connected as {client.user}')
#client.command(pass_context=True)
async def yt(ctx, url):
author = ctx.message.author
voice_channel = author.voice_channel
vc = await client.join_voice_channel(voice_channel)
player = await vc.create_ytdl_player(url)
player.start()
#client.event
async def on_message(message):
if message.content == 'play':
await yt("youtubeurl")
client.run(TOKEN)
When I run this script, it works fine. When I type play in the chat, I get this error:
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "C:\Users\user\bot.py", line 26, in on_message
await yt("youtubeurl")
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 374, in __call__
return await self.callback(*args, **kwargs)
TypeError: yt() missing 1 required positional argument: 'url'
How do I fix this? So far all I have tried is added the argument * between ctx and url, which didn't fix it
It is not possible to "ignore" the context argument, why are you invoking the command in the on_message event?
You can get the context with Bot.get_context
#client.event
async def on_message(message):
ctx = await client.get_context(message)
if message.content == 'play':
yt(ctx, "url")
I'm guessing your commands aren't working cause you didn't add process_commands at the end of the on_message event
#client.event
async def on_message(message):
# ... PS: Don't add the if statements for the commands, it's useless
await client.process_commands(message)
Every command should be working from now on.
Reference:
Bot.get_context
Bot.process_commands

Discord Python: Adding a role to a member

My bot checks whenever a user is added to a guild on Discord and then privately DMs them for their email address. It then sends a one-time code to the email address and asks the user to enter the code in the DM. All this is implemented and works. However, when the user answers with the code, I cannot seems to be able to assign a new role to the user. Here is what I currently have (I removed the code that checks the one-time code, etc. as it works and does not seem to be the source of the problem):
import discord
from discord.ext import commands
from discord.utils import get
#client.event
async def on_message(message):
# Check if message was sent by the bot
if message.author == client.user:
return
# Check if the message was a DM
if message.channel.type != discord.ChannelType.private:
return
user_code = 'some code sent via email'
if message.content == user_code:
member = message.author
new_guild = client.get_guild(int(GUILD_ID))
role = get(new_guild.roles, id=DISCORD_ROLE)
await member.add_roles(role)
response = "You can now use the Discord Server."
await message.channel.send(response)
Here is the error I receive:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/discord/client.py", line 312, in _run_event
await coro(*args, **kwargs)
File "main.py", line 89, in on_message
await member.add_roles(role)
AttributeError: 'User' object has no attribute 'add_roles'
For that, you need to transform the User object into a Member object. That way, you can call the add_roles method. Here is one way of doing it:
import discord
from discord.ext import commands
from discord.utils import get
#client.event
async def on_message(message):
# Check if message was sent by the bot
if message.author == client.user:
return
# Check if the message was a DM
if message.channel.type != discord.ChannelType.private:
return
user_code = "some code sent via email"
if message.content == user_code:
new_guild = client.get_guild(int(GUILD_ID))
member = new_guild.get_member(message.author.id)
role = new_guild.get_role(int(DISCORD_ROLE))
await member.add_roles(role)
response = "You can now use the Discord Server."
await message.channel.send(response)

Command raised an exception: NameError: name 'challenge_player' is not defined

Me and my friend are trying to make a minigame kind of discord bot. I am trying to make a challenge command that takes the id of the user-specified and asks whether they want to accept or not.
#imports
import discord
from discord.ext import commands
#DISCORD PART#
client = commands.Bot(command_prefix = '-')
#client.event
async def on_ready():
print(f'We have logged in as {client.user}')
#client.command()
async def challenge(ctx, member: discord.Member = None):
if not member:
await ctx.send("Please specify a member!")
elif member.bot:
await ctx.send("Bot detected!")
else:
await ctx.send(f"**{member.mention} please respond with -accept to accept the challenge!**")
challenge_player_mention = member.mention
challenge_player = member.id
#client.command()
async def accept(ctx):
if ctx.message.author.id == challenge_player:
await ctx.send(f"{challenge_player_mention} has accepted!")
else:
await ctx.send("No one has challenged you!")
#client.event
async def on_message(message):
print(f"{message.channel}: {message.author}: {message.author.name}: {message.content}")
await client.process_commands(message)
client.run("token")
Everything is working fine except for the accept command.
Here is the error:
Traceback (most recent call last):
File "C:\Users\impec\AppData\Local\Programs\Python\Python37\lib\site-packages\discord\ext\commands\core.py", line 83, in wrapped
ret = await coro(*args, **kwargs)
File "c:/Users/impec/Downloads/bots/epic gamer bot/epic_gamer.py", line 30, in accept
if ctx.message.author.id == challenge_player:
NameError: name 'challenge_player' is not defined
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\impec\AppData\Local\Programs\Python\Python37\lib\site-packages\discord\ext\commands\bot.py", line 892, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\impec\AppData\Local\Programs\Python\Python37\lib\site-packages\discord\ext\commands\core.py", line 797, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\impec\AppData\Local\Programs\Python\Python37\lib\site-packages\discord\ext\commands\core.py", line 92, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: NameError: name 'challenge_player' is not defined
I cannot understand what I am doing wrong.
challenge_player is defined locally, in the challenge function so you can access it from the accept function.
You need to declare challenge_player outside of your function and add global challenge_player inside your functions, same thing with challenge_player_mention:
import discord
from discord.ext import commands
challenge_player, challenge_player_mention = "", ""
client = commands.Bot(command_prefix = '-')
#client.event
async def on_ready():
print(f'We have logged in as {client.user}')
#client.command()
async def challenge(ctx, member: discord.Member = None):
global challenge_player, challenge_player_mention
if not member:
await ctx.send("Please specify a member!")
elif member.bot:
await ctx.send("Bot detected!")
else:
await ctx.send(f"**{member.mention} please respond with -accept to accept the challenge!**")
challenge_player_mention = member.mention
challenge_player = member.id
#client.command()
async def accept(ctx):
global challenge_player, challenge_player_mention
if ctx.message.author.id == challenge_player:
await ctx.send(f"{challenge_player_mention} has accepted!")
else:
await ctx.send("No one has challenged you!")
#client.event
async def on_message(message):
print(f"{message.channel}: {message.author}: {message.author.name}: {message.content}")
await client.process_commands(message)
client.run("token")
PS: Don't share your bot token on internet! Anyone could access your bot with it and do whatever they want with it. You should generate another one and use it.

Discord.py Module Python 3.6.4 kick feature

I was making a discord bot using the discord module in python... I am having a lot of trouble trying to make the kick command work. I tried using bot.kick, client.kick and ctx.kick but they all give the same error which says,
Ignoring exception in command kick:
Traceback (most recent call last):
File "C:\Users\user\AppData\Roaming\Python\Python36\site-packages\discord\ext\commands\core.py", line 62, in wrapped
ret = yield from coro(*args, **kwargs)
File "C:\Users\user\Desktop\Code\bot.py", line 44, in kick
await client.kick(user)
AttributeError: 'Client' object has no attribute 'kick'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\user\AppData\Roaming\Python\Python36\site-packages\discord\ext\commands\bot.py", line 886, in invoke
yield from ctx.command.invoke(ctx)
File "C:\Users\user\AppData\Roaming\Python\Python36\site-packages\discord\ext\commands\core.py", line 493, in invoke
yield from injected(*ctx.args, **ctx.kwargs)
File "C:\Users\user\AppData\Roaming\Python\Python36\site-packages\discord\ext\commands\core.py", line 71, in wrapped
raise CommandInvokeError(e) from e
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'Client' object has no attribute 'kick'
I tried searching various different youtube videos and posts related to the problem I am having but nobody seems to be having a solution. I have written the code below. If you spot any errors which I missed please let me know.
import time
import random
import discord
import asyncio
from discord.ext import commands
#Initialize
client = discord.Client()#Creates Client
bot = commands.Bot(command_prefix='!')#Sets prefix for commands(!Command)
#bot.event
async def on_ready():
print('Name:', end=' ')
print(bot.user.name)
print('ID: ')
print(bot.user.id)
#bot.command(pass_context=True)
async def user_info(ctx, user: discord.Member):
await ctx.send(f'The username of the user is {user.name}')
await ctx.send(f'The ID of the user is {user.id}')
await ctx.send(f'The status of the user is {user.status}')
await ctx.send(f'The role of the user is {user.top_role}')
await ctx.send(f'The user joined at {user.joined_at}')
#bot.command(pass_context=True)
async def kick(ctx, user: discord.Member):
await ctx.send(f'The Kicking Hammer Has Awoken! {user.name} Has Been Banished')
await client.kick(user)
bot.run('SECRET')
client.run('SECRET')
You appear to be using the newer discord.py 1.0, also called the rewrite branch. You should read this, which is the documentation of the many breaking changes that were made in that switch. You should also refer solely to that documentation, as most documentation for the older 0.16 version is not compatible.
Many things were moved out of Client and into places that made a little more sense. Specifically, kick is now a method of Guilds.
import asyncio
from discord.ext import commands
bot = commands.Bot(command_prefix='!')
#bot.event
async def on_ready():
print('Name:', end=' ')
print(bot.user.name)
print('ID: ')
print(bot.user.id)
#bot.command(pass_context=True)
async def user_info(ctx, user: discord.Member):
await ctx.send(f'The username of the user is {user.name}')
await ctx.send(f'The ID of the user is {user.id}')
await ctx.send(f'The status of the user is {user.status}')
await ctx.send(f'The role of the user is {user.top_role}')
await ctx.send(f'The user joined at {user.joined_at}')
#bot.command(pass_context=True)
async def kick(ctx, user: discord.Member):
await ctx.send(f'The Kicking Hammer Has Awoken! {user.name} Has Been Banished')
await ctx.guild.kick(user)
bot.run('secret')
Note that I've also removed all references to client in the above. Bot is a subclass of Client, so you can access all the Client methods through Bot.

Categories