Собственные серверы
Пользователи могут запускать GameVox на своём железе, и ваш бот работает и там. Облачный API пересылает REST-запросы и события шлюза в формате Discord по управляющему каналу собственного сервера, сервер выполняет их на своей локальной базе данных, и ответ возвращается по тому же каналу. Большинство эндпоинтов работают прозрачно. Неподдерживаемые перечислены ниже.
Как это работает
Когда ваш бот вызывает GET /guilds/{id} или POST /channels/{id}/messages, облачный bot-API проверяет тариф целевого сервера. Если это собственный сервер, мы сериализуем запрос (метод, путь, query, тело, bot_user_id) и отправляем его по постоянному управляющему WebSocket-каналу, который собственный сервер держит открытым с нами. Процесс собственного сервера выполняет аналогичный обработчик на своих базах данных SQLite и возвращает конверт ответа, который мы дословно передаём вашему боту.
Пересылка происходит на уровне bot-API. Ваша библиотека её не видит. Никакого другого токена, другого URL шлюза или другого SDK. Бот подключается к тому же gateway.gamevox.com и вызывает тот же app-api.gamevox.com, размещён ли сервер в облаке или на собственном железе.
Задержка
Время туда и обратно определяется WAN-каналом владельца сервера плюс временем запроса к SQLite, обычно это 30–300 мс сверх облачного вызова. Действует общий дедлайн 12 с. Если собственный сервер перестаёт отвечать (не в сети, обновляется, пропала сеть), бот получает 504 Gateway Timeout в пределах секунды после дедлайна.
Что работает
Всё перечисленное ниже выполняется на локальных данных собственного сервера, с той же структурой ответа, что и в облаке.
- Сообщения: список, получение, отправка, изменение, удаление, массовое удаление.
- Реакции: добавление, удаление своей, удаление чужой, удаление всех, удаление всех по эмодзи, список пользователей.
- Закрепление: закрепить, открепить, список.
- Набор текста:
POST /channels/{id}/typing. - Каналы: получение, изменение, удаление, список, создание, изменение порядка.
- Сервер (guild): получение, изменение (название и описание).
- Участники: список, поиск,
@me, получение, изменение, изменение никнейма, кик, добавление или удаление роли. - Баны: список, получение, создание (PUT), удаление.
- Роли: список, получение, создание, изменение, изменение порядка, удаление, а также права ролей.
- Эмодзи: список, получение (эмодзи сервера).
- Саундборд: список, получение (звуки сервера).
- Журнал аудита:
GET /guilds/{id}/audit-logs, только записи, важные для ботов. - Персональный URL: GET (всегда пустая структура).
- Голосовое состояние: GET (в реальном времени из SFU), PATCH (отключение микрофона, перемещение, отключение от канала).
- Вебхуки: полный CRUD и выполнение. Строки хранятся в облаке; итоговое сообщение записывается в канал собственного сервера по тому же пути пересылки, что и сообщения ботов, поэтому сообщения в канале помечаются правильно.
- Слэш-команды: вызов; права проверяются по группам самого сервера. Регистрация такая же, как в облаке.
- Компоненты сообщений: кнопки, текстовые списки выбора, модальные окна и эфемерные ответы, включая эндпоинты обратного вызова взаимодействия, последующих сообщений и исходного ответа. См. Компоненты сообщений.
Что возвращает 501 (принимается, но не реализовано)
PATCH .../voice-states/*сdeaf. Серверное отключение звука сейчас не является примитивом SFU собственного сервера. Отключение микрофона, перемещение (черезchannel_id) и отключение от канала (черезchannel_id: null) работают.PUT .../channels/{id}/permissions/{oid}. Собственный сервер использует права на уровне групп вместо перезаписей для отдельных каналов, так что применять перезапись Discord не к чему.DELETEвозвращает204(удаление несуществующей перезаписи ничего не делает).PATCH .../guilds/{id}/vanity-url. У собственных серверов нет персональных URL.
Что возвращает 404 (не маршрутизируется на собственные серверы)
Эти эндпоинты работают с ресурсами, которые существуют только в облачной инфраструктуре. Если они нужны вашему боту, используйте облачный сервер.
- Создание канала ЛС (
POST /users/@me/channels). - Поиск пользователя за пределами сервера (
GET /users/{id},GET /users/by-name/{name}). GET /users/@me/guilds.
События шлюза
Собственные серверы публикуют часть событий, которые отправляет облако. Бот получает их через ту же сессию шлюза. Никакой другой модели подписки.
Уже отправляются с собственных серверов:
MESSAGE_CREATE,MESSAGE_UPDATE,MESSAGE_DELETE,MESSAGE_DELETE_BULKMESSAGE_REACTION_ADD,MESSAGE_REACTION_REMOVECHANNEL_CREATE,CHANNEL_UPDATE,CHANNEL_DELETECHANNEL_PINS_UPDATEGUILD_UPDATE(изменение названия / описания)GUILD_MEMBER_ADD,GUILD_MEMBER_REMOVE,GUILD_MEMBER_UPDATE(изменение никнейма или роли)GUILD_BAN_ADD,GUILD_BAN_REMOVEGUILD_ROLE_CREATE,GUILD_ROLE_UPDATE,GUILD_ROLE_DELETE(срабатывает при изменении модели прав на сервере)TYPING_STARTVOICE_STATE_UPDATE(вход, выход, отключение микрофона собой или сервером, отключение звука)INTERACTION_CREATE(слэш-команды, клики по компонентам и отправка модальных окон; пересылаются облаком)
Пока не отправляются с собственных серверов:
PRESENCE_UPDATE. Нужен новый механизм рассылки присутствия на собственном сервере.- События сообщений в ЛС. На собственных серверах нет личных сообщений между серверами.
Известные расхождения
- Отключение микрофона собой и сервером: SFU собственного сервера хранит один бит отключения микрофона на участника, а не разделяет
self_muteиmute, как Discord.VOICE_STATE_UPDATEзаписывает одно и то же значение в оба поля; снятие серверного отключения может выглядеть так, будто пользователь сам включил микрофон. Ботам, которые читают только одно из двух полей, это не мешает; ботам-конечным автоматам, которые смешивают оба поля, для переключателей модераторов лучше ориентироваться наmute. - Перемещение в голосе даёт два события: в Discord PATCH
voice-states/{uid}с новымchannel_idотправляет одно событиеVOICE_STATE_UPDATE; на собственном сервере перемещение реализовано как выход + повторный вход, поэтомуchannel_idцели сначала станетnull, а затем новым каналом. Считайте последовательные обновления одного пользователя в пределах нескольких сотен миллисекунд одним перемещением.
Как определить собственный сервер
Объект guild сейчас не содержит флага «собственный сервер» (мы сохраняем побайтную совместимость с Discord). Если боту нужно ветвление, надёжный признак это 501 или 404 от одного из эндпоинтов выше с JSON-телом ошибки вроде:
{ "code": 0, "message": "voice-state modify not supported on self-hosted yet" } Если более простое определение понадобится многим ботам, мы добавим в payload сервера элемент features (например, "SELF_HOSTED"). Если это вам поможет, оставьте отзыв на вкладке поддержки вашего приложения.
Ошибки
502 Bad Gateway. Собственный сервер вернул некорректный ответ. Бывает редко; обычно из-за расхождения версий во время обновления.503 Service Unavailable. Управляющий канал сейчас не подключён. Повторите с увеличивающейся задержкой.504 Gateway Timeout. Сервер не ответил за 12 с.