Telegram
Datafly Signal delivers events server-to-server to the Telegram Bot API, posting a formatted chat message for each matched event. Use it for operational and sales alerting — a message in your team’s channel when an order completes, a sign-up happens, or a lead is captured. Because delivery is server-side, no bot token is ever exposed in the browser.
Prerequisites
-
A Telegram bot. Create one by messaging @BotFather, running
/newbot, and copying the HTTP API token it returns (looks like123456789:ABCdef…). -
A destination chat ID:
- Private chat — a positive integer. The recipient must send
/startto your bot first. - Group / supergroup — a negative integer (supergroups are prefixed
-100). The bot must be a member of the group. - Channel —
-100…or the public@channelusername. The bot must be an admin of the channel to post.
The quickest way to find a chat ID: add the bot to the chat, send a message, then open
https://api.telegram.org/bot<token>/getUpdatesand readresult[].message.chat.id. - Private chat — a positive integer. The recipient must send
Configuration
| Field | Required | Description |
|---|---|---|
| Bot Token | Yes | The HTTP API token from @BotFather. Verify it with https://api.telegram.org/bot<token>/getMe (returns ok: true). Stored as a secret. |
| Chat ID | Yes | Default destination for messages. Can be overridden per event in the blueprint. |
Configure in Signal
- In the management UI, go to Integrations and add Telegram.
- Paste your Bot Token and Chat ID.
- Attach the integration to a pipeline and select the Conversion Alerts preset (or build your own event mappings).
- Save. Signal begins posting messages for matched events.
API Endpoint
Signal sends each event as a POST to:
https://api.telegram.org/bot<token>/sendMessageThe bot token is carried in the URL path — Telegram has no separate authorization header. The request body is JSON:
{
"chat_id": "-1001234567890",
"text": "🛒 Order completed\nOrder: 1234\nValue: 49.99 GBP",
"parse_mode": "HTML",
"disable_notification": false
}A success response is { "ok": true, "result": { … } }. Failures return { "ok": false, "error_code": <int>, "description": "…" } with a matching HTTP status (400 bad request, 401 invalid token, 403 bot blocked or not an admin). Rate-limit responses (429) include a retry_after and are retried automatically.
Identity Signals
Telegram is a human-readable notification channel, not an identity-resolution destination, so there are no hashed match keys (no email/phone). Messages are delivered to a fixed chat, not matched to individual user profiles. Avoid putting raw customer PII into message text on a shared channel.
Consent is still respected: the Conversion Alerts preset maps context.consent.canonical.marketing to disable_notification, so when marketing consent is not granted the message is delivered silently (no push sound) rather than withheld — the operational alert still reaches your team without an attention-grabbing notification.
Event Mapping
The default preset maps three high-value events; everything else is dropped (defaults.action: drop) so high-frequency events like page views never flood the chat.
| Signal event | Telegram method | Message |
|---|---|---|
Order Completed | sendMessage | Order ID + value |
Signed Up | sendMessage | Sign-up method |
Lead Generated | sendMessage | Lead value |
The message body is built from event properties using templated static values, so you control exactly what appears in the chat.
Example
A Datafly.js call:
datafly.track("Order Completed", {
order_id: "1234",
revenue: 49.99,
currency: "GBP"
});produces this Telegram request body:
{
"chat_id": "-1001234567890",
"text": "🛒 <b>Order completed</b>\nOrder: <code>1234</code>\nValue: 49.99 GBP",
"parse_mode": "HTML",
"disable_notification": false
}which appears in your chat as:
🛒 Order completed Order:
1234Value: 49.99 GBP
To route a specific event to a different chat, add a mapping with target chat_id. To post into a forum topic of a supergroup, add a mapping with target message_thread_id.
Testing
-
With your bot token, confirm the bot is reachable: open
https://api.telegram.org/bot<token>/getMe— you should see{ "ok": true }. -
Send a test message manually to confirm the chat is reachable:
curl -X POST "https://api.telegram.org/bot<token>/sendMessage" \ -H "Content-Type: application/json" \ -d '{"chat_id":"<chat_id>","text":"Signal test ✅"}'A
200with"ok": truemeans the bot can post to that chat. -
Trigger one of the mapped events (e.g. complete a test order) and confirm the message arrives in the chat.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
401 Unauthorized | Invalid bot token | Re-copy the token from @BotFather; check for stray spaces. |
400 chat not found | Wrong chat ID, or bot never interacted with the chat | Re-check the ID via getUpdates; for private chats the user must /start the bot first. |
403 bot was blocked by the user | Recipient blocked the bot | Nothing to fix server-side; the user must unblock the bot. |
403 need administrator rights | Posting to a channel without admin | Make the bot an admin of the channel. |
400 can't parse entities | Invalid HTML/MarkdownV2 in the message text | Fix the markup, or remove parse_mode to send plain text. |
429 Too Many Requests | Sending faster than Telegram allows | Handled automatically (Signal retries after retry_after); reduce alert volume for very busy pipelines. |
| No message arrives, no error | Event dropped by the blueprint | Confirm the event name is in the preset’s events map (others are dropped by default). |