通过 RPC 推送告警到 Telegram
1. 场景说明
ThinkLink(TKL)平台的 RPC 支持调用外部 HTTP 接口(见 RPC 模型 §1.3.2 类型四),可以把设备告警实时推送到 Telegram。本文介绍如何创建 Telegram Bot 并在 RPC 中向指定 Chat / Channel / Group 推送消息。
2. 准备工作
2.1 创建 Telegram Bot
- 在 Telegram 中搜索 @BotFather,发送
/newbot - 按提示设置 Bot 名称(display name)和用户名(必须以
bot结尾) - BotFather 会返回 Bot Token,形如:
123456789:AAEhBPxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2.2 获取 Chat ID
- 把 Bot 加入目标群组 / 频道(频道需要把 Bot 设为管理员)
- 在目标 chat 中随便发一条消息
- 浏览器访问
https://api.telegram.org/bot<TOKEN>/getUpdates,从返回的 JSON 中找到chat.id字段 - 群组 ID 通常是负数(如
-1001234567890),个人 chat ID 是正数
2.3 妥善保管 Bot Token(必读)
⚠️ 安全提示:Bot Token 等同于 Bot 的完全控制权 —— 持有者可以伪造 Bot 发送的所有消息、读取 Bot 所在群的所有消息(如果开启了 Privacy Mode 关闭)、踢出 Bot 等。
请遵守以下规则:
- 不要把 Bot Token 硬编码进脚本、配置文件、截图,也不要写进公开仓库(GitHub 的扫描机制会自动检测泄漏的 Telegram Token)
- 推荐做法:把 Token 保存在设备(或资产)的
server_attrs中,脚本里通过device.server_attrs.tg_token引用 - 一旦发现 Token 泄漏,立即在 @BotFather 发送
/revoke撤销旧 Token 并生成新的 - 启用 Bot 的 Privacy Mode(默认开启),避免 Bot 读取群中无关消息
- 为不同业务场景使用不同的 Bot(生产 / 测试 / 内部),降低单点泄漏影响范围
- 如果 Bot 仅用于推送,建议在 BotFather 的 Bot Settings → Group Privacy 中保持开启
3. 在 RPC 中调用 Telegram
3.1 在设备属性中保存凭证
在 运维管理 → 设备管理 → 设备详情 → 属性 标签下,为 server_attrs 添加:
json
{
"tg_token": "123456789:AAEhBPxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"tg_chat_id": "-1001234567890"
}3.2 RPC 脚本:发送 Markdown 消息
Telegram 支持 Markdown 与 MarkdownV2 两种格式,下面使用 MarkdownV2(更稳定,但需对特殊字符做转义):
javascript
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 必须转义的字符:_ * [ ] ( ) ~ ` > # + - = | { } . !
let esc = (s) => String(s ?? "").replace(/([_*\[\]()~`>#+\-=|{}.!])/g, "\\$1");
let text = [
`*🚨 设备告警通知*`,
``,
`*设备名称:* ${esc(device.name)}`,
`*设备 EUI:* \`${esc(device.eui)}\``,
`*告警等级:* ${esc((params.level || "").toUpperCase())}`,
`*告警内容:* ${esc(params.desc || "无")}`,
`*时间:* ${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
}
}
];
}💡 部署 TKL 的服务器需要能够访问
api.telegram.org。如果网络环境受限,可通过代理服务器转发请求。
3.3 RPC 脚本:发送纯文本消息
javascript
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} 告警通知`
},
timeout: 10000
}
}
];
}4. 配置 RPC 参数
| 字段标识 | 类型 | 别名 | 说明 |
|---|---|---|---|
content | string | 消息内容 | 纯文本模式使用 |
level | string | 告警等级 | low / mid / high / urgent |
desc | string | 告警描述 | Markdown 模式下的详情 |
5. 集成到告警流程
参考 企业微信 AN 中的触发联动示例,把 method 改成本 RPC 的 Method 名即可。
6. 故障排查
| 现象 | 可能原因 |
|---|---|
Telegram 返回 Unauthorized | Bot Token 错误或已被吊销 |
返回 chat not found | Chat ID 错误;Bot 还未加入目标群组;频道未将 Bot 设为管理员 |
返回 Bad Request: can't parse entities | MarkdownV2 文本中有未转义的特殊字符 |
| 请求超时 | 服务器到 api.telegram.org 网络不通;建议增大 timeout 至 10000+ ms |
| 频率限制 | 同一个 chat 1 秒内不超过 1 条;不同 chat 每秒不超过 30 条 |
7. 注意事项
- Telegram 群组 ID 是负数,不要误填成正数,否则会向某个用户私聊推送
- 消息中不要泄漏 Bot Token 自身(例如不要把异常堆栈直接放进消息)
- 用 MarkdownV2 时,对所有动态内容(设备名、告警描述等)都要执行字符转义
- 重要告警建议同时配置多个通道(如 Telegram + 邮件),避免网络异常导致漏报