Веб-версия
Web app
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.
Три шага от пустого аккаунта до первого ответа от бота. Three steps from an empty account to your bot's first reply.
Открой чат с @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.
Прежде чем вызывать 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 -X POST "https://api.rossims.ru/bot-api/sendMessage" \ -H "Authorization: Bearer rb_xxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{"chat_id": "<UUID-чата>", "text": "Привет, мир!"}'
Без 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 -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-симв" }'
Все запросы к /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.
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.
База: 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).
Отправить текст. Поддерживает 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.
Отправить фото. Тело — 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.
Видео. До 50 МБ, MP4/WebM/MOV. Возвращает file_ref для последующего реиспользования.
Video. Up to 50 MB, MP4/WebM/MOV. Returns a file_ref for later reuse.
Произвольный файл. Без распознавания типа — клиент покажет иконку и кнопку «скачать». Arbitrary file. No content sniffing — client shows an icon and a "download" button.
Изменить текст ранее отправленного сообщения. message_id из sendMessage.
Edit the text of a previously sent message. message_id from sendMessage.
Удалить сообщение бота. Сообщения других пользователей удалить нельзя. Delete a message sent by the bot. Cannot delete messages from other users.
Long-polling вход для ботов без webhook'а. Параметры offset, limit, timeout — как у Telegram.
Long-polling entry point for bots without a webhook. Same offset, limit, timeout params as Telegram.
Включить 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).
Подтвердить клик по inline-кнопке (опционально с toast'ом). Без вызова Rossi сам «погасит спиннер» через 5 сек. Acknowledge an inline-button click (optionally with a toast). Without this call Rossi auto-clears the spinner after 5s.
Кто я как бот: id, username, first_name, is_verified.
Identity of the calling bot: id, username, first_name, is_verified.
После setWebhook Rossi POST'ит каждое обновление на твой URL.
На сервере проверь подпись и обработай событие.
After setWebhook Rossi POSTs every update to your URL.
On your server, verify the signature and process the event.
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: <твой-секрет>
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); }
Можно ответить прямо в теле 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:
{
"ok": true,
"method": "sendMessage",
"text": "Спасибо за заказ!",
"parse_mode": "markdown"
}
Прикрепи к сообщению матрицу кнопок — пользователь нажимает, Rossi присылает событие
на твой webhook.
Attach a button matrix to a message. When the user taps, Rossi delivers a
callback_query event to your webhook.
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"} ] ] } }'
{
"update_id": 14,
"callback_query": {
"id": "3b196bc1-…",
"from": { "id": "20d8784d-…", "username": "dekry" },
"message": { "message_id": "e931e229-…", "chat": { "id": "e7f013ce-…" } },
"data": "subscribe:yes"
}
}
Открывай полноценные веб-приложения внутри 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.
web_app button on a message
{
"chat_id": "<uuid>",
"text": "Открой магазин 👇",
"reply_markup": {
"inline_keyboard": [
[{ "text": "🛒 Каталог", "web_app": { "url": "https://shop.example/" } }]
]
}
}
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:
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; }
Минимальный рабочий 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.
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:
ROSSI_BOT_TOKEN=rb_xxx \ ROSSI_WEBHOOK_SECRET=придумай-свой-секрет \ node echo-bot.js
Не более 20 сообщений / мин / чат от одного бота. Max 20 messages / min / chat per bot.
Не более 30 команд / мин / (юзер, бот). Свыше — fail-soft с подсказкой подождать. Max 30 commands / min / (user, bot). Over this we fail-soft with a "wait" hint.
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.
5 dead-letter за 10 мин — бот замораживается до ручной разморозки владельцем. 5 dead-letter rows in 10 min freezes the bot until the owner reactivates it.
До 4096 символов текста, до 50 МБ медиа, до 200 байт callback_data.
Up to 4096 characters of text, up to 50 MB of media, up to 200 bytes of callback_data.
Синхронный fast-path — 5 c, дальше уходит в фоновую очередь. Synchronous fast-path is 5 s; longer responses fall back to the background queue.
20 — лимит как в Telegram. 20 — same as Telegram.
Сейчас вручную — напиши на 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.
Если бот общается через 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).
В дашборде бота, вкладка «События». Real-time стрим всех апдейтов с возможностью раскрыть payload и повторить доставку. On the bot dashboard, «Events» tab. Real-time stream of every update with expandable payloads and a replay button.
Только если бот — модератор группы. В личных чатах боты могут редактировать и удалять только свои сообщения. Групповая модерация — на стадии разработки. Only if the bot is a group moderator. In direct chats bots can edit/delete only their own messages. Group moderation is in development.