Назад к документации
Bot API Reference

Astral Bot API

Полная документация по Astral Bot API. Описание всех методов, типов данных, аутентификации, Gateway и OAuth2. Astral API совместим с протоколом Discord — большинство библиотек (discord.py, discord.js, JDA) работают с минимальными изменениями.

Base URL https://api.astral.ru
Gateway wss://gateway.astral.ru
CDN https://cdn.astral.ru

Обзор платформы

Astral — независимая платформа для мгновенного обмена сообщениями и голосовой связи. Bot API позволяет создавать автоматизированных ботов, которые могут отправлять сообщения, управлять серверами, модерировать участников и реагировать на события в реальном времени.


Совместимость

Astral API совместим с протоколом Discord v10. Это означает, что вы можете использовать существующие библиотеки:

discord.py
Python
discord.js
JavaScript
JDA
Java
Serenity
Rust

Для работы с Astral вместо Discord достаточно переопределить base URL API.


Эндпоинты

API (production)https://api.astral.ruREST API для всех запросов
API (canary)https://canary.api.astral.ruCanary-версия API для тестирования
Gateway (production)wss://gateway.astral.ruWebSocket для real-time событий
Gateway (canary)wss://canary.gateway.astral.ruCanary-версия Gateway
CDNhttps://cdn.astral.ruАватары, иконки, вложения
Mediahttps://media.astral.ruМедиа-прокси

Быстрый старт

Создайте бота за 5 минут. Ниже — минимальный путь от нуля до работающего бота.


1

Зарегистрируйтесь в Astral

Создайте аккаунт на astral.ru, если у вас его ещё нет.

2

Создайте приложение

Откройте Настройки → Приложения → «Создать приложение». Укажите имя бота. Приложение автоматически получит бот-пользователя.

3

Скопируйте бот-токен

Токен показывается один раз при создании. Сохраните его в безопасное место (переменная окружения). Если потеряли — пересоздайте через Reset Token.

4

Настройте библиотеку

Переопределите base URL на https://api.astral.ru в используемой библиотеке (discord.py, discord.js и т.д.).

5

Запустите бота

Запустите скрипт. Бот подключится к Gateway, получит событие READY и начнёт обрабатывать команды.


INFO Минимальный рабочий пример для Python и JavaScript — в разделах «Примеры» ниже.

Аутентификация

Все запросы к API должны содержать заголовок Authorization. Astral поддерживает три схемы аутентификации:


Bot Token

Для ботов

Используется ботами для доступа ко всем эндпоинтам. Токен генерируется при создании приложения. Формат: <application_id>.<secret>.

Заголовок
Authorization: Bot <token>
Пример
curl -H "Authorization: Bot 1234567890.aBcDeFgHiJkLmNoPqRsTuVwXyZ" \
  https://api.astral.ru/users/@me

Bearer Token (OAuth2)

Для OAuth2-приложений

Используется для доступа от имени пользователя через OAuth2 Authorization Code Flow. Доступные скоупы зависят от разрешений пользователя.

Заголовок
Authorization: Bearer <access_token>
Пример
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." \
  https://api.astral.ru/users/@me

Session Token

Только для клиента Astral

Внутренняя аутентификация клиентского приложения. Не используется ботами и сторонними приложениями.

Заголовок
Authorization: <session_token>

WARNING Запросы без заголовка Authorization или с невалидным токеном будут отклонены с ошибкой 401 Unauthorized.

Выполнение запросов

Все запросы к API отправляются как HTTP-запросы к base URL.


HTTP-методы

GET/resourceПолучить данные
POST/resourceСоздать ресурс
PATCH/resource/:idОбновить ресурс (частично)
PUT/resource/:idСоздать или заменить ресурс
DELETE/resource/:idУдалить ресурс

Заголовки

Обязательные заголовки для каждого запроса:

Authorization: Bot <token>
Content-Type: application/json
User-Agent: MyBot/1.0

Формат тела запроса

Тело запроса для POST/PATCH/PUT отправляется в формате JSON. Для отправки файлов используйте multipart/form-data с полем payload_json для JSON-части.


Audit Log Reason

Многие методы модерации поддерживают заголовок X-Audit-Log-Reason. Его значение сохраняется в журнале аудита сервера:

X-Audit-Log-Reason: Нарушение правил сервера

