Веб-версия Web app
Rossi Bots API Rossi Bots API

Боты Rossi за 5 минут. Rossi bots in 5 minutes.

REST-API и webhook'и. Создавай ботов через @botfather прямо в чате, получай токен, начинай отправлять сообщения. Inline-кнопки, callback'и, Mini Apps — всё внутри Rossi. REST API and webhooks. Create bots through @botfather right inside a chat, get a token, start sending messages. Inline buttons, callbacks, Mini Apps — all inside Rossi.

Быстрый старт Quick start

Три шага от пустого аккаунта до первого ответа от бота. Three steps from an empty account to your bot's first reply.

1. Создай бота через @botfather 1. Create a bot via @botfather

Открой чат с @botfather, напиши /newbot, ответь на два вопроса (имя и username). В ответ придёт API-токен вида rb_… — он показывается один раз, сохраняй сразу. Open a chat with @botfather, send /newbot, answer two questions (display name and username). You'll get an API token like rb_…. It's shown once — copy it now.

2. Отправь первое сообщение 2. Send the first message

Прежде чем вызывать API, надо знать chat_id — это UUID чата, в который бот будет писать. Самый простой способ: открой чат с ботом из своего аккаунта, отправь ему любое сообщение, и в ответе getUpdates увидишь chat.id. Before calling the API you need a chat_id — the UUID of the chat the bot will post to. Easiest way: open a chat with the bot from your account, send any message, then read chat.id from the response of getUpdates.

cURL sendMessage
# Просто отправь текст
curl -X POST "https://api.rossims.ru/bot-api/sendMessage" \
  -H "Authorization: Bearer rb_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"chat_id": "<UUID-чата>", "text": "Привет, мир!"}'

3. Подключи webhook (опционально) 3. Hook up a webhook (optional)

Без webhook'а бот живёт через getUpdates-long-polling. Для прод-нагрузки лучше webhook — Rossi сам POST'нет каждое событие на твой HTTPS-URL с HMAC-подписью. Настройка: Without a webhook your bot consumes updates via getUpdates long-polling. For production use a webhook — Rossi POSTs every event to your HTTPS URL with an HMAC signature. Setup:

cURL setWebhook
curl -X POST "https://api.rossims.ru/bot-api/setWebhook" \
  -H "Authorization: Bearer rb_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.example/rossi-webhook",
    "secret_token": "придумай-свой-секрет-минимум-16-симв"
  }'

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

