Telegram (jims-telegram)
jims-telegram is a Telegram bot built on aiogram wrapping the JIMS pipeline.
Running
TELEGRAM_BOT_TOKEN="123456:ABC..." \
uv run jims-telegram \
--app vedana_core.app:app \
--enable-sentry \
--metrics-port 8000
In docker-compose the tg service is commented out (lines # tg: ...), because in production it’s typically deployed separately with its own secret and scaling. Enable it by analogy with the other services:
tg:
<<: *app-common
command: uv run python -m jims_telegram.main
depends_on:
db-migrate:
condition: service_completed_successfully
memgraph:
condition: service_started
db:
condition: service_healthy
CLI
| Flag | Default | Description |
|---|---|---|
--app | app | JIMS app |
--enable-sentry | off | Sentry |
--enable-healthcheck | on | bring up /health on --healthcheck-port |
--healthcheck-port | 9000 | healthcheck port |
--metrics-port | 8000 | Prometheus |
--verbose | off | debug logs |
Getting a token
- Find
@BotFatheron Telegram. /newbot→ set a name → receive a token./setdescription,/setabouttext,/setuserpic— branding./setcommands— set commands (start - restart,help - help).
Save the token in .env:
TELEGRAM_BOT_TOKEN="123456789:AA..."
Default behaviour
When the bot is started (TelegramController.create(jims_app).run()):
- Each Telegram chat becomes a separate JIMS thread.
contact_idis built from the Telegram user id.thread_configcontains{"interface": "telegram", ...}— you can use that in your pipeline for channel-specific behaviour.- The
/startcommand always creates a new JIMS thread (it does not reuse the existing one) and then runs theconversation_start_pipeline(StartPipeline), which reads the welcome message fromConversationLifecycle["/start"]. The literal text of the command ("/start"plus any payload after a space) is also stored on the new thread as the first user message viastore_user_message, so it appears in the thread’s event log. Previous chat history for that contact stays in the database but is no longer used as conversation context. If you want/startto resume an existing thread, you’ll need to subclassTelegramController.command_start. - Every text message runs the main pipeline (
RagPipeline).
Intermediate status updates (update_agent_status) are surfaced as “typing…” via the Telegram Bot API (sendChatAction).
Markdown to Telegram
md2tgmd.py is a utility that converts Markdown answers from the LLM into Telegram’s MarkdownV2 format. Without it, Telegram chops off asterisks/underscores. The utility escapes special characters and keeps **bold**, _italic_, inline code, and quotes working.
Healthcheck
Alongside aiogram the bot brings up an aiohttp server with /health and /healthz on --healthcheck-port (default 9000). Useful for:
- Kubernetes liveness/readiness;
- load balancers;
- “is the bot alive?” monitoring.
Security
- Never commit
TELEGRAM_BOT_TOKENto the repository. - For corporate bots, use a
chat_idallow-list (you can add it in yourPipelineand ignore disallowed users). - Before going to production, enable rate limiting on the Vedana side (via aiogram middleware or an external reverse proxy).
What’s next
- Architecture: JIMS Core — thread internals.
- HTTP API — for non-Telegram integrations.