Discord.py如何在事件监听逻辑外主动向用户发送私信?
实现方案
discord.py的事件循环为异步独占设计,要在事件回调外主动发送消息,只需将发送任务提交到已运行的客户端事件队列中,同时将客户端的事件循环放到独立线程运行避免阻塞主业务逻辑即可。
封装实现代码
保存为my_discord_class.py:
import discord import asyncio from threading import Thread class DiscordDMClient: def __init__(self): # v2.x版本必须手动配置Intents,根据实际需求开启权限 intents = discord.Intents.default() intents.members = True intents.message_content = True self.client = discord.Client(intents=intents) self.loop = asyncio.new_event_loop() self.is_ready = False @self.client.event async def on_ready(): self.is_ready = True def connect(self, token): # 独立线程运行Discord客户端的事件循环,避免阻塞主程序 def run_loop(): asyncio.set_event_loop(self.loop) self.client.run(token) Thread(target=run_loop, daemon=True).start() # 等待连接就绪后再返回 while not self.is_ready: pass return self def send(self, user_id: int, content: str): # 将异步发送任务提交到事件队列执行 async def _send_task(): target_user = await self.client.fetch_user(user_id) await target_user.send(content) asyncio.run_coroutine_threadsafe(_send_task(), self.loop)
调用示例
和预期的伪代码逻辑完全一致:
from my_discord_class import DiscordDMClient BOT_TOKEN = "替换为你的机器人令牌" TARGET_USER_ID = 替换为目标用户的数字ID client = DiscordDMClient().connect(BOT_TOKEN) client.send(TARGET_USER_ID, "Hi")
注意事项
- 需提前在Discord开发者后台的机器人设置页,开启
Privileged Gateway Intents下的Server Members Intent和Message Content Intent权限,否则会触发权限报错 - Discord官方限制:机器人无法给既没有和它同处一个服务器、也没有主动给它发过消息的用户发送私信
- 示例中线程设置为守护线程,主程序退出时机器人连接会自动断开,如需长期后台运行可去掉
daemon=True参数
内容的提问来源于stack exchange,提问作者Frank
相关产品推荐
相关产品推荐

