I'm trying to build a discord bot for reaction roles. To do this, I'm trying to use the on_reaction_add combined with fetch_message to check if the reaction added was to the message that the bot sent but I keep getting various error with fetch_message. Here is the code:
#bot.command()
async def createteams(ctx):
msg = await ctx.send("React to get into your teams")
await msg.add_reaction("1️⃣")
await msg.add_reaction("2️⃣")
await msg.add_reaction("3️⃣")
await msg.add_reaction("4️⃣")
await msg.add_reaction("5️⃣")
await msg.add_reaction("6️⃣")
await msg.add_reaction("7️⃣")
await msg.add_reaction("8️⃣")
#bot.event
async def on_reaction_add(reaction, user):
id = reaction.message.id
if await reaction.message.author.fetch_message(reaction.message.id) == "React to get into your teams":
print("Success")
This gives me the error
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 "hypixel.py", line 60, in on_reaction_add
fetch = await reaction.message.author.fetch_message(id)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/discord/abc.py", line 955, in fetch_message
channel = await self._get_channel()
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/discord/member.py", line 243, in _get_channel
ch = await self.create_dm()
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/discord/member.py", line 109, in general
return getattr(self._user, x)(*args, **kwargs)
AttributeError: 'ClientUser' object has no attribute 'create_dm'
But when I go and copy the ID of the message I reacted to, its the same as the printed variable id but it still says Message Not Found
Thanks
I figured out the issue, you can't use fetch_message with user it needs to be channel so I changed my code to
await reaction.message.channel.fetch_message(id)
and it worked :)
Related
Alright I am trying to create a command where the user does (prefix)requestrole discordid roleid. It then sends a request embed to a channel where certain roles can view that channel and they can click on either the checkmark reaction or the 'x' reaction to accept or deny the role request.
#commands.command()
async def requestrole(self, ctx, discordid, roleid):
discordid = int(discordid)
roleid = int(roleid)
userid = ctx.author.id
channel = self.bot.get_channel(FILLWITHCHANNELID)
guild = ctx.guild
user = ctx.author
role = get(guild.roles, id=roleid)
embed = discord.Embed(title="Role Request", description=f"{user} requested {role} for {userid}", color=0x00ff00)
await channel.send(embed=embed)
message = await embed.send(embed=embed)
await message.add_reaction("✅")
await message.add_reaction("❌")
#self.bot.event
async def on_reaction_add(reaction, user):
if reaction.emoji == "✅":
user = reaction.message.author
guild = reaction.message.guild
role = get(guild.roles, id=roleid)
await user.add_roles(role)
await channel.send(f"{user} has been given {role}")
elif reaction.emoji == "❌":
await reaction.message.send("Role request denied")
This is the error I am now receiving
Ignoring exception in command requestrole:
Traceback (most recent call last):
File "C:\Users\name\AppData\Roaming\Python\Python310\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\name\Documents\GitHub\PRP-Bot\cogs\role_cog.py", line 31, in requestrole
message = await embed.send(embed=embed)
AttributeError: 'Embed' object has no attribute 'send'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\name\AppData\Roaming\Python\Python310\site-packages\discord\ext\commands\bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\name\AppData\Roaming\Python\Python310\site-packages\discord\ext\commands\core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\name\AppData\Roaming\Python\Python310\site-packages\discord\ext\commands\core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'Embed' object has no attribute 'send'
My question particularly is what is causing the error, and how do I properly code it so a person can basically click on the reaction checkmark to add the role, or click the x to remove the role.
you are trying to send a message to an Embed. That's not how Embeds work. you can send a message to a channel but not to a Embed. Just remove the line message = await embed.send(embed=embed) and you should be fine
I intend, if you send the bot a certain DM that it then gives a role on a certain server.
This is my code what I tried:
#bot.event
async def on_message(message):
if message.author.bot:
return
elif message.content.startswith("++neunundvierzig++"):
role = message.author.guild.get_role(861543456908640298)
guild = bot.get_guild(816021180435529758)
await message.channel.send("Erfolgreich Zerifiziert!")
await member.add_roles(role)
It says in the log:
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\aaa12\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "f:\HTML CSS JS Py Projekte\Python\bot_check\bot.py", line 36, in on_message
role = message.author.guild.get_role(861543456908640298)
AttributeError: 'User' object has no attribute 'guild'
I think you defined role wrong. Your code says that message.author.guild doesn't exist, so you should try message.guild.
Like this:
role = message.guild.get_role(861543456908640298)
Aside from that, you don't defined member. Just rename it to await message.author.add_roles(role) instead of await member.add_roles(role)
Sources
Discord Messages
Hey I started coding lately, now i want to do a Discord bot who can join a Voice Chanel. When i execute this:
BOT_PREFIX = '%'
bot = commands.Bot(command_prefix=BOT_PREFIX)
#bot.commmands(pass_context=True, aliases=['j', 'joi'])
async def join (ctx):
channel = ctx.message.author.voice.channel
voicechannel = await channel.connect()
after this Error shows up:
Traceback (most recent call last):
File "C:\DEV\Python\Einführung\venv\lib\site-packages\discord\client.py", line 333, in _run_event
await coro(*args, **kwargs)
File "C:/DEV/Python/pythonProject1/venv/Discord Bot/Bot.py", line 23, in on_message
#bot.commmands(pass_context=True, aliases=['j', 'joi'])
AttributeError: 'Bot' object has no attribute 'commmands'
Its #bot.command() not #bot.commands. Commands cannot be used in the case here.
Also Can Do
channel = ctx.author.voice.channel Rather than ctx.message.author.voice.channel
and Passing a variable for await channel.connect() is not needed .
I've been looking for a good few hours, and I've found nothing on why this isn't working for me.
Here's my code:
#bot.command()
async def ticket(ctx):
name = "tickets"
category = discord.utils.get(ctx.guild.categories, name=name)
guild = ctx.message.guild
ticket_id = randint(0, 100)
ticket_channel = await guild.create_text_channel(f"ticket-0{ticket_id}", category=category)
embed = discord.Embed(title="Tickets", description="Support will be with you shortly.\nTo close this ticket, react with :lock:.")
await ticket_channel.send(embed=embed)
await bot.add_reaction(embed, emoji=":lock:")
while True:
await bot.wait_for_reaction(emoji="\N{LOCK}", message=embed)
await bot.delete_channel(ticket_channel)
This is the error I get:
Ignoring exception in command ticket:
Traceback (most recent call last):
File "/home/runner/.local/share/virtualenvs/python3/lib/python3.7/site-packages/discord/ext/commands/core.py", line 83, in wrapped
ret = await coro(*args, **kwargs)
File "main.py", line 40, in ticket
await bot.add_reaction(embed, emoji=":lock:")
AttributeError: 'Bot' object has no attribute 'add_reaction'
Any help is resolving this issue, is much appreciated.
add_reaction is a method of the Message class, not Bot. Embed does not subclass Message. To get the Message object associated with the Embed you need to store the return value of channel.send(embed=...)
message = await ticket_channel.send(embed=embed)
await message.add_reaction('\N{LOCK}')
I'm trying to get the bot to send a message every few seconds from a set of predefined messages.
import discord
import asyncio
import random
client = discord.Client()
async def background_loop():
await client.wait_until_ready()
while not client.is_closed:
channel = client.get_channel("channel id here")
messages = ["Hello!", "How are you doing?", "Howdy!"]
await client.send_message(channel, random.choice(messages))
await asyncio.sleep(120)
client.loop.create_task(background_loop())
client.run("discord token here")
But when i try too run it, i get this error in the console and no messages are sent into the chat.
/usr/bin/python3.5 /root/PycharmProjects/untitled/Loop.py
Task exception was never retrieved
future: <Task finished coro=<background_loop() done, defined at /root/PycharmProjects/untitled/Loop.py:8> exception=InvalidArgument('Destination must be Channel, PrivateChannel, User, or Object. Received NoneType',)>
Traceback (most recent call last):
File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step
result = coro.send(None)
File "/root/PycharmProjects/untitled/Loop.py", line 13, in background_loop
await client.send_message(channel, random.choice(messages))
File "/usr/local/lib/python3.5/dist-packages/discord/client.py", line 1145, in send_message
channel_id, guild_id = yield from self._resolve_destination(destination)
File "/usr/local/lib/python3.5/dist-packages/discord/client.py", line 289, in _resolve_destination
raise InvalidArgument(fmt.format(destination))
discord.errors.InvalidArgument: Destination must be Channel, PrivateChannel, User, or Object. Received NoneType
I fixed this by writing a helper function to get the Channel object from the client
def get_channel(channels, channel_name):
for channel in client.get_all_channels():
print(channel)
if channel.name == channel_name:
return channel
return None
client = discord.Client()
general_channel = get_channel(client.get_all_channels(), 'general')
await client.send_message(general_channel, 'test msg')