Перейти к содержанию

Botfarm API Documentation

Общая информация

  • Base URL: https://app2.botfarm.me/api/v1/
  • Swagger UI: /api/docs/
  • OpenAPI Schema: /api/schema/

Аутентификация

Все запросы требуют токен компании в заголовке:

Authorization: Bearer <company_api_token>

Административные endpoints (/createCompanyBot) требуют admin токен.


Endpoints

Messages

POST /sendMessage

Отправка сообщения пользователям.

Request:

{
  "text": "Привет!",
  "user_ids": [1, 2, 3],
  "parse_mode": "MarkdownV2",
  "preview_is_disabled": false,
  "photo_url": "https://example.com/image.jpg"
}

Параметр Тип Обязательный Описание
text string да Текст сообщения (поддерживает mentions)
user_ids array[int] нет ID пользователей. Если не указан — отправка в service chat
parse_mode string нет Формат текста: MarkdownV2, HTML
preview_is_disabled boolean нет Отключить превью ссылок
photo_url string нет URL изображения для отправки с текстом

Response: 200 OK (пустой объект)


POST /navigate

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

Request:

{
  "url": "/scores",
  "user_ids": [1, 2, 3],
  "nonce": "550e8400-e29b-41d4-a716-446655440000",
  "preserve_location": false,
  "initial_delay": 0,
  "bot_type": "tg",
  "refresh_key": "scores_v1"
}

Параметр Тип Обязательный Описание
url string да URL страницы (абсолютный или относительный к home_page_url)
user_id int нет ID одного пользователя
chat_id int нет Альтернатива user_id
user_ids array[int] нет ID нескольких пользователей
nonce uuid нет UUID для отслеживания кампании (создается автоматически если не указан)
preserve_location boolean нет Сохранить текущую локацию (не обновлять ChatPage). По умолчанию: false
initial_delay int нет Начальная задержка в секундах. По умолчанию: 0
bot_type string нет Фильтр по типу бота: tg, vk, max, ig
refresh_key string нет Ключ для последующего обновления сообщений через /refresh (макс. 255 символов)

Если user_id/user_ids не указаны — навигация в service chat компании.

Response:

{
  "nonce": "550e8400-e29b-41d4-a716-446655440000",
  "active_count": 3,
  "inactive_count": 1,
  "inactive_user_ids": [4],
  "max_delay": 5
}

Примечание: Страницы, навигация на которые происходит через API, автоматически не попадают в стек навигации для возврата (аналогично метатегу bf-skip-stack).

POST /refresh

Обновление ранее отправленных сообщений по ключу refresh_key. Botfarm находит все сообщения с указанным ключом, перезапрашивает их URL у бекенда и обновляет содержимое у пользователей.

  • Текстовые сообщения редактируются на месте (editMessageText)
  • Сообщения с фото/медиа: отправляется новое сообщение
  • Обновляются только пользователи, которые все еще находятся на этой странице
  • Задачи обрабатываются в low_priority очереди с задержкой 1 сек на сообщение
  • Максимум 10 000 сообщений за один вызов

Request:

{
  "refresh_key": "scores_v1",
  "initial_delay": 0
}

Параметр Тип Обязательный Описание
refresh_key string да Ключ, указанный ранее в /navigate
initial_delay int нет Начальная задержка в секундах (0-3600). По умолчанию: 0

Response:

{
  "count": 150,
  "max_delay": 149
}

Поле Описание
count Количество сообщений, поставленных в очередь на обновление
max_delay Максимальная задержка в секундах до последнего сообщения

Пример использования:

# 1. Отправить страницу с refresh_key
curl -X POST https://app2.botfarm.me/api/v1/navigate \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "/scores", "user_ids": [1, 2, 3], "refresh_key": "scores_v1"}'

# 2. Когда данные изменились — обновить все сообщения
curl -X POST https://app2.botfarm.me/api/v1/refresh \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"refresh_key": "scores_v1"}'

Users

POST /getUserByTelegramId/{telegram_id}

Получить или создать пользователя по Telegram ID.

Request:

{
  "username": "johndoe",
  "first_name": "John",
  "last_name": "Doe"
}

Параметр Тип Обязательный Описание
username string нет Telegram username
first_name string нет Имя
last_name string нет Фамилия

Response:

{
  "id": 123,
  "first_name": "John",
  "last_name": "Doe",
  "tg_username": "johndoe",
  "tg_ext_id": 123456789
}

GET /getUserById/{user_id}

Получить пользователя по внутреннему ID.

Response:

{
  "id": 123,
  "first_name": "John",
  "last_name": "Doe",
  "tg_username": "johndoe",
  "tg_ext_id": 123456789
}

POST /importUser

Импорт пользователя из внешней системы.

Request:

{
  "telegram_ext_id": 123456789,
  "username": "johndoe",
  "first_name": "John",
  "last_name": "Doe"
}

Параметр Тип Обязательный Описание
telegram_ext_id int да Telegram ID пользователя
username string нет Telegram username
first_name string нет Имя
last_name string нет Фамилия

