You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Discord机器人票务功能:检查指定分类中是否存在文本频道

修正Discord机器人票务频道重复创建的检查逻辑

你的问题出在两个核心点上:一是没有限定检查范围到指定的票务分类,二是没处理频道名称的大小写匹配问题,导致要么误判其他分类的同名频道,要么因为大小写不一致找不到已存在的票务频道。

问题分析

  1. 原代码discord.utils.get(guild.channels, name='{}-ticket'.format(ctx.message.author.name))会遍历整个服务器的所有频道——万一其他分类里碰巧有同名的xxx-ticket频道,就会误判用户已有票务。
  2. Discord的频道名称是大小写敏感的,但用户的昵称可能有大小写变化(比如用户改了昵称的大小写格式),直接硬匹配会导致明明有频道却检测不到。
  3. 没有先确认目标票务分类是否存在,万一分类被删除,后续创建频道的代码会直接抛出错误。

修正方案

我们需要:

  • 只在指定的票务分类下检查是否存在用户的票务频道
  • 使用大小写不敏感的方式匹配频道名称
  • 先确认目标分类存在,避免后续报错

修改后的完整代码如下:

@bot.command()
async def new(ctx):
    guild = ctx.guild
    # 获取指定的票务分类(用ID定位更可靠,不受名称修改影响)
    ticket_category = discord.utils.get(guild.categories, id=404351895121952768)
    command_channel = bot.get_channel(402168280149655552)

    # 检查是否在正确的频道使用命令
    if ctx.channel != command_channel:
        wrongchannel_embed = discord.Embed(
            title="Error:",
            description=f"Use my commands in the {command_channel.mention} channel.",
            color=0xe73c24
        )
        await ctx.send(embed=wrongchannel_embed)
        return

    # 先确认票务分类存在,避免后续创建频道报错
    if not ticket_category:
        error_embed = discord.Embed(
            title="Critical Error",
            description="The ticket category could not be found! Please contact an administrator.",
            color=0xe73c24
        )
        await ctx.send(embed=error_embed)
        return

    # 检查分类下是否已有用户的票务频道(统一转小写,避免大小写匹配问题)
    existing_ticket = discord.utils.get(
        ticket_category.channels,
        name=f"{ctx.author.name.lower()}-ticket"
    )
    if existing_ticket:
        failed_embed = discord.Embed(
            title="Failed to create a ticket",
            description="You already have a ticket open, please don't try to open a ticket while you already have one.",
            color=0xe73c24
        )
        await ctx.send(embed=failed_embed)
        return

    # 到这里说明可以创建新票务
    overwrites = {
        guild.default_role: discord.PermissionOverwrite(read_messages=False),
        ctx.author: discord.PermissionOverwrite(read_messages=True)
    }
    # 创建频道时也用小写名称,保持匹配一致性
    ticket_channel = await guild.create_text_channel(
        name=f"{ctx.author.name.lower()}-ticket",
        overwrites=overwrites,
        category=ticket_category
    )

    # 发送票务频道内的提示
    ticket_embed = discord.Embed(
        title="Ticket",
        description=f"{ctx.author.mention}\nPlease be patient. A member of our support team will be with you shortly.",
        color=0x15a513
    )
    ticket_embed.set_footer(text=f"Ticket requested by {ctx.author}", icon_url=ctx.author.avatar_url)
    await ticket_channel.send(embed=ticket_embed)

    # 发送创建成功提示
    success_embed = discord.Embed(
        title="Ticket Creation",
        description=f"{ctx.author.mention}, your ticket was successfully created: {ticket_channel.mention}.",
        color=0x15a513
    )
    await ctx.send(embed=success_embed)

关键修改点说明

  • 把检查范围从guild.channels缩小到ticket_category.channels,确保只在指定分类里找票务频道,避免误判
  • 使用ctx.author.name.lower()统一转换为小写,创建频道和检查时都用小写格式,彻底解决大小写匹配问题
  • 增加了票务分类是否存在的检查,提前拦截异常情况,避免代码崩溃
  • 简化了部分写法(比如把ctx.message.author改成ctx.author,Discord.py v1.5+支持更简洁的调用方式)

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

火山引擎 最新活动