Python Discord机器人:修复仅所有者可用的全服消息命令问题
修正后的跨服务器广播命令代码
原代码问题分析
- 错误将自定义函数作为
client.event注册,Discord.py的事件有固定名称与参数规范,自定义逻辑不能这么绑定。 - 用户ID使用了字符串类型,Discord用户ID本质是整数,类型不匹配会导致判断失效。
- 权限判断逻辑颠倒:原代码中如果是所有者直接返回,实际应该拒绝非所有者的调用。
- 未实现核心需求:没有遍历所有服务器发送消息的逻辑。
修正后的完整代码
import discord import os from discord.ext import commands from keep_alive import keep_alive # 配置必要的机器人意图 intents = discord.Intents.default() intents.message_content = True intents.guilds = True # 必须开启此意图才能获取服务器列表 # 使用commands.Bot替代Client,更适配命令开发场景 bot = commands.Bot(command_prefix=os.environ['PREFIX'], intents=intents) @bot.event async def on_ready(): print(f'Logged in as {bot.user}') await bot.change_presence( activity=discord.Activity( type=discord.ActivityType.watching, name='Nothing <3' ) ) # 用is_owner装饰器限制仅机器人所有者可调用 @bot.command(name='broadcast') @commands.is_owner() async def broadcast(ctx, *, message: str): """仅所有者可用:将指定消息发送到机器人所在的所有服务器""" sent_success = 0 sent_failed = 0 # 遍历机器人加入的所有服务器 for guild in bot.guilds: # 优先找第一个机器人有发送权限的文本频道 target_channel = next( (ch for ch in guild.text_channels if ch.permissions_for(guild.me).send_messages), None ) if target_channel: try: await target_channel.send(message) sent_success += 1 except discord.Forbidden: sent_failed += 1 except Exception as e: print(f"发送到服务器[{guild.name}]失败: {str(e)}") sent_failed += 1 else: sent_failed += 1 # 向所有者反馈执行结果 await ctx.send(f"广播完成:成功发送到{sent_success}个服务器,{sent_failed}个服务器发送失败") # 处理非所有者调用命令的错误 @broadcast.error async def broadcast_error_handler(ctx, error): if isinstance(error, commands.NotOwner): await ctx.send("你没有权限使用此命令") keep_alive() bot.run(os.getenv('TOKEN'))
关键改动说明
- 改用
commands.Bot:内置成熟的命令解析与权限控制体系,比原生Client更适合开发命令功能。 - 权限控制:
@commands.is_owner()装饰器自动验证调用者身份,也可以替换为@commands.check(lambda ctx: ctx.author.id == 751535313167581265)来指定特定用户ID。 - 广播逻辑:遍历机器人所有服务器,自动筛选可发送消息的频道,同时捕获异常避免程序崩溃。
- 结果反馈:向命令调用者返回成功/失败统计,方便确认执行情况。
内容的提问来源于stack exchange,提问作者Dark
相关产品推荐
相关产品推荐

