Можно ли настроить бота так, чтобы он отправлял личные сообщения (DM) пользователям в Discord?

Пожалуйста, пришлите пример кода на Python. Помогите!
  • 6 апреля 2026 г. 19:01
Ответы на вопрос 1
Коротко — да, бот может отправлять личные сообщения (DM) пользователям в Discord. Однако есть важные ограничения и нюансы:

- Пользователь может запретить получать личные сообщения от участников сервера (в настройках приватности). В этом случае бот, который является участником сервера, не сможет ему написать — Discord вернёт Forbidden.
- Пользователь мог заблокировать бота — тоже нельзя отправлять DM.
- Нельзя рассылать массовые нежелательные сообщения (спам); соблюдайте правила Discord и следите за rate‑limit.
- Для событий, связанных с участниками сервера (например, on_member_join), требуется Intent members (его нужно включить в коде и в настройках приложения на портале разработчика).

Ниже — минимальный пример на Python с библиотекой discord.py (v2+). Установка: pip install -U discord.py

Пример бота, который:
- отправляет DM при команде !dm @user текст
- приветствует новых участников (on_member_join)

Код:
```python
import discord
from discord.ext import commands
import asyncio

intents = discord.Intents.default()
intents.members = True  # нужен для on_member_join и типа discord.Member

bot = commands.Bot(command_prefix='!', intents=intents)

@bot.event
async def on_ready():
    print(f'Logged in as {bot.user} (id: {bot.user.id})')

@bot.event
async def on_member_join(member: discord.Member):
    # Попытка отправить приватное сообщение при заходе на сервер
    try:
        await member.send(
            f"Привет, {member.name}! Добро пожаловать на сервер. Если у тебя возникнут вопросы, напиши мне."
        )
        print(f"Отправлено приветствие {member}")
    except discord.Forbidden:
        # Пользователь запретил личные сообщения или заблокировал бота
        print(f"Не удалось отправить DM {member} — доступ запрещён.")
    except discord.HTTPException as e:
        print(f"Ошибка при отправке DM {member}: {e}")

@bot.command(name='dm')
@commands.has_permissions(administrator=True)  # пример ограничения команды
async def dm_command(ctx, member: discord.Member = None, *, text: str = None):
    if member is None or text is None:
        await ctx.send("Использование: !dm @пользователь текст_сообщения")
        return

    try:
        await member.send(text)
        await ctx.send(f"Отправлено DM {member.mention}.")
    except discord.Forbidden:
        await ctx.send("Не удалось отправить DM — у пользователя отключены личные сообщения или он заблокировал бота.")
    except discord.HTTPException as e:
        await ctx.send("Ошибка при отправке DM.")
        print("HTTPException:", e)

# Пример отправки по ID (если у вас есть ID пользователя)
@bot.command(name='dmid')
async def dm_by_id(ctx, user_id: int, *, text: str):
    try:
        user = await bot.fetch_user(user_id)  # fetch_user не требует intents.members
        await user.send(text)
        await ctx.send(f"Отправил сообщение пользователю с ID {user_id}.")
    except discord.NotFound:
        await ctx.send("Пользователь с таким ID не найден.")
    except discord.Forbidden:
        await ctx.send("Не удалось отправить DM — доступ запрещён.")
    except discord.HTTPException as e:
        await ctx.send("Ошибка при отправке DM.")
        print(e)

# Запуск бота — вставьте сюда ваш токен (не публикуйте токен!)
bot.run("ВАШ_BOT_TOKEN")
```

Полезные замечания:
- Включите Intent "Server Members" (Privileged Gateway Intent) в панели разработчика Discord для вашего приложения, если вы используете intents.members = True.
- Для отправки DM по ID можно использовать bot.fetch_user(user_id) — это работает без intents, но всё равно будет возвращён Forbidden, если пользователь не принимает сообщения.
- Обрабатывайте исключения discord.Forbidden и discord.HTTPException.
- Не храните токен в публичных репозиториях; используйте переменные окружения или безопасный стор.
- Уважайте приватность пользователей и правила Discord — не рассылать спам.

Если хотите, могу прислать пример с asyncio.sleep и очередью для массовой рассылки с учётом rate limits, или показать, как хранить токен в .env. Что предпочитаете?
Похожие вопросы