同步Discord命令至测试服务器与全局时重复问题求助
问题原因
你当前的同步逻辑会导致测试服务器中同时存在服务器专属命令和全局命令,从而出现重复:
- 先通过
tree.copy_global_to(guild=server)把全局命令克隆到测试服务器的命令树,同步后创建了服务器专属的同名命令 - 随后执行全局同步
await tree.sync(),全局命令会在所有服务器(包括测试服)生效,最终测试服里就有了两个完全相同的命令。
解决方案
要实现测试服务器命令即时更新,同时不影响全局命令同步且无重复,按以下方式调整:
1. 清理测试服务器的重复命令(先执行此步骤)
先手动删除测试服务器中重复的命令,或者用代码批量清理:
# 清理指定服务器的所有命令 async def clear_guild_commands(guild_id): guild = discord.Object(guild_id) commands = await tree.fetch_commands(guild=guild) for cmd in commands: await tree.delete_command(cmd.name, guild=guild) print(f"已清理服务器 {guild_id} 的所有命令")
可以在on_ready里临时调用一次,或者做个管理员专属命令触发清理。
2. 修改同步逻辑
调整后的同步逻辑会让测试服务器只保留即时生效的服务器专属命令,全局命令正常同步到其他服务器(测试服会优先显示服务器专属命令,不会出现重复):
@client.event async def on_ready(): print(f'{client.user} has connected to Discord!') voiceGroup = VoiceGroup(name="voice", description="The voice commands can make me connect and disconnect from a voice call.") tree.add_command(voiceGroup) # 测试服务器同步(即时生效) print("Syncing test servers...") for server_id in SERVERS: guild = discord.Object(server_id) # 清理服务器现有命令(可选,避免残留) await clear_guild_commands(server_id) # 把全局命令复制到服务器命令树 tree.copy_global_to(guild=guild) # 同步服务器,创建即时生效的服务器专属命令 await tree.sync(guild=guild) print(f"已同步测试服务器 {server_id}") # 全局同步(正常生效,测试服会优先显示服务器专属命令) print("Syncing globally...") await tree.sync() if DEBUG: user = client.get_user(CAPPABOT) await user.send("Cappa Bot has started") print("Finished loading.")
3. 更优的同步触发方式(替代on_ready)
不要在on_ready中执行同步(你也提到了这点),建议添加一个仅管理员可用的同步命令,手动触发同步:
@tree.command(name="sync", description="同步命令(仅管理员可用)") async def sync(interaction: discord.Interaction, guild_id: str = None): if not interaction.user.guild_permissions.administrator: await interaction.response.send_message("你没有权限执行此命令", ephemeral=True) return await interaction.response.defer(ephemeral=True) if guild_id: # 同步指定测试服务器 guild = discord.Object(int(guild_id)) await clear_guild_commands(int(guild_id)) tree.copy_global_to(guild=guild) await tree.sync(guild=guild) await interaction.followup.send(f"已同步测试服务器 {guild_id}") else: # 全局同步 await tree.sync() await interaction.followup.send("已全局同步命令")
这样你可以在测试服手动触发服务器同步(即时生效),全局同步按需触发,避免每次启动都同步导致的问题。
内容的提问来源于stack exchange,提问作者CappaBot
相关产品推荐
相关产品推荐

