Skip to content

通过 RPC 推送告警到 Telegram

1. 场景说明

ThinkLink(TKL)平台的 RPC 支持调用外部 HTTP 接口(见 RPC 模型 §1.3.2 类型四),可以把设备告警实时推送到 Telegram。本文介绍如何创建 Telegram Bot 并在 RPC 中向指定 Chat / Channel / Group 推送消息。

2. 准备工作

2.1 创建 Telegram Bot

  1. 在 Telegram 中搜索 @BotFather,发送 /newbot
  2. 按提示设置 Bot 名称(display name)和用户名(必须以 bot 结尾)
  3. BotFather 会返回 Bot Token,形如:
    123456789:AAEhBPxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

2.2 获取 Chat ID

  1. 把 Bot 加入目标群组 / 频道(频道需要把 Bot 设为管理员)
  2. 在目标 chat 中随便发一条消息
  3. 浏览器访问 https://api.telegram.org/bot<TOKEN>/getUpdates,从返回的 JSON 中找到 chat.id 字段
  4. 群组 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 支持 MarkdownMarkdownV2 两种格式,下面使用 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 参数

字段标识类型别名说明
contentstring消息内容纯文本模式使用
levelstring告警等级low / mid / high / urgent
descstring告警描述Markdown 模式下的详情

5. 集成到告警流程

参考 企业微信 AN 中的触发联动示例,把 method 改成本 RPC 的 Method 名即可。

6. 故障排查

现象可能原因
Telegram 返回 UnauthorizedBot Token 错误或已被吊销
返回 chat not foundChat ID 错误;Bot 还未加入目标群组;频道未将 Bot 设为管理员
返回 Bad Request: can't parse entitiesMarkdownV2 文本中有未转义的特殊字符
请求超时服务器到 api.telegram.org 网络不通;建议增大 timeout 至 10000+ ms
频率限制同一个 chat 1 秒内不超过 1 条;不同 chat 每秒不超过 30 条

7. 注意事项

  • Telegram 群组 ID 是负数,不要误填成正数,否则会向某个用户私聊推送
  • 消息中不要泄漏 Bot Token 自身(例如不要把异常堆栈直接放进消息)
  • 用 MarkdownV2 时,对所有动态内容(设备名、告警描述等)都要执行字符转义
  • 重要告警建议同时配置多个通道(如 Telegram + 邮件),避免网络异常导致漏报