机器人响应频道提及
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。可能有不同的方法来避免这种情况,例如,您可以检查 中是否提到了 channel 或 user在这种情况下,消息 和 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
,它仍然会匹配。
我最近一直在尝试在 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。可能有不同的方法来避免这种情况,例如,您可以检查 中是否提到了 channel 或 user在这种情况下,消息 和 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
扩展 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
,它仍然会匹配。