当前位置: 首页 > news >正文

使用n8n+飞书搭建自动推送新闻机器人

运行效果

点击查看原文,可以跳转到新闻的36氪链接。

n8n工作流

主要功能

实现从36氪上爬取新闻,并筛选和AI相关的AI类新闻,最终将新闻的结果,推送到手机端。

工作流搭建与配置

定时器

设置成定时触发流程,可以选择按日/分钟/月/周等等,选择范围还是很广的。我设置成了按天,每天触发一次,时间为上午10点。

Http请求节点

后面用http请求节点,主要是为了抓取36氪的新闻。RSS是一个能让你在一个地方订阅各种感兴趣网站的工具

这里网址需要填36氪新闻的RSS订阅网址,也就是https://36kr.com/feed

节点配置信息如下:

只需要将method设置为get,然后网址url设置成36氪新闻的RSS订阅地址就行啦。

可以点击Execute Step去测试一下,结果为:

AI类新闻筛选

由于返回的数据有很多篇新闻,所以后面加了一个Code节点,来从中筛选数据。这里采用关键词匹配,也就是如果返回的结果中,在title标题、content内容中,如果包含'AI', '人工智能', '大模型', 'LLM', 'GPT', 'Claude', 'Gemini','通义千问', '文心一言', '豆包', '讯飞星火', 'AI Agent','机器学习', '深度学习', '神经网络', 'NLP', 'CV', 'AIGC'等词汇,就认为是AI类新闻。

这些关键词可以根据个人需求,再做一些增补。或者再增加一些语义相关的匹配去检索和AI相关的新闻,例如词向量的余弦相似度等。

代码选择使用JavaScript语言,对应的代码如下:

