Mom 分身:手把手复刻文章/笔记/Share 工作流

Mom 分身:手把手复刻文章/笔记/Share 工作流
我有一段时间特别想要一个「只管内容发布」的小助手:
- 写完笔记,一键发网页
- 图片自动处理,不手搓链接
- 想发条短动态(碎碎念),也能走同一套系统
- 发完文章顺手生成推文草稿
最后我把它做成了一套轻量工作流。你可以把它理解成 Mom 的一个分身: 只做内容这件事,不管服务器运维,不管别的杂活。
这篇就是完整复刻指南:你只要建一个文件夹、填几份配置,就能跑起来。
你会得到什么(功能清单)
跑通后,你有 6 个核心能力:
- Markdown 发布到网页(支持分类、标签、归档、文章页)
- 图片自动上传图床(内容哈希去重 + 长缓存)
- Obsidian 一键发布(插件里点一下就发)
- 碎碎念发布(短内容单独分组)
- share → X(发布后自动生成推文草稿,可预览再发)
- 管理后台(查看、复制链接、删除文章)
架构全景(先有图,后落地)
flowchart LR
A[Obsidian / Markdown 文件] --> B[发布入口\nshare.ts / Obsidian 插件 / mom-note.ts]
B --> C[img-worker\n上传图片]
B --> D[share-worker\n发布文章]
C --> E[(R2: img)]
D --> F[(R2: share)]
D --> G[网页渲染\n首页/分类/标签/归档/文章]
D --> H[管理后台 /admin]
B --> I[回写 frontmatter\nshare_url / share]
D --> J[公开链接]
J --> K[share-to-x.ts]
K --> L[x-post.ts 发布到 X]
一句话:本地负责内容处理,Worker 负责存储+渲染,脚本负责分发。
第 0 步:准备环境
先确认这些工具可用:
bun --version
node --version
python3 --version
wrangler --version
需要的账号/服务:
- Cloudflare(Workers + R2)
- 一个 Obsidian Vault(可选,但推荐)
- (可选)X 账号用于自动发帖
第 1 步:建立 mom-share-lite 文件夹
你可以从现有 mom 项目里裁剪,也可以从自己的模板仓库拷贝。
建议结构如下:
mom-share-lite/
├─ workers/
│ ├─ shared/
│ │ ├─ auth.ts
│ │ └─ r2.ts
│ ├─ img/
│ │ ├─ src/index.ts
│ │ ├─ wrangler.toml
│ │ └─ package.json
│ └─ share/
│ ├─ src/index.ts
│ ├─ src/markdown.ts
│ ├─ src/render.ts
│ ├─ wrangler.toml
│ └─ package.json
├─ tools/
│ ├─ share.ts
│ ├─ mom-note.ts
│ ├─ share-to-x.ts
│ ├─ x-post.ts
│ └─ lib/
│ ├─ ai-client.ts
│ └─ sensitive-sanitizer.ts
└─ AGENTS.md # 给“分身”限定职责
最小可用核心就是这三层:
workers/img+workers/share+tools/*。
第 2 步:配置 Cloudflare(img + share)
2.1 创建 R2 Bucket
wrangler r2 bucket create img
wrangler r2 bucket create share
2.2 配置 img-worker
workers/img/wrangler.toml 里确认:
name = "img-worker"
main = "src/index.ts"
compatibility_date = "2024-01-01"
[vars]
PUBLIC_URL = "https://img.your-domain.com"
<span class="private-link" title="未发布的笔记">r2_buckets</span>
binding = "BUCKET"
bucket_name = "img"
设置密钥并部署:
cd workers/img
wrangler secret put API_KEY
bun install
bun run deploy
2.3 配置 share-worker
workers/share/wrangler.toml 里确认:
name = "share-worker"
main = "src/index.ts"
compatibility_date = "2024-01-01"
[vars]
PUBLIC_URL = "https://s.your-domain.com"
IMG_URL = "https://img.your-domain.com"
<span class="private-link" title="未发布的笔记">r2_buckets</span>
binding = "BUCKET"
bucket_name = "share"
设置密钥并部署:
cd ../share
wrangler secret put API_KEY
bun install
bun run deploy
第 3 步:配置本地发布工具
创建配置文件:~/.config/share/config.json
{
"apiUrl": "https://s.your-domain.com",
"imgUrl": "https://img.your-domain.com",
"apiKey": "sk-share-xxxx",
"vaultPath": "/Users/you/Documents/ObsidianVault",
"autoCover": true,
"coverOnlyColumn": true,
"coverRefreshPolicy": "smart",
"compressImageBeforeUpload": true,
"imageUploadFormat": "webp",
"imageUploadQuality": 82,
"imageUploadMaxWidth": 1600
}
可选环境变量(AI 脱敏 / AI 标签等):
export AI_BASE_URL="https://ai.chen.rs/v1"
export AI_API_KEY="sk-..."
第 4 步:做一个“分身人格”文件(AGENTS Lite)
在 mom-share-lite/AGENTS.md 放这个最小版本:
# mom-share-lite
你是一个内容发布分身,只负责:
1) 文章/笔记发布到 share
2) 图片上传到 img
3) 碎碎念发布
4) share -> X 推文草稿与发布
原则:
- 发外网前先确认(默认预览)
- 不能泄露密钥
- 修改后必须给出验证结果
- 不做服务器运维、不做代理维护
这样它就是一个“专职内容助手”,不会越界干别的活。
第 5 步:跑通三条主工作流
A. 文章发布(本地 Markdown → Share)
示例文章:
---
title: "Hello Share"
slug: "hello-share"
category: "专栏"
tags: ["专栏", "demo"]
summary: "这是一篇演示文章"
share: true
---
# Hello Share
这是一篇演示文章。
发布:
bun tools/share.ts ./hello-share.md
你会得到:
- 线上链接:
https://s.your-domain.com/hello-share - 本地 frontmatter 自动回填
share_url
B. 碎碎念发布(短内容)
bun tools/mom-note.ts "今天把 mom-share-lite 跑通啦" --save
效果:
- 发布到
category = mom - 自动保存到 Obsidian 日记目录(可配置)
C. 发布后发 X(share → x)
# 默认:先发布 share,再生成推文草稿(预览模式)
bun tools/share-to-x.ts --file ./hello-share.md
# 真正发出
bun tools/share-to-x.ts --file ./hello-share.md --submit
默认文案会带 【自动】 前缀,避免误导成纯手发。
第 6 步:接入 Obsidian 插件(可选,但推荐)
插件配置好后,命令面板里可以直接:
- 发布当前笔记
- 重新发布
- 取消发布
- 复制分享链接
发布成功后 frontmatter 会自动更新:
share: trueshare_url: ...- 自动补
shared标签(若不存在)
这一步能把“命令行发布”变成“点一下就发布”。
第 7 步:验证清单(照着勾就行)
-
GET /api/verify返回valid: true - 上传本地图片后拿到
img.your-domain.com/... - 发布文章后能打开
https://s.your-domain.com/<slug> - 首页能看到文章,分类页正常
-
mom-note能发布并出现在/c/mom -
share-to-x能生成推文草稿(默认预览)
常见坑(我实际踩过的)
1) 发布成功了,但页面 404
通常是 PUBLIC_URL 和路由没配对,或者 slug 命中了保留路径(如 api/admin/archive)。
2) 图片链接是本地路径
说明图片上传流程没走通:检查 imgUrl、API_KEY、图片格式是否在白名单。
3) 本地有密钥,线上文章被暴露
要开启 share.ts 默认脱敏链路(规则 + AI),不要在发布时加 --no-sanitize。
4) 推文发帖失败
先用预览模式验证文本,再检查 Chrome Profile / CDP 端口 / 登录状态。
一套“可长期用”的日常节奏
我现在是这么跑的:
- 平时在 Obsidian 写
- 写完用插件或
share.ts发布 - 需要传播时再走
share-to-x - 临时动态用
mom-note
这套的重点不是“炫技”,而是:
- 入口统一
- 配置集中
- 默认安全
- 对外动作可控(先预览再发布)
你只要把这四件事守住,就拥有了一个稳定的 内容发布分身。
附录 A:最小命令速查
# 发布单篇
bun tools/share.ts article.md
# 发布 share: true 的所有文章
bun tools/share.ts --all
# 取消发布
bun tools/share.ts --unpublish <slug>
# 查看已发布
bun tools/share.ts --list
# 发布碎碎念
bun tools/mom-note.ts "内容" --save
# share -> X(预览)
bun tools/share-to-x.ts --file article.md
附录 B:建议的 frontmatter 模板
---
title: ""
slug: ""
category: "专栏"
tags: ["专栏"]
summary: ""
share: true
---
(如果只是草稿,先用 share: false。)