v0.1.0
Mebbling
自架的 Memos 公開貼文 Hub。將朋友各自 Memos 中的公開貼文集中展示,同時保留 Hub 內的留言、表情回應與發文功能。
功能
- 匯入多個 Memos 來源的
PUBLIC貼文、標籤與附件。 - 圖片在首頁與文章頁直接顯示;點擊後以站內全螢幕燈箱檢視。
- Hub 使用者可留言、表情回應,並可將新貼文推送到已連接的 Memos。
- 同一個「Memos 網址 + Memos 帳號」只建立一個共享來源,避免重複同步及重複貼文。
- 使用者可加入共享來源並手動同步或發文;僅來源建立者能管理 webhook URL。
- Webhook URL 採不可猜測的隨機密鑰路徑、雜湊保存與簡易速率限制。
- 控制台會顯示最近一次收到 webhook 的時間及最後同步時間。
快速啟動(WSL/Docker)
cp .env.example .env
# 編輯 .env,至少設定 SESSION_SECRET、TOKEN_ENCRYPTION_KEY、ADMIN_USERNAME、ADMIN_PASSWORD
docker compose up --build -d
預設網址為 http://localhost:8088。停止服務:
docker compose down
查看服務狀態與日誌:
docker compose ps
docker compose logs -f web worker
環境變數
以 .env.example 為範本。正式環境請更換所有 secret,且不要將 .env 加入 Git。
| 變數 | 用途 |
|---|---|
SESSION_SECRET |
登入 session 的簽章密鑰。請使用長隨機字串。 |
TOKEN_ENCRYPTION_KEY |
Memos Token 的 AES-256-GCM 加密金鑰,必須為 64 個十六進位字元。 |
ADMIN_USERNAME / ADMIN_PASSWORD |
首次啟動時建立的管理員帳號。 |
NEXT_PUBLIC_APP_URL |
Hub 的對外 HTTPS 網址,例如 https://mebbling.example.com。Webhook URL 以此組成。 |
UPLOAD_MAX_BYTES |
Hub 發文上傳附件的單檔上限,預設 10 MiB。 |
SYNC_INTERVAL_MINUTES |
背景校正同步的間隔,預設 60 分鐘。 |
SEED_MEMOS_* |
選填;首次啟動時自動建立管理員的第一個 Memos 來源。 |
系統架構
flowchart LR
Visitor[訪客/Hub 使用者] --> Web[Next.js Web\nport 8088]
Web --> DB[(SQLite\ndata/hub.db)]
Web --> Uploads[附件\npublic/uploads]
Memos[Memos 來源] -->|Webhook| Web
Web -->|建立同步工作| Jobs[同步佇列\nsync_jobs]
Worker[背景 Worker] --> Jobs
Worker --> DB
Worker <-->|Memos API| Memos
Worker --> Uploads
Web 接收使用者操作和 webhook,將同步需求寫入 SQLite 的 sync_jobs。背景 Worker 每 5 秒處理一項工作,負責:
- Pull:從 Memos 取得公開貼文,更新 Hub 鏡像;已刪除或非公開的遠端貼文會在 Hub 隱藏。
- Push:把 Hub 建立的貼文與本機附件上傳/回寫到選定的 Memos 來源。
- 排程校正:依
SYNC_INTERVAL_MINUTES定期建立 Pull 工作,避免 webhook 遺漏造成資料不同步。
Webhook 設定與驗證
- 來源建立者登入「控制台」。
- 在來源卡片按「產生 webhook URL」,立即複製完整網址。
- 在該 Memos 帳號的 webhook 設定中貼上網址。
- 在 Memos 發布或更新一篇公開貼文。
- 回到 Hub:顯示「最近收到」代表 Hub 確實收到 webhook;「上次同步」更新則代表同步已完成。
網址格式如下;來源 ID 與 隨機密鑰 都由系統產生,請勿自行修改:
https://你的網域/api/sync/webhook/來源ID/隨機密鑰
重新產生 webhook URL 會立即使舊 URL 失效。共享來源的其他成員可查看接收狀態,但沒有產生或輪替密鑰的權限。
專案結構
.
├── app/ # Next.js App Router:頁面、元件與 API
│ ├── api/ # 登入、來源、發文、同步、webhook 等路由
│ ├── components/ # 可重用 UI,例如附件圖片燈箱
│ ├── dashboard/ # 來源管理、發文與 webhook 控制台
│ ├── posts/[id]/ # 單篇貼文頁
│ ├── page.tsx # 公開貼文首頁
│ ├── layout.tsx # 全站版型與導覽
│ └── styles.css # 全站樣式
├── lib/ # 共用伺服器邏輯
│ ├── auth.ts # Session 與權限
│ ├── crypto.ts # Token 加解密
│ ├── db.ts # SQLite schema 與輕量遷移
│ ├── memos.ts # Memos API 封裝
│ ├── webhook.ts # Webhook 密鑰產生、雜湊與驗證
│ └── rate-limit.ts # Webhook 簡易速率限制
├── worker/ # 背景同步 worker
├── public/uploads/ # Hub 上傳附件的持久化資料
├── data/ # SQLite 資料庫持久化資料
├── Dockerfile # Web/Worker 共用映像檔
├── docker-compose.yml # web + worker 服務與 volume 掛載
└── .env.example # 環境變數範本
data/ 與 public/uploads/ 是正式資料,備份時請一併備份。.next/ 與 node_modules/ 是可重新產生的建置/依賴資料,不需備份。
正式部署
將 NEXT_PUBLIC_APP_URL 設成實際 HTTPS 網域,並以反向代理將該網域導向 Web 容器的 3000 連接埠(或主機的 8088 對應埠)。務必確保外部可連到 webhook URL,否則仍會由定期校正同步補回資料,但不會即時更新。
Languages
TypeScript
93.9%
Shell
4.5%
JavaScript
1.2%
Dockerfile
0.3%
CSS
0.1%