How does @here work in discord? Can you implicitly mention members using discord.py?

Question:

After some research, I couldn’t find an answer:

1.- Is @here a role?

This was the first solution I thought in due to its similarity with @everyone, which is in fact a guild role. However, it doesn’t seems to be the same case as it, since @here doesn’t appear listed in the roles property of the Member class while @everyone does.

I checked it myself by printing every role of an (online) guild member (every intent was previously set to True):

@bot.command(name = "printMemberRoles")
async def printMemberRoles(ctx : commands.Context, user_id : int):
    member = ctx.guild.get_member(user_id)
    for role in member.roles:
        print(role.name, str(role.id))

I also checked if it appeared in the guild roles’ list:

@bot.command(name = "printGuildRoles")
async def printGuildRoles(ctx : commands.Context):
    for role in ctx.guild.roles:
        print(role.name, str(role.id))

In both cases, @everyone appeared, but @here didn’t.

I ended up discarding the idea… but should I? For instance, in this class both @everyone and @here are treated in the same way (both included in the same parameter -> everyone).


2.- Assuming it is not a role, how does Discord ping members online without explicitly mention them?

The next command pings every member of the guild that has access to the TextChannel where the command is being used, only if their status is not offline. However, members are explicitly mention (this is, @member1, @member2, etc.):

@bot.command(name = "fake_here")
async def fake_here(ctx : commands.Context):
    mentions = [member.mention for member in ctx.channel.members if member.status != discord.Status.offline]
    await ctx.send(" ".join(mentions))

Does discord obtain who to ping in a similar way, and then it encapsulates those mentions into a @here "decorator"?

I didn’t find any hint about how discord gets the @here "value" looking at the documentation. I couldn’t find any reference to @here in the on_message() event. Some paths I followed:

I couldn’t find any hint about it. Does on_message() triggers another event when the message’s content includes "@here" to look for who to ping? I couldn’t find a message, guild, member, channel or role event with that functionality.


Does discord obtain who to ping in a similar way, and then it encapsulates those mentions into a @here "decorator"?

If that is the case:

3.- Can you encapsulate a custom group of mentions into a "@mention decorator" using discord.py?

For instance, would your bot be able to send a message (as an interaction / command / event response) that pinged every member with at least 5 roles, under the "@many_roles" decorator (not a role)?


If you have an answer to any of the questions, please tell me. Thank you!

Asked By: Jabro

||

Answers:

Discord stores your unread mentions at the moment they’re invoked, rather than your client going through every message in every server ever & figuring out if it should show a ping or not (obviously – that wouldn’t be very practical).

There’s an easy way to verify this:
When you get pinged (while offline), and the message gets removed, your ping will still show up next time you log in, even though you can’t find the message anymore & you weren’t online at the moment the ping was issued. People often refer to this as a "ghost ping". Where does that ping come from? It was stored at the moment the message was sent.

Does discord obtain who to ping in a similar way, and then it encapsulates those mentions into a @here "decorator"?

When you send a message, Discord will go through it and figure out if you’re pinging anyone. Users, roles, whatever it may be. If that message happens to contain @here, it will just make Discord’s servers look at the users that are currently online, and send them a ping. Something like You got mentioned in [message]. (but then obviously in a DB row [user id] [message id] [read]), even though it actually contains @here instead.

The client doesn’t care how you’re mentioned – and it doesn’t have to. All it knows is that that message mentions you in some way. Is it @user? Is it @everyone? Is it @here? Is it @some_role? It literally doesn’t matter – the only thing that matters is that it managed to ping you somehow.

Discord.py knows who got pinged because the Discord API literally tells you in the Message object passed to on_message when a message is sent: https://discord.com/developers/docs/resources/channel#message-object-message-structure

mentions || array of user objects || users specifically mentioned in the message

This is the data the library receives straight from Discord itself. The library doesn’t populate the Message.mentions field by trying to parse your message to figure out who got mentioned based on roles or anything – Discord already provides the information in the event.

This should hopefully answer another question in the post:

I didn’t find any hint about how discord gets the @here "value" looking at the documentation. I couldn’t find any reference to @here in the on_message() event

You can’t find anything because there isn’t anything. The on_message event in Discord.py doesn’t do anything with @here because it doesn’t have to.

Can you encapsulate a custom group of mentions into a "@mention decorator" using discord.py?

For instance, would your bot be able to send a message (as an interaction / command / event response) that pinged every member with at least 5 roles, under the "@many_roles" decorator (not a role)?

No. You can’t do that. Roles are the closest you’ll get.

Answered By: stijndcl
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.