利用 n8n 打造飞书 RSS 推送机器人 |
您所在的位置:网站首页 › 新云推书的密码是什么 › 利用 n8n 打造飞书 RSS 推送机器人 |
前言 本文介绍了基于开源自动化平台 n8n 搭建自动化流程,实现监控 RSS 更新并推送到飞书消息的功能。 文末会列举一些实现此工作流的其他方式,包括发送请求和接收提醒的手段。与此同时,n8n 还可以通过模块组合,实现更多更复杂的功能,本文只作为抛砖引玉。 阅读本文可能需要一定 Linux 基础知识。 n8n 是什么n8n 是一个开源的自动化流程搭建工具,可以实现类似 IFTTT 的效果,比如「如果明天下雨,就推送要带伞的消息」。优点是开源、可以自己部署并将信息都储存在本地,同时可以与 Github、Telegram、Slack 等各种服务实现联动,以搭建自动化工作流。 利用 Docker 安裝 n8nn8n 可以直接下载 Win 或是 Mac 版本,快速在本地使用,但如果想更稳定地长期运行,更适合部署在云服务器、树莓派或 NAS 等工具上。 这里以在云服务器上使用 Docker 进行部署为例,更多安装方式可参考 Installation guides for n8n。 假设已经安装好了 Docker,那么 n8n 的部署就非常简单,先新建一个文件夹储存数据。 # 创建数据储存文件夹 mkdir ~/n8n-data复制运行下面的代码,利用 Docker 安装 n8n。如果云服务器有防火墙,需要把对应的端口打开,这里需要打开云服务器的 TCP 端口 5678。 # 利用Docker安装运行n8n docker run -d \ --name n8n --restart unless-stopped \ -p 5678:5678 \ -v ~/n8n-data:/home/node/.n8n \ -e GENERIC_TIMEZONE="Asia/Shanghai" \ n8nio/n8n稍作等待,等 Docker 安装完成后,如果一切顺利,访问 服务器ip地址:5678 就能看到 n8n 的运行页面了,初次进入需要创建账号密码。 ![]() 点击右上角的 New blank workflow 即可开始创建,也可以从软件提供的 Workflow 示例中,选择自己想部署的自动化流程。 这里以搭建一个 RSS 更新自动推送到飞书的机器人为例,展示 n8n 的一些使用方式。 搭建飞书 RSS 推送机器人以下是我配置好的一个流程模板,复制以下内容粘贴到 n8n 新建 workflow 的页面。 { "nodes": [ { "parameters": { "url": "https://sspai.com/feed" }, "name": "RSS Feed Read", "type": "n8n-nodes-base.rssFeedRead", "typeVersion": 1, "position": [ 160.5, 440 ] }, { "parameters": { "conditions": { "number": [ { "value1": "={{new Date($node[\"Latest Read\"].data[\"latestRead\"]).getTime()}}", "value2": "={{new Date($node[\"RSS Feed Read\"].data[\"isoDate\"]).getTime()}}" } ], "boolean": [], "string": [ { "value1": "={{$json[\"title\"]}}", "operation": "contains" } ] } }, "name": "IF", "type": "n8n-nodes-base.if", "typeVersion": 1, "position": [ 560, 440 ] }, { "parameters": { "functionCode": "const staticData = this.getWorkflowStaticData('global');\n\nif (items.length > 0) {\n staticData.latestRead = items[0].json.isoDate || staticData.latestRead;\n}\n\n\nreturn items;" }, "name": "Write Latest Read", "type": "n8n-nodes-base.function", "typeVersion": 1, "position": [ 760, 340 ] }, { "parameters": {}, "name": "NoOp", "type": "n8n-nodes-base.noOp", "typeVersion": 1, "position": [ 750, 580 ] }, { "parameters": { "triggerTimes": { "item": [ { "mode": "everyX", "value": 1 } ] } }, "name": "Cron", "type": "n8n-nodes-base.cron", "typeVersion": 1, "position": [ -40, 440 ] }, { "parameters": { "requestMethod": "POST", "options": { "batchInterval": 3000, "batchSize": 1 }, "bodyParametersUi": { "parameter": [ { "name": "msg_type", "value": "interactive" }, { "name": "card", "value": "={\n \"config\": {\n \"wide_screen_mode\": true\n },\n \"header\": {\n \"template\": \"black\",\n \"title\": {\n \"content\": \"{{$json[\"title\"]}}\",\n \"tag\": \"plain_text\"\n }\n },\n \"elements\": [\n {\n \"tag\": \"div\",\n \"text\": {\n \"content\": \"{{$json[\"contentSnippet\"]}}\",\n \"tag\": \"lark_md\"\n }\n },\n {\n \"tag\": \"hr\"\n },\n {\n \"elements\": [\n {\n \"content\": \"[阅读原文]({{$json[\"link\"]}})\",\n \"tag\": \"lark_md\"\n }\n ],\n \"tag\": \"note\"\n }\n ]\n}" } ] }, "headerParametersUi": { "parameter": [ { "name": "Content-Type", "value": "application/json" } ] } }, "name": "HTTP Request", "type": "n8n-nodes-base.httpRequest", "typeVersion": 1, "position": [ 1000, 340 ] }, { "parameters": { "functionCode": "const staticData = this.getWorkflowStaticData('global');\n\nlatestRead = staticData.latestRead;\n\nfor (let item of items) {\n item.json.latestRead = latestRead || '2022-05-05';\n //item.json[\"content:encodedSnippet\"] = item.json[\"content:encodedSnippet\"].replace(/[\\r\\n]/g,\"\\\\n\");\n}\n\nreturn items;" }, "name": "Latest Read", "type": "n8n-nodes-base.function", "typeVersion": 1, "position": [ 360, 440 ] } ], "connections": { "RSS Feed Read": { "main": [ [ { "node": "Latest Read", "type": "main", "index": 0 } ] ] }, "IF": { "main": [ [ { "node": "Write Latest Read", "type": "main", "index": 0 } ], [ { "node": "NoOp", "type": "main", "index": 0 } ] ] }, "Write Latest Read": { "main": [ [ { "node": "HTTP Request", "type": "main", "index": 0 } ] ] }, "Cron": { "main": [ [ { "node": "RSS Feed Read", "type": "main", "index": 0 } ] ] }, "Latest Read": { "main": [ [ { "node": "IF", "type": "main", "index": 0 } ] ] } } }粘贴后可以看到如下的界面: ![]() 这里有几处可以配置,第一处是 Cron,设置自动化流程触发的频率,每隔 X 时间间隔运行一次,图中设置为每隔一小时运行。在获取 RSS 时,运行频率不宜过高。如果访问过于频繁,一方面会给对方服务器造成较大负担,同时可能被服务器禁止访问。 ![]() 第二个是在 RSS Feed Read 处,填写想订阅的 RSS 地址,这里以少数派 RSS 为例,填写完后点击Excute node,先运行一次获取数据,方便后续设置。 ![]() 第三处(可选)IF 处,设置是否需要针对标题或内容等进行过滤,默认不过滤。 ![]() 这时先转到飞书,在飞书桌面端,打开一个群(建议先创建一个单人的群进行调试),打开设置,找到群机器人,并点击添加机器人,选择自定义机器人加入群聊,详细操作可以参照 飞书自定义机器人指南。 ![]() 最后在 HTTP Request 处填入飞书机器人 webhook 地址。 ![]() 填写完成后 Excute node 尝试运行,一切顺利的话就能在飞书中看到推送来的RSS消息了。 ![]() 这里使用了卡片的形式展示消息,若是想调整消息展示样式,可以参考少数派文章 手把手教你用飞书 Webhook 打造一个消息推送 Bot。 ![]() 由于采用 Webhook 的形式,请务必保管好 Webhook 链接,如果泄露可能会导致被推送垃圾信息。为了进一步加道保险,飞书提供了三种安全设置方式,分别是自定义关键词、IP 白名单和签名校验。 前两种方式非常好理解,也都很好设置。自定义关键词是只有当消息中至少含有一个预设的关键词时,才会进行消息推送;IP 白名单则是只推送名单中来源的 IP 所发送的请求。但是这两种方式也有一定的局限性: 关键词有时使消息不够简洁部署在本地树莓派等设备上时,IP 地址不固定,无法指定关键词和 IP 白名单各自最多只能添加十个条目因此这里详细介绍一下在 n8n 中进行签名校验的配置方式。飞书的签名需要将「timestamp + "\n" + 密钥」组合起来当作签名密钥,采用 Hmac SHA256 算法计算签名,再进行 Base64 编码。在发送消息请求时,需要增加对应的 timestamp 和 sign 字段。 // 开启签名验证后发送文本消息的请求示例 { "timestamp": "1599360473", "sign": "xxxxxxxxxxxxxxxxxxxxx", "msg_type": "text", "content": { "text": "The message content is here" } }在 n8n 中,可以使用 Crypto 模块利用密钥生成签名,复制以下代码粘贴到配置界面,可以得到生成飞书签名用的模块组合。 { "nodes": [ { "parameters": { "action": "hmac", "type": "SHA256", "value": "={{''}}", "dataPropertyName": "sign", "secret": "={{$json[\"timestamp\"]+'\\n'+$json[\"secret\"]}}", "encoding": "base64" }, "name": "Crypto", "type": "n8n-nodes-base.crypto", "typeVersion": 1, "position": [ -80, 440 ] }, { "parameters": { "values": { "string": [ { "name": "timestamp", "value": "={{Math.round(new Date().getTime()/1000)}}" }, { "name": "secret" } ] }, "options": {} }, "name": "Set", "type": "n8n-nodes-base.set", "typeVersion": 1, "position": [ -280, 440 ] } ], "connections": { "Set": { "main": [ [ { "node": "Crypto", "type": "main", "index": 0 } ] ] } } }将上面新增的两个模块按下图方式进行拖拽连接: ![]() 从飞书机器人设置界面中,勾选签名校验得到密钥,填写在 Set 模块中。 ![]() 接下来将 Latest Read 模块中的代码替换为以下内容,储存计算出的签名,方便在请求的时候调用。 // JS code in the Latest Read Module const staticData = this.getWorkflowStaticData('global'); latestRead = staticData.latestRead; for (let item of items) { item.json.latestRead = latestRead || '2022-05-05'; item.json.timestamp = $item("0").$node["Crypto"].json["timestamp"]; item.json.sign = $item("0").$node["Crypto"].json["sign"]; } return items;最后在 HTTP Request 模块中增加校验用的字段:Body Parameters → Add Parameter,添加两个参数,Name 分别为 timestamp 和 sign,Value 处点击右侧 Add Expression,分别选择两个对应字段的值。 ![]() 这样一番倒腾,给飞书机器人模块增加了签名校验,使得信息推送更加安全。当一切配置妥当后,别忘了点击界面右上角的激活,让工作流开始自动运行。 ![]() 本文介绍了如何用 n8n 打造一个飞书 RSS 推送机器人。订阅什么样的 RSS 来源,可以是网站自身提供的 RSS 地址,也可以利用 RSShub 将各种奇怪的网站转化为 RSS,甚至是利用 kill-the-newsletter 将任意 Newsletter 邮件转化为 RSS 进行追踪。 同时,实现类似工作流的手段还有很多。对于 n8n 这部分,可以使用 IFTTT、Integrately,或是 Github Action 等,实现工作流中「监控 RSS 更新并发送 Webhook 请求」这部分;对于接收提醒,文中利用了飞书作为展示消息的界面,而 n8n 也支持连接到 Telegram、Slack 等通讯软件,或是通过 Send Email 模块实现邮件通知,以及发送到 Cubox、flomo 等各种支持 Webhook 的工具中。 更多功能,更多组合,尽请探索,把闲置的云服务器或是积灰的树莓派等折腾起来吧。 参考资料手把手教你用飞书 Webhook 打造一个消息推送 Bot - 少数派自定义机器人指南 - 飞书开放平台輕鬆架一套類 IFTTT 的自動化工作流 n8n - jkgtw's blogn8n Documentation |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |