Skip to content

Instantly share code, notes, and snippets.

@johnlindquist
Last active February 17, 2026 20:28
Show Gist options
  • Select an option

  • Save johnlindquist/840fe1093bc53dc3060d2bfeb2632075 to your computer and use it in GitHub Desktop.

Select an option

Save johnlindquist/840fe1093bc53dc3060d2bfeb2632075 to your computer and use it in GitHub Desktop.

Reconnecting Messaging Users to Stopped OpenClaw Sandboxes

tl;dr

  • Sandboxes stop after 10min idle — when a Telegram/Slack user sends a message, the bot is dead until it restarts
  • Sandbox URLs change on every restore, but our stable subdomain proxy ({key}.basedomain.com) already solves that
  • Option A (simpler): Enable OpenClaw's built-in channels — remove --skip-channels, use long polling mode so the Gateway polls Telegram itself. No webhook URLs needed. Downside: bot appears offline when sandbox is stopped, no way to send "booting up..." messages to users
  • Option B (better UX): Build our own webhook adapter — keep --skip-channels, add /api/webhooks/telegram on our always-on Next.js app. Queue messages in Redis, trigger restore, send "booting up..." progress messages, drain queue once sandbox is live. More code but full control over cold-start experience
  • Either way we need a wake-up mechanism to restore stopped sandboxes when messages arrive
  • OpenClaw natively supports 14+ platforms (Telegram via grammY, Slack via Bolt, Discord, WhatsApp, etc.) — --skip-channels just skips config during onboard, doesn't disable anything

The Problem

  1. User sends message on Telegram/Slack
  2. Sandbox is stopped (idle >10min)
  3. Restore takes 10-60s (lock acquisition + snapshot restore + OpenClaw readiness)
  4. User gets nothing during this time — bot looks broken

Option A: Enable Built-In Channels

  • Remove --skip-channels from onboard, pass Telegram bot token during setup
  • Use long polling — Gateway inside sandbox polls Telegram directly
  • No webhook URLs, no reverse proxy, no adapter code
  • Cold-start gap: when sandbox is stopped, Gateway isn't running, bot is offline
  • Need external wake-up: cron checking for pending Telegram updates, or extending idle timeout for active bots
  • User gets no feedback during boot — just silence until Gateway reconnects and processes queued messages
  • Telegram queues undelivered updates for long polling (unclear how long — needs testing)

Option B: Build Webhook Adapter

  • Keep --skip-channels, build /api/webhooks/telegram on always-on Next.js
  • Register webhook: https://{key}.basedomain.com/api/webhooks/telegram (bypasses proxy.ts since it's under /api/*)
  • On incoming message: return 200 OK immediately, enqueue in Redis, trigger restore via after()
  • Send "Starting up..." via Telegram API, edit message with progress every ~30s
  • Once sandbox is running, drain queue by calling OpenClaw directly via sandbox.domain(3000) + gateway token (bypasses password gate)
  • Add /api/cron/messaging-pump for progress updates and queue draining as a backstop
  • More code, but users get immediate feedback and buffered messages

Key Details

  • OpenClaw Telegram uses grammY, webhook listener defaults to 127.0.0.1:8787
  • Config: channels.telegram.webhookUrl, webhookSecret, webhookPath (default /telegram-webhook)
  • Messages deduplicated by update_id, processed sequentially per chat
  • DM access control: pairing (default), allowlist, open, or disabled
  • Current proxy returns HTML waiting pages + password gate — unusable for webhook senders

Open Questions

  • Can we hybrid? Built-in channels when running, our adapter layer for cold-start?
  • How long does Telegram queue updates for long polling bots? If long enough, Option A might be fine
  • Should we extend idle timeout (10min → 30-60min) for sandboxes with active messaging?
  • Is there a way to make OpenClaw send a "back online" message on Gateway boot?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment