Telegram Bot
Get a Telegram bot agent running in three steps. For the full trigger reference, see Triggers.
Prerequisites
- InitRunner installed (
pip install initrunneroruv tool install initrunner) - An API key for your provider (
OPENAI_API_KEY,ANTHROPIC_API_KEY, etc.) - The Telegram optional dependency:
uv sync --extra telegram(orpip install initrunner[telegram])
Step 1: Create a Bot with BotFather
- Open Telegram and search for @BotFather.
- Send
/newbotand follow the prompts to choose a name and username. - BotFather replies with a token — copy it. You'll need it in Step 2.
Step 2: Set Environment Variables
export TELEGRAM_BOT_TOKEN="your-token-here"
export OPENAI_API_KEY="your-api-key" # or your provider's keyOr, to persist keys across sessions, add them to ~/.initrunner/.env:
TELEGRAM_BOT_TOKEN=your-token-here
OPENAI_API_KEY=your-api-keyA .env file next to your role.yaml also works. Running initrunner setup writes the provider key there automatically. Existing environment variables always take precedence over .env values.
Step 3: Create a Role and Run
Create a role.yaml:
apiVersion: initrunner/v1
kind: Agent
metadata:
name: telegram-assistant
description: A Telegram bot that responds to messages via long-polling
spec:
role: |
You are a helpful assistant responding to Telegram messages.
Keep responses concise and well-formatted for mobile reading.
model:
provider: openai
name: gpt-5-mini
temperature: 0.1
max_tokens: 4096
triggers:
- type: telegram
token_env: TELEGRAM_BOT_TOKEN
guardrails:
max_tokens_per_run: 50000
daemon_daily_token_budget: 200000Start the daemon:
initrunner daemon role.yamlYou should see Telegram bot started polling in the logs.
Quick Alternative
To test without creating a role file:
initrunner chat --telegramAuto-detects your provider, launches an ephemeral bot with minimal tools and persistent memory enabled by default. Use --tool-profile all for everything, or add individual tools with --tools:
# Enable every available tool
SLACK_WEBHOOK_URL="https://hooks.slack.com/..." initrunner chat --telegram --tool-profile all
# Or add specific extras
initrunner chat --telegram --tools git --tools shell
# Restrict to specific users by ID (recommended) or username
initrunner chat --telegram --allowed-user-ids 123456789
initrunner chat --telegram --allowed-users alice --allowed-users bob
# Disable memory if not needed
initrunner chat --telegram --no-memoryRun initrunner chat --list-tools to see all available tool types.
For production, use the role.yaml approach above for access control and budgets. See Chat.
Testing
- Send a plain text message to your bot in Telegram.
- Long responses are automatically chunked at 4096-character boundaries.
/start,/help, and other commands are ignored — only plain text messages are processed.
Configuration Options
All options go under spec.triggers[].:
| Field | Type | Default | Description |
|---|---|---|---|
token_env | str | "TELEGRAM_BOT_TOKEN" | Environment variable holding the bot token. |
allowed_users | list[str] | [] | Telegram usernames allowed to interact. Empty = allow everyone. |
allowed_user_ids | list[int] | [] | Telegram user IDs allowed to interact. Empty = allow everyone. |
prompt_template | str | "{message}" | Template for the prompt. {message} is replaced with the user's text. |
Example with restrictions:
triggers:
- type: telegram
token_env: TELEGRAM_BOT_TOKEN
allowed_users: ["alice", "bob"]
allowed_user_ids: [123456789, 987654321]
prompt_template: "Telegram user asks: {message}"Security and Public Access
By default the bot responds to anyone who messages it. Lock it down before making it available to others:
- Prefer
allowed_user_idsoverallowed_users. Usernames are mutable — users can change them at any time. User IDs are permanent. Find your ID via @userinfobot. - Use
allowed_usersto restrict access by Telegram username. When eitherallowed_usersorallowed_user_idsis non-empty, messages from unmatched users are silently ignored. - Union semantics: access is granted if the user matches either
allowed_usersorallowed_user_ids. Both fields can be set together. - Set
daemon_daily_token_budgetin guardrails to cap API costs. Without a budget, a public bot can run up unlimited charges. - Keep the bot token secret. Anyone with the token can impersonate the bot. Never commit it to version control — use environment variables or a secrets manager.
- If the bot has access to tools (filesystem, HTTP, shell, etc.), restrict to known users only. An unrestricted bot lets strangers invoke those tools through the bot.
Troubleshooting
ModuleNotFoundError: No module named 'telegram'
The optional dependency is not installed. Run:
uv sync --extra telegram
# or
pip install initrunner[telegram]Env var TELEGRAM_BOT_TOKEN not set
Export the token before starting the daemon:
export TELEGRAM_BOT_TOKEN="your-token-here"Bot ignores messages
Only plain text messages are processed. /start, /help, and other slash commands are filtered out. Make sure you're sending a regular text message.