Skip to content

Telegram Integration

Purpose

Telegram is the current interactive transport for JARVIS. The runtime uses a small polling bridge to receive messages and callback actions, routes them through the orchestrator, and renders the result back into Telegram-friendly text, HTML, buttons, and optional patch attachments.

Setup

JARVIS reads Telegram configuration from environment variables in src/jarvis/settings.py.

Required variables:

  • JARVIS_TELEGRAM_BOT_TOKEN for the bot token created with BotFather
  • JARVIS_TELEGRAM_ALLOWED_CHAT_IDS for the comma-separated allowlist of chat IDs

Optional variable:

  • JARVIS_TELEGRAM_POLL_TIMEOUT_SECONDS to control long-poll duration

Example:

bash
export JARVIS_TELEGRAM_BOT_TOKEN="123456:example-token"
export JARVIS_TELEGRAM_ALLOWED_CHAT_IDS="123456789"
export JARVIS_TELEGRAM_POLL_TIMEOUT_SECONDS="30"
python -m jarvis.main

If the bot token is missing, src/jarvis/main.py does not start the Telegram polling loop. It falls back to a local sample flow and prints a /status response to stdout.

Runtime Flow

The Telegram path is wired in src/jarvis/main.py.

text
Telegram user
  -> Telegram Bot API
  -> TelegramBridge.get_next_instruction()
  -> OrchestratorAgent
  -> TelegramPresenter
  -> TelegramBridge.send_response() / send_document()

The concrete behavior is:

  1. TelegramBridge long-polls getUpdates for message and callback_query.
  2. Incoming chat IDs are checked against JARVIS_TELEGRAM_ALLOWED_CHAT_IDS.
  3. Normal text messages are normalized into TelegramInstruction.
  4. OrchestratorAgent.handle_telegram_instruction() routes and executes the request.
  5. TelegramPresenter formats the structured result into Telegram-ready output.
  6. TelegramBridge.send_response() sends the message back, splitting long replies when needed.
  7. If a diff attachment is present, send_document() uploads it as a file.

How Interaction Works

Plain messages

Normal messages are handled as instructions. The orchestrator decides whether they are:

  • authority commands such as /write
  • workspace queries
  • repo activation requests
  • code-change proposals
  • approval or rejection replies

Workspace responses and code-change previews are rendered as HTML so Telegram can show structured headings, inline code, and formatted previews.

Approval buttons

For pending code changes, JARVIS can render inline buttons built in src/jarvis/presentation/telegram/keyboards.py:

  • Approve
  • Reject

Those buttons carry compact callback payloads of the form approve:<pending_change_id> and reject:<pending_change_id>.

When a user taps one:

  1. Telegram sends a callback_query.
  2. TelegramBridge extracts callback_data.
  3. OrchestratorAgent.handle_callback_payload() parses the action.
  4. The orchestrator resolves the pending change for that chat.
  5. The approval or rejection path is dispatched through the canonical pending-change flow.
  6. JARVIS answers the callback query to stop Telegram's loading spinner.
  7. The resulting status message is sent back into the chat.

Screens

Code review flow

Telegram code review flow

Action flow

Telegram action flow

Relevant Source Files

  • src/jarvis/main.py
  • src/jarvis/services/telegram_bridge.py
  • src/jarvis/presentation/telegram/presenter.py
  • src/jarvis/presentation/telegram/formatters.py
  • src/jarvis/presentation/telegram/keyboards.py
  • src/jarvis/presentation/telegram/callbacks.py