Skip to content

Ключи и лимиты ​

Авторизация ​

Каждый запрос к API несёт заголовок с ключом приложения:

http
Authorization: Bot emb_2878fed6c91a4b7e…

Схема — именно Bot, а не Bearer. С Bearer ключ приложения не сработает: эта схема зарезервирована под токены пользователей.

js
const headers = { Authorization: `Bot ${process.env.BOT_TOKEN}` }

Держите ключ в переменных окружения. Не коммитьте его в репозиторий и не вставляйте в код фронтенда — ключ даёт право говорить от имени вашего бота во всех каналах, где он установлен.

Что открывает ключ ​

Выпуская ключ, вы отмечаете, чем ваше приложение будет пользоваться. Запрос к маршруту, не входящему в этот список, получает 403 — даже если роль бота на канале такое действие разрешает.

ScopeЧто открываетМаршруты
channel:readсведения о канале, комнаты, участникиGET /channels/*
messages:readистория текстовых комнатGET /rooms/{id}/messages
messages:writeотправка, правка, удаление своих сообщений, реакцииPOST/PATCH/DELETE сообщений и реакций
voiceвход и выход из голосовых комнатPOST/DELETE /rooms/{id}/voice
eventsподписка на поток событий и настройка вебхукаGET /events/token, GET/PUT/DELETE /webhook
moderationзакрепление, мут, кик, перенос участников/channels/{id}/members/*, /rooms/{id}/messages/{id}/pin
commandsобъявление списка команд ботаGET/PUT /commands

Какой scope нужен каждому маршруту — указано в справочнике. Маршрут GET /me открыт любому ключу.

Отмечайте только нужное

events — самый широкий доступ на чтение: поток несёт все сообщения всех каналов, где стоит бот. Боту-уведомителю, который только пишет, он не нужен — снимите его, и утёкший ключ не даст читать переписку.

moderation — самый опасный на запись: кик лишает человека канала целиком. Отмечайте его только боту-модератору.

Отказ по scope называет недостающее имя:

json
{
  "error": "Forbidden",
  "status": "error",
  "message": "Ключу не выдан scope «messages:write». Перевыпустите ключ в кабинете приложений, отметив этот доступ",
  "requiredScope": "messages:write"
}

Чтобы изменить набор, перевыпустите ключ — там же отмечаются нужные пункты. moderation и commands появились позже остальных, поэтому у ключей, выпущенных раньше, их нет: перевыпустите ключ, если собираетесь ими пользоваться.

Ключ и роль — два разных ограничения

Работает то, что разрешила и роль бота на канале, и ключ. Роль настраивает администратор канала, ключ — вы. Подробнее: права на канале.

Коды ответов ​

КодЗначениеЧто делать
200 / 201 / 204успех—
400неверные параметры запросатекст ошибки указывает поле
401ключ не принят: отсутствует, неверен, отозванпроверить ключ; перевыпуск в кабинете
403действие запрещено: не выдан scope ключа либо не хватает права ролиполе requiredScope в ответе называет недостающий scope; если его нет — см. права на канале
422запрос корректен, но выполнить нельзя (комната не того типа, чужой канал)проверить идентификаторы
429превышена квотаподождать Retry-After секунд
504портал не ответил вовремяповторить запрос

Тело ошибки всегда одной формы:

json
{ "error": "Forbidden", "status": "error", "message": "Недостаточно прав" }

401 и 403 — разные проблемы

401 — проблема с ключом: он не принят вовсе.

У 403 две причины, и различает их поле requiredScope:

  • оно есть — ключу не выдан нужный scope. Перевыпустите ключ, отметив этот доступ;
  • его нет — не хватает права роли бота на канале. Перевыпуск не поможет, попросите администратора канала дать боту роль с нужным правом.

Квоты ​

КвотаЛимит
Все запросы60 в минуту на приложение
Отправка сообщений20 в минуту на приложение

Квота считается на приложение, а не на IP: несколько ваших серверов делят одну.

Остаток виден в каждом ответе:

http
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57

При превышении приходит 429:

http
HTTP/1.1 429 Too Many Requests
Retry-After: 23
json
{
  "error": "Too Many Requests",
  "status": "error",
  "message": "Превышена квота запросов: 60 в минуту",
  "retryAfterSec": 23
}

Простейшая обработка:

js
async function api(path, options = {}) {
  const res = await fetch(`https://emotify.ru/api/v1${path}`, {
    ...options,
    headers: {
      Authorization: `Bot ${process.env.BOT_TOKEN}`,
      'Content-Type': 'application/json',
      ...options.headers
    }
  })

  if (res.status === 429) {
    const wait = Number(res.headers.get('Retry-After') ?? 5)
    await new Promise((r) => setTimeout(r, wait * 1000))
    return api(path, options) // одна повторная попытка после паузы
  }

  return res
}

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

Перевыпуск ключа ​

Настройки → Приложения → «Перевыпустить ключ».

  • Новый ключ показывается один раз — как и при создании.
  • Старый перестаёт работать сразу, промежутка с двумя рабочими ключами нет.
  • Обновите ключ в окружении бота до нажатия кнопки или сразу после — иначе бот будет получать 401 до перезапуска с новым ключом.
  • Набор scope задаётся заново. Поля подставлены текущими — снимите лишнее, если сужаете доступ, или отметьте новое, если расширяете.

Это же единственный способ изменить набор scope у работающего приложения.

Что гасит доступ ​

ДействиеКлючДоступ к каналу
Перевыпуск ключастарый умираетне меняется
Снятие scope при перевыпускеработаетмаршруты этого scope отвечают 403
Снятие бота с каналаработаетпропадает на этом канале
Удаление приложенияумираетпропадает везде

Сообщения, написанные ботом, во всех случаях остаются в истории.

Документация внешнего API Emotify