# FoloKroo Bot API > FoloKroo — российский мессенджер (folokroo.ru). Боты — аккаунты bot_…, которые работают через то же открытое HTTP API, что и приложения: https://folokroo.ru/v1. Авторизация — заголовок «Authorization: Bearer <токен>» (токен бота fkb_… выдаёт @folomasterbot, личный токен fkp_… — в разделе «Разработчикам»). Запросы и ответы — JSON, поля snake_case, ID — строки вида тип_число (chat_…, user_…, bot_…, msg_…). Обновления — GET /v1/bot/updates (длинный опрос) или вебхук. Библиотеки в одном файле без зависимостей: https://folokroo.ru/sdk/folokroo.py (Python 3.8+), https://folokroo.ru/sdk/folokroo.ts и https://folokroo.ru/sdk/folokroo.mjs (Node 18+). Права токенов: profile:read — видеть свой профиль и искать людей; profile:write — менять свой профиль (имя, описание, фото); chats:read — читать список чатов и переписку; messages:write — отправлять, править и удалять сообщения, реакции, файлы; chats:write — создавать беседы и каналы, управлять участниками; bot — методы ботов: обновления, вебхук, команды, ответы на кнопки. Оглавление и отдельные страницы: https://folokroo.ru/llms.txt --- # Боты в FoloKroo Бот — это программа, с которой можно переписываться: она отвечает на сообщения, показывает кнопки, работает в беседах. Боты пригодятся для чего угодно: подсказать погоду, вести счёт в игре, присылать новости, напоминать о делах, модерировать беседу. В FoloKroo бот выглядит как обычный собеседник с пометкой «бот». ## Чем наше API удобно - **Одно API для всех.** Бот ходит в те же методы `/v1/`, что и наши приложения. Нет отдельного «API для ботов» с другими правилами. - **Постоянные ID.** У каждого чата, человека и сообщения ID вида `chat_…`, `user_…`, `msg_…`. Они одинаковые для всех и никогда не меняются. - **Понятные ошибки.** Всегда в одном виде, с кодом и подсказкой на русском, что сделать. - **Два способа получать сообщения.** Длинный опрос (работает даже с домашнего компьютера) или вебхук (для своего сервера). - **Готовые библиотеки.** Python и TypeScript / JavaScript, по одному файлу, без установки. ## С чего начать Если вы впервые делаете бота — откройте [«Первый бот за 5 минут»](https://folokroo.ru/dev/docs/first-bot): там всё по шагам, от создания до первого ответа. > **Уже писали ботов для Telegram?.** Многое знакомо: токен от официального бота (у нас — **@folomasterbot**), обновления с `update_id` и `offset`, кнопки `inline_keyboard` и `callback_query`. Отличия — в разделе [«Как всё устроено»](https://folokroo.ru/dev/docs/how). --- # Первый бот за 5 минут Создадим бота, который здоровается, отвечает на нажатие кнопки и повторяет ваши сообщения. ### Шаг 1. Создайте бота у @folomasterbot В FoloKroo нажмите поиск, найдите **@folomasterbot** и нажмите «Начать». Отправьте команду `/newbot`, затем: - имя бота — его увидят люди, например «Мой помощник»; - адрес — латиницей, должен оканчиваться на `bot`, например `my_helper_bot`. В ответ придёт **токен** — длинная строка, начинается с `fkb_`. Это «пароль» бота. > **Токен — секрет.** С токеном кто угодно сможет писать от имени бота. Не публикуйте его и не отправляйте другим. Если токен утёк — @folomasterbot → /mybots → бот → «Новый токен»: старый сразу перестанет работать. ### Шаг 2. Скачайте библиотеку Создайте папку для бота и положите в неё один файл: - для Python — [folokroo.py](https://folokroo.ru/sdk/folokroo.py) (нужен Python 3.8 или новее); - для JavaScript — [folokroo.mjs](https://folokroo.ru/sdk/folokroo.mjs) (нужен Node.js 18 или новее). Больше ничего устанавливать не нужно. ### Шаг 3. Напишите бота Рядом с библиотекой создайте файл `bot.py` (или `bot.mjs`) и вставьте код. Вместо `fkb_ВАШ_ТОКЕН` — ваш токен. Python: ```python from folokroo import Bot bot = Bot("fkb_ВАШ_ТОКЕН") @bot.command("start") def start(ctx): ctx.reply("Привет! Я твой первый бот 🤖", buttons=[[("Нажми меня", "hello")]]) @bot.callback("hello") def hello(ctx): ctx.answer("Кнопка работает!") @bot.message() def echo(ctx): ctx.reply("Ты написал: " + ctx.text) bot.run() ``` JavaScript: ```javascript import { Bot } from "./folokroo.mjs"; const bot = new Bot("fkb_ВАШ_ТОКЕН"); bot.command("start", (ctx) => ctx.reply("Привет! Я твой первый бот 🤖", { buttons: [[["Нажми меня", "hello"]]] })); bot.callback("hello", (ctx) => ctx.answer("Кнопка работает!")); bot.message((ctx) => ctx.reply("Ты написал: " + ctx.text)); bot.run(); ``` Каждый обработчик получает `ctx` — всё о том, что произошло: `ctx.text` (текст сообщения), `ctx.user` (кто написал), `ctx.chat_id` (в каком чате; в JavaScript — `ctx.chatId`), `ctx.data` (данные нажатой кнопки). И способы ответить: `ctx.reply(...)`, `ctx.answer(...)`. Полный список — в разделе [«Python»](https://folokroo.ru/dev/docs/python). ### Шаг 4. Запустите Python: ```python python bot.py ``` JavaScript: ```javascript node bot.mjs ``` Появится строка «Бот @… запущен». Пока программа работает — бот отвечает. ### Шаг 5. Проверьте Найдите своего бота в FoloKroo по адресу и нажмите «Начать». Бот поздоровается и покажет кнопку. Нажмите её, потом напишите что-нибудь — бот повторит. > **Что дальше.** Добавьте боту описание и меню команд (@folomasterbot → /mybots), научите его кнопкам — раздел [«Кнопки и клавиатуры»](https://folokroo.ru/dev/docs/buttons). Готовые боты для примера — в разделе [«Примеры»](https://folokroo.ru/dev/docs/examples). > **Бот работает, пока работает программа.** Закрыли окно или выключили компьютер — бот замолчит, а когда запустите снова, получит всё пропущенное за последние сутки. Чтобы бот работал всегда, запустите его на сервере (например, как службу systemd). --- # Как всё устроено Что происходит между сообщением человека и ответом бота. **1** Человек пишет боту **2** Сервер FoloKroo создаёт для бота обновление **3** Программа бота забирает обновление **4** И отвечает запросом к API ## Бот — это аккаунт У бота свой аккаунт с ID `bot_…`, именем, @адресом и фото. Его можно найти поиском, добавить в беседу, переслать ему сообщение. Программа бота действует от имени этого аккаунта, предъявляя токен в каждом запросе. ## Адрес API ``` https://folokroo.ru/v1 ``` Все методы — это адрес + путь, например `https://folokroo.ru/v1/me`. Запросы и ответы — в JSON, поля пишутся `snake_case`. Время — в UTC, в формате ISO 8601: `2026-10-06T12:00:00.000Z`. ## ID ID — строки вида `тип_число`: `user_…`, `bot_…`, `chat_…`, `msg_…`, `file_…`. Тип сразу видно по началу. ID постоянные: один и тот же чат или человек всегда имеет один и тот же ID — у всех, на всех устройствах. Личная переписка — тоже чат со своим ID, как беседа или канал. ## Номер сообщения seq и ID msg_… У каждого сообщения есть и то и другое: - **`seq`** — номер внутри чата: 1, 2, 3… по порядку. **Все методы работают с парой `chat_id` + `seq`**: ответить (`reply_to_seq`), изменить, удалить, поставить реакцию, закрепить. - **`id`** (`msg_…`) — глобальный ID сообщения, уникальный на весь FoloKroo. В методы его передавать не нужно; он удобен, чтобы хранить сообщение в своей базе одной строкой или писать в журнал. > Получили сообщение — для ответа берите `message.chat_id` и `message.seq`. ## Повтор без дублей: client_key При плохой связи непонятно, дошло ли сообщение: ответ мог потеряться по дороге. Чтобы повтор не создал второе такое же сообщение, передавайте в `POST /chats/{chat_id}/messages` поле `client_key` — любую уникальную строку длиной от 1 до 64 символов (удобно — UUID). - Повтор с тем же `client_key` не создаёт новое сообщение: сервер вернёт **то же сообщение, что и в первый раз** (тот же `seq`, код 200, не ошибка). - Ключ действует бессрочно и принадлежит отправителю: один бот не может использовать один ключ дважды — ни в этом чате, ни в другом. Новое сообщение — новый ключ. - Библиотеки подставляют `client_key` сами (UUID) и при обрыве связи повторяют отправку безопасно. ## Отличия от Telegram - Методы — те же, что у приложений, а не отдельный набор: `POST /v1/chats/{chat_id}/messages` вместо `sendMessage`. - Токен — в заголовке `Authorization`, а не в адресе (адреса попадают в журналы серверов и прокси). - Вебхук подписан HMAC — поддельный запрос легко отличить. - ID — строки, а не числа (большие числа теряют точность в JavaScript). --- # Токены и права Как программа доказывает серверу, от чьего имени она действует, и что ей разрешено. Каждый запрос должен содержать токен в заголовке: ```http Authorization: Bearer fkb_ВАШ_ТОКЕН ``` Проверить, что токен работает: ```bash curl https://folokroo.ru/v1/me -H "Authorization: Bearer fkb_ВАШ_ТОКЕН" ``` ## Два вида токенов **Токен бота**`fkb_…` Выдаёт @folomasterbot. Программа действует от имени бота. **Личный токен**`fkp_…` Создаётся в «Разработчикам → Токены». Скрипт действует от *вашего* имени — например, чтобы сохранить переписку или отправлять себе напоминания. ## Права токена Право (scope) — какие группы методов токену разрешены. Без нужного права метод отвечает `403 forbidden` с подсказкой, какого права не хватает. | Право | Что разрешает | Бот | Личный токен | | --- | --- | --- | --- | | `profile:read` | Видеть свой профиль и искать людей | есть | по выбору | | `profile:write` | Менять свой профиль (имя, описание, фото) | есть | по выбору | | `chats:read` | Читать список чатов и переписку | есть | по выбору | | `messages:write` | Отправлять, править и удалять сообщения, реакции, файлы | есть | по выбору | | `chats:write` | Создавать беседы и каналы, управлять участниками | есть | по выбору | | `bot` | Методы ботов: обновления, вебхук, команды, ответы на кнопки | есть | — | У бота есть все права, включая `chats:write` — например, чтобы исключать участников беседы, где он администратор. ## Ограничения ботов — отдельно от прав Есть действия, которые ботам запрещены **правилами FoloKroo**, даже если право формально есть. Это не настройка токена — так устроено API: - бот **не пишет человеку первым** — личку с ботом открывает человек (кнопка «Начать»); - бот **не создаёт беседы и каналы** и **не вступает по ссылкам-приглашениям** — его добавляют люди; - бот не нажимает кнопки под чужими сообщениями и не пользуется черновиками, папками и архивом. > **Только из приложения.** Пароль, устройства, инвайты, админка и сам кабинет разработчика недоступны ни по какому токену — только из приложения FoloKroo. --- # Получение сообщений Как бот узнаёт о новых сообщениях и нажатиях кнопок. Всё, что происходит с ботом, приходит ему в виде **обновлений**. У каждого — номер `update_id` (растёт по порядку) и тип `type`. ## Длинный опрос — самый простой способ Бот спрашивает «есть что новое?», и сервер держит запрос открытым до `timeout` секунд (до 50), пока что-то не появится. Как только человек написал — ответ приходит сразу. Работает откуда угодно, даже с домашнего компьютера без белого IP. ```bash curl "https://folokroo.ru/v1/bot/updates?timeout=30" -H "Authorization: Bearer fkb_…" ``` ## Подтверждение: offset Сервер отдаёт обновление снова и снова, пока бот не подтвердит, что обработал его. Подтверждение — параметр `offset` в следующем запросе: > **Правило.** Передавайте `offset` = `update_id` **последнего обработанного** обновления + 1. Все обновления с меньшим номером считаются обработанными и удаляются. Обработали не всё (программа упала посередине) — передайте номер последнего, которое точно успели обработать, + 1: остальные придут ещё раз. ``` запрос: GET /v1/bot/updates?timeout=30 → пришли обновления 7, 8, 9 (обработали 7, 8 и 9) запрос: GET /v1/bot/updates?offset=10&timeout=30 → 7–9 удалены, ждём новые ``` > Библиотеки делают всё это сами: `bot.run()` — и всё. ## Виды обновлений | type | Когда приходит | Что внутри | | --- | --- | --- | | `message` | новое сообщение в чате с ботом | `chat`, `message` | | `edited_message` | человек исправил текст сообщения | `chat`, `message` — **полное** сообщение с новым текстом | | `callback_query` | нажали кнопку под сообщением бота | `callback_query`: id, from, chat_id, message, data | | `chat_removed` | бота убрали из беседы (или он вышел сам) | `chat_id` | ### message — новое сообщение ```json { "update_id": 7, "type": "message", "chat": { "id": "chat_100330922926149632", "kind": "dm", "title": "Аня", "peer": { "id": "user_…", "username": "anya", … }, … }, "message": { "id": "msg_100331…", "chat_id": "chat_100330922926149632", "seq": 12, "kind": "text", "author_id": "user_100209398554562560", "author": { "id": "user_100209398554562560", "username": "anya", "display_name": "Аня", "is_bot": false, "avatar_url": null, … }, "text": "/start", "entities": [], "attachments": [], "reply_to_seq": null, "reply_to": null, "forward": null, "reply_markup": null, "reactions": [], "created_at": "2026-10-06T12:00:00.000Z", "edited_at": null, "deleted": false } } ``` ### edited_message — сообщение исправили Приходит **полное** сообщение, как в `message`, но с новым текстом и заполненным `edited_at` (время правки). `seq` тот же — по нему понятно, какое сообщение исправили. Реакции и просмотры правкой не считаются — о них бот не получает обновлений. ```json { "update_id": 8, "type": "edited_message", "chat": { "id": "chat_100330922926149632", "kind": "dm", … }, "message": { "seq": 12, "text": "/start please", "edited_at": "2026-10-06T12:00:40.000Z", "created_at": "2026-10-06T12:00:00.000Z", … } } ``` ### callback_query — нажатие кнопки `message` — сообщение бота, под которым нажали кнопку (целиком, с его `reply_markup`); `data` — `callback_data` нажатой кнопки; `from` — кто нажал. Ответьте в течение 10 секунд: `POST /v1/bot/callbacks/{id}/answer`. ```json { "update_id": 9, "type": "callback_query", "callback_query": { "id": "Jm1yX0c2bTdkS3ZwOVE", "from": { "id": "user_100209398554562560", "username": "anya", "display_name": "Аня", "is_bot": false, … }, "chat_id": "chat_100330922926149632", "message": { "seq": 13, "text": "Какой город?", "author_id": "bot_…", "reply_markup": { "inline_keyboard": [ … ] }, … }, "data": "city:msk" } } ``` ### chat_removed — бота убрали из беседы Писать в этот чат бот больше не может; можно забыть о нём у себя в базе. ```json { "update_id": 10, "type": "chat_removed", "chat_id": "chat_100512…" } ``` > **Если бот был выключен.** Обновления хранятся сутки (до 1000 штук). Запустили бота — он получит всё пропущенное. Сообщения других ботов боту не приходят — чтобы боты не отвечали друг другу бесконечно. ## Ещё способ: поток событий Для продвинутых: бот может подключиться к WebSocket `/v1/stream`, как наши приложения, и получать «сырые» события в реальном времени (первое сообщение — `{"type":"auth","token":"fkb_…"}`). Обычно это не нужно. --- # Вебхук Сервер FoloKroo сам присылает обновления на ваш сайт — для ботов на своём сервере. Вместо того чтобы спрашивать «есть что новое?», бот сообщает свой адрес, и FoloKroo отправляет туда каждое обновление POST-запросом с JSON в теле. ## Включить Python: ```python info = bot.set_webhook("https://bot.example.com/folokroo") print(info["secret"]) # сохраните — им проверяется подпись ``` JavaScript: ```javascript const info = await bot.setWebhook("https://bot.example.com/folokroo"); console.log(info.secret); // сохраните — им проверяется подпись ``` > **Требования к адресу.** Только `https://` и только адрес в интернете — локальная сеть и localhost не подойдут. Сертификат Let's Encrypt подходит. ## Как отвечать - Ответьте кодом `200` (любой 2xx) — обновление считается доставленным. Лучше ответить сразу, а обработать потом. - Не ответили за 10 секунд или ответили ошибкой — сервер повторит через 5 с, 30 с, 2 мин, 10 мин, 30 мин, час. Обновления приходят строго по порядку. - Через сутки недоставленное обновление пропускается. - Журнал доставок с кодами ответов и ошибками — в «Разработчикам → Мои боты». ## Проверка подписи В каждом запросе есть заголовок `X-FoloKroo-Signature: sha256=…` — это HMAC-SHA256 тела запроса вашим секретом. Проверяйте его: так никто посторонний не сможет присылать вам поддельные обновления. Python: ```python from folokroo import verify_signature # body — тело запроса как есть (байты), до разбора JSON if not verify_signature(SECRET, body, headers["X-FoloKroo-Signature"]): return 403 bot.handle_update(json.loads(body)) ``` JavaScript: ```javascript import { verifySignature } from "./folokroo.mjs"; // rawBody — тело запроса как есть, до разбора JSON if (!verifySignature(SECRET, rawBody, req.headers["x-folokroo-signature"])) return res.status(403).end(); await bot.handleUpdate(JSON.parse(rawBody)); ``` Ещё заголовок `X-FoloKroo-Bot` — ID бота (если у вас несколько ботов на одном адресе). Полный пример бота с вебхуком — [webhook_bot.py](https://folokroo.ru/sdk/examples/webhook_bot.py). > Пока включён вебхук, `/bot/updates` не работает. Выключить — `POST /v1/bot/webhook/delete`. --- # Кнопки и клавиатуры Два вида кнопок: под сообщением и вместо клавиатуры. ## Кнопки под сообщением Прикрепляются к конкретному сообщению. Бывают двух видов: - `callback_data` — при нажатии боту приходит обновление `callback_query` с этими данными (до 64 байт). Человек ничего не отправляет в чат. - `url` — нажатие открывает ссылку. Python: ```python ctx.reply("Какой город?", buttons=[ [("Москва", "city:msk"), ("Казань", "city:kzn")], # первый ряд [("Наш сайт", "https://example.com")], # второй ряд: ссылка ]) ``` JavaScript: ```javascript ctx.reply("Какой город?", { buttons: [ [["Москва", "city:msk"], ["Казань", "city:kzn"]], // первый ряд [["Наш сайт", "https://example.com"]], // второй ряд: ссылка ] }); ``` JSON: ```json { "text": "Какой город?", "reply_markup": { "inline_keyboard": [ [ { "text": "Москва", "callback_data": "city:msk" }, { "text": "Казань", "callback_data": "city:kzn" } ], [ { "text": "Наш сайт", "url": "https://example.com" } ] ] } } ``` ## Ответ на нажатие На каждое `callback_query` бот должен ответить за 10 секунд — пока он не ответит, кнопка у человека «крутится». В ответе можно показать подсказку, окно или открыть ссылку. Python: ```python @bot.callback("city:") def city(ctx): name = {"city:msk": "Москва", "city:kzn": "Казань"}[ctx.data] ctx.answer(f"{name}: +12") # всплывающая подсказка ctx.edit(f"Выбран город: {name}", buttons=None) # и убрать кнопки ``` JavaScript: ```javascript bot.callback("city:", async (ctx) => { const name = { "city:msk": "Москва", "city:kzn": "Казань" }[ctx.data]; await ctx.answer(`${name}: +12`); // всплывающая подсказка await ctx.edit(`Выбран город: ${name}`, null); // и убрать кнопки }); ``` > Чтобы поменять только кнопки (например, отметить выбранное ✓), измените сообщение с новым `reply_markup` без текста — оно не будет помечено «изменено». ## Клавиатура бота Заменяет обычную клавиатуру над полем ввода. Нажатие отправляет текст кнопки в чат обычным сообщением — удобно для ответов «Да / Нет» и меню. Python: ```python ctx.reply("Продолжим?", keyboard=[["Да", "Нет"]], one_time=True) # убрать клавиатуру: ctx.reply("Хорошо!", remove_keyboard=True) ``` JavaScript: ```javascript ctx.reply("Продолжим?", { keyboard: [["Да", "Нет"]], oneTime: true }); // убрать клавиатуру: ctx.reply("Хорошо!", { removeKeyboard: true }); ``` JSON: ```json { "keyboard": [[ { "text": "Да" }, { "text": "Нет" } ]], "one_time": true, "placeholder": "Выберите ответ" } { "remove_keyboard": true } ``` - `one_time` — скрыть клавиатуру после первого нажатия. - `placeholder` — подсказка в пустом поле ввода, пока клавиатура открыта. - Действует последняя присланная клавиатура, пока бот её не уберёт. > **Ограничения.** До 10 рядов, до 8 кнопок в ряду, текст кнопки — до 64 символов (подробнее — [«Лимиты»](https://folokroo.ru/dev/docs/limits)). Кнопки могут быть только у сообщений ботов. --- # Команды и описание Как сделать бота понятным с первого взгляда. ## Команды Команда — сообщение, которое начинается с «/»: `/start`, `/help`, `/weather Москва`. Если задать меню команд, человек увидит их списком, как только наберёт «/». Python: ```python bot.set_commands({"start": "Начать", "weather": "Погода сейчас", "help": "Помощь"}) @bot.command("weather") def weather(ctx): city = ctx.args or "Москва" # всё, что после команды ctx.reply(f"{city}: +12") ``` JavaScript: ```javascript await bot.setCommands({ start: "Начать", weather: "Погода сейчас", help: "Помощь" }); bot.command("weather", (ctx) => { const city = ctx.args || "Москва"; // всё, что после команды return ctx.reply(`${city}: +12`); }); ``` Меню команд можно задать и без программы: @folomasterbot → /mybots → бот → «Команды». ## Описание и «Начать» Когда человек впервые открывает переписку с ботом, он видит фото и имя бота, описание «Что умеет этот бот?» и кнопку **«Начать»** вместо поля ввода. Нажатие отправляет боту `/start` — поэтому на `/start` бот должен отвечать всегда. Python: ```python bot.set_description("Подскажу погоду в любом городе. Нажмите «Начать».") ``` JavaScript: ```javascript await bot.setDescription("Подскажу погоду в любом городе. Нажмите «Начать»."); ``` --- # Фото и файлы Отправка картинок, видео и документов. Файл отправляется в два шага: сначала загрузить (`POST /v1/files`), потом отправить сообщение с его ID в `attachments`. Библиотеки делают оба шага одной командой. Python: ```python bot.send_file(ctx.chat_id, "cat.jpg", caption="Вот котик") bot.send_file(ctx.chat_id, "report.pdf", as_file=True) # как документ, без сжатия # несколько файлов в одном сообщении files = [bot.upload("1.jpg"), bot.upload("2.jpg")] ctx.reply("Альбом", attachments=files) ``` JavaScript: ```javascript import { readFile } from "node:fs/promises"; const photo = await bot.upload(await readFile("cat.jpg"), "cat.jpg"); await ctx.reply("Вот котик", { attachments: [photo] }); ``` - Фото сервер сжимает сам (до 2560 точек) и убирает геометку. Видео пережимает в MP4. - `as_file` / `?as=file` — отправить как есть, без сжатия. - Лимиты — **на каждый файл**: фото — до 25 МБ, видео — до 100 МБ, остальные файлы — до 8 МБ. В одном сообщении — до 10 вложений. Все лимиты — в разделе [«Лимиты»](https://folokroo.ru/dev/docs/limits). - Файлы, которые прислали боту, — в `message.attachments`; у каждого есть ссылка `url` для скачивания. --- # Боты в беседах Как бот ведёт себя, когда его добавили в беседу. Бота добавляют в беседу как обычного участника: «Информация о беседе» → «Добавить». Сам вступить по ссылке бот не может. ## Что бот видит Чтобы не читать лишнего, по умолчанию бот в беседе получает только: - команды — сообщения, начинающиеся с «/»; - сообщения, где его упомянули: `@my_helper_bot привет`; - ответы на его сообщения; - служебные сообщения: кого добавили, кто вышел. Если боту нужно видеть всё (например, это модератор или счётчик сообщений) — @folomasterbot → /mybots → бот → «Беседы: видеть все сообщения». > **Команды в беседе.** Если в беседе несколько ботов, команду можно адресовать конкретному: `/start@my_helper_bot`. Библиотеки понимают такую запись сами. ## Права администратора Владелец беседы может сделать бота администратором — тогда бот сможет закреплять сообщения, удалять чужие и исключать участников (если эти права выданы). --- # Ошибки Что значит каждая ошибка и что с ней делать. Ошибка всегда приходит в одном виде. Проверяйте `code` — он постоянный и не меняется; `message` — текст для людей, `hint` — что сделать. ```json { "error": { "code": "rate_limited", "message": "Бот отправляет слишком часто", "hint": "Повторите через 2 с", "retry_after": 2 } } ``` | code | HTTP | Что значит | Что делать | | --- | --- | --- | --- | | `validation_failed` | 400 | Неверные данные. Что именно — в message и fields | Исправить запрос; повторять бесполезно | | `invalid_id` | 400 | ID не того вида (user_… вместо chat_…) | Проверить, какой ID передаёте | | `unauthorized` | 401 | Нет токена или он недействителен | Проверить токен; выпустили новый — обновить в программе | | `forbidden` | 403 | Нельзя: нет права, бот не участник чата, бот пишет первым… | Прочитать hint; повторять бесполезно | | `not_found` | 404 | Нет такого чата / сообщения — или вам его не видно | Проверить ID и что бот в этом чате | | `conflict` | 409 | Действие противоречит состоянию: например, запрос обновлений при включённом вебхуке | Устранить причину из message | | `rate_limited` | 429 | Слишком часто | Подождать retry_after секунд и повторить | | `unavailable` | 503 | Временно недоступно (например, хранилище файлов) | Повторить через несколько секунд, лучше с растущей паузой | | `internal` | 500 | Ошибка на нашей стороне — мы о ней узнаём | Повторить позже; если повторяется — написать нам | > **Что делают библиотеки.** При `rate_limited` и `unavailable` библиотеки сами ждут и повторяют запрос (до 3 раз). Остальные ошибки приходят как исключение `FoloKrooError` с полями `code`, `message`, `hint`. Сколько чего можно — в разделе [«Лимиты»](https://folokroo.ru/dev/docs/limits). --- # Лимиты Все ограничения в одном месте. | Что | Сколько | | --- | --- | | Сообщений от бота | до 30 в секунду всего и до 60 в минуту в один чат (дальше — rate_limited с retry_after) | | Нажатий кнопок одним человеком | до 10 за 5 секунд | | Текст сообщения | до 4096 символов | | Вложений в сообщении | до 10 | | Размер одного файла | фото — до 25 МБ, видео — до 100 МБ, голосовое — до 20 МБ (до 15 минут), остальные файлы и GIF — до 8 МБ. Лимит — на каждый файл, а не на сообщение | | Изменить или удалить у всех | только свои сообщения, не старше 48 часов | | Удалить за один запрос | до 100 сообщений | | Переслать за один запрос | до 100 сообщений | | Кнопки под сообщением | до 10 рядов, до 8 кнопок в ряду, текст — до 64 символов, callback_data — до 64 байт | | Ответ на нажатие кнопки | в течение 10 секунд, один раз; текст подсказки — до 200 символов | | Меню команд | до 100 команд; команда — до 32 символов (латиница в нижнем регистре, цифры, _), описание — до 256 | | Описание бота | до 512 символов | | Длинный опрос | timeout до 50 секунд, до 100 обновлений за раз | | Хранение обновлений | сутки и не больше 1000 штук на бота | | Вебхук | ответ — за 10 секунд; повторы 5 с, 30 с, 2 мин, 10 мин, 30 мин, час; через сутки обновление пропускается | | Ботов у одного человека | до 20 | | Личных токенов | до 20 | | client_key | от 1 до 64 символов | --- # Отладка: бот не отвечает Пошаговая проверка — от токена до обработчиков. ### Шаг 1. Токен работает? ```bash curl https://folokroo.ru/v1/me -H "Authorization: Bearer fkb_…" ``` Должен прийти бот (`"is_bot": true`). `401 unauthorized` — токен неверный или вы выпустили новый у @folomasterbot (старый сразу перестаёт работать). ### Шаг 2. Обновления доходят? Остановите программу бота, напишите ему в FoloKroo и запросите обновления вручную: ```bash curl "https://folokroo.ru/v1/bot/updates" -H "Authorization: Bearer fkb_…" ``` - Ваше сообщение есть в ответе — FoloKroo работает, дело в программе (шаг 4). - Пусто, а пишете в беседе — бот по умолчанию видит только команды и обращения к себе (раздел [«Боты в беседах»](https://folokroo.ru/dev/docs/groups)). - `409 conflict` — включён вебхук, переходите к шагу 3. ### Шаг 3. Вебхук доставляет? ```bash curl https://folokroo.ru/v1/bot/webhook -H "Authorization: Bearer fkb_…" ``` `pending` растёт, в `last_error` ошибка — ваш сервер не отвечает 2xx. Подробный журнал (код ответа, время, попытка) — в «Разработчикам → Мои боты → Журнал вебхука». Частые причины: просроченный сертификат, сервер отвечает дольше 10 секунд, неверная проверка подписи (проверяйте подпись по телу запроса **до** разбора JSON). ### Шаг 4. Программа получает, но молчит? - Смотрите вывод программы: библиотеки печатают ошибки обработчиков и ошибки API (`FoloKrooError` с кодом и подсказкой). - Команда в беседе приходит как `/start@имя_бота` — библиотеки это понимают, а свой разбор текста — проверьте. - На `callback_query` обязательно отвечайте (`ctx.answer()`), иначе кнопка у человека будет «крутиться» 10 секунд. > Любой метод можно вызвать прямо со страницы — раздел [«Попробовать»](https://folokroo.ru/dev/docs/try). --- # Python folokroo.py — один файл, без зависимостей, Python 3.8+. Скачайте [folokroo.py](https://folokroo.ru/sdk/folokroo.py) и положите рядом со своим ботом. ## Обработчики | `@bot.command("start", "help")` | команды /start и /help | | --- | --- | | `@bot.callback("city:")` | нажатия кнопок, у которых callback_data начинается с «city:» (без аргумента — любые) | | `@bot.message()` | любые другие сообщения; можно с условием: `@bot.message(lambda ctx: "привет" in ctx.text.lower())` | Срабатывает первый подходящий обработчик. Запуск — `bot.run()`. ## Как работает bot.run() - Забирает обновления длинным опросом и по очереди отдаёт обработчикам; подтверждает их сам. - **Ошибка в обработчике бота не роняет**: текст ошибки печатается, бот переходит к следующему обновлению. - Пропала связь или сервер временно недоступен — ждёт 3 секунды и пробует снова, сколько потребуется. - Токен недействителен (401/403) — останавливается с понятным сообщением: дальше пробовать бессмысленно. - Остановить — `Ctrl+C`. Пропущенное за время остановки (до суток) бот получит при следующем запуске. - Отправка сообщений защищена от дублей: библиотека сама подставляет `client_key` и при `rate_limited` / `unavailable` повторяет запрос. ## Чтобы бот работал всегда Запустите его на сервере как службу — тогда он сам поднимется после перезагрузки или сбоя. Для Linux (systemd), файл `/etc/systemd/system/mybot.service`: ```ini [Unit] Description=Мой бот FoloKroo After=network-online.target [Service] WorkingDirectory=/opt/mybot Environment=FOLOKROO_TOKEN=fkb_… ExecStart=/usr/bin/python3 bot.py Restart=always RestartSec=5 [Install] WantedBy=multi-user.target ``` Затем `systemctl enable --now mybot`; журнал — `journalctl -u mybot -f` (туда попадает всё, что бот печатает). ## Что есть в ctx | `ctx.text`, `ctx.command`, `ctx.args` | текст сообщения; команда без «/»; всё, что после команды | | --- | --- | | `ctx.user`, `ctx.chat_id` | кто написал или нажал; ID чата | | `ctx.message`, `ctx.data` | сообщение целиком; данные нажатой кнопки | | `ctx.reply(...)`, `ctx.reply_to(...)` | ответить в чат; ответить цитатой | | `ctx.answer(...)`, `ctx.edit(...)` | ответ на нажатие кнопки; изменить сообщение с кнопкой | ## Методы бота ```python bot.send_message(chat_id, "текст", reply_to=seq, buttons=[[...]], keyboard=[[...]], attachments=[...]) bot.edit_message(chat_id, seq, text="новый", buttons=None) bot.delete_messages(chat_id, [seq]) bot.react(chat_id, seq, "👍") bot.typing(chat_id) bot.upload("файл.jpg") / bot.send_file(chat_id, "файл.jpg", caption="...") bot.me(), bot.chats(), bot.history(chat_id), bot.members(chat_id), bot.leave(chat_id) bot.set_commands({...}), bot.set_description("...") bot.set_webhook(url), bot.delete_webhook(), bot.webhook_info() bot.call("GET", "/любой/метод") # любой метод API ``` --- # TypeScript и JavaScript folokroo.ts / folokroo.mjs — один файл, без зависимостей, Node.js 18+ (а также Deno и Bun). Для TypeScript — [folokroo.ts](https://folokroo.ru/sdk/folokroo.ts) (с типами всех объектов), для обычного JavaScript — [folokroo.mjs](https://folokroo.ru/sdk/folokroo.mjs). ```javascript import { Bot } from "./folokroo.mjs"; const bot = new Bot("fkb_…"); bot.command(["start", "help"], (ctx) => ctx.reply("Привет!")); bot.callback("city:", (ctx) => ctx.answer(ctx.data)); bot.message((ctx) => ctx.text.includes("привет"), (ctx) => ctx.reply("И тебе привет!")); bot.message((ctx) => ctx.reply("Не понял 🙂")); bot.run(); ``` Всё асинхронное возвращает Promise. Методы — как в Python, только в camelCase: `sendMessage`, `editMessage`, `deleteMessages`, `upload`, `setCommands`, `setWebhook`, `getUpdates`, `call`… У `ctx`: `text`, `command`, `args`, `user`, `chatId`, `message`, `data`, `reply()`, `replyTo()`, `answer()`, `edit()`. `bot.run()` работает так же, как в Python: ошибка в обработчике печатается и не останавливает бота, при обрыве связи — повтор через 3 секунды, при недействительном токене — остановка. Остановить из кода — `bot.stop()`. Отправка защищена от дублей: `client_key` подставляется сам, при `rate_limited` / `unavailable` запрос повторяется. --- # Примеры Готовые боты, которые можно взять за основу. **🍺 Пивометр** Игровой бот: раз в час «выпить пива» и «взять закуску», статистика и топ участников. Команды, кнопки под сообщением, хранение данных в файле. [Скачать pivometr.py](https://folokroo.ru/sdk/examples/pivometr.py) **🚀 Бот на вебхуке** Свой маленький веб-сервер на стандартной библиотеке Python, проверка подписи, ответ на нажатие кнопки окном. [Скачать webhook_bot.py](https://folokroo.ru/sdk/examples/webhook_bot.py) > Токен примеры берут из переменной окружения `FOLOKROO_TOKEN`, а не из кода — так его не выложишь случайно. В Windows: `set FOLOKROO_TOKEN=fkb_…`, в Linux и macOS: `export FOLOKROO_TOKEN=fkb_…`. --- # Справочник: Методы бота Только для токенов ботов (fkb_…): получение обновлений, вебхук, меню команд, ответы на кнопки. ### Получить обновления `GET https://folokroo.ru/v1/bot/updates` — право `bot`, только для ботов Новые сообщения и нажатия кнопок. С timeout запрос ждёт, пока что-то появится (длинный опрос) — так бот отвечает мгновенно, не дёргая сервер каждую секунду. **Параметры:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `offset` | число | нет | update_id последнего обработанного + 1. Всё, что меньше, считается полученным и удаляется | | `timeout` | число 0–50 | нет | сколько секунд ждать новых обновлений; 0 — ответить сразу (по умолчанию 0) | | `limit` | число 1–100 | нет | сколько обновлений вернуть за раз (по умолчанию 100) | **Ответ:** ```json { "updates": [ { "update_id": 7, "type": "message", "chat": { "id": "chat_…", "kind": "dm", … }, "message": { "seq": 12, "text": "/start", … } } ] } ``` > Если у бота включён вебхук, метод отвечает ошибкой conflict — обновления в это время уходят на вебхук. ### Включить вебхук `POST https://folokroo.ru/v1/bot/webhook` — право `bot`, только для ботов Обновления будут приходить POST-запросом на ваш адрес. Подробно — в разделе «Вебхук». **Тело запроса (JSON):** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `url` | строка | да | адрес https:// в интернете (не локальная сеть), до 512 символов | | `secret` | строка 16–128 | нет | секрет для подписи запросов; не указан — сервер придумает сам | **Пример запроса:** ```json { "url": "https://bot.example.com/folokroo" } ``` **Ответ:** ```json { "url": "https://bot.example.com/folokroo", "secret": "q2mX…" } ``` ### Выключить вебхук `POST https://folokroo.ru/v1/bot/webhook/delete` — право `bot`, только для ботов После этого обновления снова можно забирать через /bot/updates — в том числе те, что вебхук не успел доставить. **Ответ:** ```json { "ok": true } ``` ### Состояние вебхука `GET https://folokroo.ru/v1/bot/webhook` — право `bot`, только для ботов Адрес, сколько обновлений ждут доставки и последняя ошибка. **Ответ:** ```json { "url": "https://bot.example.com/folokroo", "pending": 0, "last_error": null, "last_error_at": null } ``` ### Задать меню команд `POST https://folokroo.ru/v1/bot/commands` — право `bot`, только для ботов Это меню люди видят, когда набирают «/» в переписке с ботом (и в беседах, где он есть). **Тело запроса (JSON):** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `commands` | массив | да | до 100 штук: { command — латиница в нижнем регистре, цифры, _ до 32 символов; description — до 256 символов } | **Пример запроса:** ```json { "commands": [ { "command": "start", "description": "Начать" }, { "command": "weather", "description": "Погода сейчас" } ] } ``` **Ответ:** ```json { "commands": [ … ] } ``` ### Текущее меню команд `GET https://folokroo.ru/v1/bot/commands` — право `bot`, только для ботов То, что сейчас задано. **Ответ:** ```json { "commands": [ { "command": "start", "description": "Начать" } ] } ``` ### Описание бота `POST https://folokroo.ru/v1/bot/description` — право `bot`, только для ботов Текст «Что умеет этот бот?» — его видно в новой, ещё пустой переписке с ботом над кнопкой «Начать». **Тело запроса (JSON):** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `description` | строка | да | до 512 символов; пустая строка — убрать | **Пример запроса:** ```json { "description": "Подскажу погоду в любом городе. Нажмите «Начать»." } ``` **Ответ:** ```json { "ok": true } ``` ### Ответить на нажатие кнопки `POST https://folokroo.ru/v1/bot/callbacks/{id}/answer` — право `bot`, только для ботов Ответ на callback_query — у человека покажется подсказка или окно, либо откроется ссылка. Отвечать нужно в течение 10 секунд, один раз. **Параметры в адресе:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `id` | строка | да | callback_query.id из обновления (в пути адреса) | **Тело запроса (JSON):** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `text` | строка | нет | текст подсказки, до 200 символов | | `show_alert` | да/нет | нет | true — окном с кнопкой «Понятно», а не всплывающей подсказкой | | `url` | строка | нет | ссылка, которую откроет приложение | **Пример запроса:** ```json { "text": "Москва: +12, облачно" } ``` **Ответ:** ```json { "ok": true } ``` > Можно ответить и пустым телом {} — кнопка просто перестанет «крутиться». --- # Справочник: Сообщения Отправка, правка, удаление, реакции и файлы. Для ботов и для личных токенов с правом messages:write. ### Отправить сообщение `POST https://folokroo.ru/v1/chats/{chat_id}/messages` — право `messages:write` Новое сообщение в чат. Нужен текст или хотя бы одно вложение. **Параметры в адресе:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `chat_id` | строка | да | ID чата, например chat_100330922926149632 (в пути адреса) | **Тело запроса (JSON):** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `text` | строка | нет | текст, до 4096 символов | | `reply_to_seq` | число | нет | ответить цитатой на сообщение с этим номером | | `attachments` | массив ID | нет | до 10 файлов, загруженных через POST /files | | `reply_markup` | объект | нет | кнопки (только боты) — см. раздел «Кнопки и клавиатуры» | | `client_key` | строка 1–64 | нет | ключ от дублей: повтор с тем же ключом вернёт уже отправленное сообщение, а не создаст второе (раздел «Как всё устроено» → client_key) | **Пример запроса:** ```json { "text": "Город?", "reply_markup": { "inline_keyboard": [[ { "text": "Москва", "callback_data": "city:msk" } ]] } } ``` **Ответ:** ```json { "id": "msg_…", "chat_id": "chat_…", "seq": 42, "kind": "text", "author_id": "bot_…", "author": { "id": "bot_…", "username": "weather_bot", "display_name": "Погода", "is_bot": true, … }, "text": "Привет!", "entities": [], "attachments": [], "reply_to_seq": null, "reply_markup": null, "reactions": [], "created_at": "2026-10-06T12:00:00.000Z", "edited_at": null, "deleted": false, … } ``` ### Изменить сообщение `POST https://folokroo.ru/v1/chats/{chat_id}/messages/{seq}/edit` — право `messages:write` Своё сообщение — в течение 48 часов. Можно поменять только кнопки: тогда сообщение не помечается «изменено». **Параметры в адресе:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `chat_id` | строка | да | ID чата, например chat_100330922926149632 (в пути адреса) | | `seq` | число | да | номер сообщения в чате (в пути адреса) | **Тело запроса (JSON):** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `text` | строка | нет | новый текст (не указан — остаётся прежним) | | `reply_markup` | объект или null | нет | новые кнопки (только боты); null — убрать | **Пример запроса:** ```json { "text": "Готово ✓", "reply_markup": null } ``` **Ответ:** ```json { "id": "msg_…", "chat_id": "chat_…", "seq": 42, "kind": "text", "author_id": "bot_…", "author": { "id": "bot_…", "username": "weather_bot", "display_name": "Погода", "is_bot": true, … }, "text": "Привет!", "entities": [], "attachments": [], "reply_to_seq": null, "reply_markup": null, "reactions": [], "created_at": "2026-10-06T12:00:00.000Z", "edited_at": null, "deleted": false, … } ``` ### Удалить сообщения `POST https://folokroo.ru/v1/chats/{chat_id}/messages/delete` — право `messages:write` У всех — только свои и не старше 48 часов; у себя — любые. **Параметры в адресе:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `chat_id` | строка | да | ID чата, например chat_100330922926149632 (в пути адреса) | **Тело запроса (JSON):** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `seqs` | массив чисел | да | номера сообщений, до 100 | | `for_everyone` | да/нет | нет | true — у всех, false — только у себя (по умолчанию false) | **Пример запроса:** ```json { "seqs": [41, 42], "for_everyone": true } ``` **Ответ:** ```json { "ok": true, "deleted": 2 } ``` ### Поставить реакцию `POST https://folokroo.ru/v1/chats/{chat_id}/messages/{seq}/reaction` — право `messages:write` Одна реакция от одного участника; новая заменяет старую. **Параметры в адресе:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `chat_id` | строка | да | ID чата, например chat_100330922926149632 (в пути адреса) | | `seq` | число | да | номер сообщения в чате (в пути адреса) | **Тело запроса (JSON):** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `emoji` | строка или null | да | эмодзи; null — убрать свою реакцию | **Пример запроса:** ```json { "emoji": "👍" } ``` **Ответ:** ```json { "id": "msg_…", "chat_id": "chat_…", "seq": 42, "kind": "text", "author_id": "bot_…", "author": { "id": "bot_…", "username": "weather_bot", "display_name": "Погода", "is_bot": true, … }, "text": "Привет!", "entities": [], "attachments": [], "reply_to_seq": null, "reply_markup": null, "reactions": [], "created_at": "2026-10-06T12:00:00.000Z", "edited_at": null, "deleted": false, … } ``` ### Показать «печатает…» `POST https://folokroo.ru/v1/chats/{chat_id}/typing` — право `messages:write` Собеседники увидят «печатает…» примерно на 5 секунд. Удобно перед долгим ответом. **Параметры в адресе:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `chat_id` | строка | да | ID чата, например chat_100330922926149632 (в пути адреса) | **Ответ:** ```json { "ok": true } ``` ### Отметить прочитанным `POST https://folokroo.ru/v1/chats/{chat_id}/read` — право `messages:write` Всё до сообщения seq включительно — прочитано (у собеседника появятся две галочки). **Параметры в адресе:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `chat_id` | строка | да | ID чата, например chat_100330922926149632 (в пути адреса) | **Тело запроса (JSON):** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `seq` | число | да | номер последнего прочитанного | **Пример запроса:** ```json { "seq": 42 } ``` **Ответ:** ```json { "read_seq": 42 } ``` ### Переслать сообщения `POST https://folokroo.ru/v1/chats/{chat_id}/forward` — право `messages:write` Переслать сообщения из другого чата, где вы участник, в этот. **Параметры в адресе:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `chat_id` | строка | да | ID чата, например chat_100330922926149632 (в пути адреса) | **Тело запроса (JSON):** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `from_chat_id` | строка | да | откуда | | `seqs` | массив чисел | да | какие сообщения, до 100 | **Пример запроса:** ```json { "from_chat_id": "chat_…", "seqs": [5, 6] } ``` **Ответ:** ```json { "messages": [ … ] } ``` ### Загрузить файл `POST https://folokroo.ru/v1/files` — право `messages:write` Файл передаётся как форма (multipart/form-data) в поле file. В ответе — файл с id: его кладут в attachments при отправке. Фото и видео сервер пережимает сам. **Параметры в адресе:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `as` | file | нет | ?as=file — отправить без сжатия, как документ (до 8 МБ) | **Ответ:** ```json { "id": "file_…", "kind": "photo", "name": "cat.jpg", "mime": "image/jpeg", "size": 183021, "width": 1280, "height": 960, "url": "https://media.folokroo.ru/…", … } ``` > Фото — до 25 МБ, видео — до 100 МБ, файлы — до 8 МБ. В библиотеках: bot.upload(путь) / bot.send_file(чат, путь). --- # Справочник: Чаты Список чатов, история, участники. Бот видит только чаты, где он участник. ### Мои чаты `GET https://folokroo.ru/v1/chats` — право `chats:read` Все чаты: личные, беседы и каналы, свежие — сверху. **Ответ:** ```json { "chats": [ { "id": "chat_…", "kind": "dm", "title": "Аня", "peer": { … }, "unread_count": 2, "last_message": { … }, … } ] } ``` ### Один чат `GET https://folokroo.ru/v1/chats/{chat_id}` — право `chats:read` Подробности одного чата. **Параметры:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `chat_id` | строка | да | ID чата, например chat_100330922926149632 (в пути адреса) | **Ответ:** ```json { "id": "chat_…", "kind": "group", "title": "Друзья", "member_count": 5, "my_role": "member", … } ``` ### История сообщений `GET https://folokroo.ru/v1/chats/{chat_id}/messages` — право `chats:read` Последние сообщения чата, по порядку. Чтобы листать назад — before_seq = номер самого старого из полученных. **Параметры:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `chat_id` | строка | да | ID чата, например chat_100330922926149632 (в пути адреса) | | `limit` | число 1–100 | нет | сколько (по умолчанию 50) | | `before_seq` | число | нет | только сообщения раньше этого номера | **Ответ:** ```json { "messages": [ … ], "has_more": true } ``` ### Участники беседы `GET https://folokroo.ru/v1/chats/{chat_id}/members` — право `chats:read` Кто в беседе, их роли и кто в сети. **Параметры:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `chat_id` | строка | да | ID чата, например chat_100330922926149632 (в пути адреса) | **Ответ:** ```json { "members": [ { "user": { … }, "role": "admin", "online": true, … } ] } ``` ### Поиск по сообщениям `GET https://folokroo.ru/v1/chats/{chat_id}/search` — право `chats:read` Сообщения чата, в тексте которых есть q. **Параметры:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `chat_id` | строка | да | ID чата, например chat_100330922926149632 (в пути адреса) | | `q` | строка | да | что искать | | `limit` | число 1–50 | нет | сколько (по умолчанию 30) | | `before_seq` | число | нет | искать раньше этого номера | **Ответ:** ```json { "messages": [ … ], "has_more": false } ``` ### Открыть личную переписку `POST https://folokroo.ru/v1/chats/dm` — право `messages:write` Найти или создать личку с человеком. Бот не может написать первым: личку с ботом открывает человек. **Тело запроса (JSON):** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `user_id` | строка | нет | user_… или bot_… | | `username` | строка | нет | или @имя (одно из двух) | **Пример запроса:** ```json { "username": "foldash" } ``` **Ответ:** ```json { "id": "chat_…", "kind": "dm", "peer": { … }, … } ``` ### Выйти из беседы `POST https://folokroo.ru/v1/chats/{chat_id}/leave` — право `messages:write` Бот уходит из беседы. **Параметры в адресе:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `chat_id` | строка | да | ID чата, например chat_100330922926149632 (в пути адреса) | **Ответ:** ```json { "ok": true } ``` ### Исключить участника `POST https://folokroo.ru/v1/chats/{chat_id}/members/{user_id}/remove` — право `chats:write` Нужны права администратора беседы (их выдаёт владелец — в том числе боту). **Параметры в адресе:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `chat_id` | строка | да | ID чата, например chat_100330922926149632 (в пути адреса) | | `user_id` | строка | да | кого исключить (в пути адреса) | **Ответ:** ```json { "ok": true } ``` ### Название и описание беседы `POST https://folokroo.ru/v1/chats/{chat_id}/info` — право `chats:write` Только администраторы. **Параметры в адресе:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `chat_id` | строка | да | ID чата, например chat_100330922926149632 (в пути адреса) | **Тело запроса (JSON):** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `title` | строка | нет | новое название | | `about` | строка | нет | описание | **Пример запроса:** ```json { "title": "Клуб любителей погоды" } ``` **Ответ:** ```json { "id": "chat_…", "title": "Клуб любителей погоды", … } ``` --- # Справочник: Люди и профиль Кто я, поиск людей и ботов по @имени, свой профиль. ### Кто я `GET https://folokroo.ru/v1/me` — право `profile:read` Для бота — его аккаунт (bot_…), для личного токена — ваш. **Ответ:** ```json { "id": "bot_…", "username": "weather_bot", "display_name": "Погода", "about": "…", "is_bot": true, "avatar_url": null } ``` ### Найти по @имени `GET https://folokroo.ru/v1/users/resolve` — право `profile:read` Человек или бот по @имени. **Параметры:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `username` | строка | да | @имя (можно без @) | **Ответ:** ```json { "id": "user_…", "username": "foldash", "display_name": "…", "is_bot": false, … } ``` ### Описание и команды бота `GET https://folokroo.ru/v1/bots/{bot}` — право `profile:read` Любого бота — по @адресу или bot_… **Параметры:** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `bot` | строка | да | @адрес или bot_… (в пути адреса) | **Ответ:** ```json { "bot": { … }, "description": "Подскажу погоду", "commands": [ { "command": "start", "description": "Начать" } ] } ``` ### Изменить профиль `POST https://folokroo.ru/v1/me/profile` — право `profile:write` Имя и «о себе» (у бота «о себе» — это и есть его описание). **Тело запроса (JSON):** | Поле | Тип | Обязательно | Описание | | --- | --- | --- | --- | | `display_name` | строка | нет | имя | | `about` | строка | нет | о себе / описание | **Пример запроса:** ```json { "display_name": "Погода 2.0" } ``` **Ответ:** ```json { "id": "bot_…", "display_name": "Погода 2.0", … } ``` --- # Объекты Из чего состоят ответы API. ## Сообщение (message) | `id` | ID сообщения msg_… | | --- | --- | | `chat_id` | ID чата | | `seq` | номер в чате | | `kind` | text — обычное, service — служебное («добавили», «вышел») | | `author` | кто написал (человек или бот); null — служебное или пост канала | | `text` | текст | | `entities` | разметка: упоминания и ссылки (offset, length) | | `attachments` | файлы: фото, видео, голосовые, документы, стикер | | `reply_to_seq` | на какое сообщение это ответ | | `forward` | переслано откуда | | `reply_markup` | кнопки (у сообщений ботов) | | `reactions` | реакции: emoji, count, mine | | `created_at, edited_at` | когда отправлено и исправлено | ## Чат (chat) | `id` | ID чата chat_… | | --- | --- | | `kind` | dm — личный, group — беседа, channel — канал | | `title` | название (в личном — имя собеседника) | | `peer` | собеседник в личном чате | | `member_count` | участников | | `my_role` | моя роль: owner, admin, member, subscriber | | `last_message` | последнее сообщение | ## Пользователь (user) | `id` | user_… для людей, bot_… для ботов | | --- | --- | | `username` | @имя (без @) | | `display_name` | имя | | `about` | о себе / описание бота | | `is_bot` | бот ли это | | `avatar_url` | фото или null | ## Файл (file) | `id` | ID файла file_… | | --- | --- | | `kind` | photo, video, voice, file, sticker | | `name, mime, size` | имя, тип, размер в байтах | | `width, height` | размер картинки или видео | | `url` | ссылка для скачивания (действует несколько часов) |