Disnake机器人解封用户后发送私信失败的问题求助
Disnake机器人unban后无法发送私信(错误50007)
错误原因
错误码50007: Cannot send messages to this user的核心原因是机器人没有权限向目标用户发送私信,常见触发场景:
- 用户在Discord隐私设置中关闭了「允许来自服务器成员的私信」
- 用户直接屏蔽了机器人
- 解封后用户未重新加入服务器,且未开启接受陌生人私信的权限(Discord默认禁止陌生人发私信)
解决办法
- 添加异常捕获:避免因无法发送私信导致整个命令崩溃,同时给执行命令的管理员反馈状态
- 优化文件读写逻辑:修复原代码中ban列表文件读取的逻辑漏洞
- 备选通知方案:私信失败时,在服务器指定频道发送公开通知
修改后的完整代码
import disnake from disnake.ext import commands import datetime import asyncio @bot.slash_command(name="unban", description="Разбан пользователя (указание причины обязательно)" ) @commands.has_permissions(ban_members=True) async def unban(inter, member_id: str, reason: str): user = await bot.get_or_fetch_user(int(member_id)) await inter.response.send_message(f'{user.mention} разбанен по причине: "{reason}".') await bot.guilds[0].unban(user, reason=reason) ban_list_channel = bot.get_channel(1274693427811844157) notification_channel = bot.get_channel(1274130140489580584) # 服务器通知Embed unban_embed = disnake.Embed( title='Пользователь разбанен!', description=f'{user.mention} разбанен на сервере.\n{ban_list_channel.mention} обновлен.', color=disnake.Colour.yellow(), timestamp=datetime.datetime.now() ) # 用户私信Embed unban_embed_for_user = disnake.Embed( title='Вы были разбанены!', description=f'Вы были разбанены на сервере {bot.guilds[0].name}.\nПричина: "{reason}"\nПриглашаем вас: https://discord.gg/hwQM6GG4kB', color=disnake.Colour.green(), timestamp=datetime.datetime.now() ) # 修复ban列表文件读写逻辑 lines = [] with open('source/txt/ban_list.txt', 'r') as ban_list: for line in ban_list: if str(member_id) not in line.strip(): lines.append(line) with open('source/txt/ban_list.txt', 'w') as ban_list: ban_list.writelines(lines) with open('source/txt/ban_list.txt', 'r') as ban_list: text = ban_list.read() # 发送服务器通知并更新ban列表 await notification_channel.send(embed=unban_embed) await ban_list_channel.purge(limit=3) ban_list_embed = disnake.Embed( title='Список забаненных пользователей:', description=text, color=disnake.Colour.red(), timestamp=datetime.datetime.now() ) await ban_list_channel.send(embed=ban_list_embed) await asyncio.sleep(3) await inter.delete_original_message() # 处理私信发送逻辑,添加异常捕获 try: await user.send(embed=unban_embed_for_user) await inter.followup.send(f"Уведомление отправлено пользователю {user.mention}", ephemeral=True) except disnake.errors.Forbidden: # 私信失败时发送公开通知 fail_embed = disnake.Embed( title="Не удалось отправить уведомление", description=f"Не удалось отправить личное сообщение пользователю {user.mention}. Возможно, он закрыл личные сообщения или заблокировал бота.", color=disnake.Colour.red() ) await notification_channel.send(embed=fail_embed) await inter.followup.send(f"Не удалось отправить уведомление пользователю {user.mention}", ephemeral=True)
关键修改说明
- 修复了原代码中ban列表文件读取的逻辑错误(避免遗漏或重复处理行)
- 添加
try-except块捕获Forbidden异常,确保命令正常执行完成 - 私信失败时在通知频道发送公开提示,同时给管理员发送临时反馈(
ephemeral=True仅执行者可见) - 优化用户私信内容,用第二人称替代提及,更符合私信场景
内容的提问来源于stack exchange,提问作者Icold
相关产品推荐
相关产品推荐

