I have an authorization system on my server. When member reacts to message, he's getting access to stuff like chats etc. I want bot to remove reaction left by member, so number of reactions on the message will always=1
#client.event
async def on_raw_reaction_add(payload):
message=payload.reaction.message
if payload.channel_id==804320454152028170:
if str(payload.emoji) == '✅':
await message.remove_reaction("✅", payload.member)
else:
return
When I am leaving reaction under the message, I am getting this error:
message=payload.reaction.message
AttributeError: 'RawReactionActionEvent' object has no attribute 'reaction'
Ignoring exception in on_message
Read your error message! Looking at the docs you can easily find out that payload simply does not have such attribute.
To get a message from payload you will need to do something like this
guild = client.get_guild(payload.guild_id)
channel = guild.get_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
Related
so i was trying to find a way to have a message deleted if it contained bad words (i mean by finding i just copied some code)
#client.event
async def on_message(message):
if message.author.id == client.user.id:
return
msg_content = message.content.lower()
curseWord = ["cursewords i put"]
if any(word in msg_content for word in curseWord):
await message.delete()
msg = "**`Watch your mouth boiii`**"
await message.channel.send(msg)
await message.msg.add_reaction("⚠")
i was trying to add a reaction to the message but i said
'Message' object has no attribute msg
The error probably also points you to the line
await message.msg.add_reaction("⚠")
As the message says message doesn't have an attribute called msg. You can use add_reaction directly on your message object.
await message.add_reaction("⚠")
But message is referring to the message that you deleted, so you don't want to add a reaction to that message. Instead, to add the reaction to the message you just sent you need to get that message object and use it. To get it, when you did message.channel.send the message object was sent back, we just need to save it.
sent_msg = await message.channel.send(msg)
And now we can use it to add a reaction. Altogether that looks like
if any(word in msg_content for word in curseWord):
await message.delete()
msg = "**`Watch your mouth boiii`**"
sent_msg = await message.channel.send(msg)
await sent_msg.add_reaction("⚠")
Combining a user reacting with sending them a DM has had me stumped.
My project works by having an embed that has a reaction added at the bottom and when the user clicks the emoji then it will DM the user a set of instructions (for now I'm just using the word 'Test').
Here is what I have so far:
#client.event
async def on_message(message):
if message.content.startswith('.add'):
embed = discord.Embed(title="Embed Title", color=0x6610f2)
embed.add_field(name="__**Steps to get DM'd:**__", value="""
• Step 1
• Step 2
• Step 3
• Step 4
• Step 5
""")
msg = await message.channel.send(embed=embed)
await msg.add_reaction('\U0001F91D')
#client.event
async def on_raw_reaction_add(payload):
if payload.user_id == client.user.id:
return
if str(payload.emoji) == '\U0001F91D':
channel = await client.fetch_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
await message.author.send('Test')
I'm just not sure how to get the user's ID outside of the on_message() function because the only way I know how to make the on_reaction_add work is in its own client event. I'm not even sure if I'm handling the DM user aspect correctly.
Using the async version of Discord.py
In your payload, you should already get a discord.Member object you can work with. Try something like
#client.event
async def on_raw_reaction_add(payload):
if str(payload.emoji) == "\U0001F91D":
member = payload.member
await member.send('This is a DM to you!')
Because your code does not check for the message id, a reaction to ANY message (not just the one you sent) will lead to a response. To prevent this, you can check whether payload.message_id matches the id of your bot's message (which you could store somewhere when sending the message).
You also tried to prevent a response to the initial reaction of your bot. Instead of checking for payload.user_id, I would suggest
if member.bot:
return
which prevents a response to any bot reacting to your message, including your own.
If the code is correct, I want to make a bot where the bot invites me to a specific server.
but it has error.
Here's my code:
#client.command()
async def invite(ctx, *, code):
if code == "12320001":
guild = "851841115896152084"
invite = await ctx.guild.create_invite(max_uses=1)
await ctx.send(f"Here's your invite : {invite}")
else:
await ctx.send(f"Code is wrong!")
and error:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'create_invite'
ctx.guild is None, that is why you are getting this Exception.
You can check the value of ctx.guild before passing ctx as a parameter while calling invite function.
As the error suggests, ctx.guild is None. This usually occurs when invoking a command in a DM rather than in a server, as there obviously is no server in DMs.
Judging by the fact that you have a guild variable that you never used I assume that you're trying to invite people to that guild instead.
# Make sure the id is an int, NOT a string
guild = client.get_guild(85184111589615208)
# Invite users to the guild with the above id instead
invite = await guild.create_invite(max_uses=1)
You need a Channel object to create an invite as the Guild class doesn't have a create_invite() method. You can the code given below. Note that the server should have at least one channel.
#client.command()
async def invite(ctx, code):
if code == "12320001":
guild = client.get_guild(851841115896152084)
invite = await guild.channels[0].create_invite(max_uses = 1)
await ctx.send(f"Here's your invite: {invite}")
else:
await ctx.send("Invalid code!")
I want to know how to get a message content (specifically the embeds) from the message id? Just like you can get the member using a member id
on_raw_reaction_add() example:
#bot.event
async def on_raw_reaction_add(payload):
channel = bot.get_channel(payload.channel_id)
msg = await channel.fetch_message(payload.message_id)
embed = msg.embeds[0]
# do something you want to
Command example:
#bot.command()
async def getmsg(ctx, channel: discord.TextChannel, msgID: int):
msg = await channel.fetch_message(msgID)
await ctx.send(msg.embeds[0].description)
In the command I'm passing in channel and msgID, so a sample command execution would like !getmsg #general 112233445566778899 - the channel must be in the same server that you're executing the command in!
Then I'm getting the message object using the fetch_message() coroutine, which allows me to get a list of embeds in said message. I then choose the first, and only, embed by choosing position index 0.
After that, the bot then sends the description (or whatever attribute you'd like) of the embed.
References:
discord.TextChannel
TextChannel.fetch_message()
Message.embeds
discord.Embed - This is where you can find the different attributes of the embed
commands.command() - Command decorator
on_raw_reaction_add()
discord.RawReactionActionEvent - The payload returned from the reaction event
RawReactionActionEvent.message_id - The ID of the message which was reacted to
RawReactionActionEvent.channel_id - The text channel that the reaction was added in
i want send messages to all channel that bot has joined
def check(cnt):
while 1:
if hash_origin != str(subprocess.check_output(["md5sum",filename])[:-len(filename)-3])[2:-1] :
print("file destroyed alert!")
alert = 1
sleep(0.5)
i want send message to all discord channel that bot joined when specific file's hash result is different from original.
i know how to send respond message to channel
#client.event
async def on_message(message):
using this code, right?
but i want to send message to all of the channel that bot has joined when some event has happens.
In order to send a message to every channel that the bot is in, you must do:
#client.event
async def foo(bar): # change this to the event in which you wish to call it from
for guild in client.guilds:
for channel in guild.channels:
await channel.send(messagedata) # change messagedata to whatever it is you want to send.
#client.event
async def foo(bar): # change this to the event in which you wish to call it from
for guild in client.guilds:
for channel in guild.channels:
await channel.send(messagedata) # change messagedata to whatever it is you want to send.
when using this code directly, error has occurred
AttributeError: 'CategoryChannel' object has no attribute 'send'
because "guild.channels" object have list of "all channels"(including text,voice,etc..) that bot has joined.
so, if i want send text message to channel, using "guild.text_channels" instead.
anyway, thanks to Tylerr !!