Push Alerts to Telegram via RPC
1. Overview
ThinkLink (TKL) RPC can call external HTTP endpoints (see RPC Model §1.3.2 Type 4) and forward device alerts to Telegram in real time. This note shows how to create a Telegram Bot and send messages to a chat, channel, or group from an RPC.
2. Prerequisites
2.1 Create a Telegram Bot
- In Telegram, search for @BotFather and send
/newbot - Follow the prompts to set the bot's display name and username (must end with
bot) - BotFather returns a Bot Token that looks like:
123456789:AAEhBPxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2.2 Get the Chat ID
- Add the bot to the target group/channel (for channels, set the bot as admin)
- Send any message in the target chat
- Open
https://api.telegram.org/bot<TOKEN>/getUpdatesin a browser and find thechat.idfield in the JSON response - Group IDs are usually negative (e.g.
-1001234567890); personal chat IDs are positive
2.3 Protect the Bot Token (Required Reading)
⚠️ Security notice: The Bot Token is equivalent to full control of the bot — anyone holding it can forge every message the bot sends, read all messages in the bot's groups (if Privacy Mode is off), and remove the bot.
Follow these rules:
- Do not hard-code the Bot Token into scripts, config files, or screenshots, and never commit it to public repositories (GitHub's secret scanner automatically detects leaked Telegram tokens)
- Recommended: Store the token in the device's (or asset's)
server_attrsand reference it viadevice.server_attrs.tg_token - If you suspect a leak, immediately send
/revoketo @BotFather to invalidate the old token and generate a new one - Keep the bot's Privacy Mode enabled (default) so it cannot read unrelated group messages
- Use different bots for different environments (prod / staging / internal) to limit blast radius
- If the bot is push-only, keep Group Privacy enabled in BotFather → Bot Settings
3. Calling Telegram from an RPC
3.1 Store Credentials in server_attrs
In Operations → Device Management → Device Detail → Attributes, add to server_attrs:
{
"tg_token": "123456789:AAEhBPxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"tg_chat_id": "-1001234567890"
}3.2 RPC Script: Markdown Message
Telegram supports Markdown and MarkdownV2. The example below uses MarkdownV2 (more robust, but requires escaping special characters):
function rpc_script({ device, params, alarms, logger }) {
let token = device.server_attrs?.tg_token;
let chatId = device.server_attrs?.tg_chat_id;
if (!token || !chatId) {
logger.error("telegram credentials not configured", { eui: device.eui });
return null;
}
// MarkdownV2 reserved characters: _ * [ ] ( ) ~ ` > # + - = | { } . !
let esc = (s) => String(s ?? "").replace(/([_*\[\]()~`>#+\-=|{}.!])/g, "\\$1");
let text = [
`*🚨 Device Alert*`,
``,
`*Device:* ${esc(device.name)}`,
`*EUI:* \`${esc(device.eui)}\``,
`*Level:* ${esc((params.level || "").toUpperCase())}`,
`*Description:* ${esc(params.desc || "n/a")}`,
`*Time:* ${esc(new Date().toISOString())}`
].join("\n");
return [
{
sleepTimeMs: 0,
type: "axios",
dnMsg: {
method: "POST",
url: `https://api.telegram.org/bot${token}/sendMessage`,
headers: { "Content-Type": "application/json" },
data: {
chat_id: chatId,
text: text,
parse_mode: "MarkdownV2",
disable_web_page_preview: true
},
timeout: 10000
}
}
];
}💡 The TKL server must be able to reach
api.telegram.org. If direct access is not available in your network environment, configure a proxy to forward the requests.
3.3 RPC Script: Plain Text Message
function rpc_script({ device, params, alarms, logger }) {
let token = device.server_attrs?.tg_token;
let chatId = device.server_attrs?.tg_chat_id;
if (!token || !chatId) return null;
return [
{
sleepTimeMs: 0,
type: "axios",
dnMsg: {
method: "POST",
url: `https://api.telegram.org/bot${token}/sendMessage`,
headers: { "Content-Type": "application/json" },
data: {
chat_id: chatId,
text: params.content || `${device.name} alert`
},
timeout: 10000
}
}
];
}4. RPC Parameter Configuration
| Attr Name | Type | Alias | Description |
|---|---|---|---|
content | string | Message content | Used in plain-text mode |
level | string | Alert level | low / mid / high / urgent |
desc | string | Alert description | Markdown-mode body text |
5. Wiring into the Alert Flow
See WeCom AN §5 for the trigger script example — just change method to the name of this RPC.
6. Troubleshooting
| Symptom | Likely Cause |
|---|---|
Unauthorized | Wrong or revoked Bot Token |
chat not found | Wrong Chat ID; bot not yet in the target group; channel did not promote the bot to admin |
Bad Request: can't parse entities | Unescaped special characters in MarkdownV2 |
| Request timeout | TKL server cannot reach api.telegram.org; increase timeout to 10000+ ms |
| Rate limit | Max 1 message per second per chat; max 30 messages per second across all chats |
7. Notes
- Group chat IDs are negative — do not convert them to positive, or messages will go to a private chat with someone else
- Do not put the Bot Token itself in messages (e.g. don't dump full request bodies or stack traces)
- With MarkdownV2, escape every piece of dynamic content (device names, descriptions, etc.)
- For critical alerts, configure multiple notification channels (e.g. Telegram + email) so network issues do not silence alerts