Передача контекста боту при открытии чата

Выберите инструмент для разработки с AI-агентом:

  • используйте Битрикс24 Вайбкод, чтобы создать приложение для Битрикс24 по описанию задачи без знания языков программирования. Агент напишет код и разместит приложение на сервере без ручной настройки хостинга
  • используйте MCP-сервер, чтобы разрабатывать интеграцию через REST API в своем проекте. Агент будет обращаться к официальной REST-документации

Механизм передачи стартового контекста боту при открытии чата. Пользователь переходит по специальной ссылке с внешнего сайта или по QR-коду, мессенджер открывает диалог с ботом, и бот немедленно получает произвольные JSON-данные — без дополнительных шагов.

По этим данным бот сразу понимает, зачем пришел пользователь: открывает нужную карточку, запускает сценарий адаптации, выдает купон или начинает процедуру авторизации.

Как работает механизм

  1. Пользователь переходит по ссылке ?IM_DIALOG={dialogId}&BOT_CONTEXT={json} или по bx-диплинку десктопного приложения.
  2. Битрикс24 открывает чат с ботом.
  3. После инициализации диалога клиент отправляет запрос im.v2.Chat.Bot.sendContext с {dialogId, context}.
  4. Платформа направляет контекст боту — через PHP-обработчик (модульные боты) и через событие ONIMBOTV2CONTEXTGET (REST-боты).
  5. Бот реагирует собственными вызовами методов: отправляет сообщение, показывает клавиатуру и так далее.

Параметр BOT_CONTEXT автоматически удаляется из адресной строки браузера через history.replaceState — после открытия чата контекстный токен в истории не остается.

Форматы ссылок

Контекст можно передать двумя способами: через браузер или через bx-диплинк десктопного приложения. Оба способа доставляют одинаковые данные, поэтому логика обработки в боте от выбранного способа не зависит.

Определить со стороны интеграции, установлено ли у пользователя десктопное приложение, нельзя. Рекомендуемые подходы в UI:

  • Две кнопки — «Открыть в приложении» (bx-ссылка) и «Открыть в браузере» (http-ссылка), пользователь выбирает сам.
  • Посадочная страница — автоматически пытается открыть bx-ссылку. Если приложение не перехватило переход за отведенное время — показывает запасную кнопку с http-ссылкой.

Веб: GET-параметры

Работает на любой странице Битрикс24:

https://{portal}/online/?IM_DIALOG={dialogId}&BOT_CONTEXT={urlEncodedJson}

Параметр

Описание

IM_DIALOG

dialogId — числовой ID пользователя-бота

BOT_CONTEXT

JSON произвольной структуры в URL-кодировке

Пример ссылки:

https://portal.bitrix24.ru/online/?IM_DIALOG=1459503&BOT_CONTEXT=%7B%22pairCode%22%3A%2213bd812901b295c50adbc%22%7D

Диплинк десктопного приложения Битрикс24. Открывает чат с ботом напрямую через обработчик протокола bx://:

bx://v2/{portal}/botContext/dialogId/{dialogId}/context/{urlEncodedJson}

Сегмент

Описание

v2

Версия протокола приложения, сейчас всегда v2

{portal}

Домен Битрикс24

botContext

Тип диплинка, фиксированное значение

{dialogId}

Числовой ID пользователя-бота

{urlEncodedJson}

encodeURIComponent(JSON.stringify(context))

Пример:

bx://v2/portal.bitrix24.ru/botContext/dialogId/1459503/context/%7B%22pairCode%22%3A%2213bd812901b295c50adbc%22%7D

Мобильные приложения: отдельного диплинка нет

Протокол bx:// относится к десктопному приложению. Мобильные приложения Битрикс24 для Android и iOS его не обрабатывают.

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

Открыть мобильное приложение сразу на нужном чате по ссылке с внешнего сайта нельзя — такого диплинка нет. Протокол bitrix24:// выводит приложение на передний план, но адрес внутри него не разбирает. Обычная http-ссылка облачного Битрикс24 открывается в браузере телефона. Рассчитывайте сценарий на веб-ссылку и bx-диплинк десктопного приложения.

JS API

Только для кода на домене Битрикс24

Объект Messenger доступен только коду страницы и расширениям — тому коду, который выполняется на самой странице Битрикс24, на том же домене. Получить объект можно через import { Messenger } from 'im.public' или BX.Runtime.loadExtension('im.public.iframe'): оба способа дают прямой доступ к среде выполнения мессенджера.

