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
相关产品推荐
相关产品推荐