try { const rssData = $input.item.json.data || $input.item.json; if (!rssData) { console.log('RSS数据为空'); return []; } function parseAndFilterRSS(xmlString) { const items = []; // 提取所有item const itemMatches = xmlString.match(/<item[^>]*>[\s\S]*?<\/item>/gi); if (!itemMatches) { console.log('未找到RSS item'); return items; } const aiKeywords = [ 'AI', '人工智能', '大模型', 'LLM', 'GPT', 'Claude', 'Gemini', '通义千问', '文心一言', '豆包', '讯飞星火', 'AI Agent', '机器学习', '深度学习', '神经网络', 'NLP', 'CV', 'AIGC' ]; const lowerKeywords = aiKeywords.map(k => k.toLowerCase()); for (const itemXml of itemMatches) { const title = (itemXml.match(/<title[^>]*>([\s\S]*?)<\/title>/) || [])[1] || ''; const link = (itemXml.match(/<link[^>]*>([\s\S]*?)<\/link>/) || [])[1] || ''; const contentSnippet = (itemXml.match(/<description[^>]*>([\s\S]*?)<\/description>/) || [])[1] || ''; const pubDate = (itemXml.match(/<pubDate[^>]*>([\s\S]*?)<\/pubDate>/) || [])[1] || ''; const fullText = (title + ' ' + contentSnippet).toLowerCase(); const isAiRelated = lowerKeywords.some(keyword => fullText.includes(keyword)); if (isAiRelated) { items.push({ title: title.trim(), link: link.trim(), contentSnippet: contentSnippet.trim(), pubDate: pubDate.trim() }); } } return items; } const result = parseAndFilterRSS(rssData); console.log('AI相关新闻数量:', result.length); return result; } catch (e) { console.error('RSS解析/过滤出错:', e.message); return []; }

配置执行结果如下:

数据清洗节点

因为后面在飞书上,想要实现推送,并且用户可以点击推送的链接,跳转到对应的36氪新闻网址上。而我之前在实现的时候,如果不加数据清洗节点,则遇到两个问题:1)飞书的推送有数量限制,当短时间一次性推送数量过多时,会出现警告语限制。2)原来抓取的新闻数据中,link链接是类似于<![CDATA[https://36kr.com/p/3840996342073604?f=rss]]>这样的数据,需要再从中做一下处理,才能解析出网页。

所以,为了解决这两个问题,我又加了一个数据清洗节点,选择的是code节点,然后用JavaScript代码,对应代码如下:

// 拿到输入的所有数据 const items = $input.all(); // 定义清洗CDATA的函数(修复版) const cleanCdata = (str) => { if (!str) return ''; // 去掉 <![CDATA[ 和 ]]> 标签,保留内容 return str.replace(/<!\[CDATA\[/g, '').replace(/]]>/g, '').trim(); }; // 对每一条数据进行清洗 const processed = items.map(item => { const title = cleanCdata(item.json.title); const link = cleanCdata(item.json.link); const pubDate = item.json.pubDate || '未知时间'; return { title, link, pubDate }; }); // 输出前5条 return processed.slice(0, 5);

代码对每一条数据进行清洗,并且限制输出前5条。执行结果为:

飞书推送

使用webhook来实现飞书的推送。获取webhook的步骤为:

  1. 创建飞书群组

2、配置机器人

3、获取webhook地址

经过上面步骤,就可以获得飞书的webhook地址啦。然后在n8n的工作流中,加入http request节点。对应配置如下:

最后这一步,body主要是为了设置在飞书群组里面,推送的内容样式。例如下面的样式一:

样式二:

不同的推送样式,主要是在body里面,通过JSON代码来修改。分享下我的代码,为:

{ "msg_type": "interactive", "card": { "config": { "wide_screen_mode": true }, "header": { "title": { "tag": "plain_text", "content": "RSS新闻推送" }, "subtitle": { "tag": "plain_text", "content": "最新资讯更新" } }, "elements": [ { "tag": "div", "text": { "tag": "lark_md", "content": "**{{ ($json.title || '无标题').replace(/<!\\[CDATA\\[|\\]\\]>/g, '').trim() }}**" } }, { "tag": "div", "text": { "tag": "lark_md", "content": "🕒 发布时间:{{ $json.pubDate || '未知时间' }}\n📡 来源:RSS订阅\n\n🔗 [点击查看原文]({{ ($json.link || 'https://36kr.com').replace(/<!\\[CDATA\\[|\\]\\]>/g, '').trim() }})" } }, { "tag": "button", "text": { "tag": "plain_text", "content": "打开原文链接" }, "type": "primary", "url": "{{ ($json.link || 'https://36kr.com').replace(/<!\\[CDATA\\[|\\]\\]>/g, '').trim() }}" } ] } }

最终,点击execute 就可以执行整个工作流啦

http://www.gsyq.cn/news/1483701.html

相关文章:

  • 告别手动操作!教你用批处理(.bat)和VBS脚本打造一键重启Windows资源管理器工具
  • 别再乱定义变量了!汇川InoProShop全局变量类型详解(含掉电保持设置)
  • Weka数据预处理实战:用‘Discretize’滤波器一键搞定连续数据分箱,让模型更稳定
  • 为Unitree Go1机器狗部署PaddlePaddle:从环境准备到Camera SDK调用实战
  • SAP WM实战:手把手教你追踪一个仓储单位(SU)的完整生命周期(从收货到清空)
  • 手把手教你用RT-Thread点亮CH32V307开发板的LED灯(附完整代码)
  • 告别手动采样!用ArcGIS的‘创建随机点’和‘按点提取值’工具高效完成生态调查数据分析
  • AD9361接收功能验证避坑指南:从官方配置软件到SPI寄存器,手把手教你搞定LVDS数据接收
  • 别只盯着任务创建了!用STM32CubeMX玩转FreeRTOS的任务状态机(挂起、恢复、删除)
  • 可自定义报告的清洁度分析仪推荐 - 工业品牌热点
  • 飞思卡尔FRDM-KL25Z开发板入门:除了点灯,用状态机设计游戏才是正解
  • R语言实战:手把手教你用lm()和手动计算两种方法搞定MSE(附mtcars数据集案例)
  • 别再为镜像频谱发愁了!用USRP X410和正交上变频,手把手教你搭建高效无线发射链路
  • Flutter桌面开发实战:我把一个移动端App打包成了Windows安装程序(.msi)
  • 火锅店管理系统毕业设计
  • 告别频谱浪费!用USRP X410和Python动手实现正交上变频,实测对比三种发射架构
  • 量子拓扑中的SKEIN理论与q级数研究
  • 别再只用re.findall()匹配‘h’了!5个让爬虫效率翻倍的真实用例
  • 当‘寓言’照进现实:用Notion或Obsidian搭建你的第二大脑,告别知识碎片化
  • 码头船只货柜管理系统毕业设计源码
  • 告别双系统!保姆级教程:在Windows 11上用WSL2 + PyCharm Professional 2023.2配置CUDA 12.1深度学习环境
  • 动态指纹混淆:无痕绕过现代WAF的渗透测试法
  • 社区养老服务系统毕设源码
  • 手把手教你用滑模观测器(SMO)搞定PMSM无感FOC:从α-β方程到转子位置估算
  • 超越CNN?用Swin Transformer在自定义数据集上轻松实现95%+准确率
  • 别再手动一个个点了!用MATLAB的dir函数批量处理遥感TIF数据(附完整代码)
  • 别再手动修音了!用Melodyne Studio 5.3一键分析人声,Adobe Audition内录素材导入全攻略
  • 从零到自动化:手把手教你用Python脚本调用Redfish API管理服务器(附Postman转Python代码技巧)
  • 深度学习安全:权重扰动后门攻击与防御实战
  • 2026年Java面试核心预测与突破