5.6 KiB
Codex Telegram Bot Hybrid Host/App-Server Plan
Summary
Create codex-telegram-bot/ as a Docker Compose managed Go Telegram bot that connects to a host-launched Codex CLI app-server. Codex is not containerized: it runs from the installed host codex binary, using the host user's ~/.codex, sandboxing, and workspace paths. The bot runs in Docker Compose, stores state in SQLite, and communicates with Codex through a bind-mounted Unix socket.
Research
Before implementation, carefully read the official docs and check against the guidelines below. Create/Update them properly if discrepancies or new findings occur. If you are not sure, ask the user for advice/instruction.
-
Codex App Server official docs: https://developers.openai.com/codex/app-server
- App-server is intended for rich clients with authentication, conversation history, approvals, and streamed agent events.
- Protocol is JSON-RPC 2.0 with the
jsonrpcfield omitted. - Important:
unix://transport is WebSocket over Unix socket using HTTP Upgrade, not raw newline JSON. - Start flow: connect, send
initialize, sendinitialized, thenthread/startandturn/start. - Generate version-matched protocol schemas with
codex app-server generate-json-schema --out ./schemas.
-
Telegram Bot API official docs: https://core.telegram.org/bots/api
sendMessageandeditMessageTextare limited to 1-4096 chars after entity parsing.- Callback buttons require
answerCallbackQuery. getFiledownloads are limited to 20 MB via cloud Bot API.sendDocumentsupports bot-sent files up to 50 MB via cloud Bot API.- Use long polling for MVP unless webhook deployment is explicitly needed.
-
Telegram bot feature docs: https://core.telegram.org/bots/features
- Validate commands server-side regardless of BotFather command scopes.
- Reject group/supergroup/channel updates in code even if group joining is disabled.
- Use inline keyboards for approve/deny/details actions.
Key requirements
-
Scaffold a Go bot project:
cmd/botfor the bot process.internal/telegramfor commands, callbacks, message rendering, and Telegram file downloads.internal/codexappfor app-server WebSocket-over-Unix-socket JSON-RPC.internal/storefor SQLite state and migrations.scripts/start-codex-app-server,scripts/allow-user,scripts/remove-user,scripts/list-users,scripts/add-workspace,scripts/list-workspaces.
-
Docker Compose runs only the bot:
- Build the Go bot image locally.
- Mount persistent SQLite data.
- Bind-mount the host socket path into the bot container.
- Bind-mount an upload staging directory at the same absolute path visible to host Codex.
- Do not install or run Codex CLI inside the bot container.
-
Host Codex app-server:
- Started outside Compose with
scripts/start-codex-app-server. - Default command:
codex app-server --listen unix://$HOST_CODEX_SOCKET. - Uses host
~/.codex, host workspaces, and host sandbox behavior. - Socket defaults to an absolute path under the project, e.g.
$PROJECT/run/codex.sock.
- Started outside Compose with
-
Telegram UX:
- One-to-one chats only; reject groups, supergroups, and channels.
- Allowlisted Telegram user IDs only.
- Commands:
/start,/help,/new,/threads,/resume,/fork,/archive,/status,/cancel,/workspaces,/workspace,/model,/sandbox,/diff. - Plain text continues the active Codex thread, creating one if needed.
- Send assistant messages and rendered tool/status blocks as separate Telegram messages; chunk only when a single message exceeds Telegram limits.
- Send long output, logs, and diffs as chunked messages.
- Consider using HTML to render if markdown is weak/awkward.
- Render Codex approval requests as inline keyboards with approve, deny, and details actions.
-
SQLite state:
allowed_users,workspaces,sessions,threads,pending_approvals,audit_log.- Workspace paths are host absolute paths used as Codex
cwd. - The bot does not need direct workspace access except for upload staging.
Test Plan
Any interactive related test that requires user action should be done properly - ask the user to do X in telegram, then verify.
-
Unit tests:
- Allowlist enforcement and group-chat rejection.
- Workspace path validation.
- Telegram escaping, chunking, document fallback, and callback validation.
- WebSocket-over-Unix-socket JSON-RPC request correlation and reconnect behavior.
- SQLite migrations and admin scripts.
-
Integration tests:
- Use a low/mini model in codex for testing.
- Verify initialize, thread start, turn start, streamed output, approval, and cancellation.
- Verify
/start,/new,/threads,/resume,/workspace,/cancel, image input, and document staging. - Verify non-allowlisted users are rejected and logged.
-
Manual acceptance:
- Start host Codex app-server with
scripts/start-codex-app-server. - Run
docker compose up --build. - Add an allowlisted user and workspace with scripts.
- In a one-to-one Telegram chat, run
/start, select workspace, create a thread, send a prompt, approve a Codex request, inspect output, and cancel a running turn.
- Start host Codex app-server with
Assumptions
- Bot runtime is Docker Compose.
- Codex CLI app-server is launched from the installed host binary, outside Docker.
- The Unix socket is the only v1 connection between bot and Codex.
- Go is used for the bot.
- SQLite is used for state and admin-managed allowlist/workspaces.
- Codex-in-container and
codex execare both out of scope for MVP. - This computer is resource limited. Use docker/docker compose for large tools/SDKs to avoid installing locally.