Боты
Боты
Боты для Min на Bot API, совместимом с Telegram: создание, токен, апдейты через webhook или long polling, сообщения с inline-клавиатурами.
Боты Min говорят на подмножестве Telegram Bot API: тот же формат URL (/bot<token>/<method>), тот же конверт {"ok":true,"result":…} и те же объекты (Message, User, Chat, Update, CallbackQuery, InlineKeyboardMarkup). Многие Telegram-библиотеки работают после замены базового URL. Всё, чего нет в справочнике методов, не реализовано и возвращает 404.
| Есть | Пока нет |
|---|---|
| Текст, фото, документы, видео, аудио; редактирование/удаление своих сообщений | Reply-клавиатуры, force reply, inline-режим, Mini Apps, платежи |
Inline-клавиатуры (callback_data, url) + answerCallbackQuery | parse_mode / entities (текст отправляется как есть) |
getUpdates long polling, webhooks с секретом | Стикеры, опросы, голосовые, геолокация, контакты через Bot API |
Команды (setMyCommands/getMyCommands) | @username как chat_id; методы администрирования чатов |
| Личные чаты, группы, каналы | Показ sendChatAction пользователям; фильтр allowed_updates |
1. Создайте бота#
Любой пользователь может создать до 20 ботов. Логин бота должен оканчиваться на bot (например, weather_bot). Два способа:
- @BotFather — откройте чат с
@botfatherв Min и отправьте/newbot Weather Bot | weather_bot. Другие команды:/mybots,/token <username>(новый токен),/revoke <username>(удалить). - API —
POST /api/botsс вашим пользовательским токеном (см. Управление ботами).
curl -X POST https://minchatapp.com/api/bots \
-H "Authorization: Bearer $USER_TOKEN" -H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"name":"Weather Bot","username":"weather_bot"}'
# → {"success":true,"bot":{"id":5,"username":"weather_bot",…},"token":"5:RyNKXZs7Va1LvKqSLj6Snsoy2FplGb1n8FV"}
<bot_id>:<secret>) показывается один раз и хранится в виде хеша. Держите его в секрете; при утечке перевыпустите через /token или POST /api/bots/{id}/token.2. Вызывайте Bot API#
Методы принимают GET или POST с параметрами в query, application/x-www-form-urlencoded, multipart/form-data (файлы) или JSON. Вложенные объекты (reply_markup, commands) можно передавать JSON-строкой.
https://minchatapp.com/bot<token>/<method>
https://minchatapp.com/bot/<token>/<method> (alternative form)
https://minchatapp.com/file/bot<token>/<file_path> (file download)
{"ok": true, "result": { … }}
{"ok": false, "error_code": 400, "description": "Bad Request: chat not found"}
error_code — HTTP-статус: 400 неверный запрос, 401 неверный токен, 404 неизвестный метод, 409 getUpdates при включённом webhook, 429 лимит, 500 ошибка сервера.
Чаты и id#
| chat.id | Значение |
|---|---|
| положительный | Личный чат; id — это id пользователя. Бот может написать любому пользователю по id — чат создаётся при первой отправке. |
| отрицательный | Группа или канал: -<conversation_id>. Бот должен быть участником (добавляется как пользователь: POST /api/conversations/{id}/members с id бота). В канале для публикации нужна роль администрации. |
message_id — глобальный id сообщения Min. file_id привязаны к боту.
3. Получайте апдейты#
Апдейт создаётся для каждого бота-участника чата, когда кто-то другой отправляет (message) или редактирует (edited_message) сообщение, и когда пользователь нажимает inline-кнопку (callback_query). Режим приватности: в группах бот получает только команды (/start, /weather@weather_bot), если для него не включено can_read_all_group_messages. В личных чатах и каналах — всё.
Long polling#
Вызывайте getUpdates в цикле с timeout (до 50 с) и offset = последний update_id + 1 — это подтверждает и удаляет предыдущие апдейты.
import requests
TOKEN = "5:RyNKXZs7Va1LvKqSLj6Snsoy2FplGb1n8FV"
API = f"https://minchatapp.com/bot{TOKEN}"
offset = 0
while True:
r = requests.get(f"{API}/getUpdates", params={"offset": offset, "timeout": 30}, timeout=40).json()
for upd in r["result"]:
offset = upd["update_id"] + 1
if "message" in upd:
msg = upd["message"]
if msg.get("text", "").startswith("/weather"):
requests.post(f"{API}/sendMessage", json={
"chat_id": msg["chat"]["id"],
"text": "Pick a city:",
"reply_markup": {"inline_keyboard": [[
{"text": "Moscow", "callback_data": "city:moscow"},
{"text": "Berlin", "callback_data": "city:berlin"},
]]},
})
elif "callback_query" in upd:
cq = upd["callback_query"]
requests.post(f"{API}/answerCallbackQuery", json={"callback_query_id": cq["id"], "text": "Loading…"})
requests.post(f"{API}/editMessageText", json={
"chat_id": cq["message"]["chat"]["id"],
"message_id": cq["message"]["message_id"],
"text": f"Weather for {cq['data'].split(':')[1]}: +5°C",
})
const TOKEN = process.env.MIN_BOT_TOKEN;
const API = `https://minchatapp.com/bot${TOKEN}`;
const call = (method, body) =>
fetch(`${API}/${method}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body ?? {}),
}).then((r) => r.json());
let offset = 0;
for (;;) {
const { result } = await call('getUpdates', { offset, timeout: 30 });
for (const upd of result) {
offset = upd.update_id + 1;
const msg = upd.message;
if (msg?.text === '/start') {
await call('sendMessage', { chat_id: msg.chat.id, text: `Hi, ${msg.from.first_name}!` });
}
}
}
curl "https://minchatapp.com/bot$BOT_TOKEN/getUpdates?timeout=30&offset=0"
Webhook#
setWebhook с HTTPS-адресом переключает бота на push-доставку: каждый апдейт отправляется POST-запросом с JSON. Отвечайте 2xx быстро; при ошибке — 3 повтора с интервалом 30 с, ошибка видна в getWebhookInfo. Проверяйте заголовок X-Telegram-Bot-Api-Secret-Token, если задан secret_token. Пока webhook включён, getUpdates возвращает 409.
curl -X POST "https://minchatapp.com/bot$BOT_TOKEN/setWebhook" \
-H 'Content-Type: application/json' \
-d '{"url":"https://example.com/minchat-webhook","secret_token":"s3cr3t-value"}'
import express from 'express';
const app = express();
app.use(express.json());
app.post('/minchat-webhook', async (req, res) => {
if (req.get('X-Telegram-Bot-Api-Secret-Token') !== process.env.WEBHOOK_SECRET) return res.sendStatus(403);
res.sendStatus(200); // acknowledge first
const msg = req.body.message;
if (msg?.text) {
await fetch(`https://minchatapp.com/bot${process.env.MIN_BOT_TOKEN}/sendMessage`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ chat_id: msg.chat.id, text: `You said: ${msg.text}` }),
});
}
});
app.listen(3000);
from flask import Flask, request, abort
import os, requests
app = Flask(__name__)
API = f"https://minchatapp.com/bot{os.environ['MIN_BOT_TOKEN']}"
@app.post("/minchat-webhook")
def hook():
if request.headers.get("X-Telegram-Bot-Api-Secret-Token") != os.environ["WEBHOOK_SECRET"]:
abort(403)
upd = request.get_json()
msg = upd.get("message")
if msg and msg.get("text"):
requests.post(f"{API}/sendMessage", json={"chat_id": msg["chat"]["id"], "text": "Got it!"})
return "ok"
Пример тела webhook (апдейт message):
{
"update_id": 1,
"message": {
"message_id": 51,
"date": 1792660008,
"chat": {
"id": 1,
"type": "private",
"first_name": "Anna",
"username": "anna_s"
},
"from": {
"id": 1,
"is_bot": false,
"first_name": "Anna",
"last_name": "Smith",
"username": "anna_s"
},
"text": "/weather Moscow"
}
}
4. Inline-клавиатуры и callback#
Передайте reply_markup с inline_keyboard — рядами кнопок. У кнопки text (≤ 64 символов) и либо callback_data (≤ 64 байт), либо url. Клиенты показывают клавиатуру под сообщением; URL-кнопки открываются во внешнем браузере. Нажатие создаёт апдейт callback_query; ответьте answerCallbackQuery и обычно обновите сообщение через editMessageText / editMessageReplyMarkup (пустой inline_keyboard убирает клавиатуру). Изменения приходят клиентам сразу (MessageUpdated).
{
"chat_id": 1,
"text": "Pick a city:",
"reply_markup": {
"inline_keyboard": [
[ {"text": "Moscow", "callback_data": "city:moscow"}, {"text": "Berlin", "callback_data": "city:berlin"} ],
[ {"text": "Open website", "url": "https://minchatapp.com"} ]
]
}
}
Апдейт callback_query:
{
"update_id": 3,
"callback_query": {
"id": "1",
"from": {
"id": 1,
"is_bot": false,
"first_name": "Anna",
"last_name": "Smith",
"username": "anna_s"
},
"chat_instance": "8",
"data": "city:moscow",
"message": {
"message_id": 50,
"date": 1792660008,
"chat": {
"id": 1,
"type": "private",
"first_name": "Anna",
"username": "anna_s"
},
"from": {
"id": 5,
"is_bot": true,
"first_name": "Weather",
"last_name": "Bot",
"username": "weather_bot",
"can_join_groups": true,
"can_read_all_group_messages": false,
"supports_inline_queries": false
},
"text": "Pick a city:",
"reply_markup": {
"inline_keyboard": [
[
{
"text": "Moscow",
"callback_data": "city:moscow"
},
{
"text": "Berlin",
"callback_data": "city:berlin"
}
],
[
{
"text": "Open website",
"url": "https://minchatapp.com"
}
]
]
}
}
}
}
5. Команды#
Зарегистрируйте команды через setMyCommands; сообщения, начинающиеся с /, доходят до ботов в группах даже в режиме приватности. /cmd@your_bot адресует конкретного бота.
curl -X POST "https://minchatapp.com/bot$BOT_TOKEN/setMyCommands" \
-H 'Content-Type: application/json' \
-d '{"commands":[{"command":"start","description":"Start the bot"},{"command":"weather","description":"Current weather"}]}'
6. Файлы#
Медиа отправляются загрузкой (multipart), по URL (сервер скачает до 50 МБ) или по ранее полученному file_id. Чтобы скачать файл, вызовите getFile и запросите /file/bot<token>/<file_path>.
curl -F chat_id=1 -F caption='Forecast map' -F photo=@map.png \
"https://minchatapp.com/bot$BOT_TOKEN/sendPhoto"
Ограничения#
| Что | Лимит |
|---|---|
| Запросы | 120 в минуту на маршрут |
| Ботов на владельца | 20 |
| Текст / подпись | 4096 / 1024 |
| Кнопки | text ≤ 64, callback_data ≤ 64 байт |
| Медиа по URL | 50 MB |
| getUpdates | limit ≤ 100, timeout ≤ 50 с |
| Доставка webhook | 3 попытки, таймаут 10 с, пауза 30 с |
offset. Отдельного экрана ботов в настройках приложения пока нет — управляйте ими через @BotFather или методы ниже.Управление ботами (пользовательский API)#
Эти методы используют Sanctum-токен владельца, а не токен бота.
Мои боты
Параметры
Без параметров.
Запрос
curl 'https://minchatapp.com/api/bots' \
-H "Authorization: Bearer $TOKEN" \
-H 'Accept: application/json'
Ответ
{
"success": true,
"bots": [
{
"id": 5,
"name": "Weather Bot",
"username": "weather_bot",
"avatar": null,
"created_at": "2026-10-22T09:06:14+00:00"
}
]
}
Создать бота
username должен оканчиваться на bot. До 20 ботов на владельца. Токен возвращается один раз; создаётся личный чат владелец ↔ бот.
Параметры
| Имя | Тип | Описание |
|---|---|---|
name
обязательный тело
|
string |
Имя бота. max 64 chars
|
username
обязательный тело
|
string |
Логин бота ( …bot).max 32 chars
|
Запрос
curl -X POST 'https://minchatapp.com/api/bots' \
-H "Authorization: Bearer $TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"name": "Weather Bot", "username": "weather_bot"}'
Ответ
{
"success": true,
"bot": {
"id": 5,
"name": "Weather Bot",
"username": "weather_bot",
"avatar": null
},
"token": "5:AAEhBP0av28Jc9RIwmZ8P-exampleToken"
}
Перевыпустить токен бота
Старый токен сразу перестаёт работать.
Параметры
| Имя | Тип | Описание |
|---|---|---|
bot
обязательный путь
|
integer |
id бота. |
Запрос
curl -X POST 'https://minchatapp.com/api/bots/5/token' \
-H "Authorization: Bearer $TOKEN" \
-H 'Accept: application/json'
Ответ
{
"success": true,
"token": "5:AAEhBP0av28Jc9RIwmZ8P-exampleToken"
}
Удалить бота
Отзывает токен и удаляет аккаунт бота.
Параметры
| Имя | Тип | Описание |
|---|---|---|
bot
обязательный путь
|
integer |
id бота. |
Запрос
curl -X DELETE 'https://minchatapp.com/api/bots/5' \
-H "Authorization: Bearer $TOKEN" \
-H 'Accept: application/json'
Ответ
Отвечает HTTP 200.
Связанные: GET /api/username-available?kind=bot — проверка логина бота; POST /api/messages/{id}/callback — вызывается клиентом при нажатии кнопки.