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

如何实现discord.py事件监听器,仅删除指定论坛频道的违规线程?

问题解决:Discord.py监听指定论坛线程并校验名称

问题描述

我想实现一个事件监听器,监听论坛中创建的新线程,若线程名称不符合要求则将其删除。目前代码对所有论坛频道有效,但无法仅针对单个指定论坛生效。报错出在if thread.channel.id == forum_channel_id:这一行,提示Thread对象没有channel属性。

原尝试代码:

@bot.event
async def on_thread_create(thread):
    forum_channel_id = 1069778474815979570
    if thread.channel.id == forum_channel_id:
        return
    if thread.name.startswith("Request #"):
        async for entry in thread.guild.audit_logs(limit=1, action=discord.AuditLogAction.thread_create):
            user = entry.user
            break
        embed = discord.Embed(title="Request Succesfully Done", description="The thread named ''{}'' was succesfully created.".format(thread.name), color=discord.Color.green())
        await user.send(embed = embed)
    else:
        async for entry in thread.guild.audit_logs(limit=1, action=discord.AuditLogAction.thread_create):
            user = entry.user
            break
        embed = discord.Embed(title="Invalid Request", description="The thread named ''{}'' could not be created.".format(thread.name), color=discord.Color.red())
        await user.send(embed = embed)
        await thread.delete()

解决方案

核心问题修正

在Discord.py的API中,论坛线程的父频道属性不是channel,而是parent。需要将thread.channel.id替换为thread.parent.id。

逻辑调整(按需选择)

原代码中if thread.parent.id == forum_channel_id: return的逻辑是跳过指定论坛的线程,处理其他论坛的,如果你的需求是只处理指定论坛内的线程,应该把条件改为:

if thread.parent.id != forum_channel_id:
    return

这样非目标论坛的线程会直接跳过,只处理你指定的论坛。

优化后的完整代码

@bot.event
async def on_thread_create(thread):
    forum_channel_id = 1069778474815979570
    # 仅处理指定论坛内的线程,非目标论坛直接跳过
    if thread.parent.id != forum_channel_id:
        return
    
    # 获取当前线程的创建者
    user = None
    async for entry in thread.guild.audit_logs(limit=1, action=discord.AuditLogAction.thread_create):
        # 确保日志条目对应当前线程,避免获取到其他线程的记录
        if entry.target.id == thread.id:
            user = entry.user
            break
    
    # 处理获取不到创建者的情况
    if not user:
        await thread.delete()
        return
    
    if thread.name.startswith("Request #"):
        embed = discord.Embed(title="请求创建成功", description=f"名为「{thread.name}」的线程已成功创建。", color=discord.Color.green())
        await user.send(embed=embed)
    else:
        embed = discord.Embed(title="无效请求", description=f"名为「{thread.name}」的线程不符合命名规则,已被删除。", color=discord.Color.red())
        await user.send(embed=embed)
        await thread.delete()

关键修改点说明

  1. 属性替换:用thread.parent.id替代thread.channel.id,正确获取论坛线程的父频道ID。
  2. 逻辑修正:调整条件判断,确保只处理目标论坛内的线程(可根据需求反向调整)。
  3. 日志校验:增加entry.target.id == thread.id判断,避免误获取其他线程的创建记录。
  4. 边界处理:新增获取不到用户时的处理逻辑,防止代码报错。
  5. 语法优化:使用f-string替代format方法,让字符串拼接更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 03:00:59