discord.py如何获取on_message中bot发送的消息ID供on_raw_reaction_add使用
discord.py跨事件传递规则消息ID的实现方案
你可以通过两种主流方案实现跨事件传递消息ID,以下是可直接复用的实现代码:
方案1:全局变量临时存储(适合测试场景)
优点是实现简单无需额外依赖,缺点是机器人重启后存储的ID会丢失,需要重新触发!init指令生成规则消息:
- 第一步:在代码全局作用域(client实例初始化后、事件定义前)定义存储变量
# 全局变量存储规则消息ID,初始为None TARGET_RULE_MSG_ID = None
- 第二步:修改
on_message事件,发送embed后将ID赋值给全局变量,同时补全异常判断逻辑
@client.event async def on_message(message): # 必须加该行,否则你定义的其他@client.command()指令会全部失效 await client.process_commands(message) if message.content.startswith("!init"): # 增加长度判断避免用户只发!init不带参数导致的索引越界报错 if len(message.content.split()) >=2 and message.content.split()[1] == 'règles': id_channel = 893442599019511829 embed = discord.Embed(title = 'Création bot', description = "par Archi's modo") embed.add_field(name="Règlement de la LSPD", value="En cliquant sur l'icône ✅ vous reconnaissez avoir blablabla,...") mess = await client.get_channel(id_channel).send(embed=embed) await mess.add_reaction('✅') # 给全局变量赋值消息ID global TARGET_RULE_MSG_ID TARGET_RULE_MSG_ID = mess.id
- 第三步:修改
on_raw_reaction_add事件,调用全局变量做校验,同时修复原代码的typo和异常逻辑
@client.event async def on_raw_reaction_add(payload): id_channel = 893442599019511829 role_a_donner = "zabloublou" # 过滤机器人自己触发的反应事件,避免无意义报错 if payload.user_id == client.user.id: return # 校验消息ID是否匹配目标规则消息 if payload.message_id != TARGET_RULE_MSG_ID: return member = payload.member guild_id = payload.guild_id guild = discord.utils.find(lambda g : g.id == guild_id, client.guilds) if payload.emoji.name == '✅': role = discord.utils.get(guild.roles, name=str(role_a_donner)) else: # 修复原代码笔误:guild.role → guild.roles role = discord.utils.get(guild.roles, name=payload.emoji.name) if role is not None: if member is not None: await member.add_roles(role) channel = client.get_channel(id_channel) await channel.send(member.mention)
方案2:本地文件持久化存储(适合生产环境)
优点是机器人重启后不需要重新触发!init指令,ID会永久保留:
- 第一步:代码顶部导入json模块,启动时自动读取本地存储的ID
import json # 启动时读取已存储的规则消息ID try: with open("rule_msg_id.json", "r") as f: data = json.load(f) TARGET_RULE_MSG_ID = data.get("msg_id", None) except FileNotFoundError: TARGET_RULE_MSG_ID = None
- 第二步:修改
on_message事件的赋值逻辑,新增写入本地文件的代码
global TARGET_RULE_MSG_ID TARGET_RULE_MSG_ID = mess.id # 写入本地文件做持久化存储 with open("rule_msg_id.json", "w") as f: json.dump({"msg_id": TARGET_RULE_MSG_ID}, f)
- 第三步:
on_raw_reaction_add事件的代码和方案1完全一致,无需额外修改。如果是多实例/分片部署的机器人,可将存储介质替换为数据库,逻辑和写本地文件一致。
内容的提问来源于stack exchange,提问作者Archicoincoin
相关产品推荐
相关产品推荐

