简介
网页更新提醒,是一款浏览器插件,支持所有类Chomium浏览器(chrome、Edge、360、QQ、搜狗、猎豹等),可以监控任何网页任何区域的内容更新, 并通过XPusher(支持邮件、微信、飞书、钉钉、企业微信、Discord、Telegram或Webhook)进行通知。
整体架构
先看一下整体架构,后面再分解每一个部分的实现。
- 浏览器插件:实现插件的圈选、配置、定时任务及所需要的UI界面,是一个可以独立运行的实现,不依赖服务端也可以运行
- Gateway:负责接收插件、官网接口请求,参数/权限校验,并将请求路由到对应Service进行处理并返回处理结果
- Service:负责处理接口对应的业务逻辑
- XPusher:负责消息的触达,与网页更新提醒插件提醒解耦,除了提供给浏览器插件使用,也可以单独提供服务
- Feeder:负责云端任务的调度,调用Puppeteer服务完成网页更新检测,然后更新状态并调用XPusher通知用户
- Puppeteer:负责云端任务的执行,与浏览器插件的检测保持同构,功能稍微会落后一点,但代码是完全复用的
浏览器插件整体架构
浏览器插件的实现整体上由4种页面、两种脚本和消息中心几个部分组件。
- Popup页面:这个很好理解,就是点击插件按钮弹出的的那个弹框,这是一个HTML页面,主要提供各功能的入口按钮,功能比较简单
- Options页面:这个也好理解,就是显示任务列表、共享列表、设置等功能的那个页面,这是一个单页应用,全部功能在一个页面,功能比较复杂,主要是展示和响应用户操作
- Backgroud页面:这个是看不见摸不着的页面,但也是最重要的页面,负责任务的调度执行及消息的通知
- Sandbox页面:这是一个辅助页面,用于协助完成动态脚本的预处理
- Content Script:在页面加载空闲的时候注入页面,区域圈选和内容检测由这个脚本完成,包括云端的检测脚本,也负责向sandbox页面注入Injection Script
- Injection Script:由Content Script通过document.createElement('script')注入到sandbox页面,负责完成自定义脚本的解析执行并返回处理后的结果
- Message Center:通过下面的架构图可以看出,这个消息中是链接插件各页面和脚本的纽带,没有实际功能,就是专门负责各模块之间的消息通讯
- 消息①:点击Popup页面的开始圈选,会通过消息中心通知Content Script进入圈选模式
- 消息②:任务满足执行时间的时候,Backgroud页面会先自动打开任务对应页面,然后发送消息给Content Script进行内容提取并对比是否有更新
- 消息③:用的不多,当点击监控列表或者/共享列表后,需要通知Backgroud页面清除插件按钮上的未读计数
- 消息④:双向同步任务的状态、未读计数等信息
- 消息⑤:预处理任务的时候,Backgroud页面会先打开Sandbox页面,然后通过消息②通知Content Script脚本进行Injection Script注入,然后Content Script与Injection Script之间通过消息⑥完成数据预处理的调用和回调
Service服务
此模块负责共享任务及账号体系的管理,核心职责就是接受Gateway的请求,处理业务逻辑并返回接口所需的数据。不过多赘述。
XPusher服务
XPusher是一个便捷的万能消息推送服务,只需要一个接口,就可以把信息推送到各种主流消息平台(邮箱、微信、discord、telegram、飞书群、钉钉群、企业微信群或者自定义Webhook地址),与「网页更新提醒」插件共享账号和权益。 这里主要就是定义统一的数据结构并对接各消息通道,并适配各通道。
- 微信通道:是模板消息,消息摘要格式是固定的,可以根据公众号行业类型选择特定的模板,需要对接微信接口并处理订阅和取消订阅时间。消息详情是可以打开自定义页面的,详情页可以显示非常具体的富文本内容。注意:只有认证的公众号才有权限,所以是有一定门槛的,如果是个人开发者可以考虑用第三方通道,XPusher也是免费对外使用的。
- 邮件通道:使用HTML富文本格式,能够高亮显示差异和关键字信息,体验较好,但问题也是最多的,由于历史原因,邮件是广告营销的重灾区,所以有非常多的限制,很容易被限制,所以频控和黑白名单机制是非常中的。
- 企微通道:支持纯文本、markdown、图片、图文和文件格式。具体到网页更新提醒,会优先是有markdown格式,如果内容超过限制会使用纯文本+截图/文件的方式发送(回收到两条消息)。
- 钉钉通道:支持纯文本、markdown、图片、图文和文件格式。具体到网页更新提醒,会优先是有markdown格式,如果内容超过限制会使用纯文本。
除此之前还支持飞书、Discord、Telegram和自定义webhook,自定义webhook会把标题、URL、纯文本内容、富文本内容一并通过Post请求发送。
Feeder服务
这是一个定时任务,定时检测云端任务,判断是否符合条件并执行检测:
- 是否符合robots要求
- 是否符合Puppeteer可以监测的要求(连续多次检测失败会进入黑名单)
- 是否在用户设定监控时间范围
- 是否符合间隔要求(任务设置的间隔、云端任务用户类型对应的最小间隔取最大值)
- 是否符合频控要求(用户对应的频控次数是否用完)
符合条件的任务会远程调用Pupeteer服务执行更新检测,如果有更新需要入库并调用XPusher服务通知用户。
Puppeteer服务
Puppeteer服务就接收Feeder服务的请求,在页面加载完成后注入Content Script代码,然后提取内容和计算Diff并返回检测结果。另外,这里内容提取及Diff算法完全复用插件的实现,具体实现就是通过增加一个entry,暴露几个全局方法并打包成CommonJS。
这是一个容器化服务,通过云服务的弹性容器ECI部署。核心是通过NodeJs对Puppeteer的封装,控制并发量并管理无头浏览器的状态。