一个支持 newsletter(订阅通讯) 与 contact(联系表单) 的轻量级自建服务。
基于 PocketBase(Go 单文件二进制,内置 SQLite / REST API / Admin UI / SMTP 邮件客户端),用少量 JS 钩子实现两大功能。零外部依赖、单个二进制、单文件数据库,一条命令即可长期运行。
- Contact:访客留言入库,自动给站长发通知邮件(
replyTo设为访客邮箱,方便直接回复)。 - Newsletter:邮箱订阅 / 退订(专属 token 校验,防伪造);手动填文章链接即可自动抓取并群发给所有订阅者,每封带专属退订链接。
为什么自建?不依赖第三方表单 / 邮件服务,数据自己掌控,一台小 VPS 就能跑。
- ✅ 公开表单无需鉴权:联系留言与订阅走公开的
createRule,跨域默认放行,前端直接fetch提交即可。 - ✅ 自动建集合:首次启动自动创建
contact_messages与subscribers,无需手动建表。 - ✅ 服务端生成退订 token:隐藏字段 + 唯一索引,防伪造、防重复订阅。
- ✅ 一键推送:填文章链接 → 后端抓取 → 提取标题/描述/封面 → 群发,每封带专属退订链接。
- ✅ 可 Docker 化:内置
Dockerfile+docker-compose.yml,部署到 Linux 服务器一条命令起。 - ✅ 零编译:逻辑全在
pb_hooks/*.pb.js,改完热重载,无需重新编译二进制。 - ✅ 配置全靠环境变量:域名 / 发件人 / 通知邮箱 / CORS 全部走
.env或 Dockerenvironment:,无需改钩子代码。本地零配置即用默认值。
api.imashen.cn/
├─ .env.example # 环境变量模板(钩子配置 + 推送脚本凭据),复制为 .env 填值
├─ pb_hooks/
│ └─ contact.pb.js # 核心钩子:联系留言 + newsletter 订阅/退订/推送
├─ scripts/
│ └─ send-newsletter.mjs # 零依赖 Node 脚本:登录超级用户 → 调用推送
├─ Dockerfile # 构建 Linux 生产镜像
├─ .dockerignore
├─ docker-compose.yml # 一键启动 + 数据卷持久化
├─ .gitignore
├─ HANDBOOK.md # 完整使用手册(本地 / 配置 / 部署 / 排错)
├─ LICENSE.md
└─ (运行时生成,不入库)
├─ pocketbase(.exe) # 官方二进制,官网下载,勿入库
├─ pb_data/ # SQLite 数据库 + 上传文件
└─ .env # 环境变量与凭据,勿入库
cd api.imashen.cn
# 1) 下载官方二进制放到根目录(Windows 命名 pocketbase.exe,其他 pocketbase)
# https://pocketbase.io/docs/
# 2) 开发模式启动(钩子改动自动热重载)
./pocketbase serve --dev --http=127.0.0.1:8091启动后:
- REST API: http://127.0.0.1:8091/api/
- Admin UI: http://127.0.0.1:8091/_
首次启动会自动创建两个集合,并在控制台打印超级用户安装链接(或在 Admin UI 创建)。
完整配置 SMTP、Contact / Newsletter 用法、Admin 管理、Docker 部署、备份与排错,见 HANDBOOK.md。
POST /api/collections/contact_messages/records
Content-Type: application/json
{ "name": "张三", "email": "zhangsan@example.com", "message": "你好!", "hp": "" }入库后自动给站长发通知邮件(需在 Admin UI 配置 SMTP)。
# 订阅(公开)
POST /api/collections/subscribers/records
{ "email": "reader@example.com", "status": "subscribed", "hp": "" }
# 退订(点击邮件里的专属链接)
GET /unsubscribe?email=reader@example.com&token=<专属token>
# 推送(仅超级用户,脚本自动登录)
node scripts/send-newsletter.mjs "https://你的文章链接" "一句话附言"# 1) 配置环境变量(无需改代码):复制模板,填入公网域名与邮箱
cp .env.example .env # 至少把 PB_API_BASE 改为你的公网地址
# 2) 一键起容器(docker-compose 会自动读取 .env 注入容器)
docker compose up -d --build容器监听 8090,pb_data/ 数据卷持久化。项目根目录已附带 Caddyfile(反代到 8090 + 自动 HTTPS)与 nginx.conf(HTTPS + WebSocket + 可选 IP 白名单),二选一把公网域名转发并启用 HTTPS 即可。详见 HANDBOOK.md 第 5、11 节。
- HANDBOOK.md — 从零到部署的完整手册,强烈建议先读。
pb_hooks/contact.pb.js内附有详尽的 JSVM 注记(PocketBase v0.39 的关键坑)。
见 LICENSE.md。