clawgram 2.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/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 eldaruma
4
+ Copyright (c) 2026 Konstantin Dipezh (d3pre5s), for the Clawgram fork
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,589 @@
1
+ # Clawgram
2
+
3
+ Clawgram is a personal-Telegram channel plugin for [OpenClaw](https://github.com/openclaw/openclaw) — it connects as a regular Telegram user account (not a bot) via MTProto using [GramJS](https://github.com/gram-js/gramjs). Your AI assistant reads and responds as you.
4
+
5
+ > Clawgram is the actively maintained continuation of
6
+ > [eldaruma/telegram-userbot](https://github.com/eldaruma/telegram-userbot) (MIT).
7
+ >
8
+ > **Breaking change in 2.0.0:** the plugin id and channel name changed from
9
+ > `telegram-userbot` to `clawgram`. When upgrading from 1.x (or from the
10
+ > original telegram-userbot), rename the `channels.telegram-userbot` section of
11
+ > `openclaw.json` to `channels.clawgram` (contents stay as-is), update any
12
+ > `plugins.allow` entry, and replace `telegram-userbot:<target>` address
13
+ > prefixes with `clawgram:<target>`. Then restart the Gateway.
14
+
15
+ > **WARNING**: Using a user account for automated messaging may violate Telegram's Terms of Service. Use a dedicated secondary account. Your account could be banned or restricted.
16
+
17
+
18
+ ## Features
19
+
20
+ - **MTProto Client API** — operates as a user account, not a bot
21
+ - **DM & Group support** — private chats, groups, supergroups, forum topics
22
+ - **Forum topic routing** — correctly routes replies to the right forum topic thread
23
+ - **@Mention detection** — respond only when mentioned in groups (text, caption, and ID-based mentions)
24
+ - **Read receipts** — mark messages as read
25
+ - **User allowlist** — control which user has access to send messages for direct
26
+ - **Chat allowlist** — control which chats the assistant can access
27
+ - **Multi-account** — run multiple Telegram accounts simultaneously
28
+ - **Per-group settings** — different behavior for different groups
29
+ - **SOCKS4/SOCKS5 proxy** — optional native MTProto proxy per account
30
+ - **Slash commands** — [slash commands](https://docs.openclaw.ai/tools/slash-commands) are available in DM to the connected account (`/status`, `/reset`, `/new`, etc.)
31
+
32
+
33
+ ## Requirements
34
+
35
+ - OpenClaw >= 2026.5.7
36
+ - Telegram API credentials from [my.telegram.org](https://my.telegram.org)
37
+ - Node.js >= 22
38
+
39
+ ## Installation
40
+
41
+ ```bash
42
+ # from npm (default resolution)
43
+ openclaw plugins install clawgram
44
+
45
+ # or explicitly from ClawHub
46
+ openclaw plugins install clawhub:clawgram
47
+ ```
48
+
49
+ ## Setup
50
+
51
+ ### 1. Get Telegram API credentials
52
+
53
+ - Go to https://my.telegram.org
54
+ - Log in with your phone number
55
+ - Go to "API development tools"
56
+ - Create a new application
57
+ - Copy the `api_id` and `api_hash`
58
+
59
+
60
+ ### 2. Log in to your telegram account
61
+
62
+ Log in to your telegram account via cli using API credentials and phone number
63
+
64
+ ```bash
65
+ openclaw clawgram --auth
66
+ ```
67
+
68
+ If the custom OpenClaw cli command hangs, run the standalone authorization script directly:
69
+
70
+ ```bash
71
+ node ~/.openclaw/extensions/clawgram/dist/clawgram-cli.js --auth
72
+ ```
73
+
74
+ > **NOTES**: Starting with OpenClaw `2026.5.12`, hangs have been observed in some environments when running custom plugin cli commands through `openclaw <plugin command> ...`. If that happens, use the standalone command above. It runs the same authorization flow, but bypasses the custom cli entrypoint inside OpenClaw.
75
+
76
+ Follow the steps in the console
77
+
78
+ ```bash
79
+ Starting Clawgram authorization...
80
+ Please enter your apiId: 12345678
81
+ Please enter your apiHash: c4b9c0fde16342afe52907847df27596
82
+ [2026-05-10T16:01:24.570] [INFO] - [Running gramJS version 2.26.21]
83
+ [2026-05-10T16:01:24.578] [INFO] - [Connecting to x.x.x.x:80/TCPFull...]
84
+ [2026-05-10T16:01:25.804] [INFO] - [Connection to x.x.x.x:80/TCPFull complete!]
85
+ [2026-05-10T16:01:25.808] [INFO] - [Using LAYER 198 for initial connect]
86
+ Please enter your number: +1 XXX XXX XXXX
87
+ Please enter the code you received: 12345
88
+ [2026-05-10T16:01:56.384] [INFO] - [Signed in successfully as <USER>]
89
+ [2026-05-10T16:01:56.388] [WARN] - [Disconnecting...]
90
+ [2026-05-10T16:01:56.390] [INFO] - [Disconnecting from x.x.x.x:80/TCPFull...]
91
+ Telegram authorization completed successfully.
92
+
93
+ Session string:
94
+ 1BAAOMTQ5LjE1NC4xNjcuOTEAUQZ1aeNwM6O5lSD+kX/irkoUFMj+nUy5hRhpVqbkuOhEP+JOT4FEobUVnUKPnpKPxXdwQ9e
95
+ js+tWQTto86Heab4XSfyOoWK5WDA/dMhFYBuFxms/FF946HerCM+i5nh0gu//YGmIEntw7gY8JQQNYuvLB5SGdsDpa50LcJ5fK
96
+ 686qqUsnlqmRTONdVG3EOdnV8RbTFTHg5BWLztfD5uLt1lIr/bG+BWCPCLAaA85yPL8SgGRLtX4QYXrnaEVmKui8SWq5J/
97
+ Ol86oZGlrMcnj5DRQ/VeYY7yGcESwnoTSx44irCyk9GelCavzs/dfN6sAYfoZb6cN/L9jxEYXkkCQdig=
98
+ ```
99
+
100
+ Since the plugin supports connecting multiple accounts, at this step the cli will ask you for the account ID, if you do not enter anything, the [default] key will be applied. You can also enter your own value.
101
+
102
+ ```bash
103
+ Enter account id for config [default]: [2026-05-10T16:01:56.402] [INFO] - [connection closed]
104
+ [2026-05-10T16:02:02.096] [WARN] - [Disconnecting...]
105
+ [2026-05-10T16:02:02.103] [INFO] - [Disconnecting from x.x.x.x:80/TCPFull...]
106
+ ```
107
+
108
+ In the next step, you must confirm or reject the automatic update of the openclaw.json configuration file. If you reject it or receive an error updating the file, the cli will display an openclaw.json configuration fragment that you must add manually.
109
+
110
+ The automatic config update keeps the rest of `openclaw.json` intact and only updates the `channels.clawgram` section for the selected account. A timestamped backup of the config file is created before any write attempt.
111
+
112
+ Update **yes**
113
+ ```bash
114
+ Update OpenClaw config automatically? [y/N]: y
115
+
116
+ Config overwrite: /root/.openclaw/openclaw.json (sha256 97c4b55e61901aa71ff40898b5ebfbadd0f8fb9cd0145f3a08a5e5163783258a -> 6447683c687ceeb0dba09b2ca5187967e979ad2663d901977c608b6a09c9c432, backup=/root/.openclaw/openclaw.json.bak)
117
+
118
+ OpenClaw config updated: /root/.openclaw/openclaw.json
119
+ Configured account id: default
120
+ Config backup created: /root/.openclaw/openclaw.json.bak-20260512-084914-clawgram-auth
121
+
122
+ After applying config changes, restart OpenClaw:
123
+
124
+ openclaw gateway restart
125
+ ```
126
+
127
+ Update **no**
128
+ ```bash
129
+ Update OpenClaw config automatically? [y/N]: n
130
+
131
+ JSON fragment for manual insertion:
132
+ {
133
+ "channels": {
134
+ "clawgram": {
135
+ "accounts": {
136
+ "default": {
137
+ "enabled": true,
138
+ "apiId": 12345678,
139
+ "apiHash": "apiHash",
140
+ "sessionString": "sessionString",
141
+ "allowFrom": [
142
+ "*"
143
+ ],
144
+ "groups": {
145
+ "*": {
146
+ "enabled": true,
147
+ "groupPolicy": "mention",
148
+ "allowFrom": [
149
+ "*"
150
+ ]
151
+ }
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
157
+ }
158
+
159
+ After applying config changes, restart OpenClaw:
160
+
161
+ openclaw gateway restart
162
+ ```
163
+
164
+ ### 3. Restart OpenClaw gateway
165
+
166
+ ```bash
167
+ openclaw gateway restart
168
+ ```
169
+
170
+
171
+ ## Configuration Reference
172
+
173
+ ### JSON Reference
174
+
175
+ ```json
176
+ {
177
+ "channels": {
178
+ "clawgram": {
179
+ "accounts": {
180
+ "default": {
181
+ "enabled": true,
182
+ "apiId": 12345678,
183
+ "apiHash": "apiHash",
184
+ "sessionString": "sessionString",
185
+ "allowFrom": [
186
+ "*"
187
+ ],
188
+ "groups": {
189
+ "*": {
190
+ "enabled": true,
191
+ "groupPolicy": "mention",
192
+ "allowFrom": [
193
+ "*"
194
+ ]
195
+ }
196
+ }
197
+ }
198
+ }
199
+ }
200
+ }
201
+ }
202
+ ```
203
+
204
+ ### Mention fields
205
+
206
+ | Field | Type | Default | Description |
207
+ |---|---|---|---|
208
+ | `apiId` | number | required | Telegram API ID |
209
+ | `apiHash` | string | required | Telegram API hash |
210
+ | `sessionString` | string | `""` | Authenticated StringSession |
211
+ | `allowFrom` | string[] | `["*"]` | Allowed sender IDs/usernames for direct messages only |
212
+ | `groups` | object | `{}` | Allowed groups map keyed by explicit group id or `*` |
213
+ | `proxy` | object | unset | Optional SOCKS4/SOCKS5 proxy for this account — see [Proxy (SOCKS4/SOCKS5)](#proxy-socks4socks5) |
214
+
215
+ Group config fields:
216
+
217
+ | Field | Type | Default | Description |
218
+ |---|---|---|---|
219
+ | `enabled` | boolean | `true` | Enables or disables replies in the group |
220
+ | `groupPolicy` | `"open"` \| `"mention"` | `"mention"` | `open` replies to any group message, `mention` only on @mention or reply-to-self |
221
+ | `allowFrom` | string[] | `["*"]` | Allowed sender IDs/usernames inside that group |
222
+
223
+
224
+ ### Configuration variant for example
225
+
226
+ ```json
227
+ {
228
+ "channels": {
229
+ "clawgram": {
230
+ "accounts": {
231
+ "default": {
232
+ "enabled": true,
233
+ "apiId": 12345678,
234
+ "apiHash": "apiHash",
235
+ "sessionString": "sessionString",
236
+ "allowFrom": [
237
+ "@nickname1",
238
+ "@nickname2"
239
+ ],
240
+ "groups": {
241
+ "-1001234567899": {
242
+ "enabled": true,
243
+ "groupPolicy": "mention",
244
+ "allowFrom": [
245
+ "@nickname1"
246
+ ]
247
+ },
248
+ "-1009876543219": {
249
+ "enabled": true,
250
+ "groupPolicy": "mention",
251
+ "allowFrom": [
252
+ "*"
253
+ ]
254
+ },
255
+ "-1001234567891": {
256
+ "enabled": true,
257
+ "groupPolicy": "open",
258
+ "allowFrom": [
259
+ "*"
260
+ ]
261
+ }
262
+ }
263
+ }
264
+ }
265
+ }
266
+ }
267
+ }
268
+ ```
269
+
270
+
271
+ ## Proxy (SOCKS4/SOCKS5)
272
+
273
+ ### Why you may need it
274
+
275
+ GramJS speaks MTProto over **raw TCP sockets**. OpenClaw's managed proxy (`proxy.proxyUrl`) and the
276
+ standard `HTTP_PROXY` / `HTTPS_PROXY` environment variables only cover HTTP and WebSocket traffic, so
277
+ they do **not** route the userbot's Telegram connection. On hosts where Telegram is blocked or
278
+ filtered, authorization and runtime work when the whole Gateway is launched through something like
279
+ `proxychains`, but a normal systemd restart of the Gateway then fails to connect.
280
+
281
+ Configure `proxy` on the account to make GramJS dial Telegram through a SOCKS proxy natively, with no
282
+ external wrapper and no changes to how the Gateway is started.
283
+
284
+ > **This is a SOCKS proxy, not a Telegram MTProxy.** MTProxy (the `secret`-based Telegram proxy
285
+ > protocol) is a different transport and is intentionally out of scope here.
286
+
287
+ ### SOCKS5 example
288
+
289
+ ```json
290
+ {
291
+ "channels": {
292
+ "clawgram": {
293
+ "accounts": {
294
+ "default": {
295
+ "enabled": true,
296
+ "apiId": 12345678,
297
+ "apiHash": "apiHash",
298
+ "sessionString": "sessionString",
299
+ "proxy": {
300
+ "ip": "proxy.example.com",
301
+ "port": 1080,
302
+ "socksType": 5,
303
+ "username": "proxy-user",
304
+ "password": "proxy-password",
305
+ "timeout": 10
306
+ },
307
+ "allowFrom": [
308
+ "*"
309
+ ],
310
+ "groups": {
311
+ "*": {
312
+ "enabled": true,
313
+ "groupPolicy": "mention",
314
+ "allowFrom": [
315
+ "*"
316
+ ]
317
+ }
318
+ }
319
+ }
320
+ }
321
+ }
322
+ }
323
+ }
324
+ ```
325
+
326
+ ### SOCKS4 example
327
+
328
+ SOCKS4 uses the same block with `socksType: 4`. SOCKS4 has no password authentication, so pass at most
329
+ `username`:
330
+
331
+ ```json
332
+ "proxy": {
333
+ "ip": "203.0.113.10",
334
+ "port": 1081,
335
+ "socksType": 4
336
+ }
337
+ ```
338
+
339
+ ### Proxy fields
340
+
341
+ | Field | Type | Default | Description |
342
+ |---|---|---|---|
343
+ | `ip` | string | required | Proxy hostname or IP address |
344
+ | `port` | number | required | Proxy TCP port, `1`–`65535` |
345
+ | `socksType` | `4` \| `5` | required | `5` for SOCKS5, `4` for SOCKS4 |
346
+ | `username` | string | unset | Optional — only for proxies that require authentication |
347
+ | `password` | string | unset | Optional — only for proxies that require authentication |
348
+ | `timeout` | number | `5` | Optional connection timeout **in seconds** (GramJS default is `5`) |
349
+
350
+ Notes:
351
+
352
+ - `timeout` is expressed in **seconds**, not milliseconds — GramJS multiplies it by 1000 internally.
353
+ - `username` and `password` are optional. Omit both for an open proxy; blank strings are ignored.
354
+ - The proxy is configured **per account**, so one account can use SOCKS5, another SOCKS4, and another
355
+ can connect directly:
356
+
357
+ ```json
358
+ "accounts": {
359
+ "default": {
360
+ "apiId": 12345678,
361
+ "apiHash": "apiHash",
362
+ "sessionString": "sessionString",
363
+ "proxy": { "ip": "proxy.example.com", "port": 1080, "socksType": 5 }
364
+ },
365
+ "second": {
366
+ "apiId": 12345678,
367
+ "apiHash": "apiHash",
368
+ "sessionString": "sessionString",
369
+ "proxy": { "ip": "203.0.113.10", "port": 1081, "socksType": 4 }
370
+ },
371
+ "third": {
372
+ "apiId": 12345678,
373
+ "apiHash": "apiHash",
374
+ "sessionString": "sessionString"
375
+ }
376
+ }
377
+ ```
378
+
379
+ - Omitting `proxy` keeps the previous behavior exactly — a direct connection.
380
+ - If `proxy` is present but invalid (bad port, bad `socksType`, empty host), the account fails to start
381
+ with an explicit error instead of silently falling back to a direct connection that would expose the
382
+ host's real IP address to Telegram.
383
+ - On a successful connection the log line reports only `proxy: "socks5"` / `"socks4"` — never the host,
384
+ port, or credentials.
385
+ - `openclaw clawgram --auth` only updates `apiId`, `apiHash` and `sessionString`, so an existing
386
+ `proxy` block survives re-authorization. If you decline the automatic config update, the printed JSON
387
+ fragment is a fresh-account template — merge it into your account instead of replacing the block, or
388
+ you will drop the `proxy` section.
389
+
390
+ > **WARNING**: `password`, `apiHash` and `sessionString` are credentials. Never commit them to a
391
+ > repository, paste them into issues, or share config files containing them. Anyone with your
392
+ > `sessionString` has full access to your Telegram account.
393
+
394
+
395
+ ## Slash commands
396
+
397
+ OpenClaw provides a robust set of native commands. Just like in a regular Telegram bot, slash commands are also available for a user Telegram account connected via the Telegram userbot plugin. Send the slash command in DM to the connected account.
398
+
399
+ Use commands like `/status`, `/reset`, `/new` and others.
400
+
401
+ You can read more about slash commands in the [OpenClaw official documentation](https://docs.openclaw.ai/tools/slash-commands).
402
+
403
+
404
+
405
+ ## Multi-Account
406
+
407
+ The plugin also supports adding multiple accounts. You can run the cli command many times
408
+
409
+ ```bash
410
+ openclaw clawgram --auth
411
+ ```
412
+
413
+
414
+ If the custom cli command hangs on your OpenClaw version, use the standalone command instead:
415
+
416
+ ```bash
417
+ node ~/.openclaw/extensions/clawgram/dist/clawgram-cli.js --auth
418
+ ```
419
+
420
+ And in the account ID step, enter a value other than the first [default] or your previously entered one.
421
+ account ID must be unique
422
+
423
+ ```bash
424
+ Enter account id for config [default]: [2026-05-10T16:01:56.402] [INFO] - [connection closed]
425
+ [2026-05-10T16:02:02.096] [WARN] - [Disconnecting...]
426
+ [2026-05-10T16:02:02.103] [INFO] - [Disconnecting from x.x.x.x:80/TCPFull...]
427
+
428
+ second
429
+ ```
430
+
431
+ ```json
432
+ {
433
+ "channels": {
434
+ "clawgram": {
435
+ "accounts": {
436
+ "default": {
437
+ "enabled": true,
438
+ "apiId": 12345678,
439
+ "apiHash": "apiHash",
440
+ "sessionString": "sessionString",
441
+ "allowFrom": [
442
+ "*"
443
+ ],
444
+ "groups": {
445
+ "*": {
446
+ "enabled": true,
447
+ "groupPolicy": "mention",
448
+ "allowFrom": [
449
+ "*"
450
+ ]
451
+ }
452
+ }
453
+ },
454
+ "second": {
455
+ "enabled": true,
456
+ "apiId": 12345678,
457
+ "apiHash": "apiHash",
458
+ "sessionString": "sessionString",
459
+ "allowFrom": [
460
+ "*"
461
+ ],
462
+ "groups": {
463
+ "*": {
464
+ "enabled": true,
465
+ "groupPolicy": "mention",
466
+ "allowFrom": [
467
+ "*"
468
+ ]
469
+ }
470
+ }
471
+ }
472
+ }
473
+ }
474
+ }
475
+ }
476
+ ```
477
+
478
+
479
+ ## Multi-agent routing
480
+
481
+ The Clawgram channel can also be used alongside the regular Telegram channel for configuring OpenClaw multi-agent routing. In that case, accounts connected via the Clawgram channel will have independent agents.
482
+
483
+ Here is an example of how to configure OpenClaw multi-agent routing using clawgram channel in parallel with main telegram channel.
484
+
485
+ You can read more about how to set up multi-agent routing in the official [OpenClaw documentation](https://docs.openclaw.ai/concepts/multi-agent)
486
+
487
+ List model
488
+ ```json
489
+ "list": [
490
+ {
491
+ "id": "main",
492
+ "default": true,
493
+ "workspace": "/root/.openclaw/workspace"
494
+ },
495
+ {
496
+ "id": "second",
497
+ "workspace": "/root/.openclaw/workspace-second",
498
+ },
499
+ {
500
+ "id": "userbot-main",
501
+ "workspace": "/root/.openclaw/workspace-userbot-main",
502
+ },
503
+ {
504
+ "id": "userbot-second",
505
+ "workspace": "/root/.openclaw/workspace-userbot-second",
506
+ }
507
+ ]
508
+ ```
509
+
510
+ Bindings
511
+ ```json
512
+ "bindings": [
513
+ {
514
+ "agentId": "main",
515
+ "match": {
516
+ "channel": "telegram",
517
+ "accountId": "default"
518
+ }
519
+ },
520
+ {
521
+ "agentId": "second",
522
+ "match": {
523
+ "channel": "telegram",
524
+ "accountId": "second"
525
+ }
526
+ },
527
+ {
528
+ "agentId": "userbot-main",
529
+ "match": {
530
+ "channel": "clawgram",
531
+ "accountId": "default"
532
+ }
533
+ },
534
+ {
535
+ "agentId": "userbot-second",
536
+ "match": {
537
+ "channel": "clawgram",
538
+ "accountId": "second"
539
+ }
540
+ }
541
+ ]
542
+ ```
543
+
544
+
545
+ > **NOTES**: Due to a known bug in the OpenClaw core, you may encounter an error in the logs: `EmbeddedAttemptSessionTakeoverError: session file changed while embedded prompt lock was released`. This error may primarily occur when communicating in group chats and not on all LLM models — only those that support tool calls. This error does not affect functionality, but it may cause a repeated request to the fallback model and excess token usage if you have one specified. To prevent this behavior, you can remove the fallback model in the openclaw.json configuration. To avoid affecting your main settings, override the model specifically for the clawgram channel in the agent list when configuring multi-agent routing — do not specify a fallback model for it.
546
+
547
+ ```json
548
+ "list": [
549
+ {
550
+ "id": "userbot-main",
551
+ "workspace": "/root/.openclaw/workspace-userbot-main",
552
+ "model": {
553
+ "primary": "<some model>"
554
+ }
555
+ },
556
+ {
557
+ "id": "userbot-second",
558
+ "workspace": "/root/.openclaw/workspace-userbot-second",
559
+ "model": {
560
+ "primary": "<some model>"
561
+ }
562
+ }
563
+ ]
564
+ ```
565
+
566
+
567
+ ## Development
568
+
569
+ ```bash
570
+ npm install # install dependencies
571
+ npm run build # run build script
572
+ npm test # run the node:test suite (no Telegram connection required)
573
+ ```
574
+
575
+ For local authorization testing during development, you can also run the standalone cli directly:
576
+
577
+ ```bash
578
+ npm run clawgram-cli -- --auth
579
+ ```
580
+
581
+ or
582
+
583
+ ```bash
584
+ npm run clawgram-cli:auth
585
+ ```
586
+
587
+ ## License
588
+
589
+ MIT