Snowflake ID

Все идентификаторы (ID) в Astral — это snowflake: 64-битные целые числа, передаваемые как строки в JSON. Snowflake содержит метку времени создания, что позволяет сортировать объекты по дате создания.

Формат бот-токена

Бот-токен Astral состоит из двух частей, разделённых точкой:

<application_id>.<secret>

Структура

application_idstring (snowflake)ID вашего приложения, например 1476982544653742137
secretstring (base64url)Случайная строка, 32 байта. Хешируется сервером через argon2id

Пример токена

1476982544653742137.aBcDeFgHiJkLmNoPqRsTuVwXyZaBcDeFgHiJkLmN

Процесс валидации

При каждом запросе с Bot-токеном сервер выполняет следующую цепочку:

  • 1. Парсит application_id из части до точки
  • 2. Загружает приложение из базы по application_id
  • 3. Проверяет, что приложение существует и имеет bot user
  • 4. Проверяет, что у приложения сохранён хеш токена (bot_token_hash)
  • 5. Верифицирует secret через argon2id (argon2.verify(hash, secret))
  • 6. Возвращает bot user ID при успешной верификации

WARNING При ротации токена (Reset Token) старый токен становится невалидным немедленно. Все активные Gateway-сессии бота будут разорваны.

Частые ошибки

INVALID_TOKEN (401)Токен невалиденНеверный формат, несуществующее приложение, или неверный secret
ACCESS_DENIED (403)Нет доступаНекоторые библиотеки (discord.py) отображают 401 как 403 ACCESS_DENIED на этапе application_info()

Типы данных

Основные объекты, которые возвращает API. Все ID — snowflake (строки в JSON).


User

Объект пользователя или бота

ПолеТипОписание
idsnowflakeID пользователя
usernamestringИмя пользователя
discriminatorintegerДискриминатор (0000–9999)
global_name?stringОтображаемое имя (может быть null)
avatar?stringХеш аватара. null если не установлен
avatar_color?integerЦвет аватара по умолчанию
bot?booleantrue если это бот
system?booleantrue если системный пользователь
flagsintegerБитовая маска публичных флагов

Guild

Объект сервера

ПолеТипОписание
idsnowflakeID сервера
namestringНазвание сервера (2–100 символов)
icon?stringХеш иконки
banner?stringХеш баннера
splash?stringХеш splash-изображения
owner_idsnowflakeID владельца
member_countintegerКоличество участников
featuresarray of stringВключённые фичи сервера
vanity_url_code?stringКастомный vanity URL

Channel

Объект канала

ПолеТипОписание
idsnowflakeID канала
typeintegerТип канала (0=text, 2=voice, 4=category, 5=news)
guild_id?snowflakeID сервера (null для DM)
name?stringНазвание канала
topic?stringОписание канала
position?integerПозиция в списке
parent_id?snowflakeID категории-родителя
nsfw?booleanПомечен как NSFW

Message

Объект сообщения

ПолеТипОписание
idsnowflakeID сообщения
channel_idsnowflakeID канала
authorUserАвтор сообщения
contentstringТекст сообщения
timestampISO8601 stringВремя отправки
edited_timestamp?ISO8601 stringВремя последнего редактирования
attachmentsarray of AttachmentВложения
embedsarray of EmbedВстроенные объекты
reactions?array of ReactionРеакции
pinnedbooleanЗакреплено ли сообщение

Application

Объект приложения (бота)

ПолеТипОписание
idsnowflakeID приложения
namestringНазвание приложения
icon?stringХеш иконки
description?stringОписание
bot_publicbooleanМожет ли бот быть приглашён другими
bot?UserБот-пользователь (при наличии)
redirect_urisarray of stringOAuth2 redirect URI

Методы — Приложения

Управление OAuth2-приложениями и бот-аккаунтами.


POST/oauth2/applications

Создать приложение

Создаёт новое приложение с бот-пользователем. Токен показывается только в этом ответе.

