
Discord API использует уникальные идентификаторы (ID) для всех сущностей: пользователей, сообщений, серверов и каналов. Если известен ID пользователя, его можно получить напрямую через методы библиотеки discord.py без необходимости обработки событий или команд.
Для начала необходимо убедиться, что включён режим разработчика в Discord. Это позволит копировать ID пользователей: клик правой кнопкой мыши по имени пользователя и выбор пункта “Копировать ID”. ID будет представлять собой строку из 18 цифр.
Чтобы получить пользователя по ID, используется метод await bot.fetch_user(user_id). Он делает запрос к Discord API и возвращает объект discord.User. Альтернативно, если пользователь уже кэширован, можно использовать bot.get_user(user_id), что значительно быстрее, так как не требует сетевого запроса.
Пример получения пользователя через fetch_user:
user = await bot.fetch_user(123456789012345678)
await ctx.send(f"Имя пользователя: {user.name}, ID: {user.id}")
Для работы методов fetch_user и get_user необходимо, чтобы бот имел доступ к API и был запущен с актуальным токеном. Также важно помнить, что fetch_user работает только в асинхронных функциях, помеченных ключевым словом async.
Если задача состоит в получении участника сервера (объекта discord.Member), используется await guild.fetch_member(user_id) или guild.get_member(user_id). Эти методы позволяют обращаться к данным пользователя в контексте конкретного сервера, включая роли и статус.
Получение объекта пользователя по ID через bot.fetch_user()

Метод bot.fetch_user(user_id) используется для получения объекта discord.User по числовому идентификатору пользователя. В отличие от bot.get_user(), который работает только с кэшированными пользователями, fetch_user выполняет прямой запрос к API Discord и подходит для получения данных о пользователях, ранее не взаимодействовавших с ботом.
Для использования метода необходима асинхронная функция. Пример:
@bot.command()
async def get_user(ctx, user_id: int):
user = await bot.fetch_user(user_id)
await ctx.send(f'Имя: {user.name}, ID: {user.id}')
Если указанный ID недействителен или пользователь не существует, будет выброшено исключение discord.NotFound. Также возможны discord.HTTPException и discord.Forbidden при проблемах с сетью или недостатке прав. Рекомендуется обернуть вызов в try-except:
try:
user = await bot.fetch_user(user_id)
except discord.NotFound:
await ctx.send("Пользователь не найден.")
except discord.HTTPException:
await ctx.send("Ошибка при запросе к API.")
Метод возвращает объект discord.User, а не discord.Member. Это означает, что он не содержит информации о сервере, такой как роли или статус. Чтобы получить Member, используйте guild.fetch_member().
Метод эффективен для работы с логами, логинами, чёрными списками и уведомлениями, когда необходимо обратиться к пользователю вне зависимости от его присутствия на сервере.
Разница между fetch_user() и get_user()

fetch_user(user_id) – асинхронный метод, который отправляет HTTP-запрос к Discord API и получает актуальные данные пользователя по его ID. Работает всегда, даже если пользователь не кэширован, но требует ожидания ответа от сервера. Используется как user = await bot.fetch_user(user_id).
get_user(user_id) – синхронный метод, возвращает объект пользователя из локального кэша клиента. Не инициирует сетевой запрос. Если пользователь ранее не взаимодействовал с ботом и не был загружен в кэш, метод вернёт None. Используется как user = bot.get_user(user_id).
Если необходимо гарантированно получить пользователя по ID, используйте fetch_user(). Если важна скорость и допускается отсутствие результата, используйте get_user(). Комбинировать методы можно так: сначала get_user(), затем при необходимости fetch_user().
Получение участника сервера по ID через guild.fetch_member()

Метод guild.fetch_member(user_id) позволяет получить объект discord.Member по его идентификатору на конкретном сервере. Это асинхронная функция, которая выполняет прямой запрос к API Discord и возвращает актуальные данные, даже если участника нет в кэше.
Перед использованием необходимо убедиться, что у бота есть доступ к серверу и разрешение members в интенте. В discord.Intents должен быть активирован intents.members = True.
Пример использования:

