用Python开发Discord Bot:指令触发后展示指定分类的所有文本频道
Discord指定分类频道名称查询功能实现方案
完全可以基于已搭建完成的可运行基础机器人实现该功能,之前检索时仅能找到频道数量统计参考的核心原因是,多数实现示例仅调用len(category.channels)获取分类下的频道总数,并未遍历列表读取单个频道的名称属性。
核心实现逻辑
- 匹配到用户发送的指定指令(如
!vip)后,从消息对象中获取当前所在服务器的上下文 - 遍历服务器内所有
CategoryChannel(分类频道组),匹配出名称和指令对应的目标分类 - 读取目标分类自带的
channels属性,筛选出类型为TextChannel的文本频道(过滤掉语音、论坛等非文本类型频道) - 遍历筛选后的频道列表,拼接每个频道的
name属性生成可读的频道列表文本,发送回原消息频道即可
实操注意事项
- 新版
discord.py(2.0及以上版本)需要在代码中初始化对应权限:必须开启message_content意图才能读取用户发送的消息内容,开启guilds意图才能拉取服务器内的分类、频道列表;同时需要在Discord开发者后台的机器人设置页打开Message Content Intent开关,否则接口会拒绝读取相关数据 - 需要给机器人分配“查看频道”“发送消息”“读取消息历史”的服务器权限,否则会出现接口返回空列表的情况
- 匹配分类名称时建议做不区分大小写的判断,避免因用户分类名大小写不一致导致匹配失败
基于原有代码改造的可运行版本
import discord TOKEN = 'yourtoken' # 初始化所需的权限意图 intents = discord.Intents.default() intents.message_content = True # 允许读取消息内容,用于匹配指令 intents.guilds = True # 允许获取服务器内的分类、频道列表 client = discord.Client(intents=intents) @client.event async def on_message(message): # 忽略机器人自身发送的消息,避免循环触发 if message.author == client.user: return # 原有!hello指令逻辑保留 if message.content.startswith('!hello'): msg = 'Hey, {0.author.mention}'.format(message) await message.channel.send(msg) # 新增!vip指令逻辑 if message.content.startswith('!vip'): # 私信场景下无服务器上下文,直接提示 if not message.guild: await message.channel.send("该指令仅可在服务器内使用") return # 遍历服务器所有分类,找到VIP分类 target_category = None for category in message.guild.categories: # 不区分大小写匹配,降低匹配失败概率 if category.name.lower() == "vip": target_category = category break # 未匹配到对应分类的兜底提示 if not target_category: await message.channel.send("未找到名称为「VIP」的频道分类") return # 筛选分类下所有文本频道 text_channels = [ channel for channel in target_category.channels if isinstance(channel, discord.TextChannel) ] # 分类下无文本频道的兜底提示 if not text_channels: await message.channel.send("「VIP」分类下当前没有挂载任何文本频道") return # 拼接频道列表为可读格式 channel_list_str = "\n".join([f"- #{channel.name}" for channel in text_channels]) reply = f"「VIP」分类下的全部文本频道列表:\n{channel_list_str}" await message.channel.send(reply) @client.event async def on_ready(): print('Logged in as') print(client.user.name) print(client.user.id) print('------') client.run(TOKEN)
扩展优化方法
如果需要支持更多指令对应不同分类的查询,可以直接维护一个指令和分类名的映射字典,无需重复编写匹配逻辑:
- 例如添加映射规则
command_map = {"!vip": "VIP", "!mod": "管理组", "!game": "游戏交流"} - 收到指令时先判断指令是否在映射字典的键集合中,再根据映射的分类名查找对应分类即可,可大幅减少重复代码
内容的提问来源于stack exchange,提问作者Anika
相关产品推荐
相关产品推荐

