机器人响应频道提及

Bot responding to channel mentions

我最近一直在尝试在 python 中开发一个 discord 机器人。我这样做是为了如果一条消息包含某个数字,它会做出反应并发送一条消息。这是 cog 文件中的代码:

import discord

from discord.ext import commands
    
nice_numbers = ['69', '420']
    
class Auto(commands.Cog):
    def __init__(self, client):
        self.client = client
      
    @commands.Cog.listener()
    async def on_message(self, message):
        
        msg = message.content
    
        if message.author == self.client.user:
             return
    
        if any (word in msg for word in nice_numbers):
             await message.add_reaction('')
             await message.channel.send(f'lmao nice')
        
    
def setup(client):
    client.add_cog(Auto(client))

问题是,当用户提到某个频道(在本例中为#general、#super-private-testing 和#resources)时,机器人也会以相同的消息和反应进行响应。我似乎无法修复它或弄清楚为什么会这样。我对 python 还是很陌生,所以有人可以告诉我我做错了什么吗?

基本上发生的事情是 提及 在 Discord API 中有一个特殊的语法,它们基本上是一堆数字放在一起。

例如,当您提及另一个 用户 时,如下所示:

Hello @User1234!

discord 消息中的真实语法如下:

Hello <@125342019199458000>!

在提到频道的情况下,它的工作原理类似,就像提到的频道一样:

#general

内部会写成:

<#550012071928922144>

当然,问题是在这个大数字中,可能会误报找到您的 nice_numbers。可能有不同的方法来避免这种情况,例如,您可以检查 中是否提到了 channeluser在这种情况下,消息 和 return。

if message.channel_mentions or message.mentions:
    return

我认为更好的解决方案是改变检查 nice_numbers 是否在 message.content.

范围内的方式

如果 message.content 还包括 'My favourite number is 45669',则使用 if word in msg 将 return true。要克服这个问题,最好使用 regular expressions.

您可以像 this answers 解释的那样声明一个新函数,如果找到您作为参数传递的内容,它将 return 一个 <match object>

会是这样的:

import re

def findCoincidences(w):
    return re.compile(r'\b({0})\b'.format(w)).search

findCoincidences('69')('I like 69')    # -> return <match object>
findCoincidences('69')('My favourite number is 45669')                   # -> return None

扩展 , you can use message.clean_content 而不是 message.content

A property that returns the content in a “cleaned up” manner. This basically means that mentions are transformed into the way the client shows it. e.g. <#id> will transform into #name.

This will also transform @everyone and @here mentions into non-mentions.

这将防止您无意中匹配频道、用户、角色等 ID。当然,如果实际名称包含 nice_number,它仍然会匹配。