開源的 Chrome 擴充功能。在 Facebook / Threads / X / Instagram / LinkedIn 滑到一則覺得受用的貼文,按一下就存進你自己 Google Drive,並可同步進 Focus4ai 知識庫:
- 一篇一份 Google Doc,檔名是
日期_主題_發文者,例如20260813_開會前先把想問的問題寫下來_王小明 - 圖片直接嵌在 Doc 裡,不是存一條幾天後會失效的網址
- 文件開頭附原文連結,隨時跳回去看留言
- 同一篇收第二次會先問你,並附上先前那份的連結
- 最小權限:只用
drive.filescope,只碰這個擴充自己建立的檔案, 看不到你 Drive 裡的其他東西
兩種方式,都是自己按的:
右鍵(建議)——在貼文上按右鍵 →「⚡ 收這篇貼文」。 指哪篇收哪篇,沒有歧義;點在留言上也會收到整篇,不會只收到那則留言。 浮動按鈕因為版面或改版沒出來的時候,這條路還在。
浮動按鈕 —— 捲動到一則貼文,右邊會浮出 「⚡ 收這篇」, 同時那一則會有一圈淡紫外框,告訴你按下去會收哪一篇。
快速鍵預設沒有綁(免得跟慣用的鍵打架)。要的話到
chrome://extensions/shortcuts 找 Post Sync 自己設一組。
擷取一律是你自己按的。沒有任何自動收集,也不會自己捲動頁面 —— 那一秒就會從「使用者閱讀」變成「自動化擷取」,帳號風險完全不同。
| 存什麼 | 給誰用 | |
|---|---|---|
| Google Drive | 一篇一份 Doc,圖片嵌在裡面 | 給人看的 |
| Focus4ai 知識庫 | Markdown,寫入就切片建索引 | 給檢索用的 |
一邊掛了不影響另一邊。只想用知識庫、不接 Drive 也可以。
三分鐘,不需要開發環境,也不需要 npm。
第一步:把檔案拿到手(兩種都可以)
-
不會用 git:按這個 repo 上方綠色的
Code→Download ZIP, 解壓縮後你要的是裡面的extension資料夾。 -
會用 git:
git clone https://github.com/Joanna8521/PostSync.git
把它放到你放得住的地方(例如「文件」)。
第二步:載入 Chrome
- 網址列輸入
chrome://extensions,右上角把「開發人員模式」打開。 - 按左上角**「載入未封裝項目」**,選
extension這個資料夾 (選到裡面看得到manifest.json的那一層),按「選取」。 - 裝好後會自動打開設定導覽頁,按 「連接 Google」 用自己的帳號授權。
- 打開 facebook.com,捲到一則貼文,右邊會浮出「⚡ 收這篇」。
授權畫面上的權限只有一條:「查看及管理這個應用程式建立的雲端硬碟檔案」 —— 它看不到你 Drive 裡的其他東西。
-
選了資料夾卻說「資訊清單檔案遺失」 選錯層了。要選到裡面有
manifest.json的那一層。 -
按了沒反應/看不到浮動按鈕 回到那個分頁按
Cmd+R(Windows 是F5)重新整理。 擴充需要頁面重新載入才會生效。還是不行就點擴充圖示按 「檢查目前分頁」,它會直接告訴你偵測到幾則貼文。 -
Chrome 重開後跳出「停用開發人員模式擴充功能」 按「取消」就好,這是 Chrome 對未上架擴充的例行提醒。
manifest 內含固定的 key(公鑰),所以每個人載入後的擴充 ID 都相同:
mbckgmofgjkmfjofljddhgbhglfhjbom,共用同一個 OAuth client 才會成立。
manifest.json 裡已經內含一組 OAuth client_id,裝完直接按「連接 Google」就能用,
不需要自己設定任何東西。Chrome 擴充的 OAuth client 沒有 secret,client_id 本來就是
公開資訊,寫在開源專案裡是標準做法。
想完全自主(資料流從頭到尾只經過你自己的 GCP 專案)的話,自己建一組換掉:
-
到 Google Cloud Console 建一個專案, 啟用 Google Drive API 與 Google Docs API:
gcloud projects create <你的專案 ID> --name="Post Sync" gcloud services enable drive.googleapis.com docs.googleapis.com --project=<你的專案 ID>
-
「Google 驗證平台」→「開始使用」(Google 在 2025 年把「OAuth 同意畫面」 搬進這裡,選單位置跟舊教學不一樣): https://console.cloud.google.com/auth/overview 應用程式名稱自訂、目標對象選「外部」。
-
「資料存取權」→ 新增範圍
.../auth/drive.file。 這是非敏感 scope,不需要 Google 審查,也沒有測試使用者 100 人上限。 -
「目標對象」→「發布應用程式」。留在測試中的話只有名單裡的帳號能用, 而且 refresh token 七天就過期 —— 症狀是「上禮拜還好好的,今天按了就失敗」, 錯誤訊息完全不會提到七天這件事。
-
「用戶端」→「建立用戶端」→ 應用程式類型選「Chrome 擴充功能」, 項目 ID 填
mbckgmofgjkmfjofljddhgbhglfhjbom, 把拿到的 client ID 填進extension/manifest.json的oauth2.client_id。
⚠️ 同意畫面的「應用程式標誌」不要上傳。 一旦上傳 logo,這個 app 就會被歸入 需要 Google 品牌驗證的流程,而drive.file本來完全不需要審查。 為了一張圖換來幾天到幾週的等待,不划算。商店的圖示是另一套,跟這裡無關。
manifest.json 的 key(公鑰)決定擴充 ID,而 Console 裡填的項目 ID 必須跟它一致,
不然會一路授權失敗、而且錯誤訊息不會告訴你原因。改動 key 之後用這段對一次:
python3 -c "import json,base64,hashlib;d=base64.b64decode(json.load(open('extension/manifest.json'))['key']);print(''.join(chr(ord('a')+int(c,16)) for c in hashlib.sha256(d).hexdigest()[:32]))"fbcdn 的圖片網址帶時效 token,存網址等於存一個幾天後變 404 的東西。
所以一定要讓 Doc 擁有自己的副本,做法有兩層:
- 直接把原網址交給 Docs API 的
insertInlineImage—— Google 會在插入的當下把圖抓下來存進文件,原網址之後失效也不影響。最快。 - 被擋就自己下載 —— 擴充有這些圖床的 host 權限,帶得動簽章網址。 下載後上傳到 Drive、開連結權限幾秒讓 Docs 抓走,抓完立刻收回權限並刪掉暫存檔。
一張一張處理,一張壞掉不會讓其他張跟著沒了。兩層都失敗才退回貼網址, 而且會在 Doc 裡明講「這些網址通常幾天後就會失效」,不會假裝收好了。
在 popup 開啟「同步到 Focus4ai 知識庫」後,每次收錄除了寫進 Drive,
還會以 Markdown 寫進知識庫並當場切片建索引(走 PUT /api/doc,不需修改 Focus4ai)。
- 網址填站台根位址(線上站台是
https://app.focus4ai.com)。 注意focus4ai.com是官網、沒有 API,填了會被擋下來並說明原因。 - 資料夾預設
00_inbox/post-sync。 - local_only:預設不標記。社群貼文多半是公開內容,標了就進不了檢索, 等於白收。收私密社團的東西再打開這個開關。 (這跟 Mesh Sync 相反 —— 那邊收的是自己的 AI 對話,常有客戶名與報價。)
- 站台有登入牆時,擴充會帶著你在同一個瀏覽器的登入 session;請先登入再同步。 被導到登入頁時會明確報錯,不會謊報成功。
extension/
├── manifest.json # MV3,含固定 key(公鑰)與 oauth2 設定
├── popup.html # 收藏對象切換、連線狀態、Focus4ai 設定、寫入紀錄
├── onboarding.html # 安裝後自動打開的設定導覽
├── icons/
└── src/
├── adapters.js # 各平台的錨點(唯一需要跟著平台改版調的地方)
├── naming.js # 檔名主題(service worker 與測試共用)
├── extract.js # DOM → 資料(純函式,可測)
├── content.js # 浮動按鈕、展開全文、toast
├── background.js # OAuth、Drive、圖片嵌入、Focus4ai、去重
├── popup.js
├── onboarding.js
└── toast.css
tests/
├── run.html # 抽取層:用瀏覽器直接打開就跑
└── live.html # 浮動按鈕:假動態牆+假的 chrome API,實際跑 content.js
key.pem(專案根目錄、不進 git):打包 .crx 時才需要的私鑰。 載入未封裝不需要它。
python3 tools/run_tests.py # 抽取層,全綠才算過
python3 tools/check_permissions.py # manifest 的權限涵蓋度也可以用瀏覽器直接打開 tests/*.html 自己看。那樣要記得在網址後面加
?v=2 之類的參數,不然瀏覽器會拿快取裡的舊檔,你會看到「改了沒反應」。
tests/run.html —— 抽取層。釘住的是那種壞了不會有任何畫面告訴你的事:
- 留言被當成貼文(臉書的留言才是
role="article",貼文是div[aria-labelledby]) - 整個動態牆被當成「一則超大貼文」
- 臉書的反爬混淆字元被收進內文、作者、檔名
- 作者名黏著「已驗證帳號」「追蹤」「分享對象:所有人」
- 右鍵點在留言上,收到的是那則留言而不是整篇
- 頭像被當成內容圖片
- permalink 帶著追蹤參數 → 同一篇每次指紋都不同 → 去重整個失效
- 平台改版讓內文容器落空 → 安靜地收到一份空的
- 作者名或時間戳變成檔名 → 整個資料夾看起來都一樣
- 臉書送不同的 DOM 給不同人(A/B 測試與分批推送)。已知在用的三種
貼文容器:
role="article"、div[aria-labelledby]、div[aria-posinset], 三種各有 fixture。「我這邊可以」在這個平台上不能推論到別人身上。
tests/live.html —— 浮動按鈕。假的動態牆+假的 chrome API,
實際把 content.js 跑起來,左下角面板會報出:content script 有沒有注入、
偵測到幾則貼文、按鈕的 display/z-index/座標、有沒有跑出畫面。
「按鈕沒出現」的時候先看這一頁,能分辨是程式的問題還是環境的問題。
python3 tools/check_permissions.py —— 權限涵蓋度。改過 manifest.json
之後跑一次。
match pattern 寫錯不會有任何錯誤訊息:Chrome 只是安靜地不注入 content script、或安靜地擋掉 background 的 fetch,而症狀看起來完全像別的問題 (「這個平台沒反應」「圖片收不到」)。所以這支腳本自己實作一遍 Chrome 的 比對規則,拿真實的網址形狀去對:
- content script 的 matches 有沒有涵蓋各平台真正的網址形狀
(臉書的
/photo/?fbid=、Threads 新舊兩個網域、X 與 twitter.com…) - host_permissions 有沒有涵蓋四個圖床與三個 Google API
- 反過來,有沒有多要權限——宣告了卻沒有任何程式會用到的, 只會拖慢商店審查
- 手機上沒有浮動按鈕。 iOS/Android 都不允許在臉書 App 裡注入 UI。
行動端要另外走 Safari Web Extension(可以,但要 Xcode 與開發者帳號)
或 iOS 捷徑+OCR,而後者需要 Focus4ai 先提供一條帶 token 的寫入 API ——
目前的寫入靠瀏覽器 session(
credentials: 'include'),手機捷徑沒有 session。 - X 的長推文可能只收到截斷版。 X 的「Show more」是一條連結, 按下去會直接跳走,所以程式不點它。收到截斷內容好過整個跳頁。
- LinkedIn 不把 permalink 放在 DOM 上,靠
data-id/data-urn上的 activity urn 組出來。它的版面改動也比其他平台頻繁(貼文容器現在是role="listitem",舊版的.feed-shared-update-v2已經沒有了)。 - Instagram 的貼文容器沒有任何語意屬性(沒有
role、沒有data-testid, class 全是.html-div),所以改成從永久連結a[href*="/p/"]往上爬到 第一個同時有<time>與<img>的祖先。照語意找,不是照長相找。 - 平台改版可能讓抓取失準。 錨點全部集中在
src/adapters.js, 改一個檔就好。抓不到內文時畫面上會明講,不會安靜地收一份空的。 - 上架 Chrome Web Store 需要說明用途。 宣告了 facebook.com 這類
host permission 會被審查問「為什麼需要」。要降低審查摩擦的話,
可以改成
optional_host_permissions+chrome.scripting.registerContentScripts動態註冊,讓使用者逐個平台自己開。
- 擷取動作全部由使用者手動觸發(按浮動按鈕或快速鍵),不會自動上傳任何內容。
- 資料只寫進使用者自己的 Google Drive 與自己指定的 Focus4ai 站台; 本擴充沒有任何自己的伺服器。
drive.filescope 之下,擴充只能看到、修改它自己建立的資料夾與文件。- 圖片走第二層路徑時會短暫開啟「知道連結的人可讀」,插入完成後立刻收回並刪除暫存檔。
MIT