Параметры
ПолеТипОбяз.Описание
namestringДаИмя приложения (1–100 символов)
redirect_uris?array of stringНетOAuth2 redirect URI (макс. 10)
bot_public?booleanНетМожет ли кто-то другой добавить бота
Запрос
{
  "name": "Мой бот",
  "bot_public": true
}
Ответ
{
  "id": "1476982544653742137",
  "name": "Мой бот",
  "bot": {
    "id": "1476982544653742137",
    "username": "Мой бот",
    "token": "1476982544653742137.aBcDeFgHiJk..."
  },
  "client_secret": "xYz...",
  "bot_public": true
}
GET/applications/@me

Информация о текущем приложении

Возвращает данные приложения, связанного с бот-токеном. Используется при старте бота (login).

Ответ
{
  "id": "1476982544653742137",
  "name": "Мой бот",
  "icon": null,
  "description": null,
  "bot_public": true,
  "bot_require_code_grant": false,
  "verify_key": null,
  "flags": 0,
  "bot": {
    "id": "1476982544653742137",
    "username": "Мой бот",
    "discriminator": 7,
    "avatar": null,
    "bot": true
  }
}
GET/users/@me/applications

Список ваших приложений

Возвращает все приложения, созданные текущим пользователем.

Ответ
[
  { "id": "...", "name": "Bot 1", ... },
  { "id": "...", "name": "Bot 2", ... }
]
PATCH/oauth2/applications/:id

Обновить приложение

Обновляет настройки приложения.

Параметры
ПолеТипОбяз.Описание
name?stringНетНовое имя (1–100 символов)
redirect_uris?array of stringНетОбновлённые redirect URI
bot_public?booleanНетИзменить публичность бота
Запрос
{
  "name": "Новое имя",
  "bot_public": false
}
Ответ
{ ... обновлённый Application ... }
DELETE/oauth2/applications/:id

Удалить приложение

Полностью удаляет приложение и анонимизирует бот-пользователя. Требует sudo mode.

Запрос
{ "password": "your_password" }
Ответ
204 No Content
POST/oauth2/applications/:id/bot/reset-token

Пересоздать бот-токен

Генерирует новый токен. Старый немедленно аннулируется. Все Gateway-сессии бота будут разорваны. Требует sudo mode.

Запрос
{ "password": "your_password" }
Ответ
{
  "token": "1476982544653742137.newSecretHere...",
  "id": "1476982544653742137",
  "username": "Мой бот",
  ...
}
PATCH/oauth2/applications/:id/bot

Обновить профиль бота

Изменяет имя, аватар, баннер или био бот-пользователя.

Параметры
ПолеТипОбяз.Описание
username?stringНетНовое имя (2–32 символа)
discriminator?integerНетКастомный дискриминатор (только Visionary)
avatar?string (base64)НетАватар в формате data URI (null для удаления)
banner?string (base64)НетБаннер в формате data URI
bio?stringНетОписание бота (0–1024 символов)
Запрос
{
  "username": "CoolBot",
  "bio": "Бот для модерации"
}
Ответ
{ ... обновлённый User ... }

Методы — Gateway

Подключение к real-time WebSocket.


GET/gateway/bot

Получить URL Gateway

Возвращает WebSocket URL для подключения бота. Принимает ТОЛЬКО Bot-токены.

Ответ
{
  "url": "wss://gateway.astral.ru",
  "shards": 1,
  "session_start_limit": {
    "total": 1000,
    "remaining": 999,
    "reset_after": 14400000,
    "max_concurrency": 1
  }
}

Протокол Gateway

После подключения к WebSocket бот следует стандартному протоколу:

  • 1. Получить HELLO с heartbeat_interval
  • 2. Отправить IDENTIFY с токеном и intents
  • 3. Получить READY — бот онлайн
  • 4. Отправлять HEARTBEAT каждые heartbeat_interval мс
  • 5. Получать события: MESSAGE_CREATE, GUILD_MEMBER_ADD и т.д.

Основные Gateway-события

READYБот подключёнСодержит user, guilds, session_id
MESSAGE_CREATEНовое сообщениеОбъект Message
MESSAGE_UPDATEСообщение измененоЧастичный объект Message
MESSAGE_DELETEСообщение удаленоid, channel_id, guild_id
GUILD_CREATEБот добавлен на серверПолный объект Guild
GUILD_DELETEБот удалён с сервераid, unavailable
GUILD_MEMBER_ADDНовый участникОбъект Member + guild_id
GUILD_MEMBER_REMOVEУчастник ушёл/кикнутuser + guild_id
GUILD_MEMBER_UPDATEУчастник обновлёнЧастичный Member
GUILD_BAN_ADDПользователь забаненuser + guild_id
GUILD_BAN_REMOVEПользователь разбаненuser + guild_id
WARNING Bearer и session-токены будут отклонены с ошибкой INVALID_AUTH_TOKEN на /gateway/bot.

