Share

外观
风格

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

2026年2月9日 · 专栏

封面图

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

我有一段时间特别想要一个「只管内容发布」的小助手:

  • 写完笔记,一键发网页
  • 图片自动处理,不手搓链接
  • 想发条短动态(碎碎念),也能走同一套系统
  • 发完文章顺手生成推文草稿

最后我把它做成了一套轻量工作流。你可以把它理解成 Mom 的一个分身: 只做内容这件事,不管服务器运维,不管别的杂活。

这篇就是完整复刻指南:你只要建一个文件夹、填几份配置,就能跑起来。


你会得到什么(功能清单)

跑通后,你有 6 个核心能力:

  1. Markdown 发布到网页(支持分类、标签、归档、文章页)
  2. 图片自动上传图床(内容哈希去重 + 长缓存)
  3. Obsidian 一键发布(插件里点一下就发)
  4. 碎碎念发布(短内容单独分组)
  5. share → X(发布后自动生成推文草稿,可预览再发)
  6. 管理后台(查看、复制链接、删除文章)

架构全景(先有图,后落地)

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: true
  • share_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) 图片链接是本地路径

说明图片上传流程没走通:检查 imgUrlAPI_KEY、图片格式是否在白名单。

3) 本地有密钥,线上文章被暴露

要开启 share.ts 默认脱敏链路(规则 + AI),不要在发布时加 --no-sanitize

4) 推文发帖失败

先用预览模式验证文本,再检查 Chrome Profile / CDP 端口 / 登录状态。


一套“可长期用”的日常节奏

我现在是这么跑的:

  1. 平时在 Obsidian 写
  2. 写完用插件或 share.ts 发布
  3. 需要传播时再走 share-to-x
  4. 临时动态用 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。)