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

discord.py开发中@client.event事件未触发 投票踢人功能异常求助

错误点梳理

  1. discord.py没有名为kick的内置事件,你用@client.event标记的kick函数永远不会被自动触发
  2. on_reaction_add事件监听器被嵌套在votekick命令内部,每次执行votekick都会重复注册事件,会导致响应逻辑混乱
  3. 你在on_reaction_add中修改vote变量时没有加global声明,实际修改的是函数局部变量,全局vote始终为None
  4. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 14:39:03