Шлюз — WebSocket-соединение, по которому сервер присылает события в реальном времени: новые сообщения, участники, команды. Бот подключается один раз и держит соединение открытым.
Подключение
wss://voice-chat.ru/gateway?bot_token=vbt_…Токен передаётся параметром адреса (bot_token; также принимается token=Bot%20vbt_…). Сразу после подключения сервер присылает READY, затем — события. Подписываться ни на что не нужно: бот получает события всех своих серверов, каналов, которые может видеть, и личных бесед. Когда бота добавляют на новый сервер, подписка расширяется сама.
function connect(retry = 0) {
const ws = new WebSocket(`wss://voice-chat.ru/gateway?bot_token=${encodeURIComponent(TOKEN)}`);
let hb;
ws.onopen = () => (hb = setInterval(() => ws.send(JSON.stringify({ op: "HEARTBEAT", d: {} })), 25_000));
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
if (msg.op === "READY") retry = 0;
if (msg.op === "DISPATCH") handle(msg.t, msg.d);
if (msg.op === "ERROR") console.error(msg.d.message);
};
ws.onclose = (e) => {
clearInterval(hb);
if (e.code === 4001) return console.error("Неверный токен — не переподключаемся");
setTimeout(() => connect(retry + 1), Math.min(30_000, 1000 * 2 ** retry));
};
}
connect();Формат сообщений
Каждое сообщение — JSON-объект. Клиент отправляет команды, сервер — ответы и события:
{ "op": "HEARTBEAT", "d": {} } // клиент → сервер
{ "op": "READY", "d": { … } } // сервер → клиент
{ "op": "DISPATCH", "t": "MESSAGE_CREATE", "d": { "message": { … } } }
{ "op": "ERROR", "d": { "message": "Слишком часто — подождите секунду" } }READY
| Поле | Тип | Описание |
|---|---|---|
user | User | Сам бот. |
servers | { id, name, icon, banner }[] | Серверы бота. |
serverChannels | { serverId, channels: { id, categoryId }[] }[] | Каналы каждого сервера. |
dms | DmChannel[] | Личные беседы (members — id участников). |
presence | { userId, status, activity }[] | Кто сейчас в сети на серверах бота. |
voiceRooms | object[] | Кто в голосовых каналах. |
Подробности о сервере — GET /api/servers/:id. В READY есть и служебные поля приложения Voice (settings, appConfig и т. п.) — боту они не нужны.
Команды клиента
| op | d | Что делает |
|---|---|---|
HEARTBEAT | {} | Пульс раз в 25 секунд. Ответ — HEARTBEAT_ACK { at }. |
PRESENCE | { status: "online" | "idle" | "dnd" | "invisible" } | Статус бота. |
ACTIVITY_UPDATE | { activity: {…} | null } | Активность — «Играет в …». |
TYPING_START | { channelId } | «Бот печатает…» на несколько секунд (не чаще раза в 4 секунды). |
TIME_SYNC | { t0 } | Сверка часов: ответ { t0, server }. |
Живучесть соединения
- Сервер раз в 30 секунд проверяет соединение (ping на уровне WebSocket) и закрывает зависшие. Отправляйте HEARTBEAT раз в 25 секунд.
- Возобновления сессии нет: после переподключения придёт новый READY. Пропущенные сообщения можно дочитать через историю канала.
- Переподключайтесь с растущей паузой (1, 2, 4… до 30 секунд).
- Сброс токена в консоли закрывает все подключения бота.
Коды закрытия
| Код | Причина | Что делать |
|---|---|---|
| 4001 | Неверный или сброшенный токен, аккаунт заблокирован | Не переподключаться, проверить токен |
| 4003 | Почта не подтверждена (только для людей) | — |
| 4008 | Слишком много подключений (60 в минуту с адреса, 12 одновременно на аккаунт) или флуд командами | Подождать и переподключиться реже |
| 1000/1001/1006 | Обычное закрытие, перезапуск сервера, обрыв сети | Переподключиться |
Все события и их данные — в разделе События.