Response:

{
  "user": {
    "id": 123
  }
}

POST /mergeUsers

Объединение двух пользователей. Все данные (BotUser, ChatPage, ChatPageHistory и т.д.) переносятся с удаляемого пользователя на сохраняемого.

Request:

{
  "user_to_keep_id": 123,
  "user_to_delete_id": 456
}

Параметр Тип Обязательный Описание
user_to_keep_id int да ID пользователя, который остается
user_to_delete_id int да ID пользователя, который будет удален

Response:

{
  "status": "ok"
}

POST /detachBotUser

Отвязка пользователя от конкретного типа бота. Удаляет BotUser и очищает ext_id.

Request:

{
  "user_id": 123,
  "bot_type": "tg"
}

Параметр Тип Обязательный Описание
user_id int да ID пользователя
bot_type string да Тип бота: tg, max, vk

Response:

{
  "status": "ok",
  "deleted_count": 1
}

GET /getUserAvatars/{user_id}

Получить аватары пользователя из Telegram.

Response:

{
  "avatars": ["https://...photo1.jpg", "https://...photo2.jpg"]
}

GET /hits/{user_id}

История посещений страниц пользователем (последние 50).

Response:

[
  {
    "id": 1,
    "url": "https://example.com/page",
    "title": "Page Title",
    "created_at": "2024-01-15T10:30:00Z",
    "status_code": 200,
    "method": "get",
    "post_data": null,
    "response_time_total": 0.234,
    "response_time_connect": 0.05,
    "response_time_content": 0.184,
    "source": "callback",
    "referer_url": "https://example.com/prev"
  }
]


Bots

POST /setBotCommands

Установка команд бота для меню "/" в Telegram.

Request:

{
  "commands": [
    {"command": "start", "description": "Запустить бота"},
    {"command": "help", "description": "Показать помощь"},
    {"command": "settings", "description": "Настройки"}
  ]
}

Параметр Тип Обязательный Описание
commands array да Массив команд
commands[].command string да Название команды (без /)
commands[].description string да Описание команды

Response:

{
  "status": "ok"
}

Важно: Telegram API setMyCommands вызывается только если у всех команд заполнены description. Если хотя бы у одной команды пустой description, команды сохраняются в БД, но в Telegram не отправляются.

POST /updateBotToken

Обновление токена Telegram бота.

Request:

{
  "telegram_token": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz"
}

Параметр Тип Обязательный Описание
telegram_token string да Новый токен бота (макс. 512 символов)

Response:

{
  "status": "ok",
  "bot_id": 1,
  "bot_username": "my_bot"
}

POST /setHomepage

Установка домашней страницы компании.

Request:

{
  "url": "https://example.com/bot/"
}

Response: 200 OK


Nonce (Campaign Tracking)

GET /nonce/

Список всех nonce.

POST /nonce/

Создание нового nonce.

Request:

{
  "url": "https://example.com/campaign"
}

Response:

{
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "counter": 0
}

GET /nonce/{uuid}/

Получение nonce по UUID.

POST /nonce/{uuid}/stop/

Остановка кампании (отключение nonce). Все задачи, привязанные к этому nonce, будут пропущены.

Response: 200 OK


Admin

Требуют admin токен в Authorization header.

POST /createCompanyBot

Создание новой компании с ботом.

Request:

{
  "bot_type": "tg",
  "bot_token": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz",
  "company_name": "My Company",
  "home_page_url": "https://example.com/bot/",
  "service_chat_id": -1001234567890,
  "commands": [
    {"command": "start", "description": "Запустить бота"}
  ],
  "chat_chat_id": -1001234567890
}

Параметр Тип Обязательный Описание
bot_type string нет Тип бота: tg (по умолчанию), max
bot_token string да Токен бота
company_name string да Название компании (макс. 32)
home_page_url string да URL домашней страницы
service_chat_id int да ID сервисного чата
commands array да Команды бота
chat_chat_id int нет ID чата для forwarder бота (только Telegram)

Response:

{
  "api_token": "generated_api_token_here",
  "hook_secret_token": "generated_hook_secret",
  "company_id": 1,
  "bot_id": 1
}


User Mentions

Система поддерживает упоминания пользователей в сообщениях. Упоминания работают с parse_mode="HTML" и parse_mode="MarkdownV2".

HTML формат

{
  "text": "Привет, <a href=\"bf://user?id=123\">Иван Иванов</a>!",
  "user_ids": [456],
  "parse_mode": "HTML"
}

MarkdownV2 формат

{
  "text": "Привет, [Иван Иванов](bf://user?id=123)\\!",
  "user_ids": [456],
  "parse_mode": "MarkdownV2"
}

Где 123 — это BFUser.id (внутренний ID пользователя в BotFarm).

