Введение
Introduction
Боты в X2Chat — это специальные аккаунты, которые управляются через HTTP API, а не вручную. Они умеют делать всё то же, что и обычные пользователи: отправлять сообщения, файлы, реагировать на команды, показывать клавиатуры с кнопками.
API на 95% совместим с Telegram Bot API — большинство клиентских библиотек (python-telegram-bot, node-telegram-bot-api, telegraf) можно использовать после смены базового URL.
Особенности X2Chat: сообщения от ботов — plaintext (бот не имеет приватного ключа для E2E-шифрования под получателей). Зашифрованный канал между пользователями остаётся E2E.
Bots in X2Chat are special accounts controlled via HTTP API, not by humans. They can do everything regular users do: send messages, files, react to commands, show button keyboards.
The API is 95% compatible with the Telegram Bot API — most client libraries (python-telegram-bot, node-telegram-bot-api, telegraf) work after switching the base URL.
X2Chat specifics: bot messages are plaintext (bots have no private key to do E2E encryption for recipients). User-to-user E2E remains intact.
Создание бота
Creating a bot
В X2Chat нет отдельного «BotFather» — управление ботами встроено прямо в приложение.
- Откройте приложение X2Chat и перейдите в «Мои боты» (URL:
/my-bots). - Нажмите «Новый бот».
- Введите
username— должен заканчиваться наbot(напримерweather_bot,my_cool_bot). - Укажите имя бота и описание.
- Получите токен в формате
123456789:AAEh…— сохраните его, он показывается только один раз.
Если токен утерян, его можно пересоздать в карточке бота. Старый токен перестанет работать сразу.
X2Chat has no separate "BotFather" — bot management is built into the app.
- Open X2Chat and go to "My Bots" (URL:
/my-bots). - Tap "New Bot".
- Enter
username— must end withbot(e.g.weather_bot,my_cool_bot). - Set display name and description.
- Receive the token in format
123456789:AAEh…— store it securely, shown only once.
If you lose the token, you can regenerate it in the bot card. The old one stops working immediately.
Авторизация
Authorization
Токен передаётся одним из трёх способов:
- В пути URL (как в Telegram):
/api/v1/bot<TOKEN>/method - Заголовок
X-Bot-Token: <TOKEN> - Заголовок
Authorization: Bot <TOKEN>
Все запросы к Bot API делаются на хост https://ix.x2chat.com (или https://ru.x2chat.com).
The token is passed in one of three ways:
- In URL path (Telegram-style):
/api/v1/bot<TOKEN>/method - Header
X-Bot-Token: <TOKEN> - Header
Authorization: Bot <TOKEN>
All Bot API requests go to https://ix.x2chat.com (or https://ru.x2chat.com).
Запросы и ответы
Requests & responses
Все запросы — HTTP POST с Content-Type: application/json (для getMe, getUpdates, getWebhookInfo, getMyCommands — GET).
Все ответы в формате Telegram Bot API:
All requests are HTTP POST with Content-Type: application/json (for getMe, getUpdates, getWebhookInfo, getMyCommands — use GET).
Responses follow the Telegram Bot API format:
Успех:
Success:
{ "ok": true, "result": { ... } }
Ошибка:
Error:
{ "ok": false, "error_code": 400, "description": "chat_id is required" }
Methods
getMe
Базовая информация о боте. Без параметров.
Basic info about the bot. No parameters.
$ curl https://ix.x2chat.com/api/v1/bot123456789:AAEh…/getMe
{
"ok": true,
"result": {
"id": "uuid",
"is_bot": true,
"username": "my_cool_bot",
"first_name": "My Cool Bot",
"can_join_groups": true,
"can_read_all_group_messages": false,
"supports_inline_queries": false
}
}
sendMessage
Отправить текстовое сообщение в чат. Бот должен быть участником чата.
Send a text message to a chat. The bot must be a member of the chat.
| Параметр | Parameter | Тип | Type | Описание | Description |
|---|---|---|---|---|---|
chat_id | integer | ID чата (обязательно)Chat ID (required) | |||
text | string | Текст, до 4096 символов (обязательно)Text, up to 4096 chars (required) | |||
parse_mode | string | «HTML», «MarkdownV2» (опционально)"HTML", "MarkdownV2" (optional) | |||
reply_to_message_id | string | UUID сообщения для ответаUUID of message to reply | |||
reply_markup | object | InlineKeyboard / Reply / Remove / ForceReplyInlineKeyboard / Reply / Remove / ForceReply | |||
disable_notification | bool | Без пушаSilent send |
$ curl -X POST https://ix.x2chat.com/api/v1/bot<TOKEN>/sendMessage \
-H "Content-Type: application/json" \
-d '{
"chat_id": 488,
"text": "Привет! Я бот.",
"reply_markup": {
"inline_keyboard": [[
{"text": "Yes", "callback_data": "yes"},
{"text": "No", "callback_data": "no"}
]]
}
}'
editMessageText
Заменить текст уже отправленного сообщения.
Replace text of an already-sent message.
{ "chat_id": 488, "message_id": "<uuid>", "text": "Обновлённый текст" }
deleteMessage
{ "chat_id": 488, "message_id": "<uuid>" }
forwardMessage
Бот должен быть участником обоих чатов.
Bot must be a member of both chats.
{ "chat_id": 488, "from_chat_id": 476, "message_id": "<uuid>" }
getUpdates
Long-polling: получить новые updates. Используйте если не настроили webhook.
Long polling: receive new updates. Use this if no webhook is set.
{
"ok": true,
"result": [
{ "update_id": 1, "message": { ... } },
{ "update_id": 2, "callback_query": { ... } }
]
}
setWebhook
Зарегистрировать URL, на который X2Chat будет POST'ить updates. После регистрации webhook — getUpdates перестаёт получать новые updates.
Register a URL to which X2Chat will POST updates. Once a webhook is set, getUpdates will no longer return new updates.
{
"url": "https://your-server.com/x2chat-webhook",
"secret_token": "random_secret_for_x_telegram_header",
"allowed_updates": ["message", "callback_query"],
"max_connections": 40
}
setMyCommands
{
"commands": [
{ "command": "start", "description": "Начать работу" },
{ "command": "help", "description": "Справка" }
]
}
answerCallbackQuery
Подтвердить нажатие на InlineKeyboard-кнопку. text покажется как тост или alert у пользователя.
Acknowledge a tap on an InlineKeyboard button. text is shown as toast or alert to the user.
{
"callback_query_id": "<id>",
"text": "Спасибо за ответ!",
"show_alert": false
}
Типы updates
Update types
| Type | Когда | When |
|---|---|---|
message | Пользователь отправил сообщение в чат, где бот — участник. Включая /команды.User sent a message in a chat where the bot is a member. Includes /commands. | |
callback_query | Пользователь нажал на InlineKeyboard-кнопку с callback_data.User tapped an InlineKeyboard button with callback_data. |
Inline-клавиатура
Inline keyboard
Передайте reply_markup в sendMessage. Формат — 2D массив объектов кнопок:
Pass reply_markup to sendMessage. The format is a 2D array of button objects:
{
"inline_keyboard": [
[
{ "text": "👍 Like", "callback_data": "like" },
{ "text": "👎 Dislike", "callback_data": "dislike" }
],
[
{ "text": "📝 Open page", "url": "https://example.com" }
]
]
}
Поля кнопки:
Button fields:
| Field | Type | Описание | Description |
|---|---|---|---|
text | string | Подпись (обязательно)Label (required) | |
callback_data | string | Произвольная строка ≤ 64 байта. Доставляется боту как callback_query.Arbitrary string ≤ 64 bytes. Delivered to bot as callback_query. | |
url | string | Открывается внешним приложениемOpens in external app | |
switch_inline_query | string | Заполняет input bar пользователяFills user's input bar |
Команды
Commands
Когда пользователь отправляет в чат сообщение /start или /help@my_cool_bot, X2Chat:
- Парсит команду из первого слова
- Если указан
@username— отправляет только этому боту - Иначе — всем ботам, подписанным на чат
- Update приходит как
messageсentities=[{"type": "bot_command", "offset": 0, "length": N}]
Команды видны пользователю через «меню команд» (UI чата). Подсветка команд использует setMyCommands.
When a user sends /start or /help@my_cool_bot, X2Chat:
- Parses the command from the first word
- If
@usernameis specified — delivers only to that bot - Otherwise — delivers to all bots subscribed to the chat
- Update arrives as
messagewithentities=[{"type": "bot_command", "offset": 0, "length": N}]
Commands appear to the user via the command menu (chat UI). The menu uses setMyCommands for descriptions.
Examples
Node.js
import fetch from 'node-fetch';
const TOKEN = '123456789:AAEh…';
const BASE = `https://ix.x2chat.com/api/v1/bot${TOKEN}`;
async function sendMessage(chatId, text, replyMarkup) {
const r = await fetch(`${BASE}/sendMessage`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ chat_id: chatId, text, reply_markup: replyMarkup }),
});
return r.json();
}
async function poll() {
let offset = 0;
while (true) {
const resp = await fetch(`${BASE}/getUpdates?offset=${offset}&limit=100`);
const { result } = await resp.json();
for (const u of result) {
offset = Math.max(offset, u.update_id);
if (u.message?.text === '/start') {
await sendMessage(u.message.chat.id, 'Hello!');
}
}
if (result.length === 0) await new Promise(r => setTimeout(r, 1000));
}
}
poll();
Python (requests)
import requests, time
TOKEN = '123456789:AAEh…'
BASE = f'https://ix.x2chat.com/api/v1/bot{TOKEN}'
def send_message(chat_id, text, reply_markup=None):
return requests.post(f'{BASE}/sendMessage', json={
'chat_id': chat_id, 'text': text,
'reply_markup': reply_markup,
}).json()
offset = 0
while True:
r = requests.get(f'{BASE}/getUpdates', params={'offset': offset, 'limit': 100}).json()
for u in r['result']:
offset = max(offset, u['update_id'])
if u.get('message', {}).get('text') == '/start':
send_message(u['message']['chat']['id'], 'Привет!')
if not r['result']: time.sleep(1)
Простой webhook (Express)
Simple webhook (Express)
import express from 'express';
const app = express();
app.use(express.json());
app.post('/x2chat-webhook', (req, res) => {
const update = req.body;
if (update.callback_query) {
const { id, data } = update.callback_query;
// answer back
fetch(`https://ix.x2chat.com/api/v1/bot<TOKEN>/answerCallbackQuery`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ callback_query_id: id, text: `Получено: ${data}` }),
});
}
res.json({ ok: true });
});
app.listen(3000);
Лимиты и особенности
Limits & specifics
| Параметр | Parameter | Лимит | Limit |
|---|---|---|---|
| Длина текстового сообщенияText length | 4096 chars | ||
| Длина callback_datacallback_data length | 64 bytes | ||
| Кнопок в строкеButtons per row | 8 | ||
| Строк в клавиатуреRows in keyboard | 100 | ||
| Команд в setMyCommandssetMyCommands commands | 100 | ||
| TTL callback_query (для answerCallbackQuery)callback_query TTL | 5 min | ||
| Webhook retriesWebhook retries | fire-and-forget, нетfire-and-forget, none |
⚠ Важно: сообщения от ботов не зашифрованы E2E. Не отправляйте через бота приватные данные пользователей.
⚠ Important: bot messages are not E2E-encrypted. Don't send sensitive user data through a bot.
✓ Поддерживается: getMe, sendMessage, editMessageText, deleteMessage, forwardMessage, getUpdates, setWebhook/getWebhookInfo/deleteWebhook, setMyCommands/getMyCommands, answerCallbackQuery, InlineKeyboard (url/callback_data/switch_inline_query), /command routing с @username.
✓ Supported: getMe, sendMessage, editMessageText, deleteMessage, forwardMessage, getUpdates, setWebhook/getWebhookInfo/deleteWebhook, setMyCommands/getMyCommands, answerCallbackQuery, InlineKeyboard (url/callback_data/switch_inline_query), /command routing with @username.
В разработке: sendPhoto/sendDocument/sendVideo/sendVoice, ReplyKeyboard, inline_query (@bot mode), кастомные аватарки бота, статистика.
Coming soon: sendPhoto/sendDocument/sendVideo/sendVoice, ReplyKeyboard, inline_query (@bot mode), custom bot avatars, statistics.
🆕 One-click QR (два направления):
- Integration QR — X2Chat → ваш сайт. Юзер делает QR в X2Chat, ваш сайт сканит и получает bot_token + chat_id автозаполнением.
- Webhook QR — ваш сайт → X2Chat. Сайт показывает QR с webhook URL, X2Chat сканит и настраивает бота на ваш endpoint.
🆕 One-click QR (two directions):
- Integration QR — X2Chat → your site. User makes a QR in X2Chat, your site scans it and gets bot_token + chat_id by autofill.
- Webhook QR — your site → X2Chat. Site shows QR with webhook URL, X2Chat scans and configures the bot to call your endpoint.
© X2Chat · Поддержка: bots@x2chat.com
© X2Chat · Support: bots@x2chat.com