如何用disnake实现指定用户专属消息反应验证并存储消息ID?
解决方案:Disnake反应验证与消息ID存储优化
一、解决机器人自身反应触发的问题
你的代码里机器人添加反应时触发回复,是因为check函数没排除机器人自身。只需在判断条件里加上user != bot.user,就能过滤掉机器人的操作:
def check(reaction, user): return user == message.author and user != bot.user and str(reaction.emoji) in ["❌"] and reaction.message == message
二、用数据库存储并验证目标消息ID
如果需要长期监听特定消息的反应,建议用事件监听(而非一次性的wait_for),同时用数据库存储目标消息ID,验证反应对应的消息是否为目标消息。以下是SQLite实现示例:
1. 初始化数据库
先创建表存储消息ID:
import sqlite3 # 连接数据库(不存在则自动创建) conn = sqlite3.connect("reaction_messages.db") cursor = conn.cursor() # 创建存储消息ID的表 cursor.execute(''' CREATE TABLE IF NOT EXISTS target_messages ( message_id INTEGER PRIMARY KEY, allowed_user_id INTEGER NOT NULL ) ''') conn.commit()
2. 发送消息并存储ID到数据库
发送指定内容的消息后,把消息ID和允许反应的用户ID存入数据库:
# 假设指定允许反应的用户ID为allowed_user_id allowed_user_id = 1234567890 message_content = f"仅<@{allowed_user_id}>可对此消息进行反应" sent_message = await message.channel.send(message_content) await sent_message.add_reaction("❌") # 存入数据库 cursor.execute('INSERT INTO target_messages (message_id, allowed_user_id) VALUES (?, ?)', (sent_message.id, allowed_user_id)) conn.commit()
3. 监听反应事件并验证
用on_reaction_add事件监听所有反应,先检查消息ID是否在数据库中,再验证用户是否为指定用户:
@bot.event async def on_reaction_add(reaction, user): # 排除机器人自身 if user == bot.user: return # 查询数据库,验证消息是否为目标消息 cursor.execute('SELECT allowed_user_id FROM target_messages WHERE message_id = ?', (reaction.message.id,)) result = cursor.fetchone() if result and result[0] == user.id and str(reaction.emoji) == "❌": # 执行相应操作 await reaction.message.channel.send(f"Reaction added! 来自用户<@{user.id}>")
三、完整代码整合
import disnake from disnake.ext import commands import sqlite3 bot = commands.Bot(command_prefix="!", intents=disnake.Intents.all()) # 初始化数据库 conn = sqlite3.connect("reaction_messages.db") cursor = conn.cursor() cursor.execute(''' CREATE TABLE IF NOT EXISTS target_messages ( message_id INTEGER PRIMARY KEY, allowed_user_id INTEGER NOT NULL ) ''') conn.commit() @bot.command() async def send_reaction_msg(ctx, user_id: int): # 发送指定内容的消息 message_content = f"仅<@{user_id}>可对此消息进行反应" sent_message = await ctx.channel.send(message_content) await sent_message.add_reaction("❌") # 存入数据库 cursor.execute('INSERT INTO target_messages (message_id, allowed_user_id) VALUES (?, ?)', (sent_message.id, user_id)) conn.commit() await ctx.send("目标消息已发送并记录") @bot.event async def on_reaction_add(reaction, user): if user == bot.user: return cursor.execute('SELECT allowed_user_id FROM target_messages WHERE message_id = ?', (reaction.message.id,)) result = cursor.fetchone() if result and result[0] == user.id and str(reaction.emoji) == "❌": await reaction.message.channel.send(f"Reaction added! 来自用户<@{user.id}>") bot.run("你的机器人Token")
内容的提问来源于stack exchange,提问作者Sky
相关产品推荐
相关产品推荐

