我为我的不和谐创建了我的群发 DM 机器人,以便立即向每个人发送包含正确信息的消息。但每次机器人尝试向服务器上的每个人发送 DM 时,我都会收到 403 Forbidden 错误。我不明白 Discord API 或我的机器人有什么问题?
import disnake
from disnake.ext import commands
from disnake import Permissions
allowed_role_id = 725585509023350794
class DMCog(commands.Cog):
@classmethod
def setup(cls, bot, allowed_role_id):
bot.add_cog(cls(bot, allowed_role_id))
def __init__(self, bot, allowed_role_id):
self.bot = bot
self.allowed_role_id = allowed_role_id
@commands.Cog.listener()
async def on_message(self, message):
try:
if message.author.bot or message.author == self.bot.user:
return
if isinstance(message.channel, disnake.DMChannel):
# Обработка сообщений в личных сообщениях
recipients_names = ', '.join([recipient.display_name for recipient in message.channel.recipients])
log_message = f"{message.author.display_name} ({message.author.id}) отправил сообщение в приватный канал с {recipients_names}: {message.content}"
print(log_message)
print(f"Получено личное сообщение от {message.author.name} ({message.author.id}): {message.content}")
else:
# Обработка сообщений на сервере
allowed_role = message.guild.get_role(self.allowed_role_id)
if allowed_role and allowed_role in message.author.roles:
log_message = f"{message.author.display_name} ({message.author.id}) отправил сообщение в #{message.channel.name} ({message.channel.id}): {message.content}"
print(log_message)
else:
print(
f"Сообщение от {message.author.display_name} не отправлено из-за отсутствия необходимой роли.")
except Exception as e:
print(f"Произошла ошибка в on_message: {e}")
@commands.command(name="send_dm")
async def send_dm_command(self, ctx, member: disnake.Member, *, message: str):
"""
Команда для отправки личного сообщения пользователю.
Пример использования: !send_dm @username <message>
"""
try:
# Отправляем личное сообщение
await member.send(message)
await ctx.send(f"Личное сообщение отправлено пользователю {member.mention}.")
except disnake.Forbidden:
await ctx.send("Невозможно отправить личное сообщение. Возможно, у пользователя закрыты личные сообщения.")
except Exception as e:
await ctx.send(f"Произошла ошибка при отправке личного сообщения: {e}")
@commands.command(name='mass_dm', aliases=['massdm'])
async def mass_dm(self, ctx, *, message):
try:
success_count = 0
failure_count = 0
for member in ctx.guild.members:
if member != ctx.author:
try:
await member.send(message)
success_count += 1
print(f"Отправлено сообщение {success_count} пользователю {member.display_name} ({member.id})")
except disnake.Forbidden:
failure_count += 1
print(
f"Ошибка 403 Forbidden: Невозможно отправить сообщение {failure_count} пользователю {member.display_name} ({member.id})")
except Exception as e:
failure_count += 1
print(
f"Произошла ошибка при отправке сообщения {failure_count} пользователю {member.display_name} ({member.id}): {e}")
await ctx.send(
f'Массовая рассылка завершена успешно. Отправлено: {success_count}, не отправлено из-за ошибок: {failure_count}')
except Exception as e:
await ctx.send(f'Произошла ошибка при массовой рассылке личных сообщений: {e}')
def setup(bot):
DMCog.setup(bot, allowed_role_id)
我正在尝试减少发送到 Discord API atm 的请求量,因为我觉得它的反 ddos 正在被触发。
更新:我重新启动了路由器,获得了新的 IP,在每个请求后添加了“await asyncio.sleep(1)”,但在使用 !massdm 命令时仍然收到“403 Forbidden”。同时,机器人能够将消息发送到服务器上的文本通道。
查看https://discord.com/developers/docs/topics/rate-limits#global-rate-limit。
所有机器人每秒最多可以向我们的 API 发出 50 个请求。如果未提供授权标头,则限制将应用于 IP 地址。这与路线上任何单独的速率限制无关。
错误 403 表示您发送到服务器的请求已被理解,但服务器拒绝执行它。
如果您的机器人足够大,您可以通过 https://dis.gd/contact
请求提高速率限制我建议更改您的代码,以便它在少于 50 个的组中执行 DM(可能是 45 个,以允许同一秒内的其他 API 请求),然后在进入下一组之前等待 1 秒,这样您就不会受到速率限制。
希望这有帮助。