Knicknack POST summary
每天早上醒来,都会看到手机锁频界面如瀑布般展开的News推送卡片😶🌫️,bilibili的,微信公众号的,还有一堆订阅的邮件。。。消息一多,读完已是晌午(有时候读着读着,就被BILIBILI推送的视频封面吸引,推送算法害人呃)。于是想效仿纸媒时代每天送到家门口邮箱中的报纸一样,做一个自动获取、排版、总结和推送指定源的自动化程序,每天生成一份个性化、简洁的电子日报。早上只需要翻阅这份“电子都市报”,妈妈再也不用担心看新闻分心了~
其实市面上已经有相关功能软件,如基于RSS源订阅的FOLO阅读器和各种类openclaw Agent。但前者订阅源有限,且没法灵活使用LLM进行信息总结和分类(页面也没办法自定义),后者获取新闻源的方法较为“笨拙”,并且我也用不到openclaw其他功能其实是花不起token,还是得自己手搓咯。如你所见,Knicknack POST项目主要分为4个功能模块:News源订阅、LLM总结、邮件排版+渲染和邮件推送。
News源订阅
一开始考虑过使用网络爬虫实现。但受限于不同News源页面结构不同、需要账号登陆、源页面更新频繁等等原因,爬虫很难稳定长期运行,与POST项目初衷:长期运行,稳定性和可维护性较高相悖,遂放弃该方法。经过调研后,采取两种方法获取News:RSSHub和kill_the_newsletter。
RSSHub
RSS(Really Simple Syndication) 是一种用于内容订阅与分发的标准格式(基于 XML),方便自动化程序获取网站更新。就像info中提到一样,靠手动刷博客/网站获取News的方法很低效,而通过获取网站提供的“结构化更新接口”——RSS,有更新就自动推送,后者不仅更高效,还绕过了平台的推荐算法。
但许多网站并未提供RSS订阅源,RSSHub(AGPL-3.0)项目诞生了。她是一个由超过1300名贡献者维护的“万物转RSS的网关”,将整个互联网强行改造为可订阅RSS的中间层。推荐拉取docker仓库后自建服务,以免RSSHub公共实例压力太大。
1 | # RSS样例 |
kill the newsletter
还有一些订阅平台仅提供邮件订阅服务(TLDR和changelog),可以使用自动化脚本从邮箱中获取News邮件,但推荐kill the news letter服务。该服务会将邮件订阅(Newsletter)转成RSS Feed,便于统一News源格式。不过kill-the-newsletter免费服务每一个邮箱仅保留最新的20封邮件。
1 | # kill-the-newsletter rss feed格式 |
LLM总结
由于部分源每日推送News过多(TLDR,changelog等),可以先让LLM“洗”一次,然后推送分类并精炼后的总结文段,如果有感兴趣的部分再跳转精读。为了节省token,Knicknack-post会使用beautifulsoup库除去RSS中无关标签,仅提取description部分。目前主流LLM都能胜任该工作,本项目使用deepseek官方API平台提供的chat模型,且采用openai API格式。如需更换模型,需要修改post/目录下对应源调用LLM处和prompt-json提示词文件。
1 | # example |
邮件排版+渲染
为了能自己设计日报版面,同时兼容不同邮件服务平台,选择使用HTML格式的邮件正文。Knicknack POST采用MJML生成邮件模板并转为HTML格式,然后使用Jinja2库将格式化的News填入HTML模板。
MJML
MJML(Mailjet Markup Language) 是一种专门用于构建邮件(Email)HTML的标记语言。不同于普通网页开发,邮件前端通常面临许多问题(Outlook用Word引擎渲染、Gmail会删样式等等)。为了保证不同平台显示效果一致,可以先用MJML标记语言的“高级组件语法”开发:
1 | <mj-button>Click me</mj-button> |
经过编译后输出兼容性极强的HTML标记文本:
1 | <table> |
Jinja2
Jinja2是一个Python的模板引擎,主要用来将“数据+模板”渲染成最终文本,其模板通常为但不限于HTML文件,相当于一个“带逻辑的字符串生成器”。
1 | from jinja2 import Template |
邮件推送
在选择Knicknack POST项目推送形式的时候,考虑了许多种方法:
- 使用通讯平台官方机器人。飞书个人机器人每天消息限量100条,微信和QQ功能太少,且对发送文件大小有限制。
并且平台对机器人消息内容审核较严,总有一种被监视偷窥的感觉; - 自建即时通讯软件机器人。telegram等境外软件国内使用不太方便,QQ和微信的机器人框架需要和官方斗智斗勇,不仅一个不留神号容易进小黑屋,而且官方更新后有的框架就失效了,与项目稳定性高、可长期运行目标相悖;
- 使用邮件服务。虽然没有即时聊天软件方便,但技术限制和内容限制更少,且看起来更高级和正式。
综合考虑后,选择使用邮件推送的方法,下面多种都可使用:
resend服务
Resend是面向开发者的邮件发送 API + 投递基础设施。其可以省去自建SMTP服务的过程。不过其本质上是一个网站邮件服务插件,需要提供自己的网站域名、和DNS记录配置,否则只能发给自己账号绑定的邮箱。
SMTPLIB/REDMAIL
SmtpLib库是python提供的smtp协议库,可以实现一些轻量化的邮件发送服务。为了避免因没有DNS IP 信誉导致发送邮件进垃圾箱,需要通过邮件平台SMTP服务器发送(本项目使用的是QQ SMTP服务器),可以在官方开放平台申请一个SMTP 授权码使用该功能。
Redmail库则是对前者的现代化封装,免去了手动构建MIME对象结构步骤,且集成了jinja2的渲染功能。
受限于店主对token价格的敏感性目前Knicknack POST是一个简单的自动化工具,仅在总结News时使用了LLM。之后该项目会逐渐变为本地类openclaw个人agent的一个功能,店主会将以上源获取、News排版和发送模块封装为 agent tools以供调用
