窩的家系統運作流程圖
8 張圖看懂自動化系統怎麼工作
更新日期:2026-05-09
怎麼看這份文件?
這份是窩的家所有自動小幫手(Bot)的工作圖鑑。每張圖回答一個問題:誰在哪裡?訊息怎麼跑?小幫手出問題怎麼救?
8 張圖按「從大到小、從正常到故障」排序。沒空的話只看圖 1(全貌)+ 圖 5(壞了怎麼辦)就夠用。
難字白話對照表
- Bot / 機器人24 小時值班的小幫手,像不會睡覺的便利商店店員
- API服務窗口(LINE 窗口、104 窗口、Anthropic 窗口)
- OAuth Token進門鑰匙,1 年到期要換
- Mac Mini Server24 小時開機那台「總機電腦」
- Windows 客戶端Joan 平常工作那台筆電
- Ragic公司線上資料庫,所有報表存這
- n8n自動化流水線,把不同工具串起來跑
- VaultJoan 的第二大腦筆記庫
- Webhook別人有事自動敲門通知我們
- launchdMac 內建的「保母」,負責讓服務不死
- Anthropic APIClaude AI 的「大腦」窗口
- Tailscale把不同機器接成同一個內網的工具
圖 1跨機系統總覽
Win 客戶端 / Mac server / 雲端三邊資料怎麼流,用戶從哪些介面進來。
想像窩的家有兩個房間:Joan 的辦公桌(Windows 筆電)和 24 小時值班室(Mac Mini)。員工、房客、外部廠商從手機(Telegram / LINE)進來,小幫手在值班室處理事情,再把結果寫進公司的線上檔案櫃(Ragic / GitHub)。
flowchart LR
subgraph U["使用者"]
Joan["Joan 老闆"]
Emp["窩的家員工"]
Tenant["房客 / 屋主"]
Vendor["外部廠商"]
Family["簡家家人"]
end
subgraph P["公開介面"]
TG["Telegram API"]
LINE["LINE API"]
Pages["GitHub Pages"]
Funnel["Tailscale Funnel"]
Ngrok["ngrok tunnel"]
end
subgraph W["Windows 客戶端"]
Vault[("Vault
C:/Second Brain")]
CCC["Joan Claude Code"]
end
subgraph M["Mac Mini Server (24/7)"]
Bots["Bot 集群
5 活躍 + plaud-api
:18800-18807"]
N8N["n8n :5678"]
Scripts["104 / 591 / Plaud
本機腳本"]
Mem["Memory Engine"]
end
subgraph C["雲端"]
Anth["Anthropic API"]
Ragic[("Ragic ap15")]
GH["GitHub wuohome"]
end
Joan --> CCC
CCC -. SSH/scp .-> M
Vault <-. sync .-> M
Emp --> TG
Family --> TG
Tenant --> LINE
Vendor --> LINE
Tenant --> Pages
TG --> Bots
LINE --> Funnel --> N8N
LINE -. 採購 OA .-> Ngrok --> Bots
Pages -. 讀寫 .-> Ragic
Bots --> Anth
N8N --> Ragic
Scripts --> Ragic
Pages --> GH
圖 2訊息端到端流
Joan 在 Telegram 傳訊息 → claude 推論 → 回覆,總時延 ~700ms-8s。
Joan 在 Telegram 打字 → 小幫手收到 → 跑去問大腦(Claude AI)怎麼回 → 大腦想完答案 → 小幫手轉述給 Joan。整段不到 8 秒,跟 Google 一下差不多快。中間 Claude 還能「動手做事」(例如 SSH 進 Mac 跑 591 檢查腳本),不只是回字而已。
sequenceDiagram
actor Joan
participant TG as Telegram Cloud
participant SRV as server.mjs :18802
participant CLI as claude CLI
participant ANT as Anthropic API
Joan->>TG: 傳「幫我看 591 廣告」
Note over TG: 訊息暫存
等 bot 拉走
SRV->>TG: getUpdates (long polling)
TG-->>SRV: {chat_id, text}
SRV->>CLI: MCP stdio 餵訊息
Note over CLI: 載 CLAUDE.md
Opus 4.7 推論
CLI->>ANT: 推論請求 + OAuth
Note over ANT: 計入 Joan Max quota
(5h 共用)
ANT-->>CLI: streaming response
Note over CLI: tool call 例:
Bash ssh Mac
跑 591 check.py
CLI->>SRV: MCP sendMessage()
SRV->>TG: bot API sendMessage
TG-->>Joan: 顯示回覆
Note over Joan,ANT: 總時延 ~700ms-8s
圖 3Bot 啟動鏈
launchd → supervisor → tmux → run-session.sh → claude CLI → server.mjs,6 層保險誰負責什麼。
小幫手要「醒來上班」要走 6 個步驟,像俄羅斯娃娃一層包一層:最外面是 Mac 自帶的保母(launchd)→ 把它放進一個工作棚(tmux)→ 棚裡有個無限迴圈會把它叫起來(run-session.sh)→ 啟動 Claude → 開好接訊息的窗口。任何一層死掉,外面那層會把它叫醒。
flowchart TD
A["Mac 開機 或 手動 launchctl load"] --> B["launchd
com.claude.bot.plist"]
B -->|RunAtLoad + KeepAlive| C["launchd-tmux-supervisor.sh"]
C --> D["tmux new-session -d
-s claude-bot"]
D --> E["run-session.sh
bash while 無限迴圈"]
E --> F["claude CLI
--dangerously-load-development-channels
server:channel"]
F --> G["讀 ~/.claude/CLAUDE.md
+ repo CLAUDE.md
+ .claude/settings.json"]
G --> H["spawn server.mjs
(MCP stdio child)"]
H --> I["server.mjs 開 health port
+ Telegram getUpdates 或 LINE webhook"]
I --> J["Bot 上線 等訊息"]
J -. claude exit .-> E
J -. bash 死 .-> B
style J fill:#0070F3,color:#fff
style E fill:#FFFBEB,color:#000
style B fill:#F0F7FF,color:#000
圖 4OAuth oat01 認證流
Joan 一次 setup-token,注入 4 隻 Telegram bot .env,1 年期,2027-04-28 前換。LINE 採購已獨立直連 API Key。
Joan 每年產一把大門鑰匙(OAuth Token),複製給 4 隻 Telegram 小幫手共用,這樣它們才能跟 Claude AI 對話且計算進 Joan 的訂閱額度(不另外刷信用卡)。鑰匙有效 1 年,下次要換是 2027-04-28。系統有個 oauth_check 每天偷看一次,到期前 14 天就會推 Joan。
flowchart LR
A["Joan
Windows"] -->|一次手動| B["claude setup-token"]
B --> C["sk-ant-oat01-...
有效 1 年"]
C --> D["scp 注入 5 隻 .env"]
D --> E1["claude-telegram-channel/.env"]
D --> E2["claude-telegram-doctor/.env"]
D --> E3["claude-telegram-secretary/.env"]
D --> E4["claude-telegram-wealth/.env"]
D --> E5["claude-line-purchase
已脫離 OAuth 流
(2026-04-27 起直連 API Key)"]
E1 --> F["claude CLI 讀 env
走訂閱模式"]
E2 --> F
E3 --> F
E4 --> F
E5 --> G2["獨立 ANTHROPIC_API_KEY
claude-sonnet-4-6 直連"]
F --> H["Anthropic API
認 OAuth bearer
計 Max quota"]
G2 --> H2["Anthropic API
認 x-api-key
不計 Max quota"]
I["oauth_check.py 每日"] -. 讀 env .-> E1
I -->|過期 14d 內| A
style C fill:#FFFBEB
style H fill:#ECFDF5
圖 5故障決策樹
Bot 出問題 → 1 隻 vs 全部 → 對應症狀 → SOP。
小幫手生病的分診流程。第一個問題:一隻不舒服 vs 全部不舒服?
全部 → 通常是大門鑰匙過期,重產一次再分發。
一隻 → 看症狀對應 SOP(401 鑰匙沒更新 / 429 跑錯版本 / 沒反應 = 假活 / 訊息卡 / 答錯 = session 過期)。
最神秘那種「我也不知道怎麼了」,丟給 Doctor 自動修。
全部 → 通常是大門鑰匙過期,重產一次再分發。
一隻 → 看症狀對應 SOP(401 鑰匙沒更新 / 429 跑錯版本 / 沒反應 = 假活 / 訊息卡 / 答錯 = session 過期)。
最神秘那種「我也不知道怎麼了」,丟給 Doctor 自動修。
flowchart TD
Start["Bot 出問題"] --> Q1{"幾隻掛?"}
Q1 -->|"1 隻"| Q2{"症狀?"}
Q1 -->|"全部"| F1["OAuth 過期
或 token revoke"]
F1 --> S1["1. Win 重跑 claude setup-token
2. 更新 5 隻 .env
3. 依序重啟 bot"]
Q2 -->|"401"| F2["該 bot .env
token 沒更新"]
Q2 -->|"429"| F3["LINE 採購 rate limit
(直連 API)"]
Q2 -->|"沒反應
health port 沒 LISTEN"| F4["假活
server.mjs 死"]
Q2 -->|"訊息卡住
pending > 0"| F5["Telegram 佇列卡"]
Q2 -->|"答錯/吃舊規則"| F6["session 過期"]
Q2 -->|"完全不知道"| F7["Doctor /inject"]
F2 --> S2["scp 補 .env
+ launchctl kickstart"]
F3 --> S3["等候退避重試
或檢查 API Key 用量"]
F4 --> S4["check_health_port
60s streak 自動殺 claude"]
F5 --> S5["launchctl unload+load
+ pkill"]
F6 --> S6["在 Telegram 傳 /new
SIGTERM ppid 重讀"]
F7 --> S7["Doctor Opus xhigh
讀錯誤+vault 自動修"]
style Start fill:#FEF2F2
style F1 fill:#FFFBEB
style S1 fill:#ECFDF5
style S2 fill:#ECFDF5
style S3 fill:#ECFDF5
style S4 fill:#ECFDF5
style S5 fill:#ECFDF5
style S6 fill:#ECFDF5
style S7 fill:#ECFDF5
圖 6n8n LINE Collector 分支
LINE webhook 進來後,按 keyword 分支去哪個系統處理。
LINE 訊息進來時的分類郵差。看訊息開頭關鍵字:
/廣告刊登、/廣告到期、/誰沒補、/精選置頂 → 591 廣告管家處理
/點名 → 每日行程點名,寫進 Ragic
沒關鍵字 → 只記錄到資料庫,每小時整理一次推 Joan
(採購是另一條獨立 OA,不走這條 webhook)
/廣告刊登、/廣告到期、/誰沒補、/精選置頂 → 591 廣告管家處理
/點名 → 每日行程點名,寫進 Ragic
沒關鍵字 → 只記錄到資料庫,每小時整理一次推 Joan
(採購是另一條獨立 OA,不走這條 webhook)
flowchart TD
A["LINE OA push
/webhook/line-webhook"] --> B["n8n LINE Collector
GlJlOzMj9rhYUlFO"]
B --> C["拆 message events"]
C --> D{"keyword?"}
D -->|"/廣告刊登 /廣告到期
/誰沒補 /精選置頂"| E1["591 廣告管家"]
D -->|"點名"| E2["每日行程點名
Reply Message"]
D -->|"無 keyword"| E3["寫 line_messages 表"]
D -.採購由獨立 OA.- E4["LINE 採購 Bot :18801
非 webhook"]
E1 --> F1["回 LINE 群組"]
E2 --> F2["填 ragicforms4/20004
+ property-data-kept/9"]
E3 --> G["每小時 SEC workflow
EVTExdTA54AsDweL"]
G --> H["秘書 SEC bot 整理"]
H --> I["Telegram 推 Joan"]
E4 --> F4["claude-agent-sdk
建 Ragic 採購單"]
style A fill:#F0F7FF
style I fill:#FDF2F8
style F1 fill:#ECFDF5
style F2 fill:#ECFDF5
style F4 fill:#ECFDF5
圖 7104 招募流
n8n schedule 已退役;改用 launchd cron 每 30 分跑 poll-applications.js(Puppeteer)→ 關鍵字偵測房地產同業 → 結構化事件直接回應 / freeText 走 HR Agent → 推 HR Telegram bot。
招募自動化跑兩條並行的線:結構化事件(系統知道狀態變了,例如「同意面試」)→ poll-applications.js 直接照 business-rules.json 分流回應;freeText(候選人寫自由文字「我想改 5/15」)→ 呼叫 HR Agent 用 Claude 判意圖、自動回信 + 改 TimeTree。不寫 Ragic,候選人狀態存本機 seen-candidates.json + SQLite。通知都走獨立的 HR Telegram bot(不是平常 Joan 對話的小特助 CC)。
sequenceDiagram
participant Cron as launchd cron
(每30分)
participant Poll as poll-applications.js
(Mac Mini)
participant TZ as 104 企業後台
(Puppeteer)
participant Rules as business-rules.json
participant SI as seen-candidates.json
+ SQLite
participant HR as lib/hr-agent.js
(Claude Sonnet)
participant TT as TimeTree
participant TG as Telegram
HR bot 8401828070
Cron->>Poll: 觸發
Poll->>TZ: 抓應徵資料 + 訊息
Poll->>Poll: seen-messages.json 去重
alt 結構化事件
Poll->>Rules: 查分流
Rules-->>Poll: direct_invite / notify_only
Poll->>Poll: 關鍵字偵測
房地產同業
Poll->>TZ: 發詢問 / 直接邀約
Poll->>TT: 寫面試時段
Poll->>SI: 更新狀態
Poll->>TG: 推進度條
else freeText
Poll->>HR: 呼叫 hr-agent.js
HR->>HR: Claude 判 intent
(改期/問地址/爽約)
HR->>TZ: 自動回覆
HR->>TT: 改期
HR->>SI: 寫決策 log
HR->>TG: 已自動處理
end
圖 8Watchdog 4 層保險
Bot 死掉時 4 層接力救活,反應時間從 <1s 到人工。
小幫手死掉時的四層保險,越外層反應越慢但越牢靠:
L1 自己重啟(不到 1 秒)— 程式自己有迴圈,掛了重來
L2 系統托管(約 20 秒)— Mac 內建保母 launchd 把整個程式叫醒
L3 監控推 Joan(10–15 分鐘)— 連兩次 ping 不到就 Telegram 通報
L4 Joan 親自上場 — SSH 進去看,或重產鑰匙
L1 自己重啟(不到 1 秒)— 程式自己有迴圈,掛了重來
L2 系統托管(約 20 秒)— Mac 內建保母 launchd 把整個程式叫醒
L3 監控推 Joan(10–15 分鐘)— 連兩次 ping 不到就 Telegram 通報
L4 Joan 親自上場 — SSH 進去看,或重產鑰匙
flowchart LR
subgraph L1["L1 run-session.sh"]
L1A["bash while 無限迴圈
claude exit → respawn
401 → pkill+重啟
health port 60s streak"]
end
subgraph L2["L2 launchd KeepAlive"]
L2A["launchctl 托管
bash 死 → 20s 復活
透過 supervisor wrapper"]
end
subgraph L3["L3 bot-cluster-monitor"]
L3A["每 5 min
直 curl Telegram API
連 2 次失敗才推
cooldown 6h"]
end
subgraph L4["L4 人工"]
L4A["Joan 收推
SSH 進 Mac
或 setup-token"]
end
L1 --> L2
L2 --> L3
L3 --> L4
R1["反應 < 1s"] -.-> L1
R2["反應 ~20s"] -.-> L2
R3["反應 10-15min"] -.-> L3
R4["反應 人工"] -.-> L4
style L1 fill:#ECFDF5
style L2 fill:#FFFBEB
style L3 fill:#FFF7ED
style L4 fill:#FEF2F2