claude-telegram-bridge 0.4.1__tar.gz
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.
- claude_telegram_bridge-0.4.1/LICENSE +21 -0
- claude_telegram_bridge-0.4.1/PKG-INFO +265 -0
- claude_telegram_bridge-0.4.1/README.md +241 -0
- claude_telegram_bridge-0.4.1/claude_telegram_bridge.egg-info/PKG-INFO +265 -0
- claude_telegram_bridge-0.4.1/claude_telegram_bridge.egg-info/SOURCES.txt +10 -0
- claude_telegram_bridge-0.4.1/claude_telegram_bridge.egg-info/dependency_links.txt +1 -0
- claude_telegram_bridge-0.4.1/claude_telegram_bridge.egg-info/entry_points.txt +2 -0
- claude_telegram_bridge-0.4.1/claude_telegram_bridge.egg-info/top_level.txt +1 -0
- claude_telegram_bridge-0.4.1/claude_telegram_bridge.py +3895 -0
- claude_telegram_bridge-0.4.1/pyproject.toml +38 -0
- claude_telegram_bridge-0.4.1/setup.cfg +4 -0
- claude_telegram_bridge-0.4.1/tests/test_public_export.py +32 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Claude Telegram Bridge contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: claude-telegram-bridge
|
|
3
|
+
Version: 0.4.1
|
|
4
|
+
Summary: Control an existing interactive Claude Code session from Telegram.
|
|
5
|
+
Author: Claude Telegram Bridge contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ssamssae/claude-telegram-bridge
|
|
8
|
+
Project-URL: Repository, https://github.com/ssamssae/claude-telegram-bridge
|
|
9
|
+
Project-URL: Releases, https://github.com/ssamssae/claude-telegram-bridge/releases
|
|
10
|
+
Project-URL: Issues, https://github.com/ssamssae/claude-telegram-bridge/issues
|
|
11
|
+
Keywords: claude,telegram,tmux,bridge,automation
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Topic :: Communications :: Chat
|
|
19
|
+
Classifier: Topic :: Software Development
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# Claude Telegram Bridge
|
|
26
|
+
|
|
27
|
+
Control an already-running interactive Claude Code session from Telegram.
|
|
28
|
+
|
|
29
|
+
This bridge polls Telegram, pastes incoming messages into a visible tmux Claude
|
|
30
|
+
Code pane, tails Claude transcript JSONL, and sends only the matching final
|
|
31
|
+
answer back to Telegram.
|
|
32
|
+
|
|
33
|
+
The bridge is Claude-specific. It is not a general multi-AI bridge and it does
|
|
34
|
+
not share runtime code with the Codex Telegram Bridge.
|
|
35
|
+
|
|
36
|
+
## What It Supports
|
|
37
|
+
|
|
38
|
+
- Text prompts from Telegram into a live Claude Code tmux session.
|
|
39
|
+
- Telegram photos and image documents saved locally, then injected as
|
|
40
|
+
`local_path` prompts for Claude to inspect.
|
|
41
|
+
- Telegram voice, audio, video, animation, and document uploads saved locally
|
|
42
|
+
with caption and metadata preserved.
|
|
43
|
+
- Optional audio transcription through a local command configured with
|
|
44
|
+
`CLB_AUDIO_TRANSCRIBE_CMD`.
|
|
45
|
+
- Transcript-based final-answer extraction instead of screen scraping.
|
|
46
|
+
- Optional flow mirror: live "work in progress" card that mirrors each tool-use
|
|
47
|
+
step of the current turn to Telegram so you can follow long runs.
|
|
48
|
+
- Single Telegram chat allowlist and token ownership registry.
|
|
49
|
+
- Duplicate-egress guard hooks for users who also have Telegram MCP reply tools
|
|
50
|
+
or terminal mirror hooks installed.
|
|
51
|
+
|
|
52
|
+
This is not MCP. It is a local bridge daemon for one visible Claude Code
|
|
53
|
+
session.
|
|
54
|
+
|
|
55
|
+
## Public Export Model
|
|
56
|
+
|
|
57
|
+
This public repository is maintained from a private operator source through a
|
|
58
|
+
sanitized export step. The export keeps the reusable Claude bridge behavior,
|
|
59
|
+
hook templates, config examples, and documentation, while stripping private chat
|
|
60
|
+
ids, token paths, hostnames, node labels, and local automation paths before
|
|
61
|
+
release.
|
|
62
|
+
|
|
63
|
+
Claude Telegram Bridge and Codex Telegram Bridge remain separate programs
|
|
64
|
+
because they drive different interactive CLIs and transcript formats. The shared
|
|
65
|
+
maintenance rule is the same: keep one internal source for each bridge, generate
|
|
66
|
+
the public copy through an export script, and never publish private wrappers or
|
|
67
|
+
operator-specific trigger paths.
|
|
68
|
+
|
|
69
|
+
## Billing And Terms
|
|
70
|
+
|
|
71
|
+
This project does not use `claude -p` and does not create hidden one-shot
|
|
72
|
+
Claude sessions. It drives an interactive Claude Code session that you already
|
|
73
|
+
started.
|
|
74
|
+
|
|
75
|
+
The subscription billing classification of a 24/7 daemon that automatically
|
|
76
|
+
injects prompts into an interactive Claude Code session is unverified. This
|
|
77
|
+
project does not claim that this usage is subscription-safe. You are responsible
|
|
78
|
+
for deciding whether to run it under your account, plan, and applicable terms.
|
|
79
|
+
|
|
80
|
+
## Verified Backend
|
|
81
|
+
|
|
82
|
+
- Claude Code interactive tmux session: experimental, locally verified by the
|
|
83
|
+
maintainers.
|
|
84
|
+
- Other AI CLIs: not supported.
|
|
85
|
+
|
|
86
|
+
## How It Works
|
|
87
|
+
|
|
88
|
+
```text
|
|
89
|
+
Telegram user message/media
|
|
90
|
+
-> getUpdates polling
|
|
91
|
+
-> single chat id allowlist
|
|
92
|
+
-> media download to local state directory when present
|
|
93
|
+
-> paste prompt envelope into tmux Claude pane
|
|
94
|
+
-> SessionStart sidecar binds tmux pane to Claude transcript JSONL
|
|
95
|
+
-> transcript tail finds the final answer for the injected nonce
|
|
96
|
+
-> Telegram sendMessage
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The bridge uses one Bot API egress path. The included hooks prevent Claude's
|
|
100
|
+
Telegram MCP reply tool and terminal mirror hooks from sending duplicate
|
|
101
|
+
answers while the bridge owns a turn.
|
|
102
|
+
|
|
103
|
+
## Slash Commands
|
|
104
|
+
|
|
105
|
+
Slash commands sent from Telegram are classified before anything is injected
|
|
106
|
+
into the Claude pane. Commands that would open an interactive picker or dialog
|
|
107
|
+
are never pasted raw, because a blocking dialog can freeze the one visible
|
|
108
|
+
session. Each command falls into one of these groups.
|
|
109
|
+
|
|
110
|
+
| Command | Behavior |
|
|
111
|
+
| --- | --- |
|
|
112
|
+
| `/context`, `/usage`, `/cost` | Read-only info commands. The bridge widens the tmux capture window, runs the command, waits for the render to finish before capturing (no more blank "in progress" frame), trims the terminal chrome to a clean text view, and mirrors that screen back to Telegram. |
|
|
113
|
+
| `/model` | Intercepted. Pasting `/model` raw opens an interactive picker that can freeze the session, so the bridge shows an inline keyboard of model choices instead and applies the pick non-interactively as `/model <alias>`. |
|
|
114
|
+
| `/clear`, `/exit`, `/quit` | Passed through unchanged; these do not open a dialog. `/exit` and `/quit` end the session, so the bridge triggers watchdog recovery for a graceful restart afterward. `/clear` only resets context. |
|
|
115
|
+
| `/ping`, `/start`, `/status` | Bridge health and status, answered by the bridge itself. |
|
|
116
|
+
| Anything else | Blocked from injection as a freeze-guard fail-safe. The bridge replies with the supported list instead of risking a stuck session. |
|
|
117
|
+
|
|
118
|
+
To bypass the freeze guard and inject a slash command raw, prefix the Telegram
|
|
119
|
+
message with `!` (for example `!/theme`).
|
|
120
|
+
|
|
121
|
+
Capture tuning for `/context`, `/usage`, and `/cost`:
|
|
122
|
+
|
|
123
|
+
- `CLB_CONTEXT_SETTLE_SEC` - floor delay before the first capture attempt.
|
|
124
|
+
Defaults to `1.2` seconds.
|
|
125
|
+
- `CLB_CONTEXT_CAPTURE_TIMEOUT_SEC` - how long to keep polling for a finished
|
|
126
|
+
render before sending the last captured frame. Defaults to `8.0` seconds.
|
|
127
|
+
- `CLB_MODEL_CHOICES` - optional comma-separated list of model aliases shown in
|
|
128
|
+
the `/model` inline keyboard.
|
|
129
|
+
|
|
130
|
+
## Files
|
|
131
|
+
|
|
132
|
+
- `claude_telegram_bridge.py` - bridge daemon.
|
|
133
|
+
- `hooks/claude-telegram-bridge-session-start.sh` - records transcript and tmux
|
|
134
|
+
pane binding for the daemon.
|
|
135
|
+
- `hooks/claude-telegram-bridge-pretool-block.sh` - blocks Telegram MCP replies
|
|
136
|
+
during bridge-owned turns.
|
|
137
|
+
- `config.example.env` - local environment template.
|
|
138
|
+
|
|
139
|
+
## Minimal Manual Setup
|
|
140
|
+
|
|
141
|
+
1. Start Claude Code in tmux:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
tmux -L default new -s claude
|
|
145
|
+
claude --dangerously-skip-permissions
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
2. Create a Telegram bot with BotFather. Paste the bot token only into your
|
|
149
|
+
local terminal or local config file. Never send it in Telegram.
|
|
150
|
+
|
|
151
|
+
3. Copy the example config:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
cp config.example.env .env
|
|
155
|
+
chmod 600 .env
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
4. Edit `.env` and set:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
CLB_TOKEN_FILE="$HOME/.config/claude-telegram-bridge/token.json"
|
|
162
|
+
CLB_CHAT_ID="123456789"
|
|
163
|
+
CLB_TOKEN_REGISTRY="$HOME/.config/claude-telegram-bridge/token-registry.json"
|
|
164
|
+
CLB_STATE_DIR="$HOME/.local/state/claude-telegram-bridge"
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
5. Store the token locally:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
mkdir -p "$HOME/.config/claude-telegram-bridge"
|
|
171
|
+
printf '{"token":"%s"}\n' 'PASTE_BOTFATHER_TOKEN_HERE' \
|
|
172
|
+
> "$HOME/.config/claude-telegram-bridge/token.json"
|
|
173
|
+
chmod 600 "$HOME/.config/claude-telegram-bridge/token.json"
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
6. Create a token registry entry. The `token_id` is the first 16 hex chars of
|
|
177
|
+
the SHA-256 of the token.
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
python3 - <<'PY'
|
|
181
|
+
import hashlib, json, pathlib
|
|
182
|
+
root = pathlib.Path.home() / ".config/claude-telegram-bridge"
|
|
183
|
+
token = json.loads((root / "token.json").read_text())["token"]
|
|
184
|
+
token_id = hashlib.sha256(token.encode()).hexdigest()[:16]
|
|
185
|
+
(root / "token-registry.json").write_text(json.dumps({
|
|
186
|
+
"tokens": {
|
|
187
|
+
"default": {
|
|
188
|
+
"token_id": token_id,
|
|
189
|
+
"mode": "polling",
|
|
190
|
+
"owner": "claude-telegram-bridge",
|
|
191
|
+
"expected_consumer": "claude",
|
|
192
|
+
"allow_delete_webhook": False
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}, indent=2) + "\n")
|
|
196
|
+
PY
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
7. Register the SessionStart hook in Claude Code settings. The exact settings
|
|
200
|
+
file location depends on your Claude Code install.
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"hooks": {
|
|
205
|
+
"SessionStart": [
|
|
206
|
+
{
|
|
207
|
+
"hooks": [
|
|
208
|
+
{
|
|
209
|
+
"type": "command",
|
|
210
|
+
"command": "/absolute/path/to/hooks/claude-telegram-bridge-session-start.sh"
|
|
211
|
+
}
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
8. Run the daemon:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
set -a
|
|
223
|
+
. ./.env
|
|
224
|
+
set +a
|
|
225
|
+
python3 claude_telegram_bridge.py
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Send `/ping` to the bot, then send a normal prompt.
|
|
229
|
+
|
|
230
|
+
## Safety Defaults
|
|
231
|
+
|
|
232
|
+
- Polling only; no public webhook is required.
|
|
233
|
+
- One allowed Telegram chat id.
|
|
234
|
+
- Token ownership registry must match the local token before polling starts.
|
|
235
|
+
- Interactive slash commands that could open a blocking dialog are held back by
|
|
236
|
+
a freeze guard rather than pasted raw; a set of read-only and safe commands is
|
|
237
|
+
supported and mirrored. See [Slash Commands](#slash-commands) for the full set
|
|
238
|
+
and the `!` escape hatch.
|
|
239
|
+
- The PreToolUse egress guard is included for users who also have Telegram MCP
|
|
240
|
+
reply tools installed.
|
|
241
|
+
- Outgoing media auto-send is not part of this minimal export.
|
|
242
|
+
|
|
243
|
+
## Optional Settings
|
|
244
|
+
|
|
245
|
+
- `CLB_FLOW_MIRROR_FLAG` - path to a flag file that enables the flow mirror.
|
|
246
|
+
When the file exists, the bridge mirrors each tool-use step of the current
|
|
247
|
+
turn to Telegram as one live-updating card. Off by default (no file). Enable
|
|
248
|
+
with `touch "$HOME/.config/claude-telegram-bridge/flow-mirror.on"` and disable
|
|
249
|
+
by removing the file.
|
|
250
|
+
- `CLB_ACTIVE_TURN_STALE_SECONDS` - releases a previously observed Telegram turn
|
|
251
|
+
when Claude is idle but no final reply was captured, so later queued messages
|
|
252
|
+
can continue instead of being blocked behind a stale active turn. Defaults to
|
|
253
|
+
900 seconds.
|
|
254
|
+
|
|
255
|
+
### Advanced settings
|
|
256
|
+
|
|
257
|
+
The bridge reads ~20 more tuning knobs (self-update via `CLB_AUTO_UPDATE` /
|
|
258
|
+
`CLB_NO_UPDATE_CHECK`, send-retry policy, durable queue/outbox paths, session
|
|
259
|
+
binding TTLs, an optional `CLB_WATCHDOG_SCRIPT` lifecycle hook, and more). All
|
|
260
|
+
of them ship with safe defaults; the full annotated list lives at the bottom
|
|
261
|
+
of `config.example.env`.
|
|
262
|
+
|
|
263
|
+
## Release Checklist
|
|
264
|
+
|
|
265
|
+
See `RELEASE_CHECKLIST.md` before publishing a fork or release.
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# Claude Telegram Bridge
|
|
2
|
+
|
|
3
|
+
Control an already-running interactive Claude Code session from Telegram.
|
|
4
|
+
|
|
5
|
+
This bridge polls Telegram, pastes incoming messages into a visible tmux Claude
|
|
6
|
+
Code pane, tails Claude transcript JSONL, and sends only the matching final
|
|
7
|
+
answer back to Telegram.
|
|
8
|
+
|
|
9
|
+
The bridge is Claude-specific. It is not a general multi-AI bridge and it does
|
|
10
|
+
not share runtime code with the Codex Telegram Bridge.
|
|
11
|
+
|
|
12
|
+
## What It Supports
|
|
13
|
+
|
|
14
|
+
- Text prompts from Telegram into a live Claude Code tmux session.
|
|
15
|
+
- Telegram photos and image documents saved locally, then injected as
|
|
16
|
+
`local_path` prompts for Claude to inspect.
|
|
17
|
+
- Telegram voice, audio, video, animation, and document uploads saved locally
|
|
18
|
+
with caption and metadata preserved.
|
|
19
|
+
- Optional audio transcription through a local command configured with
|
|
20
|
+
`CLB_AUDIO_TRANSCRIBE_CMD`.
|
|
21
|
+
- Transcript-based final-answer extraction instead of screen scraping.
|
|
22
|
+
- Optional flow mirror: live "work in progress" card that mirrors each tool-use
|
|
23
|
+
step of the current turn to Telegram so you can follow long runs.
|
|
24
|
+
- Single Telegram chat allowlist and token ownership registry.
|
|
25
|
+
- Duplicate-egress guard hooks for users who also have Telegram MCP reply tools
|
|
26
|
+
or terminal mirror hooks installed.
|
|
27
|
+
|
|
28
|
+
This is not MCP. It is a local bridge daemon for one visible Claude Code
|
|
29
|
+
session.
|
|
30
|
+
|
|
31
|
+
## Public Export Model
|
|
32
|
+
|
|
33
|
+
This public repository is maintained from a private operator source through a
|
|
34
|
+
sanitized export step. The export keeps the reusable Claude bridge behavior,
|
|
35
|
+
hook templates, config examples, and documentation, while stripping private chat
|
|
36
|
+
ids, token paths, hostnames, node labels, and local automation paths before
|
|
37
|
+
release.
|
|
38
|
+
|
|
39
|
+
Claude Telegram Bridge and Codex Telegram Bridge remain separate programs
|
|
40
|
+
because they drive different interactive CLIs and transcript formats. The shared
|
|
41
|
+
maintenance rule is the same: keep one internal source for each bridge, generate
|
|
42
|
+
the public copy through an export script, and never publish private wrappers or
|
|
43
|
+
operator-specific trigger paths.
|
|
44
|
+
|
|
45
|
+
## Billing And Terms
|
|
46
|
+
|
|
47
|
+
This project does not use `claude -p` and does not create hidden one-shot
|
|
48
|
+
Claude sessions. It drives an interactive Claude Code session that you already
|
|
49
|
+
started.
|
|
50
|
+
|
|
51
|
+
The subscription billing classification of a 24/7 daemon that automatically
|
|
52
|
+
injects prompts into an interactive Claude Code session is unverified. This
|
|
53
|
+
project does not claim that this usage is subscription-safe. You are responsible
|
|
54
|
+
for deciding whether to run it under your account, plan, and applicable terms.
|
|
55
|
+
|
|
56
|
+
## Verified Backend
|
|
57
|
+
|
|
58
|
+
- Claude Code interactive tmux session: experimental, locally verified by the
|
|
59
|
+
maintainers.
|
|
60
|
+
- Other AI CLIs: not supported.
|
|
61
|
+
|
|
62
|
+
## How It Works
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
Telegram user message/media
|
|
66
|
+
-> getUpdates polling
|
|
67
|
+
-> single chat id allowlist
|
|
68
|
+
-> media download to local state directory when present
|
|
69
|
+
-> paste prompt envelope into tmux Claude pane
|
|
70
|
+
-> SessionStart sidecar binds tmux pane to Claude transcript JSONL
|
|
71
|
+
-> transcript tail finds the final answer for the injected nonce
|
|
72
|
+
-> Telegram sendMessage
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The bridge uses one Bot API egress path. The included hooks prevent Claude's
|
|
76
|
+
Telegram MCP reply tool and terminal mirror hooks from sending duplicate
|
|
77
|
+
answers while the bridge owns a turn.
|
|
78
|
+
|
|
79
|
+
## Slash Commands
|
|
80
|
+
|
|
81
|
+
Slash commands sent from Telegram are classified before anything is injected
|
|
82
|
+
into the Claude pane. Commands that would open an interactive picker or dialog
|
|
83
|
+
are never pasted raw, because a blocking dialog can freeze the one visible
|
|
84
|
+
session. Each command falls into one of these groups.
|
|
85
|
+
|
|
86
|
+
| Command | Behavior |
|
|
87
|
+
| --- | --- |
|
|
88
|
+
| `/context`, `/usage`, `/cost` | Read-only info commands. The bridge widens the tmux capture window, runs the command, waits for the render to finish before capturing (no more blank "in progress" frame), trims the terminal chrome to a clean text view, and mirrors that screen back to Telegram. |
|
|
89
|
+
| `/model` | Intercepted. Pasting `/model` raw opens an interactive picker that can freeze the session, so the bridge shows an inline keyboard of model choices instead and applies the pick non-interactively as `/model <alias>`. |
|
|
90
|
+
| `/clear`, `/exit`, `/quit` | Passed through unchanged; these do not open a dialog. `/exit` and `/quit` end the session, so the bridge triggers watchdog recovery for a graceful restart afterward. `/clear` only resets context. |
|
|
91
|
+
| `/ping`, `/start`, `/status` | Bridge health and status, answered by the bridge itself. |
|
|
92
|
+
| Anything else | Blocked from injection as a freeze-guard fail-safe. The bridge replies with the supported list instead of risking a stuck session. |
|
|
93
|
+
|
|
94
|
+
To bypass the freeze guard and inject a slash command raw, prefix the Telegram
|
|
95
|
+
message with `!` (for example `!/theme`).
|
|
96
|
+
|
|
97
|
+
Capture tuning for `/context`, `/usage`, and `/cost`:
|
|
98
|
+
|
|
99
|
+
- `CLB_CONTEXT_SETTLE_SEC` - floor delay before the first capture attempt.
|
|
100
|
+
Defaults to `1.2` seconds.
|
|
101
|
+
- `CLB_CONTEXT_CAPTURE_TIMEOUT_SEC` - how long to keep polling for a finished
|
|
102
|
+
render before sending the last captured frame. Defaults to `8.0` seconds.
|
|
103
|
+
- `CLB_MODEL_CHOICES` - optional comma-separated list of model aliases shown in
|
|
104
|
+
the `/model` inline keyboard.
|
|
105
|
+
|
|
106
|
+
## Files
|
|
107
|
+
|
|
108
|
+
- `claude_telegram_bridge.py` - bridge daemon.
|
|
109
|
+
- `hooks/claude-telegram-bridge-session-start.sh` - records transcript and tmux
|
|
110
|
+
pane binding for the daemon.
|
|
111
|
+
- `hooks/claude-telegram-bridge-pretool-block.sh` - blocks Telegram MCP replies
|
|
112
|
+
during bridge-owned turns.
|
|
113
|
+
- `config.example.env` - local environment template.
|
|
114
|
+
|
|
115
|
+
## Minimal Manual Setup
|
|
116
|
+
|
|
117
|
+
1. Start Claude Code in tmux:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
tmux -L default new -s claude
|
|
121
|
+
claude --dangerously-skip-permissions
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
2. Create a Telegram bot with BotFather. Paste the bot token only into your
|
|
125
|
+
local terminal or local config file. Never send it in Telegram.
|
|
126
|
+
|
|
127
|
+
3. Copy the example config:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
cp config.example.env .env
|
|
131
|
+
chmod 600 .env
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
4. Edit `.env` and set:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
CLB_TOKEN_FILE="$HOME/.config/claude-telegram-bridge/token.json"
|
|
138
|
+
CLB_CHAT_ID="123456789"
|
|
139
|
+
CLB_TOKEN_REGISTRY="$HOME/.config/claude-telegram-bridge/token-registry.json"
|
|
140
|
+
CLB_STATE_DIR="$HOME/.local/state/claude-telegram-bridge"
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
5. Store the token locally:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
mkdir -p "$HOME/.config/claude-telegram-bridge"
|
|
147
|
+
printf '{"token":"%s"}\n' 'PASTE_BOTFATHER_TOKEN_HERE' \
|
|
148
|
+
> "$HOME/.config/claude-telegram-bridge/token.json"
|
|
149
|
+
chmod 600 "$HOME/.config/claude-telegram-bridge/token.json"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
6. Create a token registry entry. The `token_id` is the first 16 hex chars of
|
|
153
|
+
the SHA-256 of the token.
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
python3 - <<'PY'
|
|
157
|
+
import hashlib, json, pathlib
|
|
158
|
+
root = pathlib.Path.home() / ".config/claude-telegram-bridge"
|
|
159
|
+
token = json.loads((root / "token.json").read_text())["token"]
|
|
160
|
+
token_id = hashlib.sha256(token.encode()).hexdigest()[:16]
|
|
161
|
+
(root / "token-registry.json").write_text(json.dumps({
|
|
162
|
+
"tokens": {
|
|
163
|
+
"default": {
|
|
164
|
+
"token_id": token_id,
|
|
165
|
+
"mode": "polling",
|
|
166
|
+
"owner": "claude-telegram-bridge",
|
|
167
|
+
"expected_consumer": "claude",
|
|
168
|
+
"allow_delete_webhook": False
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}, indent=2) + "\n")
|
|
172
|
+
PY
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
7. Register the SessionStart hook in Claude Code settings. The exact settings
|
|
176
|
+
file location depends on your Claude Code install.
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"hooks": {
|
|
181
|
+
"SessionStart": [
|
|
182
|
+
{
|
|
183
|
+
"hooks": [
|
|
184
|
+
{
|
|
185
|
+
"type": "command",
|
|
186
|
+
"command": "/absolute/path/to/hooks/claude-telegram-bridge-session-start.sh"
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
]
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
8. Run the daemon:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
set -a
|
|
199
|
+
. ./.env
|
|
200
|
+
set +a
|
|
201
|
+
python3 claude_telegram_bridge.py
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Send `/ping` to the bot, then send a normal prompt.
|
|
205
|
+
|
|
206
|
+
## Safety Defaults
|
|
207
|
+
|
|
208
|
+
- Polling only; no public webhook is required.
|
|
209
|
+
- One allowed Telegram chat id.
|
|
210
|
+
- Token ownership registry must match the local token before polling starts.
|
|
211
|
+
- Interactive slash commands that could open a blocking dialog are held back by
|
|
212
|
+
a freeze guard rather than pasted raw; a set of read-only and safe commands is
|
|
213
|
+
supported and mirrored. See [Slash Commands](#slash-commands) for the full set
|
|
214
|
+
and the `!` escape hatch.
|
|
215
|
+
- The PreToolUse egress guard is included for users who also have Telegram MCP
|
|
216
|
+
reply tools installed.
|
|
217
|
+
- Outgoing media auto-send is not part of this minimal export.
|
|
218
|
+
|
|
219
|
+
## Optional Settings
|
|
220
|
+
|
|
221
|
+
- `CLB_FLOW_MIRROR_FLAG` - path to a flag file that enables the flow mirror.
|
|
222
|
+
When the file exists, the bridge mirrors each tool-use step of the current
|
|
223
|
+
turn to Telegram as one live-updating card. Off by default (no file). Enable
|
|
224
|
+
with `touch "$HOME/.config/claude-telegram-bridge/flow-mirror.on"` and disable
|
|
225
|
+
by removing the file.
|
|
226
|
+
- `CLB_ACTIVE_TURN_STALE_SECONDS` - releases a previously observed Telegram turn
|
|
227
|
+
when Claude is idle but no final reply was captured, so later queued messages
|
|
228
|
+
can continue instead of being blocked behind a stale active turn. Defaults to
|
|
229
|
+
900 seconds.
|
|
230
|
+
|
|
231
|
+
### Advanced settings
|
|
232
|
+
|
|
233
|
+
The bridge reads ~20 more tuning knobs (self-update via `CLB_AUTO_UPDATE` /
|
|
234
|
+
`CLB_NO_UPDATE_CHECK`, send-retry policy, durable queue/outbox paths, session
|
|
235
|
+
binding TTLs, an optional `CLB_WATCHDOG_SCRIPT` lifecycle hook, and more). All
|
|
236
|
+
of them ship with safe defaults; the full annotated list lives at the bottom
|
|
237
|
+
of `config.example.env`.
|
|
238
|
+
|
|
239
|
+
## Release Checklist
|
|
240
|
+
|
|
241
|
+
See `RELEASE_CHECKLIST.md` before publishing a fork or release.
|