Skip to main content
The ouroborai Telegram bot is a thin client built on grammY that forwards user messages to the agent API server and renders responses as formatted HTML. It supports slash commands for common actions and free-form natural language for everything else.

Commands

CommandDescription
/startWelcome message with command reference
/healthCheck API server connectivity
/trade <prompt>Execute a spot swap via natural language
/perp <prompt>Open or close a perpetual position
/portfolioView positions across all protocols
/timeboost <prompt>Query express lane status or trigger a bid
All command prompts are forwarded verbatim to POST /agent/prompt on the API server. The bot polls the job status endpoint until the result is ready or a timeout is reached.

Free-Form Messages

Any text message that does not start with / is forwarded directly to the agent as a natural language prompt. This allows users to type requests like “swap 100 USDC for ETH” without using a specific command.

Inline Confirmation Buttons

When the agent response contains action-oriented language (e.g. “confirm” or “execute”), the bot presents inline keyboard buttons:

Confirm

Triggers execution of the proposed action. Each confirmation token is a UUID bound to the user ID with a 5-minute TTL.

Cancel

Cancels the proposed action and updates the message text.
Confirmation tokens are stored in-memory with periodic cleanup (every 60 seconds). A token is invalidated after use or expiration, preventing replay.

Architecture

User (Telegram) --> grammY Bot --> API Client --> Hono API Server
                                                      |
                                                Agent Runner
                                                      |
                                            Protocol Adapters
The bot is stateless beyond the confirmation token store. All agent logic, thread management, and execution happen on the API server.

Setup

Open @BotFather on Telegram and run /newbot. Copy the bot token.
VariableRequiredDescription
TELEGRAM_BOT_TOKENYesBot token from BotFather
API_URLNoAPI server URL (default: http://localhost:3000)
bun run apps/telegram/src/index.ts
The bot starts in long polling mode by default. On startup it logs the bot username and API URL.

Deployment

Long polling is the simplest deployment — the bot opens a persistent connection to Telegram’s servers and receives updates in real time. No public URL or TLS certificate required.Suitable for development and single-instance production deployments.
For higher throughput or serverless deployments, configure grammY’s webhook handler:
  1. Set a public HTTPS URL for the bot.
  2. Call bot.api.setWebhook(url) on startup.
  3. Route incoming POST requests to bot.handleUpdate(update).
See the grammY webhook guide for framework-specific examples.

Response Formatting

Bot responses are sent as Telegram HTML. The formatResponse helper:
  • Escapes HTML entities in agent output to prevent injection.
  • Wraps the response in a format suitable for Telegram’s HTML parse mode.
  • Preserves code blocks and structured data from the agent.
The bot uses parse_mode: "HTML" for all messages. Markdown is not used because Telegram’s Markdown parser is more restrictive and error-prone with special characters common in DeFi output (addresses, decimals, etc.).

Error Handling

  • API unreachable/health reports the specific error message.
  • Job timeout — if the job does not complete within the polling window, the bot reports the current status and job ID so the user can check later.
  • Agent failure — failed jobs surface the error message from the agent runner.