Приложение запускается в своем фрейме, на другом домене, и доступа к этой среде выполнения не имеет: ни Messenger.*, ни BX.Runtime.loadExtension из него не вызываются. Чтобы открыть чат из приложения, используйте BX24.im.openMessenger или $b24.parent.imOpenMessenger из библиотеки b24jssdk.

Если чат открывается программно из кода, размещенного на домене Битрикс24, используйте JS API:

import { Messenger } from 'im.public';

Messenger.openChatWithBotContext(dialogId, { pairCode: '13bd812901b295c50adbc' });

Параметр

Тип

Описание

dialogId

string

Идентификатор бота (числовой ID)

context

object

Произвольный JSON-объект

Метод создает внутренний сервис контекста, подписывается на onDialogInited и после инициализации диалога отправляет запрос im.v2.Chat.Bot.sendContext.

Этот же запрос доступен по REST. Вызовите im.v2.Chat.Bot.sendContext с параметрами dialogId и context, чтобы воспроизвести доставку контекста при отладке бота, без перехода по ссылке.

Событие ONIMBOTV2CONTEXTGET

Основная точка обработки контекста для бота. Событие доставляется в том же режиме, который выбран при регистрации бота через imbot.v2.Bot.register — отдельной подписки не требуется.

  • Fetch-режим (eventMode: "fetch", по умолчанию): событие забирается через imbot.v2.Event.get.
  • Webhook-режим (eventMode: "webhook"): событие приходит запросом на webhookUrl.

Полное описание всех полей, режимов доставки и примеры данных — в справочнике событий.

Поля события

Поле

Тип

Описание

bot

object

Бот-получатель. Формат зависит от режима: в fetch — полный объект бота, в webhook — {id, code, auth}

dialogId

string

Идентификатор диалога, из которого пришел контекст. В приватном чате с ботом — числовой ID пользователя, например "274", в групповом чате — "chat5"

context

object

Произвольный JSON, переданный при открытии чата

chat

object

Объект чата

user

object

Пользователь, инициировавший открытие

language

string

Язык бота

user.id в событии приходит как number (не string) и в fetch-, и в webhook-режиме. Используйте user.id напрямую для сопоставления с хранимыми данными.

Ответ обработчика не влияет на сценарий: бот реагирует собственными вызовами методов, например imbot.v2.Chat.Message.send.

Пример: webhook-обработчик контекста

// webhook_handler.php
$data = json_decode(file_get_contents('php://input'), true);

if (($data['event'] ?? '') === 'ONIMBOTV2CONTEXTGET') {
    $eventData = $data['data'] ?? [];
    $context   = $eventData['context'] ?? [];
    $dialogId  = $eventData['chat']['dialogId'] ?? '';
    $botId     = (int)($eventData['bot']['id'] ?? 0);

    if (($context['action'] ?? null) === 'openTask') {
        $taskId = (int)($context['taskId'] ?? 0);
        CRest::call('imbot.v2.Chat.Message.send', [
            'botId'    => $botId,
            'dialogId' => $dialogId,
            'fields'   => ['message' => "Открываю задачу #{$taskId}"],
        ]);
    }

    http_response_code(200);
    echo json_encode(['status' => 'ok']);
}

Сценарии использования

Запуск по диплинку

Самый частый случай: ссылка несет короткий стартовый контекст, бот при открытии сразу «знает, зачем пришел пользователь», и запускает нужный сценарий. Привязка личности и подтверждение не требуются.

Сценарий

Пример context

Что делает бот

Диплинк к контенту

{"action":"openTask","taskId":456}

Открывает карточку, запускает сценарий

Реферал / приглашение

{"ref":"u12345"}

Привязывает нового пользователя к пригласившему

Адаптация

{"onboard":"teamX"}

Предзаполняет команду, роль или организацию

Активация / погашение

{"claim":"GIFT-7H2K"}

Выдает купон / подарок / заказ

Офлайн → чат (QR)

{"table":42}

Контекст поддержки или заказа из офлайна

Два способа передать данные:

  • Встроенные данные — прямо в ссылке. Подходит для небольших и неконфиденциальных данных.
  • Токен-ссылка — в BOT_CONTEXT кладется короткий токен, а реальные данные восстанавливаются по нему на вашем сервере. Подходит для объемных или конфиденциальных данных.