Методы — Сообщения


GET/channels/:channel_id/messages

Получить сообщения

Возвращает список сообщений канала. Поддерживает пагинацию.

Параметры
ПолеТипОбяз.Описание
limit?integerНетКоличество (1–100, по умолчанию 50)
before?snowflakeНетПолучить сообщения до этого ID
after?snowflakeНетПолучить сообщения после этого ID
around?snowflakeНетПолучить сообщения вокруг этого ID
Ответ
[
  {
    "id": "1234567890",
    "channel_id": "9876543210",
    "author": { "id": "...", "username": "User" },
    "content": "Привет!",
    "timestamp": "2026-02-28T00:00:00.000Z"
  }
]
GET/channels/:channel_id/messages/:message_id

Получить сообщение

Возвращает конкретное сообщение по ID.

Ответ
{ ... объект Message ... }
POST/channels/:channel_id/messages

Отправить сообщение

Отправляет новое сообщение в канал.

Параметры
ПолеТипОбяз.Описание
content?stringНет*Текст сообщения (0–4000 символов)
embeds?array of EmbedНет*Встроенные объекты
attachments?arrayНетМетаданные вложений (при multipart)
message_reference?objectНетОтвет на сообщение {message_id}
Запрос
{
  "content": "Привет от бота!"
}
Ответ
{ ... объект Message ... }
INFO * Обязательно хотя бы одно из: content, embeds, attachments.
PATCH/channels/:channel_id/messages/:message_id

Редактировать сообщение

Редактирует ранее отправленное ботом сообщение.

Параметры
ПолеТипОбяз.Описание
content?stringНетНовый текст
embeds?array of EmbedНетНовые embed-объекты
Запрос
{
  "content": "Обновлённый текст"
}
Ответ
{ ... обновлённый Message ... }
DELETE/channels/:channel_id/messages/:message_id

Удалить сообщение

Удаляет сообщение. Бот может удалять свои и чужие (при наличии MANAGE_MESSAGES).

Ответ
204 No Content

Методы — Серверы (Guilds)


POST/guilds

Создать сервер

Создаёт новый сервер.

Параметры
ПолеТипОбяз.Описание
namestringДаНазвание сервера (2–100 символов)
icon?string (base64)НетИконка в формате data URI
Запрос
{
  "name": "Мой сервер"
}
Ответ
{ ... объект Guild ... }
GET/guilds/:guild_id

Получить сервер

Возвращает информацию о сервере.

Ответ
{
  "id": "...",
  "name": "Мой сервер",
  "icon": "abc123",
  "owner_id": "...",
  "member_count": 42
}
PATCH/guilds/:guild_id

Обновить сервер

Обновляет настройки сервера. Требует MANAGE_GUILD.

Параметры
ПолеТипОбяз.Описание
name?stringНетНовое название
icon?string (base64)НетНовая иконка
banner?string (base64)НетНовый баннер
splash?string (base64)НетНовое splash-изображение
Запрос
{
  "name": "Обновлённое название"
}
Ответ
{ ... обновлённый Guild ... }
GET/users/@me/guilds

Список серверов бота

Возвращает все серверы, на которых состоит бот.

Ответ
[
  { "id": "...", "name": "Server 1" },
  { "id": "...", "name": "Server 2" }
]
DELETE/users/@me/guilds/:guild_id

Покинуть сервер

Бот покидает сервер.

Ответ
204 No Content

Методы — Участники


GET/guilds/:guild_id/members

Список участников

Возвращает список участников сервера.

Ответ
[
  {
    "user": { "id": "...", "username": "User" },
    "nick": "Никнейм",
    "roles": ["..."],
    "joined_at": "2026-01-01T00:00:00.000Z"
  }
]
GET/guilds/:guild_id/members/:user_id

Получить участника

Возвращает данные конкретного участника.

Ответ
{ ... объект Member ... }
PATCH/guilds/:guild_id/members/:user_id

Обновить участника

