@ihazz/bitrix24 0.2.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,18 +1,17 @@
1
1
  # @ihazz/bitrix24
2
2
 
3
- OpenClaw channel plugin for Bitrix24 Messenger. Allows using a Bitrix24 chatbot as a communication interface for OpenClaw AI agents.
3
+ OpenClaw channel plugin for Bitrix24 Messenger based on Bot Platform 2.0 (`imbot.v2.*` / `im.v2.*`).
4
4
 
5
- ## Features
5
+ ## Current Status
6
6
 
7
- - Receive messages from Bitrix24 users via webhook
8
- - Send responses through the Bitrix24 REST API (`imbot.message.add`)
9
- - Typing indicator (`imbot.chat.sendTyping`)
10
- - Markdown to BB-code conversion
11
- - Interactive keyboard buttons
12
- - Rate limiting (2 req/sec token-bucket)
13
- - Webhook deduplication (MESSAGE_ID, 5 min TTL)
14
- - Access control: open, allowlist, pairing modes
15
- - Multi-account support (multiple portals)
7
+ - Works with Bitrix24 Bot Platform 2.0
8
+ - Supports direct messages only
9
+ - Supports inbound and outbound media
10
+ - Uses secure default access policy: `webhookUser`
11
+ - Supports optional pairing flow for controlled approval
12
+ - Production recommendation today: one portal per plugin instance
13
+
14
+ Group chats are intentionally not supported. If the bot is added to a group chat, it sends a short notice and leaves the chat.
16
15
 
17
16
  ## Installation
18
17
 
@@ -20,230 +19,185 @@ OpenClaw channel plugin for Bitrix24 Messenger. Allows using a Bitrix24 chatbot
20
19
  openclaw plugins install @ihazz/bitrix24
21
20
  ```
22
21
 
22
+ Allow the plugin in `openclaw.json`:
23
+
24
+ ```json
25
+ {
26
+ "plugins": {
27
+ "allow": ["bitrix24"]
28
+ }
29
+ }
30
+ ```
31
+
23
32
  ## Bitrix24 Setup
24
33
 
25
- 1. Go to your Bitrix24 portal: **Apps** > **Developer resources** > **Other** > **Inbound webhook**
26
- 2. Name it, e.g. "OpenClaw Bot"
27
- 3. Under **Access permissions**, select scopes:
28
- - **`imbot`** chatbot management (register, send/update messages)
29
- - **`im`** — messenger (chats, typing indicator)
30
- - **`disk`**file operations (optional, for future support)
31
- 4. Click **Save**
32
- 5. Copy the **Webhook URL** it will look like:
33
- ```
34
- https://your-portal.bitrix24.com/rest/1/abc123xyz456/
35
- ```
34
+ Create an inbound webhook in Bitrix24:
35
+
36
+ 1. Open **Apps** > **Developer resources** > **Other** > **Inbound webhook**
37
+ 2. Create a webhook for your OpenClaw bot
38
+ 3. Grant scopes:
39
+ - `imbot`the minimum scope required for full bot operation
40
+ - `im` — additionally required only for `agentMode`, so the bot can read incoming messages addressed to the webhook owner
41
+ - you may also grant any extra scopes beyond this set if they are needed for your Bitrix24 scenarios
42
+ 4. Save the webhook and copy the URL
36
43
 
37
- > The webhook URL contains authentication (user_id + token) — do not publish or commit it to a repository.
44
+ Example webhook URL:
45
+
46
+ ```text
47
+ https://your-portal.bitrix24.com/rest/1/abc123xyz456/
48
+ ```
49
+
50
+ The webhook URL contains credentials. Do not publish it or commit it to a repository.
38
51
 
39
52
  ## Configuration
40
53
 
41
- Add to your `openclaw.json`:
54
+ Minimal configuration:
42
55
 
43
56
  ```json
