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

Discord.py如何让机器人定时给用户发DM?ctx未定义问题怎么解决

问题原因

ctx是Discord.py触发命令、事件时自动生成的上下文对象,仅在对应回调函数的作用域内有效。你编写的定时任务是独立运行的异步任务,默认不持有ctx对象,强行传入会因为找不到实例报错,且这个场景下你完全不需要依赖ctx实现功能。

解决方案

不需要硬传ctx参数,直接通过bot实例获取你需要的用户、频道对象即可,修改逻辑如下:

  1. 提前准备好两个ID:你要生成邀请的目标频道ID、目标用户KexoTV#8921的用户ID(开启Discord开发者模式后右键对应对象即可复制)
  2. 在bot的on_ready事件触发后再启动定时任务,避免bot未完成资源加载时找不到对应对象

修正后的参考代码:

import discord
from discord.ext import tasks, commands
import time
import asyncio

# 替换为你自己的实际ID
TARGET_USER_ID = 123456789012345678 # 替换为KexoTV#8921的用户ID
TARGET_CHANNEL_ID = 987654321098765432 # 替换为你要生成邀请的频道ID

bot = commands.Bot(command_prefix='!', intents=discord.Intents.all())

async def timecheck():
    tm = time.localtime()
    if tm[6] == 6: # 每周日触发
        # 直接通过bot获取用户对象
        member = bot.get_user(TARGET_USER_ID)
        if not member:
            # 缓存里没找到就主动拉取
            member = await bot.fetch_user(TARGET_USER_ID)
        # 获取目标频道对象
        channel = bot.get_channel(TARGET_CHANNEL_ID)
        if not channel:
            channel = await bot.fetch_channel(TARGET_CHANNEL_ID)
        # 生成邀请链接
        invitelink = await channel.create_invite(max_uses=1, unique=True)
        # 发送私信
        await member.send(invitelink)

@tasks.loop(seconds=60)
async def mainloop():
    await timecheck()

# 等bot启动完成后再启动定时任务
@bot.event
async def on_ready():
    print(f'登录成功:{bot.user}')
    if not mainloop.is_running():
        mainloop.start()

bot.run('你的机器人Token')
注意事项
  • 确保你给机器人开启了足够的权限:对应频道的创建邀请权限、发送私信的权限
  • 不推荐使用用户名+识别码的方式匹配用户,用户改名后规则会直接失效,用固定ID兼容性更强
  • 如果需要适配多个频道/多个目标用户,直接扩展对应的ID配置即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 15:45:06