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

Discord.py机器人在DM中发送消息时出现403权限缺失错误的求助

Discord.py机器人在DM中发送消息时出现403权限缺失错误的求助

嘿,我刚好碰到过类似的Discord DM权限问题,来帮你捋一捋!你现在的情况是机器人在DM里触发斜杠命令后,能通过interaction.response.send_message回复,但直接调用interaction.channel.send就报403错误,而且还需要找到不用历史记录读取用户消息的方法,对吧?

先说说发送消息的403问题

你打印的权限显示send_messages=True但实际发送失败,这是因为Discord的DM场景里,直接频道消息权限和交互上下文权限是分开的。当用户触发斜杠命令时,机器人获得的是这个交互会话的临时权限,允许你用interaction.response或者后续的followup发送消息,但直接调用channel.send需要机器人拥有独立的DM发送权限——这可能因为用户隐私设置(比如用户没允许机器人主动发消息)或者权限配置的细节导致失败。

最快的解决办法:用交互跟进消息替代channel.send

直接把你代码里的await interaction.channel.send("Hello 2!")改成:

await interaction.followup.send("Hello 2!")

因为跟进消息是基于用户触发的命令上下文,Discord会默认允许这种消息发送,不会触发权限错误。如果需要延迟回复,也可以先调用await interaction.response.defer()(告诉Discord你要稍后回复),再用跟进消息发送内容。

另外再检查两个配置细节:

  • 开发者门户里,机器人的bot Scope必须勾选,同时权限里要确保开启Send Messages(虽然DM场景权限逻辑特殊,但这是基础配置)
  • 确认用户没有在Discord里把你的机器人拉黑或者设置成“不接收消息”(用户可以在机器人资料页调整这个设置)

再说说不用历史记录读取消息的方法

如果你不想用channel.history或last_message,可以用wait_for事件来监听用户的回复,而且可以限定只监听当前用户在当前DM频道的消息,非常精准:
给你的Start命令加一段监听逻辑(记得先导入asyncio库):

import asyncio

@bot.tree.command(name="start",description="Start a game!")
async def Start(interaction:discord.Interaction, players: int=2):
    await interaction.response.send_message("Hello! Please reply with your choice.")
    
    # 定义检查条件:只接收当前用户在当前DM频道的消息
    def check(msg):
        return msg.author == interaction.user and msg.channel == interaction.channel
    
    try:
        # 等待用户回复,超时时间设为60秒
        user_reply = await bot.wait_for('message', check=check, timeout=60.0)
        await interaction.followup.send(f"You said: {user_reply.content}")
    except asyncio.TimeoutError:
        await interaction.followup.send("You didn't reply in time!")

注意:用这个方法需要开启message_content意图——你得在开发者门户的Bot页面找到Message Content Intent并勾选,同时代码里的Intents要包含它:

# 要么用全量Intents
intents = discord.Intents.all()
# 要么明确开启需要的意图
# intents = discord.Intents.default()
# intents.message_content = True

bot = commands.Bot(command_prefix="/", intents=intents)

你的原始代码(方便参考)

import discord
from discord.ext import commands

bot = commands.Bot(command_prefix="/", intents=discord.Intents.all())

@discord.app_commands.allowed_installs(guilds=True, users=True)
@discord.app_commands.allowed_contexts(guilds=True, dms=True, private_channels=True)
@bot.tree.command(name="start",description="Start a game!")
async def Start(interaction:discord.Interaction, players: int=2):
    
    print(f"{interaction.channel.permissions_for(interaction.channel.me).send_messages=}")
    await interaction.response.send_message("Hello!")
    await interaction.channel.send("Hello 2!")

@bot.event
async def on_ready():
    print("Bot is online!")
    await bot.tree.sync()

bot.run(token)

补充你提供的场景说明

  • 运行场景:尝试让应用工作的DM窗口与斜杠命令界面
  • Scope设置:机器人在开发者门户中已勾选的Scope选项

备注:内容来源于stack exchange,提问作者Abyss

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 17:28:03