公众号活动总是错过?我做了一个自动整理工具

1. 我为什么做它
有一次周五晚上,我才在公众号历史消息里翻到一个周六上午的科技馆活动,点进去一看,报名两天前就截止了。
这不是第一次了。手机上关注了十几个亲子类的号——科技馆、少年宫、图书馆、商场、体育中心、美术馆——每家的活动都藏在推文里发一篇,报完名就沉底。下个月想找活动,得挨个号翻历史消息。几个号的活动时间叠在一起,全靠脑子和备忘录记,漏是迟早的事。
我当时的想法其实挺简单:把这些号统一管起来,新文章自动拉下来,活动信息自动抠出来,整理成一张表。过期的自动消失,不用手动清理。
翻了一圈,没有找到顺手又开源的方案。那就自己写一个。
we-events 就是这么来的。

2. 从公众号文章到活动日历
整个流程分五步走。
第一步,把公众号加进来。 关注列表里的号可以按主题进行分组管理——“亲子活动””课外培训””公益讲座””免费展览”——想怎么分都行。每个分组可以设置独立的采集周期,比如亲子活动组每周一早上自动跑一次,公益讲座组每天检查一次更新。

设置好之后,系统就会按照每个组的时间配置,自动拉取组内所有公众号的最新文章。新加入的号只要放进对应的组,下次定时采集时自然会被覆盖到,不需要对每个号单独配置。刚加完一批新号,也可以随时手动触发采集,不用等定时任务。

第二步,系统自动采集文章。 正文抓下来转成 Markdown,里面的图片也一并保存,避免微信的图片链接过期后文章看不全。

第三步,系统自动识别活动信息。 标题、时间、地点、报名方式、费用和适用年龄,会被整理成结构化数据,一般不需要手动录入。
第四步,在管理面板里查看和核对。 所有抽出来的活动都列在一张表里,能筛、能改。每一条活动都附了原文引用,觉得不对劲可以直接点回原文核对。
第五步,导出到手机日历。 一键导出 iCalendar(.ics)文件,导入日历 App 之后,周末带娃去哪玩,一眼扫过去就知道。

3. 系统架构
整个系统分三部分:后端服务、管理前端、数据层。
3.1. 后端
Python 3.12 + FastAPI,三层拆分:
- API 层 — 路由、鉴权、参数校验,薄薄一层
- Core 层 — 文章采集、活动抽取、定时调度、过期清理,核心业务逻辑都在这里
- Driver 层 — 对接外部系统:Playwright 控制的浏览器自动化、微信公众号 HTTP 接口
后端启动时自动拉起三个后台协程:文章采集 Worker(串行消费队列任务,因微信登录态全局共享)、活动抽取 Worker(调用 LLM 分析文章)、分组定时调度器(按 cron 触发采集)。采集和抽取都走数据库队列,进程挂了重启后 stale 任务自动重新入队。
3.2. 前端
React 18 + TypeScript + Vite,组件库 Ant Design。TanStack Query 管理服务端状态。
3.3. 数据层
Supabase(PostgreSQL)。只通过 FastAPI 的 Service Role 操作业务表,前端不直接连数据库。文章正文转 Markdown 存储,图片下载到 Supabase Storage,避免微信 CDN 链接过期后失效。
3.4. 核心流程
1 | 公众号文章 → 采集服务 → Markdown 正文 → LLM 抽取 → 活动列表 / 日历导出 |
LLM 默认接 Qwen3-32B,可通过环境变量切换到其他兼容 OpenAI 接口的模型。每条抽取结果附带原文证据位置,方便人工核对。
4. 活动信息是怎么自动提取的
最开始,我试过用正则匹配”时间””地点””报名方式”这些关键词。实际跑了一批文章后,很快就发现这条路走不通。
同样是活动时间,有的写”本周六下午”,有的写”即日起至月底”,还有的直接夹在一大段介绍里。规则越加越多,漏掉的情况还是不少。而且有些重要信息只放在图片里,不识别图片文字就抓不到,这部分目前仍需要人工核对。
后来改成了用 LLM 来读整篇正文。效果比纯规则好很多,但也不是百分之百可靠,偶尔会编造时间或者漏掉信息。所以我给每个字段都保留了原文引用——抽错了可以直接回到对应句子看原文。
目前默认使用的模型是 Qwen3-32B,可以通过环境变量切换到其他兼容 OpenAI 接口的模型。
5. 部署介绍
项目已开源:github.com/phoenine/we-events。Docker Compose 一键启动,支持两种 Supabase 运行模式:
5.1. 本地 Supabase(自托管)
项目根目录自带 supabase 子目录(PostgreSQL + Auth + Storage + Studio),用 Docker Compose 启动后,再启动应用:
1 | # 启动本地 Supabase |
本地 Supabase 不需要外部依赖,适合开发调试和内网部署。
5.2. 云端 Supabase
如果已经有 Supabase 项目,可以直接连接:
1 | docker compose --env-file .env.online up --build |
需要配置 SUPABASE_URL 和 SUPABASE_ANON_KEY / SUPABASE_SERVICE_KEY。
5.3. 手动部署
后端用 uv 管理 Python 依赖:
1 | cd backend |
前端用 pnpm:
1 | cd frontend |
两种模式共用一个代码仓库,区别仅在于环境变量指向本地还是云端 Supabase。数据库 Schema、RLS 策略、存储桶配置迁移脚本都在 supabase/migrations/ 下,README 里有完整的初始化步骤。
6. 最后
目前它首先解决的是我自己”周末带孩子去哪儿”的问题。功能还不算成熟,但文章采集、活动抽取和日历导出这条流程已经可以完整跑通。
项目已经放在 GitHub。如果你所在的城市也有一批值得长期关注的活动公众号,可以部署起来试试。遇到抽取不准确的文章也欢迎提 Issue——这些真实案例会直接决定下一步怎么改。