Преобразование

  • Telegram -> Telegram: [Иван](tg://user?id=987654321) @username
  • Telegram -> VK: Иван https://vk.com/username
  • VK -> VK: Иван https://vk.com/username
  • VK -> Telegram: Иван https://t.me/username

Получение BFUser.id

# Получить пользователя по Telegram ID
curl -X GET https://app2.botfarm.me/api/v1/getUserByTelegramId/123456789 \
  -H "Authorization: Bearer YOUR_TOKEN"

# Response:
{
  "id": 123,  # <- BFUser.id для mention
  "first_name": "Иван",
  "tg_ext_id": 123456789
}

Метатеги страниц

Специальные метатеги для управления поведением страниц.

Метатег Описание
bf-skip-stack Страница не попадает в стек навигации
bf-stack Страница явно попадает в стек (для режима only_stack)
bf-strip-query При вычислении base_url убирается вся query string

bf-skip-stack

Страница с этим метатегом не будет участвовать в навигации "Назад". Полезно для: - Промежуточных страниц (подтверждения, загрузки) - Страниц с результатом действия - Редиректов

<head>
  <meta name="bf-skip-stack">
</head>

При нажатии "Назад" пользователь перейдет на страницу, которая была до этой (пропустив её в истории).

bf-stack

Работает в связке с настройкой бота stack_mode="only_stack". В этом режиме в стек навигации попадают только страницы с этим метатегом.

<head>
  <meta name="bf-stack">
</head>

bf-strip-query

При наличии этого метатега base_url страницы вычисляется без query string — все GET-параметры полностью убираются. Без метатега убирается только служебный параметр bf_page.

Полезно когда одна и та же страница вызывается с разными GET-параметрами, но для навигации "Назад" должна считаться одной страницей.

<head>
  <meta name="bf-strip-query">
</head>

Пример: страница /profile?user_id=1 и /profile?user_id=2: - Без метатега: разные base_url -> разные записи в стеке - С метатегом: одинаковый base_url /profile -> кнопка "Назад" пропустит обе за один шаг


CSS классы для кнопок

Специальные CSS классы для управления поведением кнопок в HTML-разметке страниц.

Класс Описание
bf-url Внешняя ссылка — открывается как URL в браузере, не через callback
bf-back Кнопка "Назад" — возврат на предыдущую страницу из истории навигации
bf-file Ссылка на файл
bf-keep-message Не удалять предыдущее сообщение при переходе

В сообщениях с классом bf-html все ссылки, ведущие на company.home_page_url, автоматически преобразуются в Telegram deeplinks. Это позволяет пользователям пересылать сообщения со ссылками другим пользователям.

Алгоритм: 1. Из href убирается путь company.home_page_url 2. Убирается ведущий / из оставшегося пути 3. Путь кодируется в base64 (URL-safe, без padding) 4. Формируется ссылка https://t.me/{bot_username}?start={base64_path}

Пример:

<!-- company.home_page_url = https://example.com/b -->
<div class="bf-message bf-html">
  <div class="bf-text">
    Профиль: <a href="/b/user/384">Иван Иванов</a>
  </div>
</div>

Ссылка автоматически преобразуется в: https://t.me/mybot?start=dXNlci8zODQ

При переходе по deeplink user/384 будет добавлен к company.home_page_url: https://example.com/b + /user/384 = https://example.com/b/user/384

Примечание: Внешние ссылки (на другие домены) не преобразуются.


Коды ошибок

Код Описание
200 Успешно
400 Ошибка валидации / неверные данные
401 Не авторизован
404 Ресурс не найден
500 Внутренняя ошибка сервера

Примеры использования

cURL

# Отправка сообщения
curl -X POST https://app2.botfarm.me/api/v1/sendMessage \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello!", "user_ids": [1, 2, 3]}'

# Навигация с refresh_key
curl -X POST https://app2.botfarm.me/api/v1/navigate \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "/scores", "user_ids": [1, 2, 3], "refresh_key": "scores_v1"}'

# Обновление сообщений по refresh_key
curl -X POST https://app2.botfarm.me/api/v1/refresh \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"refresh_key": "scores_v1"}'

# Установка команд бота
curl -X POST https://app2.botfarm.me/api/v1/setBotCommands \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"commands": [{"command": "start", "description": "Запустить бота"}]}'

Python

import requests

TOKEN = "your_api_token"
BASE_URL = "https://app2.botfarm.me/api/v1"

headers = {
    "Authorization": f"Bearer {TOKEN}",
    "Content-Type": "application/json"
}

# Отправка сообщения
response = requests.post(
    f"{BASE_URL}/sendMessage",
    headers=headers,
    json={"text": "Hello!", "user_ids": [1, 2, 3]}
)

# Навигация с refresh_key
response = requests.post(
    f"{BASE_URL}/navigate",
    headers=headers,
    json={"url": "/scores", "user_ids": [1, 2, 3], "refresh_key": "scores_v1"}
)

# Обновление сообщений
response = requests.post(
    f"{BASE_URL}/refresh",
    headers=headers,
    json={"refresh_key": "scores_v1"}
)