Изменяет никнейм, роли и другие свойства участника. Требует MANAGE_MEMBERS или соответствующие права.

Параметры
ПолеТипОбяз.Описание
nick?stringНетНовый никнейм (null для сброса)
roles?array of snowflakeНетНовый список ролей
mute?booleanНетСерверный мут
deaf?booleanНетСерверная глушилка
Запрос
{
  "nick": "Новый ник"
}
Ответ
{ ... обновлённый Member ... }
DELETE/guilds/:guild_id/members/:user_id

Кикнуть участника

Удаляет участника с сервера. Требует KICK_MEMBERS.

Ответ
204 No Content

Методы — Каналы


GET/channels/:channel_id

Получить канал

Возвращает информацию о канале.

Ответ
{
  "id": "...",
  "type": 0,
  "name": "general",
  "guild_id": "...",
  "position": 0,
  "topic": "Общий чат"
}

Дополнительные методы каналов (создание, обновление, удаление, permission overwrites) совместимы с Discord API v10. Подробности в спецификации Discord.

Методы — Роли


PUT/guilds/:guild_id/members/:user_id/roles/:role_id

Добавить роль

Добавляет роль участнику. Требует MANAGE_ROLES и позиция роли ниже вашей высшей роли.

Ответ
204 No Content
DELETE/guilds/:guild_id/members/:user_id/roles/:role_id

Убрать роль

Убирает роль у участника. Те же требования к правам.

Ответ
204 No Content

Методы — Баны


GET/guilds/:guild_id/bans

Список банов

Возвращает список забаненных пользователей на сервере.

Ответ
[
  {
    "user": { "id": "...", "username": "BadUser" },
    "reason": "Спам"
  }
]
PUT/guilds/:guild_id/bans/:user_id

Забанить пользователя

Банит пользователя на сервере. Требует BAN_MEMBERS.

Параметры
ПолеТипОбяз.Описание
delete_message_days?integerНетУдалить сообщения за N дней (0–7)
reason?stringНетПричина бана
ban_duration_seconds?integerНетВременный бан (секунды). null = перманентный
Запрос
{
  "delete_message_days": 1,
  "reason": "Нарушение правил"
}
Ответ
204 No Content
DELETE/guilds/:guild_id/bans/:user_id

Разбанить пользователя

Снимает бан. Требует BAN_MEMBERS.

Ответ
204 No Content

Методы — Приглашения


Для приглашения бота на сервер сформируйте URL:

https://astral.ru/oauth2/authorize?client_id=<APP_ID>&scope=bot&permissions=<PERMISSIONS>

Параметры URL

client_idsnowflakeID вашего приложения
scopestringОбязательно: bot
permissionsintegerБитовая маска нужных разрешений
guild_id?snowflakeID сервера для предвыбора (опционально)

Основные permissions

SEND_MESSAGES0x800Отправка сообщений
MANAGE_MESSAGES0x2000Управление сообщениями
READ_MESSAGE_HISTORY0x10000Чтение истории
EMBED_LINKS0x4000Встраивание ссылок
ATTACH_FILES0x8000Отправка файлов
ADD_REACTIONS0x40Добавление реакций
KICK_MEMBERS0x2Кик участников
BAN_MEMBERS0x4Бан участников
MANAGE_ROLES0x10000000Управление ролями
ADMINISTRATOR0x8Все права (используйте осторожно)

INFO Если bot_public = false, пригласить бота может только его владелец.

OAuth2

Astral поддерживает OAuth2 Authorization Code Flow для действий от имени пользователя.


Авторизация (шаг 1)

Перенаправьте пользователя на:

GET https://astral.ru/oauth2/authorize
  ?client_id=<APP_ID>
  &redirect_uri=<ENCODED_URI>
  &response_type=code
  &scope=identify guilds
  &state=<RANDOM_STATE>

Обмен кода на токен (шаг 2)

POST /oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=<AUTH_CODE>
&redirect_uri=<SAME_URI>
&client_id=<APP_ID>
&client_secret=<CLIENT_SECRET>

Ответ:

{
  "access_token": "eyJ...",
  "token_type": "Bearer",
  "expires_in": 604800,
  "refresh_token": "dGhp...",
  "scope": "identify guilds"
}

Обновление токена