44
57
  {
45
58
  "channels": {
46
59
  "bitrix24": {
47
60
  "webhookUrl": "https://your-portal.bitrix24.com/rest/1/abc123xyz456/",
48
- "callbackUrl": "https://your-server.com/hooks/bitrix24",
49
61
  "botName": "OpenClaw",
50
- "botCode": "openclaw",
51
- "dmPolicy": "open",
52
- "allowFrom": ["*"],
53
- "showTyping": true,
54
- "capabilities": ["inlineButtons"]
62
+ "dmPolicy": "webhookUser",
63
+ "showTyping": true
55
64
  }
56
65
  }
57
66
  }
58
67
  ```
59
68
 
60
- Set allow in plugin section:
61
- ```json
62
- {
63
- "plugins": {
64
- "allow": [
65
- "bitrix24"
66
- ],
67
- }
68
- }
69
- ```
70
- Only `webhookUrl` is required. The gateway will not start without it.
71
-
72
- ### Configuration Options
73
-
74
- | Parameter | Default | Description |
75
- |---|---|---|
76
- | `webhookUrl` | — | Bitrix24 REST webhook URL (**required**) |
77
- | `botName` | `"OpenClaw"` | Bot display name (shown in welcome message) |
78
- | `botCode` | `"openclaw"` | Unique bot code for `imbot.register` |
79
- | `callbackUrl` | — | Full public URL for bot EVENT_HANDLER (e.g. `https://your-server.com/hooks/bitrix24`). Path is auto-extracted for route registration. |
80
- | `dmPolicy` | `"open"` | Access policy: `"open"` / `"allowlist"` / `"pairing"` |
81
- | `allowFrom` | — | Allowed B24 user IDs (when `dmPolicy: "allowlist"`) |
82
- | `showTyping` | `true` | Send typing indicator before responding |
83
- | `streamUpdates` | `false` | Stream response via message updates |
84
- | `updateIntervalMs` | `10000` | Throttle interval for streaming updates (ms, min 500) |
85
- | `enabled` | `true` | Whether this account is enabled |
86
- | `capabilities` | `[]` | Runtime capabilities to enable (see below) |
87
-
88
- ### Capabilities
89
-
90
- The `capabilities` array activates additional runtime features for the AI agent. Add them to the channel config in `openclaw.json`:
69
+ Webhook delivery mode:
91
70
 
92
71
  ```json
93
72
  {
94
73
  "channels": {
95
74
  "bitrix24": {
96
- ...
97
- "capabilities": ["inlineButtons"]
75
+ "webhookUrl": "https://your-portal.bitrix24.com/rest/1/abc123xyz456/",
76
+ "callbackUrl": "https://your-server.com/hooks/bitrix24",
77
+ "eventMode": "webhook"
98
78
  }
99
79
  }
100
80
  }
101
81
  ```
102
82
 
103
- | Capability | Description |
104
- |---|---|
105
- | `inlineButtons` | Enables inline keyboard buttons in bot messages. The AI agent will be able to send interactive buttons using `action=send` with `buttons=[[{text, callback_data, style?}]]`. Without this capability the agent will not attempt to generate buttons. |
83
+ If `eventMode` is omitted, the plugin uses:
106
84
 
107
- ### Access Policies
108
-
109
- - **`"open"`** — any Bitrix24 portal user can message the bot
110
- - **`"allowlist"`** — only users listed in `allowFrom`:
111
- ```json
112
- {
113
- "dmPolicy": "allowlist",
114
- "allowFrom": ["42", "b24:108", "bitrix24:256"]
115
- }
116
- ```
117
- Prefixes `b24:`, `bx24:`, `bitrix24:` are stripped automatically.
118
- - **`"pairing"`** — pairing mode (work in progress)
85
+ - `webhook` when `callbackUrl` is set
86
+ - `fetch` when `callbackUrl` is not set
119
87
 
120
- ### Multi-Account (Multiple Portals)
88
+ ## Configuration Options
121
89
 
