I have a problem. How can I check which emoji the user reacted with? That did not work for me How do you check if a specific user reacts to a specific message [discord.py]
I want to check if the reaction is ✅ or ❌
folder structure
├── main.py
├── cogs
│ ├── member.py
The problem is that I don't get an error message. Nothing happens. As soon as I react with an emoji, nothing happens.
member.py
import discord
from discord.ext import commands
from datetime import datetime
class command(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.Cog.listener()
async def on_message(self, message):
...
...
for emoji in emojis:
await msg.add_reaction(emoji)
await message.author.send('Send me that ✅ reaction, mate')
def check(reaction, user):
return user == message.author and str(reaction.emoji) == '✅'
res = await self.bot.wait_for(
"reaction_add",
check=check, timeout=None
)
print(res.emoji)
if res.content.lower() == "✅":
await message.author.send("Got it")
else:
await message.author.send("Thanks")
confirmation = await self.bot.wait_for("reaction_add", check=check)
await message.author.send("You responded with {}".format(reaction.emoji))
async def setup(bot):
await bot.add_cog(command(bot))
import asyncio
import os
from dotenv import load_dotenv
import discord
from discord.ext import commands
from discord.ext.commands import has_permissions
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
import discord
from discord.utils import get
class MyBot(commands.Bot):
def __init__(self):
intents = discord.Intents.default()
intents.message_content = True
super().__init__(command_prefix=commands.when_mentioned_or('-'), intents=intents, max_messages=1000)
async def on_ready(self):
print(f'Logged in as {self.user} (ID: {self.user.id})')
async def setup_hook(self):
for file in os.listdir("./cogs"):
if file.endswith(".py"):
extension = file[:-3]
try:
await self.load_extension(f"cogs.{extension}")
print(f"Loaded extension '{extension}'")
except Exception as e:
exception = f"{type(e).__name__}: {e}"
print(f"Failed to load extension {extension}\n{exception}")
bot = MyBot()
bot.run(TOKEN)
You're using a function called check, and it doesn't exist - like your error is telling you. There's one in your class, but that isn't in the same scope so you can't just call it using its name.
To access a method in a class, use self.<name>.
Also, you should only pass the check function, not call it.
(..., check=self.check
EDIT the code in the original question was edited. You're not loading your cogs asynchronously. Extensions & cogs were made async in 2.0. Docs: https://discordpy.readthedocs.io/en/stable/migrating.html#extension-and-cog-loading-unloading-is-now-asynchronous
Put this code in your #commands.Cog.listener() decorator, and the code will work if your cogs loader is working. If you would like me to show you my cogs loader, I can.
accept = '✅'
decline = '🚫'
def check(reaction, user):
return user == author
messsage = await ctx.send("test")
await message.add_reaction(accept)
await message.add_reaction(decline)
reaction = await self.bot.wait_for("reaction_add", check=check)
if str(reaction[0]) == accept:
await ctx.send("Accepted")
elif str(reaction[0]) == decline:
await ctx.send("Denied")
Related
I want to receive information from the user from discord, but I don't know what to do.
I want to make a class to input data
if user write !make [name] [data], bot generate class A, A(name, data)
The following is the code I made. What should I do?
Ps. command_prefix is not working properly. What should I do with this?
`
import discord, asyncio
import char # class file
from discord.ext import commands
intents=discord.Intents.all()
client = discord.Client(intents=intents)
bot = commands.Bot(command_prefix='!',intents=intents)
#client.event
async def on_ready():
await client.change_presence(status=discord.Status.online, activity=discord.Game("Game"))
#client.event
async def on_message(message):
if message.content == "test":
await message.channel.send ("{} | {}, Hello".format(message.author, message.author.mention))
await message.author.send ("{} | {}, User, Hello".format(message.author, message.author.mention))
if message.content =="!help":
await message.channel.send ("hello, I'm bot 0.0.1 Alpha")
async def new_class(ctx,user:discord.user,context1,context2):
global char_num
globals()['char_{}'.format(char_num)]=char(name=context1,Sffter=context2,username=ctx.message.author.name)
char_num+=1
await ctx.message.channel.send ("done", context1,"!")
client.run('-')
`
I advice to not using on message for making commands
what I do advice:
import discord
from discord.ext import commands
#bot.command(name="name here if you want a different one than the function name", description="describe it here", hidden=False) #set hidden to True to hide it in the help
async def mycommand(ctx, argument1, argument2):
'''A longer description of the command
Usage example:
!mycommand hi 1
'''
await ctx.send(f"Got {argument1} and {argument2}")
if you will use the two ways together then add after this line
await message.channel.send ("hello, I'm bot 0.0.1 Alpha")
this:
else:
await bot.process_commands(message)
if you want to make help command u should first remove the default one
by editing this line bot = commands.Bot(command_prefix='!',intents=intents) to :
bot = commands.Bot(command_prefix='!',intents=intents,help_command=None)
overall code should look like
import discord, asyncio
import char # class file
from discord.ext import commands
intents=discord.Intents.all()
client = discord.Client(intents=intents)
bot = commands.Bot(command_prefix='!',intents=intents,help_command=None)
#client.event
async def on_ready():
await client.change_presence(status=discord.Status.online, activity=discord.Game("Game"))
#client.event
async def on_message(message):
async def new_class(ctx,user:discord.user,context1,context2):
global char_num
globals()['char_{}'.format(char_num)]=char(name=context1,Sffter=context2,username=ctx.message.author.name)
char_num+=1
await ctx.message.channel.send ("done", context1,"!")
#bot.command()
async def make(ctx,name,data):
#do whatever u want with the name and data premeter
pass
#bot.command()
async def help(ctx):
await ctx.send("hello, I'm bot 0.0.1 Alpha")
#bot.command()
async def test(ctx):
await ctx.send ("{} | {}, Hello".format(ctx.author, ctx.author.mention))
client.run('-')
and yeah if u want to know what is ctx
ctx is context which is default premeter and have some methods like send,author and more
I'm trying to get custom commands to work in my Discord server. But it doesn't work when I'm not using a decorator, and I do not know how to make it work within a class.
Please help.
(XXX.. just replaces an ID here)
Please have a look at add_my_commands() function. This one should be able to take the prefix and respond with the info. This doesn't work currently.
I have a main.py file which runs separately, as follows:
# Import discord.py
import discord
from discord.ext import commands
# Import Bot Token
from apikeys import *
# Import classes
from steward_bot import MyClient
intents = discord.Intents.default() # or .all() if you ticked all, that is easier
intents.message_content = True
intents.members = True # If you ticked the SERVER MEMBERS INTENT
# Initialize client
bot = MyClient(command_prefix="!", intents=intents)
bot.run(DISCORD_TOKEN)
The MyClient class:
class MyClient(commands.Bot):
def __init__(self, *args, command_prefix, **kwargs):
super().__init__(
*args, command_prefix=command_prefix, case_insensitive=True, **kwargs
)
self.target_message_id = XXXX
self.add_my_commands()
async def on_ready(self):
print("We have logged in as {0.user}".format(self))
print("---------------------------------------------")
async def on_member_remove(self, member):
channel = self.get_channel(XXXX)
await channel.send("Goodbye")
async def on_raw_reaction_add(self, payload):
"""
Give a role based on a reaction emoji
"""
if payload.message_id != self.target_message_id:
return
guild = self.client.get_guild(payload.guild_id)
print(payload.emoji.name)
print("Hello")
# Responding to messages
async def on_message(self, message):
if message.author == self.user:
return
if message.content == "Test":
await message.channel.send("Hey hey chill")
if message.content == "cool":
await message.add_reaction("\U0001F60E")
if message.content == "give me our prefix":
await message.channel.send(str(self.command_prefix))
await self.process_commands(message)
# Throws out reactions to messages
async def on_reaction_add(self, reaction, user):
await reaction.message.channel.send(f"{user} reacted with {reaction.emoji}")
def add_my_commands(self):
#self.command(name="info", pass_context=True)
async def info(ctx):
"""
ctx - context (information about how the command was executed)
info
"""
print(ctx)
await ctx.send("Hello X")
await ctx.send(ctx.guild)
await ctx.send(ctx.author)
await ctx.send(ctx.message.id)
Within the server, I want to run the command "!info" and get the information out. Would appreciate any help!
No need to define your entire bot within a class. Create a main.py file with your bot defined and import cogs from there. I'd also set up my commands through a cog with commands.command().
Example of how I'd go about adding an !info command:
main.py
import discord
from discord.ext import commands
from info import InfoCog
intents = discord.Intents.default()
intents.members = True
intents.guilds = True
intents.messages = True
intents.reactions = True
intents.presences = True
# Initialize client
bot = commands.Bot(command_prefix='!', intents=intents)
bot.add_cog(InfoCog(bot))
#bot.event
async def on_ready(self):
print("We have logged in as {0.user}".format(self))
print("---------------------------------------------")
bot.run(TOKEN)
info.py
import discord
from discord.ext import commands
class InfoCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.command()
async def info(self, ctx):
await ctx.send('Info')
Or, you could jumble everything into one file. This is how I used to do it with all my commands & events. It was easier to get the hang of at first.
main.py
# Import discord.py
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
intents.guilds = True
intents.messages = True
intents.reactions = True
intents.presences = True
bot = commands.Bot(command_prefix='!', intents=intents)
#bot.event
async def on_ready(bot):
print("We have logged in as {0.user}".format(bot))
print("---------------------------------------------")
# [...]
#bot.command()
async def info(ctx):
await ctx.send('info')
# [...]
#bot.event
async def on_message(message):
if message.author == bot.user:
return
if message.content == "give me our prefix":
await message.channel.send(str(bot.command_prefix))
if message.content == "Test":
await message.channel.send("Hey hey chill")
# [...]
#bot.event()
async def on_member_remove(member):
channel = bot.get_channel(CHANNELID)
await channel.send(f"Goodbye, {member}")
# [...]
bot.run(TOKEN)
Not sure that I need to use the both runs at the same time, but:
from multiprocessing.dummy.connection import Client
from telnetlib import DM
from typing_extensions import Required
import discord
from discord.utils import get
from discord.ext import commands
from dislash import InteractionClient, Option, OptionType
from dislash.interactions import *
client = discord.Client()
from message import *
#client.event
async def on_message(message):
if message.author == client.user:
return
User_id = message.author.id
if message.channel.id == 1009530463108476968:
NewMessage = message.content.split(' ', 1)[0]
LimitLenght = len(NewMessage) + 11
if len(message.clean_content) >= LimitLenght:
await message.delete()
await message.author.send("Hello, " + f"<#{User_id}>" + "\nPlease, don't send any messages that break the **Counting-game** rules!\nIt's forbidden to post a comment that is longer than 10 characters.")
# More code
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
bot = commands.Bot(command_prefix="!")
inter_client = InteractionClient(bot)
#inter_client.slash_command(name="help", description="Shows the help-menu")
async def help(ctx):
embedVar = discord.Embed(title="Test project", description="*The blue text is clickable.*\n⠀", color=0x0000ff)
embedVar.add_field(name="Rules", value='To see rules write **/Rules**\n⠀', inline=False)
await ctx.reply(embed=embedVar, delete_after=180)
bot.run('ToKeN')
client.run('ToKeN')
If you run this code and comment the "bot.run('ToKeN')", the first part of the code will work (def on_message), however the command '/help' will not work. If you change it (comment 'client.run('ToKeN')'), the command '/help' will work, but def on_message not.
What are the possible solutions? Thanks.
The .runs block each other and prevent from running. You shouldn't be using a client and a bot anyway. Use one commands.Bot instead. It subclasses a Client and it should be able to do everything you can do with the client.
bot = commands.Bot(command_prefix="!")
inter_client = InteractionClient(bot)
#bot.event
async def on_message(message):
...
#inter_client.slash_command(name="help", description="Shows the help-menu")
async def help(ctx):
...
bot.run(token)
i want to make a discord bot but i cant run it.
idk what to do
it just runs
and no log
idk REALLY what to do
import discord
from discord.ext import commands
import os
import keep_alive
client = commands.Bot(command_prefix="!")
token = os.environ.get('Token')
GUILD = os.environ.get('Guild')
async def on_ready():
print(f'{client.user} is connected')
#client.command()
async def dm(ctx, member: discord.Member):
await ctx.send('what do u want to say bitch!')
def check(m):
return m.author.id == ctx.author.id
massage = await client.wait_for('massage', check=check)
await ctx.send(f'send massage to {member} ')
await member.send(f'{ctx.member.mention} has a massage for you: \n {massage}')
#client.event
async def on_member_join(member):
channel = discord.util.get(member.Guild, name='general')
await channel.send(f'Hey welcome to my server {member.mention}, hope you enjoy this server!')
keep_alive.keep_alive()
client.run(token)
client.close()
i dont know what to do anymore
I tried everything i could i ran it in pycharm
vscode
nothing works
There's a lot of errors on your code. so I fixed it
First thing is your client events, keep_alive, client.run, also why did you put client.close()
import os, discord
import keep_alive
from discord.ext import commands
client = commands.Bot(command_prefix="!")
token = os.environ.get('Token')
GUILD = os.environ.get('Guild')
#client.event # You need this event
async def on_ready():
print(f'{client.user} is connected')
"""
client.wait_for('massage') is invalid. Changed it into 'message'. Guess it is a typo.
You can replace this command with the new one below.
"""
#client.command()
async def dm(ctx, member: discord.Member):
await ctx.send('what do u want to say bitch!')
def check(m):
return m.author.id == ctx.author.id
massage = await client.wait_for('message', check=check)
await ctx.send(f'send massage to {member} ')
await member.send(f'{ctx.member.mention} has a massage for you: \n {massage}')
"""
I also moved this on_member_join event outside because it blocks it.
"""
#client.event
async def on_member_join(member):
channel = discord.util.get(member.Guild, name='general')
await channel.send(f'Hey welcome to my server {member.mention}, hope you enjoy this server!')
"""
I put the keep_alive call outside because the function blocks it in your code.
And also removed client.close() to prevent your bot from closing
"""
keep_alive.keep_alive()
client.run(token)
For the dm command. Here it is:
#client.command()
async def dm(ctx, member:discord.Member=None):
if member is None:
return
await ctx.send('Input your message:')
def check(m):
return m.author.id == ctx.author.id and m.content
msg = await client.wait_for('message', check=check) # waits for message
if msg:
await member.create_dm().send(str(msg.content)) # sends message to user
await ctx.send(f'Message has been sent to {member}\nContent: `{msg.content}`')
Sorry, I'm kinda bad at explaining things, also for the delay. I'm also beginner so really I'm sorry
I made a discord bot with a main file and one other file of commands that are loaded with cogs and the problem is that the commands are not loaded.
I simplified the code triny to resolve the error but even this does not work:
bot.py:
import discord
from discord.ext import commands
import config
# declaring intents and launching client
intents = discord.Intents.default()
intents.members = True
intents.presences = True
bot = commands.Bot(command_prefix='.', description="Useful bot", intents=intents)
startup_extensions = ["private_channels"]
# listener
#bot.event
async def on_ready():
print(f'Connected to Discord as {bot.user} !')
#bot.event
async def on_message(message):
if message.author == bot.user:
return
print("message received")
# starting extensions
for extension in startup_extensions:
try:
bot.load_extension(extension)
except Exception as e:
exc = '{}: {}'.format(type(e).__name__, e)
print('Failed to load extension {}\n{}'.format(extension, exc))
# starting bot
bot.run(config.token)
private_channels.py:
from discord.ext import commands
class PrivateChannels(commands.Cog):
def __init__(self, bot):
self.bot = bot
# creates a new private channel
#commands.command(name="test")
async def test(self, ctx):
await ctx.send("test")
def setup(bot):
print("Loading private channels")
bot.add_cog(PrivateChannels(bot))
print("Private channels loaded")
Okay, the main problem that I had is that on_message event overwrites the commands. To correct that, I added await bot.process_commands(message) to on_message to process commands and now it works.