如何实现Discord机器人事件仅在授权服务器触发?含代码示例
解决方案:Discord机器人仅在授权服务器触发客户端事件
完全可以用JSON文件来持久化记录已授权的服务器ID,这样机器人重启后也不会丢失授权信息,完美适配多服务器场景。下面我会分别给出普通脚本形式和Cog模块化形式的实现代码。
一、普通脚本形式实现
首先准备一个authorized_guilds.json文件(初始内容设为[])用来存储授权服务器ID,然后实现授权命令和带权限校验的客户端事件:
import discord from discord.ext import commands import json import os # 初始化机器人,按需开启所需意图 intents = discord.Intents.default() intents.message_content = True bot = commands.Bot(command_prefix="!", intents=intents) # 授权文件路径定义 AUTH_FILE = "authorized_guilds.json" # 加载已授权服务器列表 def load_authorized_guilds(): if os.path.exists(AUTH_FILE): with open(AUTH_FILE, "r") as f: return json.load(f) return [] # 保存更新后的授权服务器列表 def save_authorized_guilds(guild_ids): with open(AUTH_FILE, "w") as f: json.dump(guild_ids, f, indent=4) # 授权命令:仅服务器管理员可执行 @bot.command() @commands.has_permissions(administrator=True) async def allow(ctx): guild_id = ctx.guild.id authorized_list = load_authorized_guilds() if guild_id not in authorized_list: authorized_list.append(guild_id) save_authorized_guilds(authorized_list) await ctx.send(f"✅ 服务器 {ctx.guild.name} 已成功授权!") else: await ctx.send(f"⚠️ 服务器 {ctx.guild.name} 已经处于授权状态!") # 示例客户端事件:仅授权服务器触发 @bot.event async def on_message(message): # 忽略机器人自身消息 if message.author.bot: return # 校验服务器是否在授权列表中 authorized_guilds = load_authorized_guilds() if message.guild and message.guild.id not in authorized_guilds: return # 非授权服务器直接跳过事件处理 # 这里写你的事件逻辑,仅授权服务器会执行 if message.content.lower() == "hello": await message.channel.send(f"Hello {message.author.mention}!") # 必须调用此方法,否则命令会失效 await bot.process_commands(message) # 启动机器人 bot.run("你的机器人TOKEN")
二、Cog模块化形式实现
用Cog可以让代码更模块化,便于后续扩展和维护。我们把授权逻辑和事件逻辑封装到单独的Cog文件中:
1. 创建Cog文件auth_cog.py
import discord from discord.ext import commands import json import os class AuthCog(commands.Cog): def __init__(self, bot): self.bot = bot self.AUTH_FILE = "authorized_guilds.json" # 加载授权服务器列表 def load_authorized_guilds(self): if os.path.exists(self.AUTH_FILE): with open(self.AUTH_FILE, "r") as f: return json.load(f) return [] # 保存授权服务器列表 def save_authorized_guilds(self, guild_ids): with open(self.AUTH_FILE, "w") as f: json.dump(guild_ids, f, indent=4) # 授权命令 @commands.command() @commands.has_permissions(administrator=True) async def allow(self, ctx): guild_id = ctx.guild.id authorized_list = self.load_authorized_guilds() if guild_id not in authorized_list: authorized_list.append(guild_id) self.save_authorized_guilds(authorized_list) await ctx.send(f"✅ 服务器 {ctx.guild.name} 已成功授权!") else: await ctx.send(f"⚠️ 服务器 {ctx.guild.name} 已经处于授权状态!") # 示例客户端事件:仅授权服务器触发 @commands.Cog.listener() async def on_message(self, message): if message.author.bot: return authorized_guilds = self.load_authorized_guilds() if message.guild and message.guild.id not in authorized_guilds: return if message.content.lower() == "hello": await message.channel.send(f"Hello {message.author.mention}!") # 注册Cog的方法 def setup(bot): bot.add_cog(AuthCog(bot))
2. 主脚本main.py
import discord from discord.ext import commands import auth_cog # 初始化机器人 intents = discord.Intents.default() intents.message_content = True bot = commands.Bot(command_prefix="!", intents=intents) # 加载Cog @bot.event async def on_ready(): await bot.add_cog(auth_cog.AuthCog(bot)) print(f"已登录为 {bot.user}") # 启动机器人 bot.run("你的机器人TOKEN")
额外提示
- 权限自定义:示例中用
administrator权限限制授权命令,你可以根据需求换成manage_guild等其他权限。 - 持久化方案:如果需要更高效的存储,也可以把JSON换成SQLite、MySQL等数据库。
- 事件扩展:所有需要限制的客户端事件(如
on_member_join、on_guild_update)都可以按照示例中的校验逻辑来处理。
内容的提问来源于stack exchange,提问作者bat beat
相关产品推荐
相关产品推荐