import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
bot = commands.Bot(command_prefix='!', intents=intents)
@bot.command()
async def get_member(ctx, user_id: int):
try:
member = await ctx.guild.fetch_member(user_id)
await ctx.send(f'Найден пользователь: {member.name}#{member.discriminator}')
except discord.NotFound:
await ctx.send('Участник с таким ID не найден на этом сервере.')
except discord.Forbidden:
await ctx.send('Недостаточно прав для получения информации о пользователе.')
except discord.HTTPException as e:
await ctx.send(f'Ошибка при запросе: {e}')
fetch_member() возвращает только тех пользователей, которые являются участниками конкретного сервера. Для получения данных о пользователе вне контекста сервера используется bot.fetch_user().
Рекомендуется использовать fetch_member() только при отсутствии участника в кэше, так как запрос к API медленнее, чем доступ к кэшу через guild.get_member().
Обработка ошибок при получении пользователя по ID

При работе с методом bot.fetch_user(id) или guild.get_member(id) возможны разные сбои. Корректная обработка исключений позволяет избежать краха бота и своевременно информировать пользователя о проблеме.
-
discord.NotFound – объект с указанным ID не найден:
except discord.NotFound: await ctx.send("Пользователь с таким ID не существует.") - Не запрашивайте повторно без изменения ID: это увеличит число лишних запросов к API.
-
discord.Forbidden – недостаточно прав:
- Убедитесь, что у бота есть права
VIEW_CHANNELили соответствующие для получения информации. - В блоке
except discord.Forbiddenуведомляйте администратора или логируйте сбой:except discord.Forbidden: logger.warning(f"Нет прав для получения пользователя {user_id}")
- Убедитесь, что у бота есть права
-
discord.HTTPException – ошибка сети или лимиты API:
- При частых ошибках с кодом 429 (rate limit) реализуйте задержку и повторный запрос:
await asyncio.sleep(retry_after) return await fetch_user(id, retries-1) - Для остальных кодов (500 и выше) повторите запрос не более 2 раз с экспоненциальной задержкой.
- При частых ошибках с кодом 429 (rate limit) реализуйте задержку и повторный запрос:
-
ValueError – неверный формат ID:
- Проверяйте, что ID состоит только из цифр и длина от 17 до 19 символов:
if not user_id.isdigit(): raise ValueError - В блоке
except ValueErrorпросите ввести корректный ID:await ctx.send("ID должен быть числом из 17–19 цифр.")
- Проверяйте, что ID состоит только из цифр и длина от 17 до 19 символов:
Рекомендуется оборачивать логику получения в отдельную функцию с параметром retries и логированием. Это упростит тестирование и повторное использование:
async def safe_fetch_user(bot, user_id, retries=3):
try:
return await bot.fetch_user(int(user_id))
except (discord.NotFound, discord.Forbidden, discord.HTTPException, ValueError) as e:
if retries > 0 and isinstance(e, discord.HTTPException):
await asyncio.sleep(2 ** (4 - retries))
return await safe_fetch_user(bot, user_id, retries-1)
raise
Работа с user объектом: получение имени, аватара и статуса

После получения объекта пользователя через await bot.fetch_user(user_id), доступ к имени осуществляется через user.name. Это основное имя, установленное пользователем, без тега. Чтобы получить полное имя с тегом, используйте user.name + '#' + user.discriminator или str(user).
Аватар пользователя доступен по URL: user.avatar.url. Этот атрибут возвращает прямую ссылку на изображение в высоком разрешении. Если у пользователя нет кастомного аватара, будет возвращена ссылка на дефолтный.
Чтобы получить текущий статус (online, idle, dnd, offline), необходимо использовать discord.Member вместо discord.User. Это требует наличия пользователя в кешированном списке участников сервера. Пример: member = guild.get_member(user.id), затем member.status. Значение может быть Status.online, Status.idle, Status.dnd или Status.offline.
Если требуется работа с пользовательским статусом вне контекста сервера, статус недоступен. Только через Member внутри гильдии можно получить activity, status и joined_at.
Как получить ID пользователя из сообщения или события

Для получения ID пользователя из сообщения в discord.py используйте атрибут message.author.id. Пример:
@bot.event
async def on_message(message):
user_id = message.author.id
print(f'ID пользователя: {user_id}')
При обработке событий, таких как присоединение пользователя на сервер, используйте объект события. Для on_member_join:
@bot.event
async def on_member_join(member):
user_id = member.id
print(f'ID нового участника: {user_id}')
Если нужно получить ID пользователя, который отправил команду, в функции команды примените ctx.author.id:
@bot.command()
async def userid(ctx):
user_id = ctx.author.id
await ctx.send(f'Твой ID: {user_id}')
Во всех случаях ID – это целое число типа int. Используйте его для дальнейших запросов, проверки прав или хранения в базе данных.
