Passing Context to the Bot When Opening a Chat
If you are developing integrations for Bitrix24 using AI tools (Codex, Claude Code, Cursor), connect to the MCP server so that the assistant can utilize the official REST documentation.
The mechanism for passing the initial context to the bot when opening a chat. The user follows a special link from an external site, via a QR code, or a deep link from the application, the messenger opens a dialog with the bot, and the bot immediately receives arbitrary JSON data—without any additional steps.
With this data, the bot instantly understands why the user has arrived: it opens the required detail form, launches the adaptation workflow, issues a coupon, or starts the authorization procedure.
How the Mechanism Works
- The user follows the link
?IM_DIALOG={dialogId}&BOT_CONTEXT={json}or the nativebxdeep link. - The Bitrix24 web interface opens a chat with the bot.
- After initializing the dialog, the client sends a request
im.v2.Chat.Bot.sendContextwith{dialogId, context}. - The platform forwards the context to the bot—through a PHP handler (modular bots) and through the event
ONIMBOTV2CONTEXTGET(REST bots). - The bot responds with its own method calls: sends a message, displays a keyboard, and so on.
The BOT_CONTEXT parameter is automatically removed from the browser's address bar via history.replaceState—after the chat is opened, the context token is no longer in the history.
Link Formats
The context can be passed in two ways: through the browser or via a bx deep link for desktop and mobile applications. Both methods deliver the same data, so the logic for processing in the bot does not depend on the chosen method.
It is not possible to determine from the integration side whether the user has the application installed. Recommended approaches in the UI:
- Two buttons—“Open in App” (
bxlink) and “Open in Browser” (http link), allowing the user to choose. - Landing page—automatically attempts to open the
bxlink. If the application does not intercept the transition within the allotted time, it shows a fallback button with the http link.
Web: GET Parameters
Works on any Bitrix24 page:
https://{portal}/online/?IM_DIALOG={dialogId}&BOT_CONTEXT={urlEncodedJson}
|
Parameter |
Description |
|
|
|
|
|
JSON of arbitrary structure in URL encoding |
Example link:
https://portal.bitrix24.com/online/?IM_DIALOG=1459503&BOT_CONTEXT=%7B%22pairCode%22%3A%2213bd812901b295c50adbc%22%7D
Application: bx Deep Link
Deep link for the desktop and mobile Bitrix24 application. Opens a chat with the bot directly through the bx:// protocol handler:
bx://v2/{portal}/botContext/dialogId/{dialogId}/context/{urlEncodedJson}
|
Segment |
Description |
|
|
Version of the application protocol, currently always |
|
|
Bitrix24 domain |
|
|
Type of deep link, fixed value |
|
|
Numeric ID of the user-bot |
|
|
|
Example:
bx://v2/portal.bitrix24.com/botContext/dialogId/1459503/context/%7B%22pairCode%22%3A%2213bd812901b295c50adbc%22%7D
JS API
If the chat is opened programmatically from within the Bitrix24 page, use the JS API:
import { Messenger } from 'im.public';
Messenger.openChatWithBotContext(dialogId, { pairCode: '13bd812901b295c50adbc' });
|
Parameter |
Type |
Description |
|
|
|
Identifier of the bot (numeric ID) |
|
|
|
Arbitrary JSON object |
The method creates an internal context service, subscribes to onDialogInited, and after initializing the dialog, sends a request im.v2.Chat.Bot.sendContext.
Event ONIMBOTV2CONTEXTGET
The main point for processing context for the bot. The event is delivered in the same mode that was chosen when registering the bot via imbot.v2.Bot.register—no separate subscription is required.
- Fetch mode (
eventMode: "fetch", by default): the event is retrieved via imbot.v2.Event.get. - Webhook mode (
eventMode: "webhook"): the event arrives as a request towebhookUrl.
Complete descriptions of all fields, delivery modes, and data examples can be found in the event reference.
Event Fields
|
Field |
Type |
Description |
|
|
|
Recipient bot. Format depends on the mode: in fetch — full bot object, in webhook — |
|
|
|
Identifier of the dialog, for example |
|
|
|
Arbitrary JSON passed when opening the chat |
|
|
|
Chat object |
|
|
|
User who initiated the opening |
|
|
|
Language of the bot |
user.id in the event comes as number (not string) in both fetch and webhook modes. Use user.id directly for matching with stored data.
The handler's response does not affect the scenario: the bot responds with its own method calls, for example, imbot.v2.Chat.Message.send.
Example: Webhook Context Handler
// 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' => "Opening task #{$taskId}"],
]);
}
http_response_code(200);
echo json_encode(['status' => 'ok']);
}
Use Cases
Launch via Deep Link
The most common case: the link carries a short startup context, and the bot immediately "knows why the user has come" and launches the required scenario. Identity binding and confirmation are not required.
|
Scenario |
Example |
What the bot does |
|
Deep link to content |
|
Opens the detail form, launches the scenario |
|
Referral / invitation |
|
Binds the new user to the inviter |
|
Adaptation |
|
Pre-fills the team, role, or organization |
|
Activation / redemption |
|
Issues a coupon / gift / order |
|
Offline → chat (QR) |
|
Context for support or order from offline |
Two ways to pass data:
- Embedded data—directly in the link. Suitable for small and non-confidential data.
- Token link—a short token is placed in
BOT_CONTEXT, and the real data is restored from it on your server. Suitable for large or confidential data.
Binding and Authorization
The same deep link, but the parameter is an authorization or binding token, and the result is the binding of a verified identity: session creation or issuance of a personal key. The server lifecycle of pairCode and mandatory confirmation in the bot are added on top of the basic scenario.
Typical scenario:
- The external server generates
pairCodeand returns a link to the bot to the browser. - The user follows the link—the bot receives
ONIMBOTV2CONTEXTGETwith the verifieduser.id. - The bot does not perform the binding immediately but shows a confirmation detail form with information about the initiator.
- The user clicks "Confirm"—a separate event
ONIMBOTV2COMMANDADDarrives. - Only after the button is pressed does the server perform the binding (creates a session, issues a key).
Security
The event ONIMBOTV2CONTEXTGET should not immediately perform actions with side effects: creating a session, binding an account, issuing a key. The event only initiates the scenario—its completion requires explicit user confirmation in the bot.
Why confirmation is mandatory. Without it, CONTEXTGET is an unnoticed automatic binding. An attacker embeds an image on their page with a URL like https://victim-address.com/online/?...BOT_CONTEXT={attacker_pairCode}—the victim's browser silently calls CONTEXTGET, and the victim's identity is bound to the attacker's code. An explicit confirmation detail form in the bot with the name or IP/time of the initiator allows the user to see the foreign request and reject it.
Recommendations for implementing binding:
- Two independent secrets.
pairCodeis passed via the link, while the result (session or key) is received by the browser through a separatehttpOnlycookie. An interceptedpairCodedoes not reveal the binding result. - Atomic state change. Upon receiving
CONTEXTGET, change the record state toawaiting_confirmin one atomic operation and storeuser.idin it. When the button is pressed, change the state fromawaiting_confirm → consumedalso in one atomic operation and only if theuser.idof the button presser matches the stored one. - String escaping. Escape user data (name, email) before inserting it into the bot's message BB markup.
- Initiator of the request should be displayed in the confirmation detail form: name/email or IP/browser/time.
Lifecycle of pairCode
|
Parameter |
Recommendation |
|
Format |
64 hexadecimal characters (256 bits), cryptographically random |
|
Time to live (TTL) |
~10–15 minutes |
|
States |
|
|
One-time use |
Change state in one atomic operation: |
|
Protection against brute force |
Unknown, expired, or foreign code → |
Examples
Link from an External Site
<a href="https://portal.bitrix24.com/online/?IM_DIALOG=1234&BOT_CONTEXT=%7B%22action%22%3A%22openTask%22%2C%22taskId%22%3A456%7D">
Ask the bot a question about the task
</a>
The bot will receive in context: {"action": "openTask", "taskId": 456}.
Call from JS Code of the Application
import { Messenger } from 'im.public';
Messenger.openChatWithBotContext('1234', {
action: 'openTask',
taskId: 456,
source: 'taskCard',
});
Event ONIMBOTV2CONTEXTGET (fetch mode)
{
"type": "ONIMBOTV2CONTEXTGET",
"data": {
"bot": { "id": 456, "code": "my_bot", "eventMode": "fetch" },
"dialogId": "chat5",
"context": { "action": "openTask", "taskId": 456 },
"chat": { "id": 5, "dialogId": "chat5", "type": "chat" },
"user": { "id": 274, "name": "John Smith" },
"language": "en"
}
}
Binding Event with pairCode
{
"type": "ONIMBOTV2CONTEXTGET",
"data": {
"chat": { "dialogId": "274" },
"user": { "id": 274, "name": "John Smith" },
"context": { "pairCode": "e5142e4ad735..." }
}
}
user.id here is 274—this is a number, not a string. Use it for binding after confirmation.
Continue Learning
- Event Formats for imbot.v2 — complete description of all events, including
ONIMBOTV2CONTEXTGETandONIMBOTV2COMMANDADD - Chatbots 2.0: Quick Start — step-by-step start with bot registration and the first message
- Register the Automation rule imbot.v2.Bot.register — bot registration parameters,
eventMode, andwebhookUrl - Get Events from imbot.v2.Event.get — retrieving events in fetch mode
- Send Message imbot.v2.Chat.Message.send — sending a response message from the bot