How to use MessageType - discord.py

so I am trying to make the bot do something when the premium_guild_subscription message comes. I have tried:
#bot.event
async def on_message(message):
MessageType = discord.MessageType
if MessageType == 'pins_add':
await message.channel.send('ITS WORKING!!!')
but its not working. The above code does nothing when the message comes. If I do message.MessageType then it says that message object has no attribute MessageType.

You need to use an instance of a class and compare that to see if it's the correct type, not comparing the class itself to a string.
#bot.event
async def on_message(message):
if message.type == discord.MessageType.pins_add:
await message.channel.send('ITS WORKING!!!')
A further example:
#bot.command()
async def test(ctx):
print(ctx.message.type == discord.MessageType.pins_add)
print(ctx.message.type == discord.MessageType.default)
Results in
!test
> False
> True

In your code, you're trying to use class. You have to call the init function from that class. So you need to access a MessageType type data from message.
According to API References, you can use message.type to access MessageType object. Then you can check if a message is pins_add type with message.type.pins_add.
#bot.event
async def on_message(message):
if message.type == discord.MessageType.pins_add:
await message.channel.send('ITS WORKING!!!')

Related

Discord.py: How do I use #commands.check on an on_message event

I am trying to get the bot to send an emoji when someone else sends one. I have managed to get this to work, but when I use #commands.check to make sure the bot is not responding to itself, it responds anyway and the bot gets stuck in a loop of replying to itself.
def is_it_me_event(message):
if message.author.id == 1234567890:
return False
#commands.Cog.listener("on_message")
#commands.check(is_it_me_event)
async def on_message(self, message):
if str(message.content) == ":smile:":
await message.channel.send(":smile:")
I know I can do this with an if statement inside the function itself, but is there a way of doing this with the commands.check decorator or is this not compatible with functions that aren't commands?
As you suspected, you can't decorate your on_message function with a #commands.check(...) because it isn't a command. However, you can set up a predicate for these events:
def check_author_isnt_self():
def decorator(func):
async def wrapper(message):
return message.author.id != 1234567890:
# or `return message.author.id != self.bot.id` as better practice
return wrapper
return decorator
#commands.Cog.listener("on_message")
#check_author_isnt_self()
async def smile_back(self, message):
if str(message.content) == ":smile:":
await message.channel.send(":smile:")
I got it to work:
def check_author_isnt_self(func):
async def decorator(ctx, *args, **kwargs):
message = args[0]
if message.author.id != 1234567890:
await func(ctx, message)
decorator.__name__ = func.__name__
sig = inspect.signature(func)
decorator.__signature__ = sig.replace(parameters=tuple(sig.parameters.values())[1:])
return decorator
#commands.Cog.listener("on_message")
#check_author_isnt_self
async def on_message(self, message):
if str(message.content) == ":smile:":
await message.channel.send(":smile:")
This article explains how this works: https://scribe.rip/#cantsayihave/decorators-in-discord-py-e44ce3a1aae5

Sending a message through discord.py after message edit check

I have a function that checks if 'your' is changed to 'you're' and I am having trouble having the bot send a message after this check. What is the proper way to do this? (I want this to apply to all channels.)
import discord
from discord.ext import commands
client = discord.Client()
bot = commands.Bot(command_prefix='$')
#client.event
async def on_ready():
print("We have logged in as {0.user}".format(client))
#client.event
async def on_message_edit(before,after):
if(before.content == "your" and after.content == "you're"):
# I want to send message here
client.run('Token') # I have my token here
Add ctx into the parameters (before,after,ctx), and
then put in await ctx.send("message") where you want your message to send.
the parameters before and after are of type discord.Message. discord.Message has an attribute channel, with which you can use the function send.
#client.event
async def on_message_edit(before, after):
if before.content == 'your' and after.content == "you're":
await before.channel.send(send_whatever_you_want)

How do I get bot to read mention?

If someone mentions me how do I get the bot to read that? like if someone mentions me I want the bot to say something back. How would I do that?
#client.event
me = '<#user_id>'
async def on_message(message):
member = message.author.id
if message.content == me:
await message.channel.send('my master will be back shortly')
else:
return
await client.process_commands(message)
You can use discord.Message.mentions. It returns a list of discord.Member that were mentioned in message.
#client.event
async def on_message(message):
me = message.guild.get_member(<user id>)
if me in message.mentions:
await message.channel.send('my master will be back shortly')
await client.process_commands(message)
Reference
discord.Message.mentions

Discord.py adding a role through reactions

I am using code that I found here.
But, I'm getting an error that the client object doesn't have the attribute send_message. I have tried message.channel.send but that failed as well.
#client.event
async def on_ready():
Channel = client.get_channel('YOUR_CHANNEL_ID')
Text= "YOUR_MESSAGE_HERE"
Moji = await client.send_message(Channel, Text)
await client.add_reaction(Moji, emoji='🏃')
#client.event
async def on_reaction_add(reaction, user):
Channel = client.get_channel('YOUR_CHANNEL_ID')
if reaction.message.channel.id != Channel:
return
if reaction.emoji == "🏃":
Role = discord.utils.get(user.server.roles, name="YOUR_ROLE_NAME_HERE")
await client.add_roles(user, Role)
One of the reasons why your code might not be working is because you may have your channel id stored in a string. Your code shows:
Channel = client.get_channel('YOUR CHANNEL ID')
The code above shows that your channel id is stored in a string, which it should not be. With the code above, your actual code may look like this:
Channel = client.get_channel('1234567890')
Instead you should have:
Channel = client.get_channel(1234567890)

The reaction-role function of my discord.py bot didn't function properly.. Why?

This is the code I got so far but for some reason, it doesn't really work...
async def on_ready():
Channel = client.get_channel('777877476558110737')
Text= "React to Verify"
Moji = await client.send_message(Channel, Text)
await client.add_reaction(Moji, emoji='🏃')
#client.event
async def on_reaction_add(reaction, user):
Channel = client.get_channel('777877476558110737')
if reaction.message.channel.id != Channel:
return
if reaction.emoji == "🏃":
Role = discord.utils.get(user.server.roles, name="12 Year Old")
await client.add_roles(user, Role)
Use Channel.send(Text) not client.send_message(Channel, Text) because send_message is not a method of client, but send is a method of Channel.
Use Moji.add_reaction("🏃") not client.add_reaction(Moji, emoji='🏃') because the add_reaction is a method of the Message class.
Change user.server.roles to user.guild.roles because server is not an attribute of the Member class, but guild is.
Use user.add_roles(Role) not client.add_roles(user, Role) because add_roles is a method of the Member class.
Make sure to reference the docs. You are calling many methods from the client when they are supposed to be called from other classes. Update discord.py to the latest version too.

Resources