Automatisch 集成 Telegram Bot:New Message Webhook 触发器的实现原理与配置指南
【免费下载链接】automatischThe open source Zapier alternative. Build workflow automation without spending time and money.项目地址: https://gitcode.com/GitHub_Trending/au/automatisch
本指南以 Telegram Bot 触发器文档 为骨架,深入解析 Automatisch 中 Telegram Bot 应用提供的New message触发器:它如何在消息到达机器人时被触发、如何通过setWebhook注册回调、如何配置允许接收的更新类型,以及如何将触发数据流转到后续动作。读完本文,你将能独立完成 Telegram Bot 的连接配置、触发器创建、更新类型筛选与消息内容解析,并理解其底层 Webhook 工作机制。
一、触发器总览:New message
在 Automatisch 的文档体系中,每个应用都通过triggers.md页面以列表形式声明其可用触发器。Telegram Bot 的 triggers.md 声明了当前应用唯一的一个触发器:
| 触发器名称 | 触发时机 |
|---|---|
| New message | 当有新消息发送给机器人时触发(Triggers when a new message is sent to the bot) |
从源码结构看,该触发器的注册入口在 triggers/index.js,它导出一个触发器数组,其中包含new-message这一唯一成员;同时 index.js 中通过defineApp({ key: 'telegram-bot', triggers, actions, ... })将触发器挂载到 Telegram 应用上,供流程编辑器按telegram-bot+ 触发器 key 检索使用。
二、前置条件:通过 BotFather 创建机器人并建立连接
在使用 New message 触发器之前,需要先在 Automatisch 中建立一个 Telegram 连接。官方连接文档 connection.md 给出了完整的接入步骤,核心流程如下:
- 在 Telegram 中与 @BotFather 开始对话;
- 发送
/newbot指令; - 输入你的机器人的显示名称(name);
- 输入机器人的用户名(username);
- 从 BotFather 返回的结果中复制token值,填入 Automatisch 的Bot token字段;
- 点击 Automatisch 上的Submit按钮提交;
- 连接建立成功,即可在流程中开始使用该 Telegram 连接。
从实现细节看,token 会被存储为连接的认证数据$.auth.data.token,并在每次 HTTP 请求前由 add-auth-header.js 注入:
const addAuthHeader = ($, requestConfig) => { if ($.auth.data?.token) { const token = $.auth.data.token; requestConfig.baseURL = new URL( `/bot${token}`, requestConfig.baseURL ).toString(); } return requestConfig; };也就是说,应用的apiBaseUrl(https://api.telegram.org,见 index.js)会被自动拼接为https://api.telegram.org/bot<你的token>形式,这正是 Telegram Bot API 的标准鉴权路径格式。这一步无需用户手动处理,属于 Automatisch 对 Bot API 鉴权约定的内置封装。
三、New message 触发器核心定义
New message 触发器的完整定义位于 new-message/index.js,其元数据如下:
| 字段 | 值 | 说明 |
|---|---|---|
| name | New message | 在流程编辑器中展示的名称 |
| key | newMessage | 程序内部使用的唯一标识 |
| type | webhook | 触发器类型为 Webhook,由 Telegram 服务端主动回调 |
| description | Triggers when a new message is sent to the bot. | 触发语义说明 |
关键点在于type: 'webhook':这意味着该触发器不是轮询式(polling)触发,而是依赖 Automatisch 注册到 Telegram 的 Webhook 地址,由 Telegram 在事件发生时实时推送更新。这是理解本触发器整个生命周期的主线。
3.1 允许接收的更新类型(Allowed Update Types)
触发器接受一个可选的allowedUpdates下拉参数(源码见 new-message/index.js),用于筛选你希望接收的 Telegram Update 类型。参数描述明确指出:留空则接收除chat_member、message_reaction、message_reaction_count之外的所有更新类型。
该下拉菜单共提供 22 个选项,完整映射如下:
| 界面标签(Label) | 提交值(Value) |
|---|---|
| Message | message |
| Edited Message | edited_message |
| Channel Post | channel_post |
| Edited Channel Post | edited_channel_post |
| Business Connection | business_connection |
| Business Message | business_message |
| Edited Business Message | edited_business_message |
| Deleted Business Messages | deleted_business_messages |
| Message Reaction | message_reaction |
| Message Reaction Count | message_reaction_count |
| Inline Query | inline_query |
| Chosen Inline Result | chosen_inline_result |
| Callback Query | callback_query |
| Shipping Query | shipping_query |
| Pre-checkout Query | pre_checkout_query |
| Purchased Paid Media | purchased_paid_media |
| Poll | poll |
| Poll Answer | poll_answer |
| My Chat Member | my_chat_member |
| Chat Member | chat_member |
| Chat Join Request | chat_join_request |
| Chat Boost | chat_boost |
| Removed Chat Boost | removed_chat_boost |
该参数类型为dropdown、required: false、variables: false,意味着它是一个固定的枚举选择(不支持在参数中使用流程变量动态取值),但你可以根据业务需要只勾选感兴趣的事件类型,从而减少无关回调对流程的触发。
四、Webhook 注册与注销:触发器的底层生命周期
触发器通过registerHook与unregisterHook两个钩子管理 Webhook 的生命周期(源码见 new-message/index.js)。
4.1 注册:调用 setWebhook
async registerHook($) { const webhookPayload = { url: $.webhookUrl, secret_token: appConfig.webhookSecretKey, allowed_updates: $.step.parameters.allowedUpdates ? [$.step.parameters.allowedUpdates] : [], }; await $.http.post('/setWebhook', webhookPayload); }注册阶段做三件事:
- 回传回调地址:将 Automatisch 为该流程步骤生成的
$.webhookUrl作为url参数提交给 Telegram 的/setWebhook接口,告诉 Telegram 之后把更新推送到哪里; - 设置 secret_token:携带
appConfig.webhookSecretKey(来自后端 config/app.js 的 Webhook 密钥配置)作为安全令牌,用于回调时的验签; - 下发更新过滤规则:把用户选择的
allowedUpdates以数组形式传给 Telegram。注意源码中的实现是[$.step.parameters.allowedUpdates],即把单个下拉值包装为单元素数组,这对应的是 Bot API 中allowed_updates的数组语义。
4.2 注销:调用 deleteWebhook
async unregisterHook($) { await $.http.post('/deleteWebhook'); }当流程被删除、停用或该步骤被移除时,Automatisch 会调用/deleteWebhook清除 Telegram 侧的回调注册,避免遗留僵尸 Webhook 继续向已不存在的地址推送数据。
五、收到更新后的数据流转:run 与 internalId
当 Telegram 向 Webhook 地址推送一条更新时,触发器的run函数被调用(源码见 new-message/index.js):
async run($) { const dataItem = { raw: $.request.body, meta: { internalId: $.request.body.update_id?.toString() || Crypto.randomUUID(), }, }; $.pushTriggerItem(dataItem); }这里有两个值得注意的实现细节:
- raw 数据:Telegram 推送的整个更新对象(JSON)被原样保存在
raw字段中,后续流程步骤可以直接通过$.step.parameters之外的方式引用其中的字段(例如message.text、message.chat.id等); - internalId 去重机制:
update_id是 Telegram 为每次更新分配的自增标识,源码将其字符串化后作为internalId,Automatisch 用它做去重判断,避免同一条更新被重复执行;当请求体中缺少update_id时,则回退为Crypto.randomUUID()生成的随机 ID(见 import 的Crypto模块)。
这种设计保证了"每收到一条新消息只执行一次流程"的语义,是 Webhook 类触发器可靠性的关键。
六、测试运行:testRun 与示例数据
在流程编辑器中点击"测试"该触发器时,执行的是testRun函数(源码见 new-message/index.js)。其逻辑分为两步:
- 优先复用上一次真实执行的结果:通过
$.getLastExecutionStep()获取最近一次执行步骤的输出dataOut,如果存在则直接将其作为触发数据重新推入,保证测试数据与真实数据形态一致; - 首次测试时提供示例数据:如果没有任何历史执行记录,则推送一段内置的
sampleData模拟真实更新,其结构如下(节选):
{ "update_id": 123456789, "message": { "message_id": 42, "from": { "id": 987654321, "is_bot": false, "first_name": "John", "last_name": "Doe", "username": "johndoe", "language_code": "en" }, "chat": { "id": 987654321, "first_name": "John", "last_name": "Doe", "username": "johndoe", "type": "private" }, "date": 1720000000, "text": "Hello, bot!" } }这份示例数据完整覆盖了update_id、发送者(from)、会话(chat)、时间戳(date)与消息正文(text)等核心字段,开发者可以据此直接在流程后续步骤中绑定字段,例如将message.text作为下游动作的输入。
七、触发器与动作联动:一个完整的消息回执场景
New message 触发器通常与 Telegram 的Send message动作搭配使用,构成"收到消息 → 自动回复"的闭环。Send message 动作定义在 send-message/index.js,需要以下参数:
| 参数 | 是否必填 | 说明 |
|---|---|---|
| Chat ID | 是 | 目标会话的唯一标识,或目标频道的用户名(@channelusername格式) |
| Message text | 是 | 要发送的文本,1–4096 字符 |
| Disable notification | 否 | 是否静默发送(有通知但无提示音),默认false |
| Parse Mode | 否 | 文本格式:None、Markdown、MarkdownV2、HTML |
实现上,动作会构造{ chat_id, text, disable_notification }载荷并仅在设置了parseMode时附加parse_mode字段,然后请求POST /sendMessage,把 Telegram 的响应存为动作输出:
const response = await $.http.post('/sendMessage', payload); $.setActionItem({ raw: response.data });因此,一个典型的自动应答流程可以这样设计:
- 触发器:Telegram Bot → New message(可选勾选
message更新类型,避免收到edited_message等干扰); - 动作:Telegram Bot → Send message,其中
Chat ID绑定触发器输出中的message.chat.id,Message text绑定message.text(或拼接自定义回复文案)。
由于触发器、动作共用同一个telegram-bot应用(index.js),连接鉴权由add-auth-header中间件统一处理,用户只需在流程中复用同一个 Telegram 连接即可。
八、小结与排查建议
围绕New message触发器,可以总结出以下要点:
- 它是 Automatisch 中 Telegram Bot 应用唯一的触发器,类型为
webhook,基于 Telegram Bot API 的setWebhook/deleteWebhook机制实现实时推送; - 通过
Allowed Update Types参数可在 22 种 Telegram 更新类型中筛选,留空时默认排除chat_member、message_reaction、message_reaction_count三类; - 每条更新以
update_id作为internalId实现幂等去重,缺失时回退为随机 UUID; - 首次测试时使用内置示例数据,之后优先复用上一次真实执行的输出。
如果在实际使用中遇到"触发器没有触发"的问题,可以按以下顺序排查:
- 确认连接是否成功建立(Bot token 是否有效,参见 connection.md 的 BotFather 步骤);
- 确认
Allowed Update Types是否误选、导致实际发生的事件类型被过滤(例如只选message却期望捕获channel_post); - 确认 Webhook 是否成功注册——若流程创建后 Telegram 侧仍返回 404,可检查后端的
appConfig.webhookSecretKey与回调地址配置; - 检查该流程步骤是否处于启用状态,以及执行历史中是否因
internalId去重而跳过了重复更新。
【免费下载链接】automatischThe open source Zapier alternative. Build workflow automation without spending time and money.项目地址: https://gitcode.com/GitHub_Trending/au/automatisch
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考