POST /oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=<REFRESH_TOKEN>
&client_id=<APP_ID>
&client_secret=<CLIENT_SECRET>

Отзыв токена

POST /oauth2/token/revoke
Content-Type: application/x-www-form-urlencoded

token=<ACCESS_OR_REFRESH_TOKEN>
&client_id=<APP_ID>
&client_secret=<CLIENT_SECRET>

Доступные скоупы

identifystringДоступ к /users/@me (без email)
emailstringДоступ к email пользователя
guildsstringДоступ к списку серверов пользователя
botstringДобавление бота на сервер

Rate Limits

API применяет ограничения частоты запросов к каждому эндпоинту. Лимиты возвращаются в заголовках ответа.


Заголовки ответа

X-RateLimit-LimitintegerМаксимум запросов в текущем окне
X-RateLimit-RemainingintegerОставшиеся запросы в окне
X-RateLimit-ResetfloatUnix timestamp (секунды) сброса лимита
X-RateLimit-Reset-AfterfloatСекунд до сброса лимита
X-RateLimit-BucketstringУникальный идентификатор bucket
Retry-AfterintegerСекунд ожидания (только при 429)

Обработка 429

При получении HTTP 429 Too Many Requests:

  • 1. Прочитайте заголовок Retry-After
  • 2. Подождите указанное количество секунд
  • 3. Повторите запрос
HTTP/1.1 429 Too Many Requests
Retry-After: 5

{
  "code": "RATE_LIMITED",
  "message": "You are being rate limited",
  "retry_after": 5.0
}
INFO Большинство библиотек (discord.py, discord.js) обрабатывают rate limits автоматически.

Коды ошибок

API возвращает структурированные JSON-ошибки:

{
  "code": "ACCESS_DENIED",
  "message": "Access denied"
}

КодHTTPОписание
INVALID_TOKEN401Бот-токен или access token невалиден
MISSING_AUTHORIZATION401Заголовок Authorization отсутствует
INVALID_AUTH_TOKEN401Неверный тип токена для данного эндпоинта
ACCESS_DENIED403Нет доступа к ресурсу
MISSING_PERMISSIONS403Недостаточно permissions на сервере
UNKNOWN_APPLICATION404Приложение не найдено
BOT_USER_NOT_FOUND404У приложения нет бот-пользователя
BOT_ALREADY_IN_GUILD400Бот уже на этом сервере
INVALID_FORM_BODY400Ошибка валидации JSON-тела
INVALID_SCOPE400Неподдерживаемый OAuth2 scope
INVALID_GRANT400Невалидный authorization code или refresh token
RATE_LIMITED429Превышен лимит запросов
SUDO_MODE_REQUIRED403Требуется подтверждение паролем/2FA

Пример — Python (discord.py)

discord.py по умолчанию подключается к discord.com. Для Astral переопределите base URL:

import discord
import os

# === Переопределяем эндпоинт на Astral ===
discord.http.Route.BASE = "https://api.astral.ru"

intents = discord.Intents.default()
intents.message_content = True

bot = discord.Bot(intents=intents)

@bot.event
async def on_ready():
    print(f"[Astral] Бот {bot.user} подключён!")
    print(f"[Astral] Серверов: {len(bot.guilds)}")

@bot.event
async def on_message(message):
    if message.author.bot:
        return

    if message.content == "!ping":
        await message.channel.send("Pong!")

    if message.content == "!serverinfo":
        guild = message.guild
        embed = discord.Embed(
            title=guild.name,
            description=f"Участников: {guild.member_count}"
        )
        if guild.icon:
            embed.set_thumbnail(url=guild.icon.url)
        await message.channel.send(embed=embed)

# Токен из переменной окружения
bot.run(os.environ["ASTRAL_BOT_TOKEN"])

Для форков discord.py

py-corddiscord.http.Route.BASE = ...Аналогично discord.py
nextcordnextcord.http.Route.BASE = ...Аналогично discord.py
disnakedisnake.http.Route.BASE = ...Аналогично discord.py

Пример — JavaScript (discord.js)

Для discord.js v14+ передайте api в опции rest:

const { Client, GatewayIntentBits } = require('discord.js');

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
  ],
  rest: {
    api: 'https://api.astral.ru',
  },
});

