Skip to content

Latest commit

 

History

History
413 lines (347 loc) · 13.1 KB

File metadata and controls

413 lines (347 loc) · 13.1 KB

IM_CONTEXT_MENU Message Context Menu Item

{% note tip "" %}

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.

{% endnote %}

Scope: placement, im

The widget adds its item to the context menu of a message in the chat.

The placement code is specified in the PLACEMENT parameter of the placement.bind method.

{% note info "" %}

The widget is not displayed in the interface until the application installation is complete. Check the application installation

{% endnote %}

Where the Widget is Embedded

#| || Placement Code | Location || || IM_CONTEXT_MENU | Message context menu item || |#

Where to Find It in the Interface

Open any chat and hover over a message. In the message action bar, click the ... button to open the context menu. Hover over More to reveal additional menu items. The application item with PLACEMENT=IM_CONTEXT_MENU appears at the end of the action list above the message.

Message context menu item

What the Handler Receives

Data is sent in a POST request: some parameters come in the handler URL query string, the rest in the request body {.b24-info}

Array
(
    [DOMAIN] => xxx.bitrix24.com
    [PROTOCOL] => 1
    [LANG] => de
    [APP_SID] => 99c80eff6378726287350416ee5fef0
    [AUTH_ID] => 6061e72600631fcd00005a4b00000001f0f1076700000000f69dd5fc643d9ce2fdbc1
    [AUTH_EXPIRES] => 3600
    [REFRESH_ID] => 50e00aa340631fcd00005a4b00000001f0f1071111116580a5b83c2de639ef28c12
    [SERVER_ENDPOINT] => https://oauth.bitrix.info/rest/
    [APPLICATION_TOKEN] => ec1b2074a9d3f5c81b6e40d27a95cf38
    [APPLICATION_SCOPE] => im,placement
    [member_id] => da45a03b265ed12127f8a258d793cc5d
    [status] => L
    [PLACEMENT] => IM_CONTEXT_MENU
    [PLACEMENT_OPTIONS] => {"messageId":"2431","dialogId":"chat2","URI":"\/online\/"}
)

After parsing, the PLACEMENT_OPTIONS string from this example looks like this:

{
    "messageId": "2431",
    "dialogId": "chat2",
    "URI": "/online/"
}

{% include Note on required parameters %}

{% include notitle Description of Standard Data %}

PLACEMENT_OPTIONS

The value of PLACEMENT_OPTIONS is passed as a JSON string with the context of the call.

#| || Parameter type | Description || || messageId* string | Identifier of the message whose menu the widget is called from. The value comes as a string. The application works with the message by this identifier using the chat message methods || || dialogId* string | Chat identifier: chatNNN for a group chat, the user identifier for a private conversation. The chat can be retrieved by this identifier with the im.dialog.get method. For a private conversation, the data of the interlocutor is returned by the user.get method || || URI* string | Address of the page the widget is opened from. For the messenger this is /online/ || |#

OPTIONS When Registering via placement.bind

For IM_CONTEXT_MENU, the placement.bind method supports OPTIONS parameters.

{% include Note on required parameters %}

#| || Parameter type | Description || || extranet string | Access in the extranet, default is N.

Possible values:

  • N — the application is not available to extranet users
  • Y — the application is available to extranet users || || context string | Display context, default is ALL. Multiple values can be passed using ;.

Possible values:

  • ALL — all chats
  • USER — personal chats of users, excluding chats with bots
  • CHAT — group chats, excluding LINES and CRM
  • LINES — open lines chats
  • CRM — chats created within CRM

If ALL is passed along with other values, only ALL is used. An invalid value will cause a registration error. || || role string | User role, default is USER.

Possible values:

  • USER — the application is available to all users
  • ADMIN — the application is available only to portal administrators || |#

Code Examples

{% include Note on Examples %}