Привязка и авторизация

Тот же диплинк, но параметр — это токен авторизации или привязки, а результат — привязка проверенной личности: создание сессии или выдача персонального ключа. Поверх базового сценария добавляются серверный жизненный цикл pairCode и обязательное подтверждение в боте.

Типичный сценарий:

  1. Внешний сервер генерирует pairCode и возвращает браузеру ссылку на бота.
  2. Пользователь переходит по ссылке — бот получает ONIMBOTV2CONTEXTGET с проверенным user.id.
  3. Бот не выполняет привязку сразу, а показывает карточку подтверждения с информацией об инициаторе.
  4. Пользователь нажимает «Подтвердить» — приходит отдельное событие ONIMBOTV2COMMANDADD.
  5. Только после нажатия кнопки сервер выполняет привязку (создает сессию, выдает ключ).

Безопасность

Событие ONIMBOTV2CONTEXTGET не должно сразу выполнять действия с побочными эффектами: создавать сессию, привязывать аккаунт, выдавать ключ. Событие только инициирует сценарий — завершает его явное подтверждение пользователя в боте.

Почему обязательно подтверждение. Без него CONTEXTGET — это незаметная автоматическая привязка. Атакующий встраивает на свою страницу изображение с URL вида https://адрес-жертвы/online/?...BOT_CONTEXT={pairCode_атакующего} — браузер жертвы молча вызывает CONTEXTGET, и личность жертвы привязывается к коду атакующего. Явная карточка подтверждения в боте с именем или IP/временем инициатора позволяет пользователю увидеть чужой запрос и отклонить его.

Рекомендации при реализации привязки:

  • Два независимых секрета. pairCode передается через ссылку, а результат (сессия или ключ) браузер получает по отдельному httpOnly-cookie. Перехваченный pairCode не раскрывает результат привязки.
  • Атомарная смена состояния. При получении CONTEXTGET одной операцией переводите запись в состояние awaiting_confirm и сохраняйте в ней user.id. При нажатии кнопки меняйте состояние awaiting_confirm → consumed тоже одной атомарной операцией и только если user.id нажавшего совпадает с сохраненным.
  • Экранирование строк. Пользовательские данные (имя, email) экранируйте перед вставкой в BB-разметку сообщения бота.
  • Инициировавший запрос отображайте в карточке подтверждения: имя/email или IP/браузер/время.

Жизненный цикл pairCode

Параметр

Рекомендация

Формат

64 шестнадцатеричных символа (256 бит), криптографически случайный

Время жизни (TTL)

~10–15 минут

Состояния

pending → awaiting_confirm → confirmed | declined | expired

Одноразовость

Меняйте состояние одной атомарной операцией: SELECT … FOR UPDATE или UPDATE … WHERE status=… RETURNING

Защита от перебора

Неизвестный, просроченный или чужой код → 200 без утечки данных; просроченные записи удаляйте по расписанию

Примеры

Ссылка с внешнего сайта

<a href="https://portal.bitrix24.ru/online/?IM_DIALOG=1234&BOT_CONTEXT=%7B%22action%22%3A%22openTask%22%2C%22taskId%22%3A456%7D">
    Задать вопрос боту о задаче
</a>

Бот получит в context: {"action": "openTask", "taskId": 456}.

Вызов из JS-кода приложения

import { Messenger } from 'im.public';

Messenger.openChatWithBotContext('1234', {
    action: 'openTask',
    taskId: 456,
    source: 'taskCard',
});

Событие ONIMBOTV2CONTEXTGET (fetch-режим)

{
    "type": "ONIMBOTV2CONTEXTGET",
    "data": {
        "bot": { "id": 456, "code": "my_bot", "eventMode": "fetch" },
        "dialogId": "274",
        "context": { "action": "openTask", "taskId": 456 },
        "chat": { "id": 4511, "dialogId": "274", "type": "private" },
        "user": { "id": 274, "name": "Евгений Шеленков" },
        "language": "ru"
    }
}

Событие привязки с pairCode

{
    "type": "ONIMBOTV2CONTEXTGET",
    "data": {
        "chat": { "dialogId": "274" },
        "user": { "id": 274, "name": "Евгений Шеленков" },
        "context": { "pairCode": "e5142e4ad735..." }
    }
}

user.id здесь 274 — это number, не строка. Используйте его для привязки после подтверждения.

Продолжите изучение