- 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/telegramon 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-channelsjust skips config during onboard, doesn't disable anything
- User sends message on Telegram/Slack
- Sandbox is stopped (idle >10min)
- Restore takes 10-60s (lock acquisition + snapshot restore + OpenClaw readiness)
- User gets nothing during this time — bot looks broken
- Remove
--skip-channelsfrom 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)
- Keep
--skip-channels, build/api/webhooks/telegramon 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 OKimmediately, enqueue in Redis, trigger restore viaafter() - 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-pumpfor progress updates and queue draining as a backstop - More code, but users get immediate feedback and buffered messages
- 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
- 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?