我最近一直在尝试用 python 开发一个不和谐的机器人。我这样做是为了如果一条消息包含某个数字,它会做出反应并发送一条消息。这是 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 还是很陌生,所以有人可以告诉我我做错了什么吗?
答案 0 :(得分:3)
基本上发生的事情是提及在 Discord API 中有一种特殊的语法,它们基本上是一堆数字放在一起。
例如,当您提到另一个用户时,如下所示:
<块引用>你好@User1234!
discord 消息中的实际语法如下:
<块引用>你好 <@125342019199458000>!
在提到频道的情况下,它的工作方式类似,就像提到的频道一样:
<块引用>#general
内部会写成:
<块引用><#550012071928922144>
当然,问题是在这个大数字中,可能会误报您的nice_numbers。可以有不同的方法来避免这种情况,例如,您可以检查 channel 或 user 是否在 message 中被提及,然后返回那种情况。
if message.channel_mentions or message.mentions:
return
我认为更好的解决方案是改变您检查 nice_numbers 是否在 message.content
内的方式。
如果 if word in msg
还包含诸如'我最喜欢的数字是 45669' 之类的内容,则使用 true
将返回 message.content
。为了解决这个问题,最好使用 regular expressions。
您可以声明一个像 this answers 解释的新函数,如果找到您作为参数传递的内容,它将返回一个 <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
答案 1 :(得分:2)
在 Shunya's answer 上展开,您可以使用 message.clean_content
代替 message.content
:
以“清理”方式返回内容的属性。这基本上意味着提及被转换成客户展示它的方式。例如<#id> 将转换为 #name。
这也会将@everyone 和@here 的提及转换为不提及。
这将防止您无意中匹配频道、用户、角色等的 ID。当然,如果实际名称包含 nice_number
,它仍然会匹配。