You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 22:39:02