You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 21:45:00