Discord.py开发:reaction达标后未向moderation频道推送消息问题
问题排查
- 消息对象未更新:
asyncio.sleep(200)后使用的message仍是事件触发时的旧对象,不会自动同步200秒内新增的reaction数据,必须主动重新拉取最新的消息状态。 - reaction统计逻辑错误:
x = int是将x赋值为int类型本身,不是声明整数变量message.reactions.count(x)用法错误,该方法用于统计列表内指定元素的出现次数,无法统计reaction的数量- 你需要筛选出之前添加的自定义表情对应的reaction,再读取它的
count属性获取真实的反应数量
- 阈值与计数逻辑混乱:需求为2个及以上reaction,机器人本身已经添加了1个,只需判断指定表情的
count≥2即可(排除机器人自身的计数就是count-1≥1),原代码的≥3和x = x-1逻辑完全不成立。 - 未过滤机器人自身消息:没有跳过机器人自己发送的消息,可能出现重复触发的问题。
- 链接拼接易出错:手动拼接消息链接容易写错参数,直接使用discord.py内置的
jump_url属性更稳妥。
修复后代码
import discord import asyncio from discord.ext import commands # 请根据自己的实际配置修改以下常量 TARGET_EMOJI = "<:uut:828580756384120912>" WATCH_CHANNEL_ID = 828579458167996420 MOD_CHANNEL_ID = 892065611876823100 # 注意:discord.py v2.0及以上版本需要开启message_content intent intents = discord.Intents.default() intents.message_content = True client = commands.Bot(command_prefix="!", intents=intents) @client.event async def on_message(message): # 忽略所有机器人发送的消息,避免死循环 if message.author.bot: return # 仅处理指定频道的消息 if message.channel.id == WATCH_CHANNEL_ID: # 判断是否带附件或包含http if message.attachments or "http" in message.content: await message.add_reaction(TARGET_EMOJI) # 等待200秒 await asyncio.sleep(200) # 重新拉取最新的消息对象,获取实时reaction数据 fresh_msg = await message.channel.fetch_message(message.id) # 查找我们要统计的目标表情 target_reaction = None for reaction in fresh_msg.reactions: if str(reaction.emoji) == TARGET_EMOJI: target_reaction = reaction break # 满足阈值条件则发送到审核频道 if target_reaction and target_reaction.count >= 2: mod_channel = client.get_channel(MOD_CHANNEL_ID) user_like_count = target_reaction.count - 1 await mod_channel.send(f"this post {fresh_msg.jump_url} is liked {user_like_count} times.") # 如果你还有其他命令功能,保留这行保证命令正常触发 await client.process_commands(message) client.run("你的机器人Token")
额外注意事项
- 请在Discord开发者后台的机器人设置页开启
Message Content Intent权限,否则无法读取消息内容判断是否包含http。 - 长时间在
on_message里sleep会阻塞事件循环,高并发场景下建议改用discord.ext.tasks实现延迟任务,避免机器人卡顿。
内容的提问来源于stack exchange,提问作者CupQuakes
相关产品推荐
相关产品推荐