122
- Connect multiple Bitrix24 portals to a single OpenClaw server:
90
+ | Parameter | Default | Description |
91
+ |---|---|---|
92
+ | `webhookUrl` | — | Bitrix24 REST webhook URL. Required. |
93
+ | `callbackUrl` | — | Public HTTPS URL for webhook delivery mode. Required only for `eventMode: "webhook"`. |
94
+ | `eventMode` | auto | `fetch` or `webhook`. Auto-selects from `callbackUrl` when omitted. |
95
+ | `botName` | `"OpenClaw"` | Bot display name. |
96
+ | `botCode` | auto | Optional explicit bot code. If omitted, the plugin registers the bot as `openclaw_<webhookUserId>`, and if that code is occupied it tries `openclaw_<webhookUserId>_2`, `_3`, and so on. |
97
+ | `botToken` | derived from `webhookUrl` | Optional explicit bot token for `imbot.v2.Bot.*`. If omitted, it is derived automatically from `webhookUrl`. |
98
+ | `botAvatar` | — | Optional base64 avatar override. |
99
+ | `dmPolicy` | `"webhookUser"` | Access policy: `webhookUser` or `pairing`. |
100
+ | `showTyping` | `true` | Sends typing indicator before response. |
101
+ | `enabled` | `true` | Enables or disables the account. |
102
+ | `agentMode` | `false` | Enables additional user-event integration. Requires `im` scope. |
103
+ | `pollingIntervalMs` | `3000` | Base poll interval for `fetch` mode. |
104
+ | `pollingFastIntervalMs` | `100` | Fast follow-up poll interval when more events are pending. |
105
+
106
+ To enable agent-driven reactions, add `reactions` to the channel capabilities in your OpenClaw config:
123
107
 
124
108
  ```json
125
109
  {
126
110
  "channels": {
127
111
  "bitrix24": {
128
- "webhookUrl": "https://main-portal.bitrix24.com/rest/1/token1/",
129
- "botName": "Main Bot",
130
- "accounts": {
131
- "sales": {
132
- "webhookUrl": "https://sales.bitrix24.com/rest/1/token2/",
133
- "botName": "Sales Bot",
134
- "dmPolicy": "allowlist",
135
- "allowFrom": ["10", "20", "30"]
136
- },
137
- "support": {
138
- "webhookUrl": "https://support.bitrix24.com/rest/1/token3/",
139
- "botName": "Support Bot"
140
- }
141
- }
112
+ "webhookUrl": "...",
113
+ "capabilities": ["reactions"]
142
114
  }
143
115
  }
144
116
  }
145
117
  ```
146
118
 
147
- The root config acts as the `"default"` account. Each entry in `accounts` inherits all root settings and can override any of them.
119
+ The plugin maps standard Unicode emoji (👍, 🔥, 👀, etc.) to Bitrix24 reaction codes automatically. B24 reaction codes (like `like`, `fire`, `eyes`) can also be used directly.
148
120
 
149
- ## Network Access
121
+ ## Access Policies
150
122
 
151
- The OpenClaw gateway must be reachable over HTTPS for POST requests from Bitrix24 servers.
123
+ ### `webhookUser`
152
124
 
153
- Default callback URL: `https://your-server.com/hooks/bitrix24`
125
+ Default and recommended mode for production.
154
126
 
155
- For local development, use ngrok or a similar tool:
127
+ Only the Bitrix24 user whose ID is embedded in the webhook URL may talk to the bot. For a URL like:
156
128
 
