Discord机器人票务功能:检查指定分类中是否存在文本频道
修正Discord机器人票务频道重复创建的检查逻辑
你的问题出在两个核心点上:一是没有限定检查范围到指定的票务分类,二是没处理频道名称的大小写匹配问题,导致要么误判其他分类的同名频道,要么因为大小写不一致找不到已存在的票务频道。
问题分析
- 原代码
discord.utils.get(guild.channels, name='{}-ticket'.format(ctx.message.author.name))会遍历整个服务器的所有频道——万一其他分类里碰巧有同名的xxx-ticket频道,就会误判用户已有票务。 - Discord的频道名称是大小写敏感的,但用户的昵称可能有大小写变化(比如用户改了昵称的大小写格式),直接硬匹配会导致明明有频道却检测不到。
- 没有先确认目标票务分类是否存在,万一分类被删除,后续创建频道的代码会直接抛出错误。
修正方案
我们需要:
- 只在指定的票务分类下检查是否存在用户的票务频道
- 使用大小写不敏感的方式匹配频道名称
- 先确认目标分类存在,避免后续报错
修改后的完整代码如下:
@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.




