# OpenClaw Telegram (/docs/agents/openclaw/openclaw-telegram)

<!-- agent-signals: reading_time_min: 5 · est_tokens: 2562 · updated: 2026-07-30 -->
Related: [Deploy OpenClaw](/docs/agents/openclaw/openclaw-gateway.md), [OpenCode](/docs/agents/opencode.md)

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.

This guide covers the working flow we used:

1. Start OpenClaw in a sandbox.
2. Enable the Telegram plugin.
3. Add Telegram channel credentials.
4. Start the channel runtime in background.
5. Approve Telegram pairing.

## Prerequisites [#prerequisites]

* A Telegram bot token from [@BotFather](https://t.me/BotFather). There's instructions to follow there, it runs /newbot for you and walks you through naming and creating your bot.
* An OpenAI API key for the OpenClaw model.
* E2B API key configured locally.

## Quick start [#quick-start]

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```typescript  
      import { Sandbox } from 'e2b'

      const GATEWAY_PORT = 18789
      const GATEWAY_TOKEN = process.env.OPENCLAW_APP_TOKEN || 'my-openclaw-token'

      const sandbox = await Sandbox.create('openclaw', {
        envs: {
          OPENAI_API_KEY: process.env.OPENAI_API_KEY,
          TELEGRAM_BOT_TOKEN: process.env.TELEGRAM_BOT_TOKEN,
        },
        timeoutMs: 3600_000,
      })

      await sandbox.commands.run('openclaw config set agents.defaults.model.primary openai/gpt-5.2')

      // Enable the Telegram plugin (required before adding the channel)
      await sandbox.commands.run('openclaw config set plugins.entries.telegram.enabled true')
      await sandbox.commands.run('openclaw channels add --channel telegram --token "$TELEGRAM_BOT_TOKEN"')

      await sandbox.commands.run(
        `bash -lc 'openclaw config set gateway.controlUi.allowInsecureAuth true && ` +
          `openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true && ` +
          `openclaw gateway --allow-unconfigured --bind lan --auth token --token ${GATEWAY_TOKEN} --port ${GATEWAY_PORT}'`,
        { background: true }
      )

      for (let i = 0; i < 45; i++) {
        const probe = await sandbox.commands.run(
          `bash -lc 'ss -ltn | grep -q ":${GATEWAY_PORT} " && echo ready || echo waiting'`
        )
        if (probe.stdout.trim() === 'ready') break
        await new Promise((r) => setTimeout(r, 1000))
      }
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python  
      import os
      import time
      from e2b import Sandbox

      GATEWAY_PORT = 18789
      GATEWAY_TOKEN = os.environ.get("OPENCLAW_APP_TOKEN", "my-openclaw-token")

      sandbox = Sandbox.create("openclaw", envs={
          "OPENAI_API_KEY": os.environ["OPENAI_API_KEY"],
          "TELEGRAM_BOT_TOKEN": os.environ["TELEGRAM_BOT_TOKEN"],
      }, timeout=3600)

      sandbox.commands.run("openclaw config set agents.defaults.model.primary openai/gpt-5.2")

      # Enable the Telegram plugin (required before adding the channel)
      sandbox.commands.run("openclaw config set plugins.entries.telegram.enabled true")
      sandbox.commands.run('openclaw channels add --channel telegram --token "$TELEGRAM_BOT_TOKEN"')

      sandbox.commands.run(
          f"bash -lc 'openclaw config set gateway.controlUi.allowInsecureAuth true && "
          f"openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true && "
          f"openclaw gateway --allow-unconfigured --bind lan --auth token --token {GATEWAY_TOKEN} --port {GATEWAY_PORT}'",
          background=True,
      )

      for _ in range(45):
          probe = sandbox.commands.run(
              f"bash -lc 'ss -ltn | grep -q \":{GATEWAY_PORT} \" && echo ready || echo waiting'"
          )
          if probe.stdout.strip() == "ready":
              break
          time.sleep(1)
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

<Info>
  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.
</Info>

## Pair your Telegram user [#pair-your-telegram-user]

1. Open your bot in Telegram and send a message (for example: `hi`).
2. Telegram will return a pairing prompt similar to:

```text
OpenClaw: access not configured.

Your Telegram user id: ...
Pairing code: XXXXXXXX

Ask the bot owner to approve with:
openclaw pairing approve telegram XXXXXXXX
```

3. Approve that pairing code via `sandbox.commands.run(...)`:

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```typescript  
      const PAIRING_CODE = 'XXXXXXXX' // from Telegram

      await sandbox.commands.run(
        `openclaw pairing approve --channel telegram ${PAIRING_CODE}`
      )
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python  
      PAIRING_CODE = "XXXXXXXX"  # from Telegram

      sandbox.commands.run(
          f"openclaw pairing approve --channel telegram {PAIRING_CODE}"
      )
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

`openclaw pairing approve telegram <PAIRING_CODE>` also works if you prefer that form.

## Verify channel status [#verify-channel-status]

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```typescript  
      const channels = await sandbox.commands.run('openclaw channels list --json')
      const status = await sandbox.commands.run('openclaw channels status --json --probe')
      const pairing = await sandbox.commands.run('openclaw pairing list --json --channel telegram')

      console.log(JSON.parse(channels.stdout))
      console.log(JSON.parse(status.stdout))
      console.log(JSON.parse(pairing.stdout))
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python  
      import json

      channels = sandbox.commands.run("openclaw channels list --json")
      status = sandbox.commands.run("openclaw channels status --json --probe")
      pairing = sandbox.commands.run("openclaw pairing list --json --channel telegram")

      print(json.loads(channels.stdout))
      print(json.loads(status.stdout))
      print(json.loads(pairing.stdout))
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

If you need logs from channel handlers:

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```typescript  
      const logs = await sandbox.commands.run(
        'openclaw channels logs --channel telegram --lines 200'
      )
      console.log(logs.stdout)
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python  
      logs = sandbox.commands.run(
          "openclaw channels logs --channel telegram --lines 200"
      )
      print(logs.stdout)
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

## Troubleshooting [#troubleshooting]

* `Unknown channel: telegram`
  * The Telegram plugin is not enabled. Run `openclaw config set plugins.entries.telegram.enabled true` before adding the channel.
* `OpenClaw: access not configured`
  * Pairing has not been approved yet. Run `openclaw pairing approve ...`.
* `No API key found for provider ...`
  * This guide uses `openai/gpt-5.2`. Set `OPENAI_API_KEY` in sandbox envs.
* No pending pairing requests from `pairing list`
  * Send a fresh message to the bot first, then retry `pairing list --channel telegram`.

## Related [#related]

<CardGroup cols="1">
  <Card title="OpenClaw gateway" icon="<svg xmlns=&#x22;http://www.w3.org/2000/svg&#x22; viewBox=&#x22;0 0 24 24&#x22; fill=&#x22;none&#x22;><path d=&#x22;M12.5 19L12.5 22&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M10.5 22H14.5&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><circle cx=&#x22;7&#x22; cy=&#x22;7&#x22; r=&#x22;7&#x22; transform=&#x22;matrix(-1 0 0 1 20.5 2)&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M8.5 4C9.15431 4.0385 9.49236 4.35899 10.0735 4.97301C11.1231 6.08206 12.1727 6.1746 12.8724 5.80492C13.922 5.2504 13.04 4.35221 14.2719 3.86409C15.0748 3.54595 15.1868 2.68026 14.7399 2&#x22; stroke=&#x22;currentColor&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M20 10C18.5 10 18.2338 11.2468 17 11C14.5 10.5 13.7916 11.0589 13.7916 12.2511C13.7916 13.4432 13.7916 13.4432 13.2717 14.3373C12.9335 14.9189 12.8153 15.5004 13.4894 16&#x22; stroke=&#x22;currentColor&#x22; stroke-linejoin=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/><path d=&#x22;M6.5 2C4.64864 3.79995 3.5 6.3082 3.5 9.08251C3.5 14.5598 7.97715 19 13.5 19C16.2255 19 18.6962 17.9187 20.5 16.165&#x22; stroke=&#x22;currentColor&#x22; stroke-linecap=&#x22;round&#x22; stroke-width=&#x22;1.5&#x22;/></svg>" href="/docs/agents/openclaw/openclaw-gateway">
    Run OpenClaw's web gateway with token auth
  </Card>
</CardGroup>
