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

如何在discord.py的独立文件someFunc.py中向指定频道发消息?

解决定时任务发送Discord消息的方案

核心问题说明

你遇到的是循环导入(bot.py导入someFunc.py,反向导入会触发循环依赖错误)加上异步API与同步定时任务的适配问题,下面是两种可行的解决思路:


方案1:给定时任务传递频道对象

Discord客户端必须完成初始化(on_ready事件触发后)才能正确获取频道,所以要把定时任务的添加逻辑放到客户端就绪后执行:

修改someFunc.py

让func接受频道对象作为参数,同时适配异步消息发送:

import asyncio

async def func(channel):
    # 发送目标消息
    await channel.send("定时推送的消息内容")

修改bot.py

在on_ready事件中获取频道并传递给定时任务,用asyncio.run桥接同步调度器和异步Discord API:

import os
import someFunc
import discord
from discord.ext import commands
from dotenv import load_dotenv
from apscheduler.schedulers.background import BackgroundScheduler
import asyncio

load_dotenv()
TOKEN = os.getenv('TOKEN')
# 开启必要的Intents,否则无法发送消息或获取频道
intents = discord.Intents.default()
intents.message_content = True
client = commands.Bot(command_prefix='!', intents=intents)
scheduler = BackgroundScheduler(timezone="Asia/Seoul")

@client.event
async def on_ready():
    print(f'已登录为 {client.user}')
    # 替换为你的目标频道ID(纯数字)
    target_channel_id = 123456789012345678
    target_channel = client.get_channel(target_channel_id)
    
    if target_channel:
        # 添加定时任务,用lambda包装传递频道参数
        scheduler.add_job(
            lambda: asyncio.run(someFunc.func(target_channel)),
            'cron',
            hour='19',
            minute='47,48'
        )
        scheduler.start()
        print("定时任务已启动")
    else:
        print("无法找到目标频道,请检查频道ID是否正确")

try:
    client.run(TOKEN)
except (KeyboardInterrupt, SystemExit):
    scheduler.shutdown()
    print("定时任务已关闭")

方案2:通过全局回调函数解耦

在someFunc中定义一个全局变量存储发送消息的方法,由bot.py在初始化后赋值,避免直接传递对象:

修改someFunc.py

import asyncio

# 全局变量:存储发送消息的异步方法
send_message_callback = None

def func():
    if send_message_callback:
        # 调用预设的发送方法
        asyncio.run(send_message_callback("定时推送的消息内容"))

修改bot.py

在on_ready事件中把发送消息的逻辑赋值给someFunc的全局变量:

import os
import someFunc
import discord
from discord.ext import commands
from dotenv import load_dotenv
from apscheduler.schedulers.background import BackgroundScheduler
import asyncio

load_dotenv()
TOKEN = os.getenv('TOKEN')
intents = discord.Intents.default()
intents.message_content = True
client = commands.Bot(command_prefix='!', intents=intents)
scheduler = BackgroundScheduler(timezone="Asia/Seoul")

async def send_to_target_channel(content):
    # 替换为你的目标频道ID
    target_channel_id = 123456789012345678
    target_channel = client.get_channel(target_channel_id)
    if target_channel:
        await target_channel.send(content)

@client.event
async def on_ready():
    print(f'已登录为 {client.user}')
    # 给someFunc设置发送消息的回调
    someFunc.send_message_callback = send_to_target_channel
    # 添加定时任务
    scheduler.add_job(someFunc.func, 'cron', hour='19', minute='47,48')
    scheduler.start()
    print("定时任务已启动")

try:
    client.run(TOKEN)
except (KeyboardInterrupt, SystemExit):
    scheduler.shutdown()
    print("定时任务已关闭")

注意事项

  • 必须在Discord开发者面板开启对应机器人的Message Content Intent,否则无法发送消息。
  • 频道ID需要是纯数字,你可以在Discord开启开发者模式后右键频道复制ID。
  • BackgroundScheduler是同步线程,调用异步的Discord API必须用asyncio.run包裹,否则会报错。

内容的提问来源于stack exchange,提问作者dohyunii

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 16:25:21