X2Chat Bot API

X2Chat Bot API

Telegram-совместимый API для ботов в защищённом мессенджере X2Chat с end-to-end шифрованием. Создавайте ботов прямо в приложении, отправляйте сообщения, обрабатывайте команды, рендерите inline-клавиатуры.

Telegram-compatible Bot API for the secure E2E-encrypted messenger X2Chat. Create bots in-app, send messages, handle commands, render inline keyboards.

Введение

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» — управление ботами встроено прямо в приложение.

  1. Откройте приложение X2Chat и перейдите в «Мои боты» (URL: /my-bots).
  2. Нажмите «Новый бот».
  3. Введите username — должен заканчиваться на bot (например weather_bot, my_cool_bot).
  4. Укажите имя бота и описание.
  5. Получите токен в формате 123456789:AAEh… — сохраните его, он показывается только один раз.

Если токен утерян, его можно пересоздать в карточке бота. Старый токен перестанет работать сразу.

X2Chat has no separate "BotFather" — bot management is built into the app.

  1. Open X2Chat and go to "My Bots" (URL: /my-bots).
  2. Tap "New Bot".
  3. Enter username — must end with bot (e.g. weather_bot, my_cool_bot).
  4. Set display name and description.
  5. 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

Токен передаётся одним из трёх способов:

  1. В пути URL (как в Telegram): /api/v1/bot<TOKEN>/method
  2. Заголовок X-Bot-Token: <TOKEN>
  3. Заголовок Authorization: Bot <TOKEN>

Все запросы к Bot API делаются на хост https://ix.x2chat.com (или https://ru.x2chat.com).

The token is passed in one of three ways:

  1. In URL path (Telegram-style): /api/v1/bot<TOKEN>/method
  2. Header X-Bot-Token: <TOKEN>
  3. 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

GET/api/v1/bot<TOKEN>/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

POST/api/v1/bot<TOKEN>/sendMessage

Отправить текстовое сообщение в чат. Бот должен быть участником чата.

Send a text message to a chat. The bot must be a member of the chat.

ПараметрParameterТипTypeОписаниеDescription
chat_idintegerID чата (обязательно)Chat ID (required)
textstringТекст, до 4096 символов (обязательно)Text, up to 4096 chars (required)
parse_modestring«HTML», «MarkdownV2» (опционально)"HTML", "MarkdownV2" (optional)
reply_to_message_idstringUUID сообщения для ответаUUID of message to reply
reply_markupobjectInlineKeyboard / Reply / Remove / ForceReplyInlineKeyboard / Reply / Remove / ForceReply
disable_notificationboolБез пуша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

POST/api/v1/bot<TOKEN>/editMessageText

Заменить текст уже отправленного сообщения.

Replace text of an already-sent message.

{ "chat_id": 488, "message_id": "<uuid>", "text": "Обновлённый текст" }

deleteMessage

POST/api/v1/bot<TOKEN>/deleteMessage
{ "chat_id": 488, "message_id": "<uuid>" }

forwardMessage

POST/api/v1/bot<TOKEN>/forwardMessage

Бот должен быть участником обоих чатов.

Bot must be a member of both chats.

{ "chat_id": 488, "from_chat_id": 476, "message_id": "<uuid>" }

getUpdates

GET/api/v1/bot<TOKEN>/getUpdates?offset=0&limit=100

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

POST/api/v1/bot<TOKEN>/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

POST/api/v1/bot<TOKEN>/setMyCommands
{
  "commands": [
    { "command": "start", "description": "Начать работу" },
    { "command": "help",  "description": "Справка" }
  ]
}

answerCallbackQuery

POST/api/v1/bot<TOKEN>/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:

FieldTypeОписаниеDescription
textstringПодпись (обязательно)Label (required)
callback_datastringПроизвольная строка ≤ 64 байта. Доставляется боту как callback_query.Arbitrary string ≤ 64 bytes. Delivered to bot as callback_query.
urlstringОткрывается внешним приложениемOpens in external app
switch_inline_querystringЗаполняет 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 @username is specified — delivers only to that bot
  • Otherwise — delivers to all bots subscribed to the chat
  • Update arrives as message with entities=[{"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 length4096 chars
Длина callback_datacallback_data length64 bytes
Кнопок в строкеButtons per row8
Строк в клавиатуреRows in keyboard100
Команд в setMyCommandssetMyCommands commands100
TTL callback_query (для answerCallbackQuery)callback_query TTL5 min
Webhook retriesWebhook retriesfire-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