client.on('ready', () => {
  console.log(`[Astral] Бот ${client.user.tag} подключён!`);
  console.log(`[Astral] Серверов: ${client.guilds.cache.size}`);
});

client.on('messageCreate', async (message) => {
  if (message.author.bot) return;

  if (message.content === '!ping') {
    await message.reply('Pong!');
  }

  if (message.content === '!serverinfo') {
    const guild = message.guild;
    const embed = {
      title: guild.name,
      description: `Участников: ${guild.memberCount}`,
      thumbnail: guild.iconURL() ? { url: guild.iconURL() } : undefined,
    };
    await message.channel.send({ embeds: [embed] });
  }
});

client.login(process.env.ASTRAL_BOT_TOKEN);

Пример — curl

Базовые запросы через командную строку для быстрого тестирования.


Проверить токен

curl -s -H "Authorization: Bot $TOKEN" \
  https://api.astral.ru/users/@me | jq .

Получить информацию о приложении

curl -s -H "Authorization: Bot $TOKEN" \
  https://api.astral.ru/applications/@me | jq .

Получить Gateway URL

curl -s -H "Authorization: Bot $TOKEN" \
  https://api.astral.ru/gateway/bot | jq .

Отправить сообщение

curl -X POST \
  -H "Authorization: Bot $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content": "Привет из curl!"}' \
  https://api.astral.ru/channels/<CHANNEL_ID>/messages | jq .

Забанить пользователя

curl -X PUT \
  -H "Authorization: Bot $TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Audit-Log-Reason: Спам" \
  -d '{"delete_message_days": 1}' \
  https://api.astral.ru/guilds/<GUILD_ID>/bans/<USER_ID>

Переменные окружения

Рекомендуемый .env файл:

# === Обязательные ===

# Бот-токен Astral
ASTRAL_BOT_TOKEN=<application_id>.<secret>

# Base URL API
ASTRAL_API_BASE=https://api.astral.ru

# === Опциональные ===

# Gateway URL (обычно автоопределяется из /gateway/bot)
ASTRAL_GATEWAY_URL=wss://gateway.astral.ru

# CDN для аватаров и вложений
ASTRAL_CDN_URL=https://cdn.astral.ru

# Логирование (debug, info, warn, error)
LOG_LEVEL=info

WARNING Никогда не коммитьте .env в git. Добавьте .env в .gitignore до первого коммита.

Безопасность

Обязательные правила

  • Храните токен ТОЛЬКО в переменных окружения. Никогда не вставляйте токен в исходный код.
  • При подозрении на утечку — немедленно пересоздайте токен через POST /oauth2/applications/:id/bot/reset-token.
  • Используйте минимальные permissions при приглашении бота (принцип least privilege).
  • Для OAuth2: всегда генерируйте и проверяйте state-параметр для защиты от CSRF-атак.
  • Валидируйте все входящие данные от пользователей перед обработкой.
  • Делайте обработчики событий идемпотентными — повторная обработка не должна вызывать побочных эффектов.
  • Добавьте .env в .gitignore до первого коммита в репозиторий.
  • Не логируйте токены или секреты. Используйте маскирование в логах.

FAQ

Почему я получаю 403 ACCESS_DENIED при запуске бота?

Скорее всего, токен невалиден. Пересоздайте токен в настройках приложения. Также убедитесь, что библиотека указывает на Astral API (https://api.astral.ru), а не на discord.com.

Можно ли использовать discord.py / discord.js без изменений?

Почти. Нужно только переопределить base URL. Для discord.py: discord.http.Route.BASE = "https://api.astral.ru". Для discord.js: передайте rest.api в конструктор Client.

Как пересоздать утерянный токен?

POST /oauth2/applications/:id/bot/reset-token. Требует подтверждения паролем (sudo mode). После ротации старый токен перестаёт работать мгновенно.

Есть ли ограничение на количество серверов для бота?

На данный момент явного лимита нет. При масштабировании рекомендуем использовать sharding (параметр shards из /gateway/bot).

Поддерживаются ли slash-команды?

API совместим с протоколом Discord. Slash-команды работают через стандартные Application Commands эндпоинты.

Как отлаживать бота?

Используйте curl для ручных запросов (раздел «Пример: curl»). Проверяйте токен через GET /users/@me. Включите debug-логирование в вашей библиотеке.