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

基于Discord.py实现反应角色功能及嵌入消息持久化需求

实现Discord.py表情角色分配机器人(重启无需重发嵌入消息)

核心思路

要实现重启后不用重发消息,关键是保存嵌入消息的频道ID和消息ID,机器人启动时直接拉取这条已存在的消息,重新绑定表情监听逻辑。这里用本地JSON文件存储消息信息,简单易上手。

完整代码实现

import discord
from discord.ext import commands
import json
import os

# 初始化机器人,开启必要意图
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
bot = commands.Bot(command_prefix="!", intents=intents)

# 自定义配置:表情对应角色,替换成你服务器的实际内容
EMOJI_ROLE_MAP = {
    "😎": "酷玩达人",
    "🤓": "技术宅",
    "🥳": "派对动物"
}

# 存储消息ID的本地文件
MESSAGE_DATA_PATH = "role_reaction_msg.json"

def save_msg_info(channel_id, msg_id):
    """把消息的频道ID和消息ID存到本地文件"""
    data = {"channel_id": channel_id, "message_id": msg_id}
    with open(MESSAGE_DATA_PATH, "w") as f:
        json.dump(data, f)

def load_msg_info():
    """从本地文件读取已保存的消息信息"""
    if os.path.exists(MESSAGE_DATA_PATH):
        with open(MESSAGE_DATA_PATH, "r") as f:
            return json.load(f)
    return None

@bot.command()
@commands.has_permissions(administrator=True)
async def setup_role(ctx):
    """管理员专属命令:创建角色分配嵌入消息并保存信息"""
    # 构建嵌入消息
    embed = discord.Embed(title="自助领角色", description="点击下方表情获取对应身份:", color=discord.Color.green())
    for emoji, role_name in EMOJI_ROLE_MAP.items():
        embed.add_field(name=emoji, value=f"领取「{role_name}」", inline=False)
    
    # 发送消息并批量添加表情
    target_msg = await ctx.send(embed=embed)
    for emoji in EMOJI_ROLE_MAP.keys():
        await target_msg.add_reaction(emoji)
    
    # 保存消息信息到本地
    save_msg_info(ctx.channel.id, target_msg.id)
    await ctx.send("角色分配消息已创建完成!")

@bot.event
async def on_ready():
    print(f"机器人已登录:{bot.user.name}")
    # 重启后自动绑定已有的消息
    msg_data = load_msg_info()
    if msg_data:
        try:
            channel = bot.get_channel(msg_data["channel_id"])
            target_msg = await channel.fetch_message(msg_data["message_id"])
            # 检查消息上的表情是否完整,缺失的话补加
            for emoji in EMOJI_ROLE_MAP.keys():
                if not any(reaction.emoji == emoji for reaction in target_msg.reactions):
                    await target_msg.add_reaction(emoji)
            print("已成功绑定现有角色分配消息")
        except Exception as e:
            print(f"加载旧消息失败:{str(e)}")

@bot.event
async def on_raw_reaction_add(payload):
    """处理表情添加事件,给用户分配角色"""
    # 忽略机器人自己的操作
    if payload.user_id == bot.user.id:
        return
    
    # 确认是我们监听的消息
    msg_data = load_msg_info()
    if not msg_data or payload.message_id != msg_data["message_id"]:
        return
    
    # 匹配对应的角色
    emoji = str(payload.emoji)
    if emoji not in EMOJI_ROLE_MAP:
        return
    
    guild = bot.get_guild(payload.guild_id)
    role = discord.utils.get(guild.roles, name=EMOJI_ROLE_MAP[emoji])
    if not role:
        print(f"找不到对应角色:{EMOJI_ROLE_MAP[emoji]}")
        return
    
    member = guild.get_member(payload.user_id)
    if member:
        await member.add_roles(role)
        print(f"已给{member.name}添加角色{role.name}")

@bot.event
async def on_raw_reaction_remove(payload):
    """处理表情移除事件,移除用户对应角色"""
    if payload.user_id == bot.user.id:
        return
    
    msg_data = load_msg_info()
    if not msg_data or payload.message_id != msg_data["message_id"]:
        return
    
    emoji = str(payload.emoji)
    if emoji not in EMOJI_ROLE_MAP:
        return
    
    guild = bot.get_guild(payload.guild_id)
    role = discord.utils.get(guild.roles, name=EMOJI_ROLE_MAP[emoji])
    if not role:
        print(f"找不到对应角色:{EMOJI_ROLE_MAP[emoji]}")
        return
    
    member = guild.get_member(payload.user_id)
    if member:
        await member.remove_roles(role)
        print(f"已给{member.name}移除角色{role.name}")

# 替换成你的机器人Token
bot.run("YOUR_BOT_TOKEN")

使用步骤

  1. 配置修改:
    • 调整EMOJI_ROLE_MAP里的表情和角色名称,对应你服务器的实际角色
    • 把YOUR_BOT_TOKEN替换成你的Discord机器人Token
  2. 首次部署:
    • 机器人上线后,用管理员账号在服务器发送!setup_role,机器人会自动创建嵌入消息并保存消息ID
  3. 重启机器人:
    • 重启后机器人会自动读取本地保存的消息信息,找到旧的嵌入消息并重新监听表情事件,不需要重新发送消息

注意事项

  • 确保机器人拥有管理角色的权限,否则无法给用户添加/移除角色
  • 不要删除role_reaction_msg.json文件,否则机器人重启后会找不到旧消息
  • 如果需要修改嵌入消息内容,先删除旧消息和JSON文件,再重新执行!setup_role命令

内容的提问来源于stack exchange,提问作者GiveOff

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 17:42:39