Harjot
Harjot

Reputation: 943

How do I make the bot respond when someone mentions it? discord.py

Here is the code I've tried:

@client.event
async def on_message(message):
    if client.user.mention in message.content.split():
        await client.say("You can type `!vx help` for more info.")

But it doesn't seem to be working.

Upvotes: 5

Views: 19989

Answers (4)

1412 kaito
1412 kaito

Reputation: 11

@bot.event#ping reply
async def on_message(message):
  if message.author.bot == False and bot.user.mentioned_in(message) and len(message.content) == len(bot.user.mention)+1:
    await message.channel.send(f'Hello! I am the {bot.user.mention}!\nMy Prefix is $')
  else:
    await bot.process_commands(message)

The method is quite simple, in the bot.event the bot will read every message, check for the following

  1. That the ping is not from a different bot, it's from a user only
  2. That the bot has been mentioned in the message
  3. That only the bot has been mentioned, it avoids the accidental mention/ping in a convo. that +1 in length is for the newline character.

bot.process_commands(message) is there so that if it's not a ping then the bot can process the message/command further.

Upvotes: 1

TimN
TimN

Reputation: 101

Here is a similar solution using a class. I was having issues with the exact situation and eventually managed to solve it, but couldn't find any examples like this. The key is the if self.user in message.mentions: line.

message.mentions refers to a list of users so you can check for yourself or anyone else.

class MyClient(discord.Client):
    async def on_ready(self):
        print('Logged on as', self.user)

    async def on_message(self, message):
        # Don't respond to ourselves
        if message.author == self.user:
            return

        # If bot is mentioned, reply with a message
        if self.user in message.mentions:
            await message.channel.send("You can type `!vx help` for more info.")
            return

def main():
    client = MyClient()
    client.run(DISCORD_TOKEN)

if __name__ == "__main__":
    main()

Upvotes: 0

That Indian Dev
That Indian Dev

Reputation: 21

 @client.event async def on_message(message):
     if client.user.mention in message.content.split():
         await client.say("You can type `!vx help` for more info.")

Instead of content.split() use content: And instead of client.say use message.channel.send() so we will get

 @client.event
 async def on_message(message):
     if client.user.mention in message.content:
         await message.channel.send("You can type `!vx help` for more info.")

Upvotes: 2

Diggy.
Diggy.

Reputation: 6944

When using command decorators, you can do:

from discord.ext import commands # necessary for this task

client = commands.Bot(command_prefix=commands.when_mentioned_or("!"))

Or using an on_message() event, this is one of many ways you can check the mention:

@client.event
async def on_message(message):
    if client.user.mentioned_in(message):
        await message.channel.send("You can type `!vx help` for more info")

Also, I noticed your method of sending a message to the channel wasn't quite right.

In d.py rewrite (v1.x), you have an abc.Messageable object, which is something like a server's text channel, or a DM or a group chat, as the name implies.

And this object has a method called send() which allows you to send content. Some common instances where you'll be finding this would be; ctx.send() when you're using command decorators - they have Context as the first parameter - and message.channel.send() when you're using the on_message() event like you are. It will also appear in some other places, but these will be the most common.

You've got the right idea about it being a coroutine, and therefore needing to await it. In the documentation it'll state whether something is a coroutine or not.


References:

Upvotes: 10

Related Questions