discord.py开发中@client.event事件未触发 投票踢人功能异常求助
错误点梳理
- discord.py没有名为
kick的内置事件,你用@client.event标记的kick函数永远不会被自动触发 on_reaction_add事件监听器被嵌套在votekick命令内部,每次执行votekick都会重复注册事件,会导致响应逻辑混乱- 你在
on_reaction_add中修改vote变量时没有加global声明,实际修改的是函数局部变量,全局vote始终为None member、reason都是votekick命令的局部变量,你的kick函数没有权限访问这些值
修复后代码
from keepawake import keepawake import os import asyncio import requests import discord from discord import Webhook, RequestsWebhookAdapter, File from discord.ext import commands webhook = Webhook.partial(863030277597036574, os.environ['WTOKEN'], adapter=RequestsWebhookAdapter()) # 必须开启对应网关意图,否则无法接收反应、成员相关事件 intents = discord.Intents.default() intents.message_content = True intents.members = True client = commands.Bot(command_prefix="!", intents=intents) # 存储投票数据,避免全局变量冲突,支持同时发起多个投票 vote_pool = {} @client.command() async def votekick(ctx, member: discord.Member, *, reason="inconnue"): emojis = ['✅', '❌'] vote_msg = await ctx.send(f"是否踢出 {str(member)[:-5]}?\n投票理由:{reason}\n投票时长60秒") # 存储当前投票的关联数据 vote_pool[vote_msg.id] = { "target": member, "reason": reason, "ctx": ctx } # 初始化投票反应 for emoji in emojis: await vote_msg.add_reaction(emoji) # 等待投票结束 await asyncio.sleep(60) # 拉取最新消息统计票数 end_msg = await ctx.channel.fetch_message(vote_msg.id) yes = 0 no = 0 for react in end_msg.reactions: if str(react.emoji) == "✅": yes = react.count - 1 # 减去机器人自己投的一票 elif str(react.emoji) == "❌": no = react.count - 1 # 执行结果 current_vote = vote_pool.pop(vote_msg.id) if yes > no: try: await current_vote["target"].send(f"你已被踢出 {ctx.guild.name},理由:{current_vote['reason']}") await current_vote["target"].kick(reason=current_vote["reason"]) await ctx.send(f"{current_vote['target']} 已被踢出服务器") except discord.Forbidden: await ctx.send("踢出失败,机器人权限不足") else: await ctx.send(f"赞成票不足,{current_vote['target']} 不会被踢出") @client.event async def on_reaction_add(reaction, user): if user.bot: return if str(reaction.emoji) == "🔒": admin_channel = client.get_channel(863158034292801577) await admin_channel.send("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") # 替换为你的机器人Token client.run(os.environ["BOT_TOKEN"])
额外注意事项
- 你需要前往Discord开发者平台的机器人管理页,开启
Message Content Intent、Server Members Intent两个开关,否则代码无法正常接收消息和反应事件 - 机器人需要拥有踢人权限,且角色等级高于要踢出的成员,否则会执行失败
内容的提问来源于stack exchange,提问作者david
相关产品推荐
相关产品推荐

