如何用Python实现Discord bot接收用户回复的DM私信
核心问题根源
- discord.py 框架不存在
on_private_message这个事件名,这类错误写法大多是网上旧教程的拼写失误,这个事件永远不会被框架触发 - 事件回调的参数类型完全错位:
ctx是命令执行时传入的命令上下文对象(commands.Context),纯事件回调传入的第一个参数是原生Message消息对象,找不到ctx.content属性本质是把两种完全不同的对象搞混了 - 缺失必要的网关意图配置:就算事件名写对,没有开启对应权限时,bot既收不到DM事件推送,也读不到DM的文本内容
可直接运行的实现代码
import discord from discord.ext import commands # 订阅所需的网关意图,缺任意一项都会导致DM读取失效 intents = discord.Intents.default() intents.dm_messages = True intents.message_content = True bot = commands.Bot(command_prefix="!", intents=intents) @bot.event async def on_message(message: discord.Message): # 筛选逻辑:仅处理普通用户发来的DM,跳过bot自身发送的消息避免循环触发 if isinstance(message.channel, discord.DMChannel) and not message.author.bot: # 直接从原生message对象获取用户发送的DM文本 received_content = message.content # 示例业务逻辑:收到DM后向用户回发确认 await message.channel.send(f"已接收你的私信内容:{received_content}") # 必加逻辑:否则自定义on_message会覆盖框架默认的命令处理流程,所有前缀/斜杠命令将完全失效 await bot.process_commands(message)
额外踩坑注意事项
- 代码内开启意图后,还需要到Discord开发者后台的Bot配置页,手动打开MESSAGE CONTENT INTENT的开关,否则框架会返回空的消息内容,哪怕事件已经触发
- 不要使用
ctx.channel.id == ctx.author.dm_channel.id的判断逻辑,直接校验消息频道是否为discord.DMChannel类型更可靠,能避免权限不足、频道未初始化等边界场景的判断错误 - Discord平台本身存在限制:只有和bot共享至少一个服务器的用户,才能给bot发送DM,无共同服务器的陌生用户发起的DM请求会被平台直接拦截,这不属于代码可解决的范畴
内容的提问来源于stack exchange,提问作者bad_coder
相关产品推荐
相关产品推荐

