Коротко — да, бот может отправлять личные сообщения (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. Что предпочитаете?