Все запросы к /bot-api/* используют bearer-токен вида rb_xxx…, выданный @botfather при создании или через /token. Every request to /bot-api/* uses a bearer token of the form rb_xxx… issued by @botfather on creation or via /token.

HTTP Заголовок Header
Authorization: Bearer rb_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
⚠ Не публикуй токен в публичном репо. Если утёк — открой чат с @botfather, выбери бота (/use @твой_бот), сделай /revoke чтобы погасить все старые токены, и /token для нового. ⚠ Don't commit your token to a public repo. If leaked: open a chat with @botfather, switch to the bot (/use @your_bot), run /revoke to invalidate all old tokens, then /token to issue a fresh one.

API endpoints API endpoints

База: https://api.rossims.ru/bot-api. Ответы — JSON со стандартным конвертом { ok: boolean, result?, description? } (как у Telegram). Base: https://api.rossims.ru/bot-api. Responses are JSON with a standard envelope { ok: boolean, result?, description? } (Telegram-style).

Messaging

POST
/bot-api/sendMessage

Отправить текст. Поддерживает parse_mode: "markdown", reply_to_message_id, reply_markup с inline-кнопками. Send text. Supports parse_mode: "markdown", reply_to_message_id, reply_markup with inline buttons.

POST
/bot-api/sendPhoto

Отправить фото. Тело — multipart с полем file ИЛИ JSON с media_ref ранее загруженного фото. Send a photo. Body is either multipart with file field OR JSON with a media_ref from a prior upload.

POST
/bot-api/sendVideo

Видео. До 50 МБ, MP4/WebM/MOV. Возвращает file_ref для последующего реиспользования. Video. Up to 50 MB, MP4/WebM/MOV. Returns a file_ref for later reuse.

POST
/bot-api/sendDocument

Произвольный файл. Без распознавания типа — клиент покажет иконку и кнопку «скачать». Arbitrary file. No content sniffing — client shows an icon and a "download" button.

POST
/bot-api/editMessageText

Изменить текст ранее отправленного сообщения. message_id из sendMessage. Edit the text of a previously sent message. message_id from sendMessage.

POST
/bot-api/deleteMessage

Удалить сообщение бота. Сообщения других пользователей удалить нельзя. Delete a message sent by the bot. Cannot delete messages from other users.

Updates

GET
/bot-api/getUpdates

Long-polling вход для ботов без webhook'а. Параметры offset, limit, timeout — как у Telegram. Long-polling entry point for bots without a webhook. Same offset, limit, timeout params as Telegram.

POST
/bot-api/setWebhook

Включить webhook. Поля url (https-only) и secret_token (хранится у нас, отправляется в заголовке X-Telegram-Bot-Api-Secret-Token). Enable a webhook. Fields url (https-only) and secret_token (stored server-side, sent as the X-Telegram-Bot-Api-Secret-Token header).

POST
/bot-api/answerCallbackQuery

Подтвердить клик по inline-кнопке (опционально с toast'ом). Без вызова Rossi сам «погасит спиннер» через 5 сек. Acknowledge an inline-button click (optionally with a toast). Without this call Rossi auto-clears the spinner after 5s.

Identity

GET
/bot-api/getMe

Кто я как бот: id, username, first_name, is_verified. Identity of the calling bot: id, username, first_name, is_verified.

Webhook

После setWebhook Rossi POST'ит каждое обновление на твой URL. На сервере проверь подпись и обработай событие. After setWebhook Rossi POSTs every update to your URL. On your server, verify the signature and process the event.

Заголовки запроса Request headers

HTTP
POST /your-webhook HTTP/1.1
Host: your-server.example
Content-Type: application/json
User-Agent: Rossi-Bots/1.0
X-Rossi-Bot-Id: 4dd2dbd3-6262-476d-...
X-Rossi-Attempt: 1
X-Rossi-Signature: sha256=<hex hmac of body>
X-Telegram-Bot-Api-Secret-Token: <твой-секрет>

Верификация подписи (Node.js) Signature verification (Node.js)

Node.js
import { createHmac, timingSafeEqual } from 'node:crypto';

function verify(rawBody, sigHeader, secret) {
  const [, hex] = sigHeader.split('=');
  const expected = createHmac('sha256', secret).update(rawBody).digest();
  const got = Buffer.from(hex, 'hex');
  return expected.length === got.length && timingSafeEqual(expected, got);
}

Inline-ответ из webhook'а Inline response from a webhook

Можно ответить прямо в теле POST (без второго round-trip к sendMessage) — верни JSON в Telegram-стиле: You can reply right in the body of your POST response (no second round-trip to sendMessage) — return Telegram-style JSON:

JSON
{
  "ok": true,
  "method": "sendMessage",
  "text": "Спасибо за заказ!",
  "parse_mode": "markdown"
}
Retries и DLQ. Если твой сервер ответит не-2xx или зависнет дольше 5 с — апдейт уйдёт в очередь и Rossi повторит доставку 6 раз с экспоненциальной задержкой (5 с → 30 с → 2 мин → 10 мин → 1 ч → 4 ч). После — в dead-letter, который виден на вкладке «События» в дашборде бота с кнопкой «Повторить». Retries and DLQ. If your server returns non-2xx or hangs longer than 5 s, the update is queued and Rossi retries delivery 6 times with exponential backoff (5 s → 30 s → 2 min → 10 min → 1 h → 4 h). After that it lands in the dead-letter queue, visible on the «Events» tab of the bot dashboard with a «Replay» button.

Inline-кнопки и callback_query Inline buttons and callback_query

Прикрепи к сообщению матрицу кнопок — пользователь нажимает, Rossi присылает событие на твой webhook. Attach a button matrix to a message. When the user taps, Rossi delivers a callback_query event to your webhook.

cURL Отправить сообщение с кнопками Send a message with buttons
curl -X POST "https://api.rossims.ru/bot-api/sendMessage" \
  -H "Authorization: Bearer rb_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "chat_id": "<uuid>",
    "text": "Хочешь подписаться на рассылку?",
    "reply_markup": {
      "inline_keyboard": [
        [
          {"text": "Да", "callback_data": "subscribe:yes"},
          {"text": "Нет", "callback_data": "subscribe:no"}
        ],
        [
          {"text": "Подробнее", "url": "https://example.com/info"}
        ]
      ]
    }
  }'

Что прилетает на webhook при клике What you receive on the webhook on click

JSON
{
  "update_id": 14,
  "callback_query": {
    "id": "3b196bc1-…",
    "from": { "id": "20d8784d-…", "username": "dekry" },
    "message": { "message_id": "e931e229-…", "chat": { "id": "e7f013ce-…" } },
    "data": "subscribe:yes"
  }
}

Mini Apps

Открывай полноценные веб-приложения внутри Rossi — как Telegram Web Apps. Подпись initData совместима с Telegram, так что существующие TWA SDK (@telegram-apps/sdk, @twa-dev/sdk) работают без правок. Run full web apps inside Rossi — same model as Telegram Web Apps. The initData signing follows the same scheme, so existing TWA SDKs (@telegram-apps/sdk, @twa-dev/sdk) work unchanged.

Шаг 1: кнопка web_app в сообщении Step 1: a web_app button on a message

JSON
{
  "chat_id": "<uuid>",
  "text": "Открой магазин 👇",
  "reply_markup": {
    "inline_keyboard": [
      [{ "text": "🛒 Каталог", "web_app": { "url": "https://shop.example/" } }]
    ]
  }
}

Шаг 2: верификация initData на сервере Step 2: verify initData on your server

При клике Rossi открывает твой URL во фрейме и кладёт подписанный initData в hash-фрагмент. На своём сервере проверь подпись HMAC-SHA256 точно как у Telegram: On click, Rossi opens your URL inside a frame with a signed initData in the hash fragment. Verify the HMAC-SHA256 signature on your server exactly the way Telegram does:

Node.js
import { createHmac } from 'node:crypto';

function verifyInitData(initData, botToken) {
  const params = new URLSearchParams(initData);
  const hash = params.get('hash');
  params.delete('hash');
  const checkString = [...params.entries()]
    .sort(([a], [b]) => a.localeCompare(b))
    .map(([k, v]) => `${k}=${v}`)
    .join('\n');
  const secretKey = createHmac('sha256', 'WebAppData').update(botToken).digest();
  const expected = createHmac('sha256', secretKey).update(checkString).digest('hex');
  return expected === hash;
}

Пример: эхо-бот за 40 строк Example: echo-bot in 40 lines

Минимальный рабочий Node.js-бот: получает webhook, проверяет подпись, отвечает тем же текстом. Запусти на любом HTTPS-хосте, укажи URL в setWebhook — готово. Minimal working Node.js bot: receives the webhook, verifies the signature, echoes the user's text back. Run it on any HTTPS host, point setWebhook at it — done.

Node.js · ESM echo-bot.js
import http from 'node:http';
import { createHmac, timingSafeEqual } from 'node:crypto';

const BOT_TOKEN = process.env.ROSSI_BOT_TOKEN;
const SECRET    = process.env.ROSSI_WEBHOOK_SECRET;
const API_BASE  = 'https://api.rossims.ru/bot-api';

function verify(body, sigHeader) {
  if (!sigHeader?.startsWith('sha256=')) return false;
  const got      = Buffer.from(sigHeader.slice(7), 'hex');
  const expected = createHmac('sha256', SECRET).update(body).digest();
  return expected.length === got.length && timingSafeEqual(expected, got);
}

async function sendMessage(chat_id, text) {
  await fetch(`${API_BASE}/sendMessage`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${BOT_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ chat_id, text }),
  });
}

http.createServer(async (req, res) => {
  if (req.method !== 'POST') { res.writeHead(404).end(); return; }

  const chunks = [];
  for await (const c of req) chunks.push(c);
  const raw = Buffer.concat(chunks);

  if (!verify(raw, req.headers['x-rossi-signature'])) {
    res.writeHead(401).end('bad signature');
    return;
  }

  const update = JSON.parse(raw.toString('utf-8'));
  if (update.message?.text) {
    await sendMessage(update.message.chat.id, `Ты сказал: ${update.message.text}`);
  }

  res.writeHead(200).end('{"ok":true}');
}).listen(3000, () => console.log('echo-bot слушает :3000'));

Запусти: Run:

bash
ROSSI_BOT_TOKEN=rb_xxx \
ROSSI_WEBHOOK_SECRET=придумай-свой-секрет \
node echo-bot.js

Лимиты и поведение Limits and behaviour

Исходящие Outgoing

Не более 20 сообщений / мин / чат от одного бота. Max 20 messages / min / chat per bot.

Входящие Incoming

Не более 30 команд / мин / (юзер, бот). Свыше — fail-soft с подсказкой подождать. Max 30 commands / min / (user, bot). Over this we fail-soft with a "wait" hint.

Webhook retries Webhook retries

6 попыток за 24 ч с backoff 5 c → 4 ч. После — dead-letter, replay из дашборда. 6 attempts over 24 h with 5 s → 4 h backoff. Then dead-letter, replay from the dashboard.

Auto-suspension Auto-suspension

5 dead-letter за 10 мин — бот замораживается до ручной разморозки владельцем. 5 dead-letter rows in 10 min freezes the bot until the owner reactivates it.

Размер сообщения Message size

До 4096 символов текста, до 50 МБ медиа, до 200 байт callback_data. Up to 4096 characters of text, up to 50 MB of media, up to 200 bytes of callback_data.

Время отклика webhook Webhook response budget

Синхронный fast-path — 5 c, дальше уходит в фоновую очередь. Synchronous fast-path is 5 s; longer responses fall back to the background queue.

FAQ

Сколько ботов можно завести на один аккаунт? How many bots per account?

20 — лимит как в Telegram. 20 — same as Telegram.

Как получить галочку верификации? How to get verified?

Сейчас вручную — напиши на support@rossims.ru с обоснованием (медиа, бизнес, public figure). В разработке — заявка прямо через @botfather. Currently manual — email support@rossims.ru with justification (media, business, public figure). A self-service flow through @botfather is on the way.

Можно ли мигрировать существующего Telegram-бота? Can I migrate an existing Telegram bot?

Если бот общается через webhook — поменяй base URL на api.rossims.ru/bot-api, повторно вызови setWebhook с твоим URL, обнови токен. 80% бота-кода работает без изменений (API работает аналогично). If your bot uses webhooks: swap the base URL to api.rossims.ru/bot-api, call setWebhook again with your URL, swap the token. 80% of bot code works unchanged (API works the same way).

Где смотреть события и логи доставки? Where are the event and delivery logs?

В дашборде бота, вкладка «События». Real-time стрим всех апдейтов с возможностью раскрыть payload и повторить доставку. On the bot dashboard, «Events» tab. Real-time stream of every update with expandable payloads and a replay button.

Можно ли давать боту команды на удаление сообщений других пользователей? Can a bot delete messages from other users?

Только если бот — модератор группы. В личных чатах боты могут редактировать и удалять только свои сообщения. Групповая модерация — на стадии разработки. Only if the bot is a group moderator. In direct chats bots can edit/delete only their own messages. Group moderation is in development.