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

discord.py开发:点击链接后自动授予Discord verified身份组问题咨询

Discord机器人验证功能实现方案

你的现有代码仅完成了「发送带验证链接的embed消息」的步骤,缺少用户点击链接后的回调通知、角色授予逻辑,完整实现流程如下:

核心实现逻辑

  • 生成验证链接时,将当前用户ID、所属服务器ID通过对称加密后作为参数附加到链接上,避免明文传输被伪造请求
  • 你部署的验证站点在获取到用户授权的IP信息后,携带加密的用户、服务器参数向机器人的Webhook接口发送验证完成通知
  • 机器人校验请求合法性后,在对应服务器为目标用户添加verified身份组

完整代码示例

import discord
from discord.ext import commands
import os
import hmac
import hashlib
from quart import Quart, request
import asyncio

# 加密密钥,和验证站点使用的密钥保持一致
SECRET_KEY = os.getenv("SECRET_KEY", "your_custom_secret_key")
BOT_TOKEN = os.getenv("BOT_TOKEN", "your_bot_token")
# 验证站点地址
VERIFY_SITE = "https://your-verify-site.com"
# 已验证角色名
VERIFIED_ROLE_NAME = "verified"

# 初始化机器人和web服务
intents = discord.Intents.default()
intents.members = True
bot = commands.Bot(command_prefix="!", case_insensitive=True, intents=intents)
app = Quart(__name__)

# 接收验证站点回调的接口
@app.route("/verify-callback", methods=["POST"])
async def verify_callback():
    data = await request.get_json()
    # 校验签名合法性
    received_sign = data.get("sign")
    raw_data = f"{data.get('user_id')}{data.get('guild_id')}".encode()
    expected_sign = hmac.new(SECRET_KEY.encode(), raw_data, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(received_sign, expected_sign):
        return {"status": "error", "msg": "invalid sign"}, 403
    
    # 给用户加角色
    guild = bot.get_guild(int(data.get("guild_id")))
    if not guild:
        return {"status": "error", "msg": "guild not found"}, 404
    member = guild.get_member(int(data.get("user_id")))
    if not member:
        return {"status": "error", "msg": "member not found"}, 404
    verified_role = discord.utils.get(guild.roles, name=VERIFIED_ROLE_NAME)
    if not verified_role:
        return {"status": "error", "msg": "verified role not found"}, 404
    await member.add_roles(verified_role)
    return {"status": "success", "msg": "role added"}

@bot.event
async def on_ready():
    print(f'Connected to bot: {bot.user.name}')
    print(f'Bot ID: {bot.user.id}')
    print(''' 
 
    ██████╗░░░█████╗░████████╗███████╗░
    ██╔══██╗░██╔══██╗╚══██╔══╝██╔════╝░ 
    ██████╦╝░██║░░██║░░░██║░░░█████╗░░░ 
    ██╔══██╗░██║░░██║░░░██║░░░██╔══╝░░░
    ██████╦╝░╚█████╔╝░░░██║░░░███████╗░
    ╚═════╝░░░╚════╝░░░░╚═╝░░░╚══════╝░
    ''')
    await bot.change_presence(activity=discord.Game(name="Verification Service"))

@bot.command()
async def verify(ctx):  
    nome = ctx.author.name
    # 生成加密参数
    raw_param = f"{ctx.author.id}|{ctx.guild.id}".encode()
    encrypt_param = hmac.new(SECRET_KEY.encode(), raw_param, hashlib.sha256).hexdigest()
    verify_link = f"{VERIFY_SITE}?user_id={ctx.author.id}&guild_id={ctx.guild.id}&sign={encrypt_param}"
    embed = discord.Embed(
        title=nome,
        description = f':flag_pt:Clica [aqui]({verify_link}) para te verificares\n :flag_us:Click [here]({verify_link}) to verify',
        colour = discord.Colour.green()
    )
    botmsg = await ctx.send(embed = embed)
    await botmsg.add_reaction("✅")

# 同时启动机器人和web服务
async def main():
    async with bot:
        await bot.start(BOT_TOKEN)

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    # 启动web服务,端口可自定义
    loop.create_task(app.run_task(host="0.0.0.0", port=11451))
    loop.run_until_complete(main())

注意事项

收集用户IP的行为必须明确告知用户,获得用户的明确授权,不得用于约定外的用途,避免违反Discord服务条款和各地数据保护法规

  • 提前在Discord服务器创建好名为verified的角色,将机器人的角色权限等级调整到verified角色之上,否则机器人无法为用户分配该角色
  • SECRET_KEY不要泄露,验证站点校验参数合法性的逻辑要和机器人保持一致,避免恶意请求伪造验证完成的通知
  • BOT_TOKEN、SECRET_KEY建议通过环境变量读取,不要硬编码在代码中防止泄露

内容的提问来源于stack exchange,提问作者Simão Pinto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 02:57:04