{% list tabs %}

  • cURL (OAuth)

    curl -X POST \
      -H "Content-Type: application/json" \
      -H "Accept: application/json" \
      -d '{
        "PLACEMENT": "IM_CONTEXT_MENU",
        "HANDLER": "https://your-domain.com/widgets/im-context-menu-handler.php",
        "TITLE": "My menu item",
        "LANG_ALL": {
          "de": {
            "TITLE": "Mein Menüpunkt"
          },
          "en": {
            "TITLE": "My menu item"
          }
        },
        "OPTIONS": {
          "context": "ALL",
          "role": "USER",
          "extranet": "N"
        },
        "auth": "**put_access_token_here**"
      }' \
      https://**put_your_bitrix24_address**/rest/placement.bind
  • JS (TS)

    // This snippet is an ES module: top-level await requires type="module" or a bundler.
    // $b24 is an already-initialized SDK instance (see the SDK "Get started" guide).
    import { Text } from '@bitrix24/b24jssdk'
    import type { B24Frame } from '@bitrix24/b24jssdk'
    
    declare const $b24: B24Frame
    
    try {
      const response = await $b24.actions.v2.call.make<boolean>({
        method: 'placement.bind',
        params: {
          PLACEMENT: 'IM_CONTEXT_MENU',
          HANDLER: 'https://your-domain.com/widgets/im-context-menu-handler.php',
          TITLE: 'My menu item',
          LANG_ALL: {
            ru: {
              TITLE: 'My menu item',
            },
            en: {
              TITLE: 'My menu item',
            },
          },
          OPTIONS: {
            context: 'ALL',
            role: 'USER',
            extranet: 'N',
          },
        },
        requestId: Text.getUuidRfc4122()
      })
    
      // The payload is available only on a successful response
      if (!response.isSuccess) {
        console.error(response.getErrorMessages().join('; '))
      } else {
        const result = response.getData()!.result
        console.info('Placement registered:', result)
      }
    } catch (error) {
      // Thrown on transport or SDK failures (AjaxError, SdkError, etc.)
      console.error(error)
    }
  • JS (UMD)

    <!-- Load the SDK (UMD build); it is exposed as the global B24Js -->
    <script src="https://unpkg.com/@bitrix24/b24jssdk@1/dist/umd/index.min.js"></script>
    <script>
      async function bindImContextMenu() {
        try {
          // Initialize the SDK inside a Bitrix24 frame
          const $b24 = await B24Js.initializeB24Frame()
    
          const response = await $b24.actions.v2.call.make({
            method: 'placement.bind',
            params: {
              PLACEMENT: 'IM_CONTEXT_MENU',
              HANDLER: 'https://your-domain.com/widgets/im-context-menu-handler.php',
              TITLE: 'My menu item',
              LANG_ALL: {
                ru: {
                  TITLE: 'My menu item',
                },
                en: {
                  TITLE: 'My menu item',
                },
              },
              OPTIONS: {
                context: 'ALL',
                role: 'USER',
                extranet: 'N',
              },
            },
            requestId: B24Js.Text.getUuidRfc4122()
          })
    
          // The payload is available only on a successful response
          if (!response.isSuccess) {
            console.error(response.getErrorMessages().join('; '))
            return
          }
    
          const result = response.getData().result
          console.info('Placement registered:', result)
        } catch (error) {
          // Thrown on transport or SDK failures (AjaxError, SdkError, etc.)
          console.error(error)
        }
      }
    
      document.addEventListener('DOMContentLoaded', bindImContextMenu)
    </script>
  • PHP

    try {
        $response = $b24Service
            ->core
            ->call(
                'placement.bind',
                [
                    'PLACEMENT' => 'IM_CONTEXT_MENU',
                    'HANDLER' => 'https://your-domain.com/widgets/im-context-menu-handler.php',
                    'TITLE' => 'My menu item',
                    'LANG_ALL' => [
                        'de' => [
                            'TITLE' => 'Mein Menüpunkt',
                        ],
                        'en' => [
                            'TITLE' => 'My menu item',
                        ],
                    ],
                    'OPTIONS' => [
                        'context' => 'ALL',
                        'role' => 'USER',
                        'extranet' => 'N',
                    ],
                ]
            );
    
        $result = $response->getResponseData()->getResult();
        if ($result->error()) {
            error_log($result->error());
        } else {
            echo 'Success: ' . print_r($result->data(), true);
        }
    } catch (Throwable $e) {
        error_log($e->getMessage());
        echo 'Error binding placement: ' . $e->getMessage();
    }
  • BX24.js

    BX24.callMethod(
        'placement.bind',
        {
            PLACEMENT: 'IM_CONTEXT_MENU',
            HANDLER: 'https://your-domain.com/widgets/im-context-menu-handler.php',
            TITLE: 'My menu item',
            LANG_ALL: {
                de: { TITLE: 'Mein Menüpunkt' },
                en: { TITLE: 'My menu item' }
            },
            OPTIONS: {
                context: 'ALL',
                role: 'USER',
                extranet: 'N'
            }
        },
        function(result) {
            if (result.error()) {
                console.error(result.error());
            } else {
                console.log(result.data());
            }
        }
    );
  • PHP CRest

    require_once('crest.php');
    
    $result = CRest::call(
        'placement.bind',
        [
            'PLACEMENT' => 'IM_CONTEXT_MENU',
            'HANDLER' => 'https://your-domain.com/widgets/im-context-menu-handler.php',
            'TITLE' => 'My menu item',
            'LANG_ALL' => [
                'de' => [
                    'TITLE' => 'Mein Menüpunkt',
                ],
                'en' => [
                    'TITLE' => 'My menu item',
                ],
            ],
            'OPTIONS' => [
                'context' => 'ALL',
                'role' => 'USER',
                'extranet' => 'N',
            ],
        ]
    );
    
    echo '<PRE>';
    print_r($result);
    echo '</PRE>';
  • Go

    // client and ctx are already created — see the Go SDK section
    res, err := client.Core().Call(ctx, "placement.bind", b24.Params{
    	"PLACEMENT": "IM_CONTEXT_MENU",
    	"HANDLER":   "https://your-domain.com/widgets/im-context-menu-handler.php",
    	"TITLE":     "My menu item",
    	"LANG_ALL": b24.Params{
    		"ru": b24.Params{
    			"TITLE": "My menu item",
    		},
    		"en": b24.Params{
    			"TITLE": "My menu item",
    		},
    	},
    	"OPTIONS": b24.Params{
    		"context":  "ALL",
    		"role":     "USER",
    		"extranet": "N",
    	},
    })
    if err != nil {
    	return fmt.Errorf("placement.bind: %w", err)
    }
    
    // The response arrives as json.RawMessage — unmarshal it into a struct
    // matching the response shape from the "Response Handling" section of the placement.bind page.
    fmt.Printf("%s\n", res.Result)

{% endlist %}

Typical Errors

#| || Error | How to Resolve || || placement.bind returns WRONG_AUTH_TYPE with the description Application context required | Register the embedding point on behalf of an application. An embedding point cannot be bound with a webhook || || The item did not appear in the context menu of a message | Complete the application installation and reopen the chat || || The item is not found in the menu because only the first actions are checked | The application item is placed at the end of the list. Hover over More to open the remaining items || || Registration fails because of the context value | Use only the valid values: ALL, USER, CHAT, LINES, CRM || || The item is visible in chats other than those set by context | ALL was passed along with the other values, and the other values are ignored. Pass either ALL or a list of specific contexts separated by ; || |#

Other registration error codes are listed in the "Possible Error Codes" section of the placement.bind page.

Continue Learning