discord.py如何无需先发送消息修改频道权限并按名称获取多服务器频道
解决方案
1. 无需消息触发修改频道权限的实现
你之前查到的示例用ctx是因为属于用户命令触发场景,定时后台任务不需要依赖消息上下文,只要拿到对应的服务器、频道、角色对象即可直接调用权限修改接口。
2. 多服务器场景按名称获取频道
你可以通过client.guilds获取所有机器人已加入的服务器列表,再用discord.utils.get按名称筛选对应频道,示例逻辑:
import discord.utils # 遍历所有服务器,找到名称匹配的频道 def get_channels_by_name(channel_name): matched_channels = [] for guild in client.guilds: channel = discord.utils.get(guild.channels, name=channel_name) if channel: matched_channels.append(channel) return matched_channels
如果存在多服务器频道重名的情况,建议提前维护「服务器ID-频道名称」的映射表,避免匹配错误。
3. 核心逻辑补全
你可以直接用以下代码替换原有的live_day相关逻辑,实现定时修改权限的需求:
import discord import datetime import asyncio from discord.utils import get # discord.py v2.0+ 要求显式声明intents,必须开启服务器访问权限 intents = discord.Intents.default() intents.guilds = True client = discord.Client(intents=intents) def get_channels_by_name(channel_name): matched_channels = [] for guild in client.guilds: channel = discord.utils.get(guild.channels, name=channel_name) if channel: matched_channels.append(channel) return matched_channels async def live_day(schedule): current_place = "the void" while True: current_time = str((datetime.datetime.now() - datetime.timedelta(hours=7)).time()) int_time = int(current_time[:2] + current_time[3:5]) for x in range(len(schedule)): try: start_time = schedule[x][1] end_time = schedule[x + 1][1] except IndexError: end_time = 2400 if current_place != schedule[x][0] and int_time >= start_time and int_time < end_time: new_place = schedule[x][0] # 关闭旧频道的全员查看权限 if current_place != "the void": old_channels = get_channels_by_name(current_place) for ch in old_channels: await ch.set_permissions(ch.guild.default_role, view_channel=False) # 开启新频道的全员查看权限 new_channels = get_channels_by_name(new_place) for ch in new_channels: await ch.set_permissions(ch.guild.default_role, view_channel=True) current_place = new_place # 加延时避免空跑占用资源,每分钟检查一次即可 await asyncio.sleep(60) @client.event async def on_ready(): print("{0.user} has arrived for duty".format(client)) client.loop.create_task(live_day([ ("Home", 0), ("Work", 900), ("Home", 1700), ("Nightclub", 2000), ("Home", 2200), ])) client.run(my_secret)
注意事项
- 机器人需要拥有对应频道的「管理权限」权限,否则无法修改频道权限设置
- 如果需要针对特定角色而非所有成员修改权限,可以用
get(guild.roles, name="角色名")拿到指定角色对象,替换代码里的ch.guild.default_role即可 - 频道名称匹配区分大小写,建议统一频道名的大小写规范避免匹配失败
内容的提问来源于stack exchange,提问作者MasterPeanut
相关产品推荐
相关产品推荐

