Skip to content

Commit 6fbfcf8

Browse files
start on telegram - can make this easier tho
1 parent d05769d commit 6fbfcf8

2 files changed

Lines changed: 195 additions & 2 deletions

File tree

docs/agents/openclaw-gateway.mdx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,17 @@ Once approved, the browser connects and the gateway UI loads.
154154

155155
## Related
156156

157-
<CardGroup cols={3}>
157+
<CardGroup cols={4}>
158158
<Card title="OpenClaw agent" icon="terminal" href="/docs/agents/openclaw">
159159
Run OpenClaw headless in a sandbox
160160
</Card>
161+
<Card title="OpenClaw Telegram" icon="message-circle" href="/docs/agents/openclaw-telegram">
162+
Connect OpenClaw to Telegram and approve pairing
163+
</Card>
161164
<Card title="Sandbox persistence" icon="clock" href="/docs/sandbox/persistence">
162165
Auto-pause, resume, and manage sandbox lifecycle
163166
</Card>
164167
<Card title="SSH access" icon="terminal" href="/docs/sandbox/ssh-access">
165168
Connect to the sandbox via SSH
166169
</Card>
167-
</CardGroup>
170+
</CardGroup>

docs/agents/openclaw-telegram.mdx

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
---
2+
title: "OpenClaw Telegram"
3+
description: "Connect OpenClaw to Telegram in an E2B sandbox, approve pairing, and chat through your bot."
4+
icon: "/images/icons/openclaw.svg"
5+
---
6+
7+
OpenClaw supports Telegram as a chat channel. In E2B you can run OpenClaw in a sandbox, attach your bot token, and approve user pairing from the terminal.
8+
9+
This guide covers the working flow we used:
10+
11+
1. Start OpenClaw in a sandbox.
12+
2. Add Telegram channel credentials.
13+
3. Start the channel runtime in background.
14+
4. Approve Telegram pairing.
15+
16+
## Prerequisites
17+
18+
- A Telegram bot token from [@BotFather](https://t.me/BotFather).
19+
- An OpenAI or Anthropic provider key for the OpenClaw model.
20+
- E2B API key configured locally.
21+
22+
## Quick start
23+
24+
<CodeGroup>
25+
```typescript JavaScript & TypeScript
26+
import { Sandbox } from 'e2b'
27+
28+
const GATEWAY_PORT = 18789
29+
const GATEWAY_TOKEN = process.env.OPENCLAW_APP_TOKEN || 'my-openclaw-token'
30+
31+
const sandbox = await Sandbox.create('openclaw', {
32+
envs: {
33+
OPENAI_API_KEY: process.env.OPENAI_API_KEY,
34+
TELEGRAM_BOT_TOKEN: process.env.TELEGRAM_BOT_TOKEN,
35+
},
36+
timeoutMs: 3600_000,
37+
})
38+
39+
await sandbox.commands.run('openclaw config set agents.defaults.model.primary openai/gpt-5.2')
40+
await sandbox.commands.run('openclaw channels add --channel telegram --token "$TELEGRAM_BOT_TOKEN"')
41+
42+
await sandbox.commands.run(
43+
`openclaw gateway --allow-unconfigured --bind lan --auth token --token ${GATEWAY_TOKEN} --port ${GATEWAY_PORT}`,
44+
{ background: true }
45+
)
46+
47+
for (let i = 0; i < 45; i++) {
48+
const probe = await sandbox.commands.run(
49+
`bash -lc 'ss -ltn | grep -q ":${GATEWAY_PORT} " && echo ready || echo waiting'`
50+
)
51+
if (probe.stdout.trim() === 'ready') break
52+
await new Promise((r) => setTimeout(r, 1000))
53+
}
54+
```
55+
```python Python
56+
import os
57+
import time
58+
from e2b import Sandbox
59+
60+
GATEWAY_PORT = 18789
61+
GATEWAY_TOKEN = os.environ.get("OPENCLAW_APP_TOKEN", "my-openclaw-token")
62+
63+
sandbox = Sandbox.create("openclaw", envs={
64+
"OPENAI_API_KEY": os.environ["OPENAI_API_KEY"],
65+
"TELEGRAM_BOT_TOKEN": os.environ["TELEGRAM_BOT_TOKEN"],
66+
}, timeout=3600)
67+
68+
sandbox.commands.run("openclaw config set agents.defaults.model.primary openai/gpt-5.2")
69+
sandbox.commands.run('openclaw channels add --channel telegram --token "$TELEGRAM_BOT_TOKEN"')
70+
71+
sandbox.commands.run(
72+
f"openclaw gateway --allow-unconfigured --bind lan --auth token --token {GATEWAY_TOKEN} --port {GATEWAY_PORT}",
73+
background=True,
74+
)
75+
76+
for _ in range(45):
77+
probe = sandbox.commands.run(
78+
f"bash -lc 'ss -ltn | grep -q \":{GATEWAY_PORT} \" && echo ready || echo waiting'"
79+
)
80+
if probe.stdout.strip() == "ready":
81+
break
82+
time.sleep(1)
83+
```
84+
</CodeGroup>
85+
86+
<Info>
87+
For Telegram setup, you do **not** need to open the gateway URL in a browser. The gateway process is used here as a long-running channel runtime.
88+
</Info>
89+
90+
## Pair your Telegram user
91+
92+
1. Open your bot in Telegram and send a message (for example: `hi`).
93+
2. Telegram will return a pairing prompt similar to:
94+
95+
```text
96+
OpenClaw: access not configured.
97+
98+
Your Telegram user id: ...
99+
Pairing code: XXXXXXXX
100+
101+
Ask the bot owner to approve with:
102+
openclaw pairing approve telegram XXXXXXXX
103+
```
104+
105+
3. Approve that pairing code via `sandbox.commands.run(...)`:
106+
107+
<CodeGroup>
108+
```typescript JavaScript & TypeScript
109+
const PAIRING_CODE = 'XXXXXXXX' // from Telegram
110+
111+
await sandbox.commands.run(
112+
`openclaw pairing approve --channel telegram ${PAIRING_CODE}`
113+
)
114+
```
115+
```python Python
116+
PAIRING_CODE = "XXXXXXXX" # from Telegram
117+
118+
sandbox.commands.run(
119+
f"openclaw pairing approve --channel telegram {PAIRING_CODE}"
120+
)
121+
```
122+
</CodeGroup>
123+
124+
`openclaw pairing approve telegram <PAIRING_CODE>` also works if you prefer that form.
125+
126+
## Verify channel status
127+
128+
<CodeGroup>
129+
```typescript JavaScript & TypeScript
130+
const channels = await sandbox.commands.run('openclaw channels list --json')
131+
const status = await sandbox.commands.run('openclaw channels status --json --probe')
132+
const pairing = await sandbox.commands.run('openclaw pairing list --json --channel telegram')
133+
134+
console.log(JSON.parse(channels.stdout))
135+
console.log(JSON.parse(status.stdout))
136+
console.log(JSON.parse(pairing.stdout))
137+
```
138+
```python Python
139+
import json
140+
141+
channels = sandbox.commands.run("openclaw channels list --json")
142+
status = sandbox.commands.run("openclaw channels status --json --probe")
143+
pairing = sandbox.commands.run("openclaw pairing list --json --channel telegram")
144+
145+
print(json.loads(channels.stdout))
146+
print(json.loads(status.stdout))
147+
print(json.loads(pairing.stdout))
148+
```
149+
</CodeGroup>
150+
151+
If you need logs from channel handlers:
152+
153+
<CodeGroup>
154+
```typescript JavaScript & TypeScript
155+
const logs = await sandbox.commands.run(
156+
'openclaw channels logs --channel telegram --lines 200'
157+
)
158+
console.log(logs.stdout)
159+
```
160+
```python Python
161+
logs = sandbox.commands.run(
162+
"openclaw channels logs --channel telegram --lines 200"
163+
)
164+
print(logs.stdout)
165+
```
166+
</CodeGroup>
167+
168+
## Troubleshooting
169+
170+
- `OpenClaw: access not configured`
171+
- Pairing has not been approved yet. Run `openclaw pairing approve ...`.
172+
- `No API key found for provider ...`
173+
- Model/provider mismatch. If model is `openai/...`, set `OPENAI_API_KEY`.
174+
- If model is `anthropic/...`, set `ANTHROPIC_API_KEY`.
175+
- No pending pairing requests from `pairing list`
176+
- Send a fresh message to the bot first, then retry `pairing list --channel telegram`.
177+
178+
## Related
179+
180+
<CardGroup cols={3}>
181+
<Card title="OpenClaw gateway" icon="globe" href="/docs/agents/openclaw-gateway">
182+
Run OpenClaw's web gateway with token auth
183+
</Card>
184+
<Card title="OpenClaw agent" icon="terminal" href="/docs/agents/openclaw">
185+
Run OpenClaw headless in a sandbox
186+
</Card>
187+
<Card title="Secured access" icon="shield" href="/docs/sandbox/secured-access">
188+
Protect exposed endpoints with tokens
189+
</Card>
190+
</CardGroup>

0 commit comments

Comments
 (0)