Skip to main content

Messaging Gateway — Telegram Bot

Talk to your data from Telegram. The same QRY brain — workspaces, datasources, RBAC, scheduled tasks, alerts — accessible from your phone via a chat with the bot.

Status

Production Ready — Telegram is live. WhatsApp is on the roadmap and reuses the same backend.

Overview

The Messaging Gateway exposes QRY to chat platforms without duplicating any of the platform's logic. The Telegram bot speaks to the gateway, the gateway runs the request through the same worker pipeline that powers the web UI, and the response comes back in a phone-friendly format.

Three things you can do with it:

  • Notifications: in-app notifications fan out to your Telegram chat automatically (bell-toggleable per token).
  • Scheduled deliveries: ask the bot to schedule a query and have the result delivered to this chat at a specific time, daily, weekly…
  • Conditional alerts: tell the bot to watch a condition and only ping you when something requires attention, with a cooldown to avoid spam.

Quick start

1. Get a token

In the web UI, open Settings → Messaging Tokens and click Create token. The plaintext token (qry_msg_…) is shown once — copy it. Toggle the 🔔 bell on the token to receive notifications via Telegram.

2. Connect to the bot

Open Telegram and find your tenant's bot (your admin can share its handle, e.g. @qryai_bot). Then:

/start
/login qry_msg_xxxxxxxxxxxx

You're authenticated. The bot remembers your session and, if you have multiple chats with it, your tokens for fan-out delivery.

3. Pick a workspace and ask

/ws Sales
What were our top 10 customers last month?

The bot replies with the answer in plain text or a small chart. Done.

Personal commands

The bot is stateful per chat: workspace, datasource, model, and the active conversation are remembered between messages.

CommandPurpose
/login <token>Authenticate with a qry_msg_* token
/logoutForget the session in this chat
/whoamiShow who you are and which workspace / datasource / model are active
/ws [name]Pick a workspace by name (fuzzy match) or open the picker
/ds [name]Pick a datasource (fuzzy match) — overrides the workspace default
/model [name]Override the LLM model for this chat
/newStart a fresh conversation thread

Workspace defaults (catalog, schema, datasource) are auto-applied when you switch with /ws — same behaviour as the web UI when you open a workspace.

Conversation commands

CommandPurpose
/shareMake the current conversation public and return a link
/lastSend back the most recent assistant reply (handy after losing the chat scroll)
/recentShow the last 5 conversations as buttons; tap to resume
/cancelInterrupt the in-flight request (also responds to ESC if your client supports it)

/share returns a URL pointing at your tenant's public host — the same link works in any browser.

Notifications

When the platform writes an in-app notification (job done, scheduled task completed, alert fired, etc.) the gateway can fan it out to your Telegram chats automatically.

To enable: go to Settings → Messaging Tokens and toggle the 🔔 on the tokens that should receive notifications. Multiple chats are supported — every chat that did /login with one of those tokens receives the message.

To mute: toggle the bell off on the token. Scheduled deliveries (see below) are NOT affected — those bypass the opt-in because you explicitly scheduled them.

Scheduled deliveries

Schedule a task and have its result delivered straight to the Telegram chat that asked for it.

You: Every Monday at 9am, count last week's signups
and send the result here.

The bot creates a scheduled task with output_type='telegram' and the platform routes the result to this chat. No separate setup needed — the bot already knows your chat from the active session.

One-off deliveries work the same way: "schedule a one-time task in 30 minutes…" — the platform fires it, runs the prompt, and pushes the answer to Telegram once.

If the bot fails to deliver three times in a row (revoked token, bot blocked, network outage), the task is auto-disabled. Re-enable from Scheduled Tasks in the web UI.

Conditional alerts

Conditional alerts are scheduled tasks that only deliver when a condition is met, with a cooldown to prevent spam during noisy events.

You: Watch our daily error rate and alert me here if it
goes above 1%. Cooldown 30 minutes.

