Telegram (Integrations)
Integration-tile view. For inbox behaviour, see Chat Inbox → Telegram.
Connecting
The simplest integration on the list. From @BotFather:
- Send
/newbot. - Provide display name +
_bot-suffixed username. - Copy the Bot Token (
123456789:ABCDef…).
On Kinderpedia: Integrations → Telegram → Connect → paste the token. We validate via GET /getMe. Done.
No Business Manager, no admin approval queue, no consent dialog.
Webhook auto-registration
After validation, we auto-register the webhook via:
POST /bot{TOKEN}/setWebhook
{
"url": "https://<your-domain>/api/integrations/telegram/webhook",
"secret_token": "<random-per-school>",
"allowed_updates": ["message", "callback_query", "edited_message", "chat_member"]
}The secret_token is a per-school random string we generate and save with the integration. Inbound webhooks must carry it in the X-Telegram-Bot-Api-Secret-Token header — mismatches are 401'd.
You don't need to do anything on Telegram's side after Connect — the registration is API-driven.
Bot info display
The tile shows:
- Bot display name + username
- Avatar
- Last webhook event timestamp
- Connection health
The avatar / display name are pulled once at connect time. If you rename the bot in BotFather, re-click Refresh on the tile to update.
Bot commands
setMyCommands defines the / autocomplete list users see when typing. Default shipped:
| Command | Purpose |
|---|---|
/start | Begin conversation (with optional payload like /start ref_lead_42) |
/help | Quick instructions |
/contact | Trigger contact-share prompt |
Customise via Integrations → Telegram → Configure commands. We update the bot's command list via setMyCommands.
QR codes for bot deep-links
Telegram supports deep-link URLs of the form https://t.me/<botusername>?start=<payload>. The payload (≤64 chars) is auto-supplied as the /start command argument when the user clicks the link.
The public form's post-submit page renders a Telegram QR when this channel is connected. The QR encodes a deep-link with payload = ref_lead_<id>, which our handler decodes on receipt to auto-link the new conversation to the lead.
Privacy mode
Bots in group chats are in "privacy mode" by default — they only see messages that explicitly mention them (@yourbot) or reply to one of their messages. We don't currently support group chats in the inbox, so this doesn't matter for the standard flow.
If you ever flip privacy mode off (via BotFather → /setprivacy), the bot will start receiving every message in any group it's in. We still drop group inbounds; this would just generate more webhook traffic for no benefit.
No 24-hour window
Telegram has no customer-service window. Once a user has tapped Start on your bot, you can message them anytime. The only blockers:
- User blocks the bot (Telegram delivers a
chat_memberevent reflecting this; we mark the thread Blocked) - User deletes their Telegram account (sends return "chat not found")
Disconnecting
Disconnect:
- Calls
deleteWebhookto un-register from Telegram. - Clears credentials.
- Marks row
disconnected.
The bot account itself stays alive in BotFather — we just sever the link. Re-connecting later with the same token restores the integration (no need to recreate the bot).
Common errors
| Symptom | Likely cause |
|---|---|
| Connect rejects with "Unauthorized" | Token revoked / regenerated in BotFather. |
| Webhook events never arrive | Telegram's setWebhook returned 200 but the URL isn't reachable from outside. Verify your Kinderpedia domain serves HTTPS publicly. |
| Send returns "Forbidden: bot was blocked by the user" | User tapped Block. Thread → Blocked. |
| Send returns "chat not found" | User deleted their Telegram account. Mark thread Blocked. |
| User scans QR but no conversation appears | They didn't tap Start — Telegram only delivers webhook events after explicit user acceptance. |