157
- ```bash
158
- ngrok http 3000
129
+ ```text
130
+ https://your-portal.bitrix24.com/rest/42/secret/
159
131
  ```
160
132
 
161
- Use the HTTPS URL from ngrok as the event handler URL in Bitrix24 bot settings.
133
+ only user `42` is allowed to use the bot in direct messages.
162
134
 
163
- ## Running
135
+ ### `pairing`
164
136
 
165
- ```bash
166
- openclaw start
167
- ```
137
+ Pairing mode allows a user to request access and wait for approval through the OpenClaw pairing flow.
168
138
 
169
- On successful start, logs will show: `Bitrix24 gateway started, webhook at /hooks/bitrix24`
139
+ Approval hint:
170
140
 
171
- ### Verification
141
+ ```bash
142
+ openclaw pairing approve bitrix24 <CODE>
143
+ ```
172
144
 
173
- 1. Open a chat with the bot on your Bitrix24 portal
174
- 2. Send any message
175
- 3. The bot should show a typing indicator and respond
145
+ ## Delivery Modes
176
146
 
177
- ### Troubleshooting
147
+ ### `fetch`
178
148
 
179
- - Webhook URL is correct and accessible (`webhookUrl`)
180
- - OpenClaw server is reachable from the internet over HTTPS
181
- - Scopes `imbot`, `im`, `disk` are enabled in the B24 webhook settings
182
- - No `QUERY_LIMIT_EXCEEDED` errors in logs (rate limit)
149
+ - No public callback endpoint required
150
+ - Events are polled with `imbot.v2.Event.get`
151
+ - Best default for private or internal deployments
183
152
 
184
- ## How It Works
153
+ ### `webhook`
185
154
 
186
- ```
187
- B24 user sends a message to the bot
188
- |
189
- B24 POSTs to /hooks/bitrix24 (application/x-www-form-urlencoded)
190
- |
191
- InboundHandler parses the request body
192
- |
193
- Event routing:
194
- ONIMBOTMESSAGEADD -> message processing
195
- ONIMBOTJOINCHAT -> welcome message
196
- ONIMCOMMANDADD -> slash command (WIP)
197
- ONIMBOTDELETE -> cleanup
198
- |
199
- Deduplication (MESSAGE_ID, 5 min TTL)
200
- |
201
- Access control (senderId vs. dmPolicy + allowFrom)
202
- |
203
- Normalize to MsgContext -> pass to OpenClaw AI agent
204
- |
205
- OpenClaw processes -> calls outbound.sendText()
206
- |
207
- SendService:
208
- imbot.chat.sendTyping -> typing indicator
209
- imbot.message.add -> response (Markdown -> BB-code)
210
- ```
155
+ - Requires public HTTPS `callbackUrl`
156
+ - Bitrix24 sends events directly to OpenClaw
157
+ - The plugin accepts both JSON and form-encoded webhook bodies
211
158
 
212
- ### Handled Events
159
+ ## Supported Behavior
213
160
 
214
- | Event | Plugin Action |
215
- |---|---|
216
- | `ONIMBOTMESSAGEADD` | Incoming message -> normalize -> AI agent |
217
- | `ONIMBOTJOINCHAT` | Bot added to chat -> welcome message |
218
- | `ONIMCOMMANDADD` | Slash command (stub) |
219
- | `ONAPPINSTALL` | App installed (stub) |
220
- | `ONIMBOTDELETE` | Bot removed -> cleanup |
161
+ - Direct messages
162
+ - Typing indicators
163
+ - Text replies with BBCode conversion
164
+ - Inline keyboard buttons
165
+ - Reactions (agent can add/remove reactions on messages via `imbot.v2.Chat.Message.Reaction.*`)
166
+ - File upload to chat via `imbot.v2.File.upload`
167
+ - File download via `imbot.v2.File.download`
168
+ - Slash command registration via `imbot.v2.Command.*`
169
+ - Deduplication for repeated deliveries
170
+ - Rate limiting for Bitrix24 API calls
221
171
 
222
- ### Built-in Safeguards
172
+ ## Not Supported
223
173
 
224
- - **Rate limiter**: token-bucket, 2 requests/sec (B24 webhook limit)
225
- - **Deduplication**: B24 retries webhooks if it doesn't get a 200 in time — the plugin stores MESSAGE_IDs for 5 minutes
226
- - **Text conversion**: B24 uses BB-code, not Markdown — automatic conversion (`**bold**` -> `[B]bold[/B]`, etc.)
174
+ - Group chat conversations
175
+ - Production-ready multi-account operation in one process
227
176
 
228
- ## Customization
177
+ There is already account-config scaffolding in the plugin, but the current production recommendation is still one active Bitrix24 portal per instance.
229
178
 
230
- ### Bot Avatar
179
+ ## Verification
231
180
 
232
- The default bot avatar is stored in `src/bot-avatar.ts` as a base64-encoded JPEG string. To change the avatar:
181
+ 1. Start OpenClaw with the plugin enabled.
182
+ 2. Open a direct chat with the bot in Bitrix24.
183
+ 3. Send a message.
184
+ 4. Verify that the bot shows typing and returns a response.
185
+ 5. If `dmPolicy` is `webhookUser`, verify that only the webhook owner can talk to the bot.
233
186
 
234
- 1. Prepare a JPEG or PNG image (recommended: 200×200 px, ≤ 50 KB)
235
- 2. Convert it to base64
236
- 3. Replace the `DEFAULT_AVATAR_BASE64` value in `src/bot-avatar.ts`
237
- 4. Rebuild and redeploy
187
+ ## Troubleshooting
238
188
 
239
- The avatar can also be overridden per-account via the `botAvatar` config option (base64 string).
189
+ - Verify `webhookUrl` is valid and active.
190
+ - If you use `eventMode: "webhook"`, verify `callbackUrl` is reachable from the internet over HTTPS.
191
+ - If `agentMode` is enabled, verify the webhook also has `im` scope.
192
+ - Do not expect the bot to work in group chats.
193
+ - If file transfer fails, verify the file size and Bitrix24-side availability of the attachment.
240
194
 
241
195
  ## Development
242
196
 
243
197
  ```bash