How it works:

  1. The bot creates a recurring task tagged is_alert=true with the cooldown you specified.
  2. On each tick the LLM evaluates the condition and ends its reply with [ALERT_FIRE] or [ALERT_OK].
  3. The platform delivers only on [ALERT_FIRE] AND elapsed cooldown. Quiet evaluations and cooldown-suppressed fires are silent.
  4. The marker is stripped from the message you actually receive.

This makes it safe to run alerts every minute on noisy data — you'll only hear from the bot when something actually warrants your attention.

Tuning the cooldown: the default is 60 minutes. Set it to 0 to fire on every breach (spammy on noisy conditions); set it longer for slow-moving signals.

Workspaces and access control

Telegram requests go through the same workspace membership and RBAC checks as the web UI:

  • The bot's /ws listing only includes workspaces you're a member of.
  • /ds only shows datasources you have RBAC permission on.
  • ABAC tag-based row filtering applies to every query the bot runs on your behalf.
  • A qry_msg_* token is scoped to one user — there's no token sharing across users.

Configuration (admins)

The Telegram integration is configured entirely from the admin UI — no env vars, no Kubernetes Secrets to rotate.

System Settings → Messaging:

  • Telegram enabled — master toggle. The bot supervisor reconciles every 30s, so flipping the toggle takes effect within the minute.
  • Telegram bot token — from BotFather. Stored encrypted; rotating it triggers a reconnect.
  • API base URL — defaults to https://api.telegram.org; only override for self-hosted Telegram Bot API.
  • Default LLM model — the model used when a request doesn't specify one (typical for messaging adapters).
  • Per-token rate limit — defaults to 30 messages/minute per token.

Telegram bot deployment: a single Kubernetes Deployment (replicas: 1 hardcoded — Telegram only allows one long-poller per token; strategy: Recreate avoids 409 conflicts on rollout). The pod stays up whether or not Telegram is enabled, reconciles config every 30s, and reconnects automatically on token rotation.

Limitations

  • One Telegram chat is one QRY user. To switch users, /logout then /login with a different token.
  • Telegram's per-message limit is 4096 chars. The bot paginates longer answers across messages, breaking on paragraph / sentence / word boundaries.
  • The bot uses Markdown for emphasis (single *bold*, _italic_, `code`). Tables, headers, and fenced code blocks are intentionally avoided — they don't render well on phones.
  • Charts are sent as inline images (matplotlib/seaborn). Plotly's interactive HTML doesn't display inline; if the LLM produces one anyway, you'll get a still preview only.
  • File downloads work for Excel, PDF, and similar non-trivial outputs (the executor captures them when the code imports openpyxl, reportlab, etc.). Plain pd.to_csv is silently dropped — if you need a CSV, ask for it via Excel format or with import openpyxl first.
  • /cancel interrupts the in-flight LLM call but cannot rewind already-sent messages.

Troubleshooting

The bot doesn't reply to /login

Check that the Telegram integration is enabled in System Settings → Messaging and that the bot token is correct. The supervisor reconciles every 30s, so wait up to a minute after toggling.

"Need /login" loop after a known-good token

Token may have been revoked from the web UI. Issue a fresh one in Settings → Messaging Tokens.

Schedule says "send to Telegram" but result doesn't arrive

Verify the scheduled task in the web UI under Scheduled Tasks:

  • output_type should be telegram
  • the chat_id should match yours
  • consecutive_failures should be 0; if 3+ the task auto-disabled (revoked token / bot blocked)

Alert fires too often / not often enough

Adjust cooldown_minutes in the task. Set to 0 for instant repeats, or longer (60+) for slow-moving signals. The cooldown is measured from the last actual delivery, so cooldown-suppressed evaluations don't reset the clock.

/share returns a localhost URL

The tenant's public URL isn't configured. Set application.public_url in System Settings. The bot reads it directly from the system configuration table, so changes take effect immediately.

See also


WhatsApp

WhatsApp support is on the roadmap. The same gateway and bot supervisor pattern apply, so when it ships your scheduled tasks and notification preferences carry over. Stay tuned to the release notes.

QRYA product of IXEN.