244
198
  npm install
245
- npm test # run tests
246
- npm run build # compile TypeScript
199
+ npm test
200
+ npm run build
247
201
  ```
248
202
 
249
203
  ## License
package/index.ts CHANGED
@@ -8,10 +8,47 @@ interface OpenClawPluginApi {
8
8
  registerChannel: (opts: { plugin: typeof bitrix24Plugin }) => void;
9
9
  registerHttpRoute: (params: {
10
10
  path: string;
11
+ auth?: 'plugin';
11
12
  handler: (req: IncomingMessage, res: ServerResponse) => Promise<void>;
12
13
  }) => void;
13
14
  }
14
15
 
16
+ export function collectBitrix24CallbackPaths(config: Record<string, unknown>): string[] {
17
+ const channels = config?.channels as Record<string, Record<string, unknown>> | undefined;
18
+ const bitrix24 = channels?.bitrix24 as {
19
+ callbackUrl?: string;
20
+ accounts?: Record<string, { callbackUrl?: string }>;
21
+ } | undefined;
22
+
23
+ const callbackUrls: string[] = [];
24
+ if (typeof bitrix24?.callbackUrl === 'string') {
25
+ callbackUrls.push(bitrix24.callbackUrl);
26
+ }
27
+
28
+ for (const account of Object.values(bitrix24?.accounts ?? {})) {
29
+ if (typeof account?.callbackUrl === 'string') {
30
+ callbackUrls.push(account.callbackUrl);
31
+ }
32
+ }
33
+
34
+ const paths: string[] = [];
35
+ const seenPaths = new Set<string>();
36
+
37
+ for (const callbackUrl of callbackUrls) {
38
+ try {
39
+ const path = new URL(callbackUrl).pathname;
40
+ if (!seenPaths.has(path)) {
41
+ seenPaths.add(path);
42
+ paths.push(path);
43
+ }
44
+ } catch {
45
+ console.warn(`[bitrix24] Invalid callbackUrl "${callbackUrl}", skipping HTTP route`);
46
+ }
47
+ }
48
+
49
+ return paths;
50
+ }
51
+
15
52
  /**
16
53
  * OpenClaw Bitrix24 Channel Plugin
17
54
  *
@@ -28,16 +65,14 @@ export default {
28
65
 
29
66
  api.registerChannel({ plugin: bitrix24Plugin });
30
67
 
31
- // Register HTTP webhook route — derive path from callbackUrl
32
- const channels = api.config?.channels as Record<string, Record<string, unknown>> | undefined;
33
- const callbackUrl = channels?.bitrix24?.callbackUrl as string | undefined;
34
- const callbackPath = callbackUrl ? new URL(callbackUrl).pathname : '/hooks/bitrix24';
35
-
36
- api.registerHttpRoute({
37
- path: callbackPath,
38
- handler: async (req: IncomingMessage, res: ServerResponse) => {
39
- await handleWebhookRequest(req, res);
40
- },
41
- });
68
+ for (const callbackPath of collectBitrix24CallbackPaths(api.config)) {
69
+ api.registerHttpRoute({
70
+ path: callbackPath,
71
+ auth: 'plugin',
72
+ handler: async (req: IncomingMessage, res: ServerResponse) => {
73
+ await handleWebhookRequest(req, res);
74
+ },
75
+ });
76
+ }
42
77
  },
43
78
  };
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "id": "bitrix24",
3
3
  "channels": ["bitrix24"],
4
+ "skills": ["skills/bitrix24"],
4
5
  "configSchema": {
5
6
  "type": "object",
6
7
  "additionalProperties": true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ihazz/bitrix24",
3
- "version": "0.2.4",
3
+ "version": "1.0.0",
4
4
  "description": "Bitrix24 Messenger channel for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: bitrix24
3
+ description: "Bitrix24 Messenger ops via the message tool (channel=bitrix24)."
4
+ metadata: { "openclaw": { "emoji": "💬", "requires": { "config": ["channels.bitrix24.webhookUrl"] } } }
5
+ allowed-tools: ["message"]
6
+ ---
7
+
8
+ # Bitrix24 (Via `message`)
9
+
10
+ Use the `message` tool. No provider-specific `bitrix24` tool exposed to the agent.
11
+
12
+ ## Musts
13
+
14
+ - Always: `channel: "bitrix24"`.
15
+ - The bot works in direct messages only (no group chats).
16
+
17
+ ## Common Actions (Examples)
18
+
19
+ Send message:
20
+
21
+ ```json
22
+ {
23
+ "action": "send",
24
+ "channel": "bitrix24",
25
+ "message": "Hello!"
26
+ }
27
+ ```
28
+
29
+ React to the current (last received) message:
30
+
31
+ ```json
32
+ {
33
+ "action": "react",
34
+ "channel": "bitrix24",
35
+ "emoji": "👍"
36
+ }
37
+ ```
38
+
39
+ - When `messageId` is **omitted**, the reaction is applied to the current inbound message automatically.
40
+ - `emoji` can be a standard Unicode emoji (👍, 🔥, ❤️, 😂, 😢, 😮, 👀, 🎉, 🤔, 👎, etc.) or a Bitrix24 reaction code (`like`, `fire`, `heart`, `laugh`, `cry`, `wonder`, `eyes`, `hooray`, `think`, `dislike`).
41
+ - To react to a **specific** message, pass `"messageId": "<numeric id>"`.
42
+ - To remove a reaction, add `"remove": true`.
43
+
44
+ Remove a reaction:
45
+
46
+ ```json
47
+ {
48
+ "action": "react",
49
+ "channel": "bitrix24",
50
+ "emoji": "👍",
51
+ "remove": true
52
+ }
53
+ ```
54
+
55
+ ## Reactions Guidance
56
+
57
+ When you see a message from a Bitrix24 user, you can react to acknowledge it before (or instead of) sending a text reply. Common patterns:
58
+
59
+ - React with 👍 to acknowledge a request.
60
+ - React with 👀 to indicate you're looking into something.
61
+ - React with ✅ or 🎉 when a task is completed.
62
+ - React with 🤔 if you need to think about the request.
63
+
64
+ **Important:** Do NOT invent or guess messageId values. Either omit `messageId` to react to the current message, or use a messageId that was explicitly provided to you.
65
+
66
+ ## Writing Style (Bitrix24)
67
+
68
+ - Direct, professional, moderate length.
69
+ - Bitrix24 uses BBCode for formatting (conversion is automatic).
70
+ - Inline keyboard buttons are supported for interactive responses.