@willh/fb-ad-blocker
v1.0.7
Published
Intelligent Facebook spam detection and automation tool using Google Gemini AI and Playwright browser automation
Maintainers
Readme
FB Ad Blocker - 智慧型 Facebook 垃圾留言偵測與自動化工具
這是一個智慧型 Facebook 垃圾留言偵測與自動化工具,使用 Google Gemini AI 來分析留言並自動處理垃圾內容。此工具可以自動偵測垃圾留言、刪除它們,並使用 Playwright 瀏覽器自動化來封鎖使用者。
🌟 功能特色
- AI 驅動的垃圾留言偵測:使用 Google Gemini API 進行智慧留言分析
- 自動化留言管理:自動刪除、隱藏或檢舉垃圾留言
- 使用者封鎖:自動封鎖發布垃圾內容的使用者
- 隱藏垃圾留言處理:針對已被隱藏的垃圾留言進行批次封鎖處理
- 封鎖記錄追蹤:自動記錄封鎖的頁面資訊到
blocked-pages.json,並同步維護純文字清單blocked-pages.txt - 增強式日誌系統:提供彩色輸出、表情符號和檔案日誌等功能
- 啟發式備援:在沒有 API 金鑰時使用本地啟發式分析
- 可配置動作:自訂垃圾留言處理行為的閾值和動作
- 多語言支援:支援英文和繁體中文內容
- 瀏覽器自動化:由 Playwright 提供可靠的 Facebook 互動
📁 專案結構
✨ 重構完成: 本專案已完成模組化重構,採用更清晰的分層架構。詳見下方「重構後的架構」章節。
fb-ad-blocker/
├── src/
│ ├── commands/ # CLI 命令入口點
│ │ ├── block-hidden-pages.js # 封鎖已隱藏留言者命令
│ │ ├── block-page.js # 封鎖頁面命令
│ │ └── hide-spam-comments.js # 隱藏垃圾留言命令
│ ├── core/ # 核心業務邏輯
│ │ ├── comment-processor.js # 留言處理器
│ │ └── page-blocker.js # 頁面封鎖處理器
│ ├── services/ # 外部服務整合
│ │ ├── browser.js # 瀏覽器服務
│ │ ├── gemini.js # Gemini API 服務
│ │ └── logger.js # 日誌服務
│ ├── utils/ # 工具函式
│ │ ├── blocked-pages.js # 封鎖記錄管理
│ │ ├── file-handler.js # 檔案讀寫操作
│ │ └── url-parser.js # URL 解析與處理
│ └── cli.js # CLI 主入口
├── examples/
│ ├── usage_example.js # 使用範例與功能展示
│ └── pages.txt # 範例封鎖頁面清單
├── test_gemini.js # 留言分析測試腳本
├── package.json # 專案相依性與腳本
├── .env.example # 環境配置範本
├── API.md # 詳細 API 文件
├── BLOCKED_PAGES.md # 封鎖記錄檔案格式說明
├── blocked-pages.json # 封鎖記錄(執行後自動產生/更新)
├── blocked-pages.txt # 被封鎖頁面 URL 純文字清單
├── analysis_results.json # 留言分析結果(執行後自動產生/更新)
├── storageState.json # 已登入會話狀態(您本機產生)
└── README.md # 本檔案🚀 快速開始
系統需求
- Node.js 18 或更高版本
- npm 或 yarn 套件管理器
- Google Gemini API 金鑰(選用,但建議使用以獲得更好的準確性)
- 已儲存登入狀態的 Facebook 帳號 (請利用 Chrome DevTools ➜ Playwright 工具)
安裝步驟 (docker + npm)
啟動 Playwright 容器
docker run --rm --name=fb-ad-blocker -it --entrypoint=bash mcr.microsoft.com/playwright:v1.55.1-noble使用 Playwright 官方映像檔,就會內建所有必要的瀏覽器和相依性,免去安裝以下兩行命令:
npx -y playwright install-deps npx -y playwright install chromium安裝 npm 套件
npm install -g @willh/fb-ad-blocker執行
fb-ad-blocker以確認安裝成功fb-ad-blocker -h手動取得 FB 登入狀態檔 (storageState.json)
請利用 Chrome DevTools ➜ Playwright 工具,將登入狀態儲存到
storageState.json檔案中,並放在目前目錄。docker cp storageState.json fb-ad-blocker:/驗證連線
export HEADLESS_MODE=1 # Linux 容器必須設定無頭模式 fb-ad-blocker test設定環境變數
export GEMINI_API_KEY=your_api_key_here export DRY_RUN=0執行範例
export HEADLESS_MODE=1 # Linux 容器必須設定無頭模式 fb-ad-blocker hide-spam "https://www.facebook.com/will.fans/posts/pfbid0fCkVwz1e1QQKBFC2QJvtgGDSVicvVLLBqWdZ6RiwRtAP69JUcGpeQtSoxWwdFPmCl"
安裝步驟 (source code)
複製儲存庫
git clone https://github.com/doggy8088/fb-ad-blocker.git cd fb-ad-blocker安裝相依性
npm install npm run install-browser設定環境變數配置檔
cp .env.example .env配置環境變數(編輯
.env檔案):# Google Gemini API 金鑰(從 https://aistudio.google.com/app/apikey 取得) GEMINI_API_KEY=your_api_key_here # 選用:指定 Gemini 模型 GEMINI_MODEL=gemini-2.5-pro # 垃圾留言偵測配置 SPAM_ACTION=hide # 選項:hide, delete, report, none SPAM_THRESHOLD=0.85 # 信心閾值(0.0 - 1.0) DRY_RUN=0 # 設為 0 進行實際執行 # 瀏覽器執行模式(選用) HEADLESS_MODE=0 # 1 或 true = 無頭模式;未設定/0/false = 顯示瀏覽器 # 針對 block-page 並行封鎖數(選用) CONCURRENT_LIMIT=5 # 同時處理的頁面數;未設定則逐一處理 # Gemini 端點(選用) # GEMINI_API_BASE=https://generativelanguage.googleapis.com設定 Facebook 登入狀態(自動化所需)
- 執行任何 Playwright 腳本一次以產生
storageState.json - 或手動登入 Facebook 並儲存會話狀態
驗證連線
export HEADLESS_MODE=1 # Linux 容器必須設定無頭模式 npm run cli '--' test- 執行任何 Playwright 腳本一次以產生
📖 使用範例
基本留言分析
測試留言分析功能而不進行 Facebook 自動化:
npm test
# 或
npm run analyze這將分析範例留言並顯示分類結果。
您也可以執行綜合範例來查看所有功能:
npm run examples這將展示:
- 基本垃圾留言偵測:單一留言分析
- 批次處理:多個留言含統計資訊
- 動作決策:根據設定會採取什麼動作
- API 與啟發式比較:查看 AI 與本地分析的差異
範例輸出:
[
{
"comment": "很棒的貼文!謝謝分享。",
"label": "not_spam",
"confidence": 0.5,
"reason": "heuristic",
"raw": null
},
{
"comment": "🎉 免費賺錢 💰 立即點擊!🚀",
"label": "spam",
"confidence": 0.9,
"reason": "包含促銷語言和過多表情符號",
"raw": null
}
]自動化垃圾留言偵測與隱藏
處理 Facebook 貼文並自動隱藏垃圾留言:
npm run cli -- hide-spam "https://www.facebook.com/posts/your-post-url"
# 或安裝為全域命令後
fb-ad-blocker hide-spam "https://www.facebook.com/posts/your-post-url"這將會:
- 導航到指定的 Facebook 貼文
- 提取所有留言
- 分析每個留言的垃圾指標
- 對偵測到的垃圾留言採取配置的動作(隱藏/檢舉)
- 將分析結果儲存到
analysis_results.json
封鎖已被隱藏的留言者
處理已被粉絲專頁隱藏的留言,並封鎖發布者:
npm run cli -- block-hidden "https://www.facebook.com/posts/your-post-url"
# 或安裝為全域命令後
fb-ad-blocker block-hidden "https://www.facebook.com/posts/your-post-url"這將會:
- 導航到指定的 Facebook 貼文
- 查看「已被此粉絲專頁隱藏」的留言
- 自動封鎖這些留言的發布者
- 將封鎖記錄儲存到
blocked-pages.json(包含頁面名稱、URL、留言內容等詳細資訊) - 另同步更新
blocked-pages.txt(僅 URL 清單,便於批次封鎖使用) - 刪除已被隱藏的留言
📝 新功能:封鎖記錄追蹤
系統會自動記錄所有封鎖的頁面資訊到
blocked-pages.json檔案,包含:
- 封鎖日期和時間
- 被封鎖的頁面名稱和 URL
- 觸發封鎖的垃圾留言內容
- 封鎖理由
詳細格式請參考 BLOCKED_PAGES.md
提醒:即使在測試模式(
DRY_RUN=1)下,實際的「封鎖點擊」不會執行,但仍會將目標與理由寫入blocked-pages.json與blocked-pages.txt,方便後續人工/批次處理。
以檔案清單批次處理貼文(-f)
當需要一次處理多個貼文網址時,支援用 -f 指定一個文字檔,從檔案逐行讀取 URL:
npm run cli -- hide-spam -f posts.txt
# 或安裝為全域命令後
fb-ad-blocker hide-spam -f posts.txt檔案格式說明:
- 每行一個 Facebook 貼文網址
- 允許空行(會被忽略)
範例 posts.txt(每行一個貼文網址):
https://www.facebook.com/<page>/posts/<post-id>
https://www.facebook.com/story.php?story_fbid=<id>&id=<id>封鎖個別 Facebook 專頁/個人檔案
封鎖特定的 Facebook 專頁或個人檔案:
npm run cli -- block-page "https://www.facebook.com/profile-url" "https://www.facebook.com/another-profile"
# 或安裝為全域命令後
fb-ad-blocker block-page "https://www.facebook.com/profile-url"以檔案清單批次封鎖(-f)
同樣支援以 -f 從檔案讀取多個專頁/個人檔案網址:
npm run cli -- block-page -f examples/pages.txt
# 支援並行處理(-c 選項)
npm run cli -- block-page -c 3 -f blocked-pages.txt
# 或安裝為全域命令後
fb-ad-blocker block-page -c 5 -f examples/pages.txt檔案格式說明:
- 每行一個 Facebook 專頁或個人檔案的網址
- 允許空行(會被忽略)
- 可直接使用執行結果所產生的
blocked-pages.txt作為輸入,或使用examples/pages.txt
並行處理:
- 可透過環境變數
CONCURRENT_LIMIT控制同時封鎖處理的數量(僅block-page腳本適用)
程式化使用
在您的程式碼中使用留言分析 API:
import { analyzeComments } from './src/gemini.js';
async function analyzeComment() {
const mainPost = "今天我要分享一些關於技術的想法...";
const comment = "很棒的貼文!非常有見地。";
const result = await analyzeComments(mainPost, comment, {
apiKeyEnv: 'GEMINI_API_KEY',
model: 'gemini-2.5-pro',
forceHeuristic: false // 設為 true 僅使用本地分析
});
console.log(result);
// {
// comment: "很棒的貼文!非常有見地。",
// label: "not_spam",
// confidence: 0.2,
// reason: "與相關內容的正面參與",
// raw: "..."
// }
}批次處理多個留言
import { analyzeComments } from './src/gemini.js';
async function processComments(mainPost, comments) {
const results = [];
for (const comment of comments) {
const result = await analyzeComments(mainPost, comment, {
apiKeyEnv: 'GEMINI_API_KEY'
});
results.push(result);
// 如果偵測到垃圾留言就處理
if (result.label === 'spam' && result.confidence > 0.85) {
console.log(`🚨 偵測到垃圾留言:${result.comment}`);
console.log(` 原因:${result.reason}`);
// 在此採取動作(刪除、檢舉等)
}
}
return results;
}⚙️ 配置選項
環境變數
| 變數名稱 | 說明 | 預設值 | 選項 |
|----------|------|--------|------|
| GEMINI_API_KEY | Google Gemini API 金鑰 | - | 從 AI Studio 取得 |
| GEMINI_MODEL | 使用的 Gemini 模型 | gemini-2.5-pro | gemini-2.5-pro, gemini-1.5-flash |
| SPAM_ACTION | 對垃圾留言採取的動作 | hide | delete, hide, report, none |
| SPAM_THRESHOLD | 信心閾值 | 0.85 | 0.0 - 1.0 |
| DRY_RUN | 測試模式(不執行實際動作) | 1 | 0(執行),1(僅測試) |
| HEADLESS_MODE | 無頭模式開關 | 未設定(顯示瀏覽器) | 1/true(無頭),0/false(顯示) |
| CONCURRENT_LIMIT | 封鎖專頁並行數(僅 block-page) | - | 正整數 |
| GEMINI_API_BASE | Gemini 端點 | https://generativelanguage.googleapis.com | 自訂企業代理或官方端點 |
| LOG_FILE_PATH | 日誌檔案路徑(選用) | - | 例如:./logs/fb-blocker.log |
垃圾留言偵測標籤
AI 分類器會回傳以下其中一個標籤:
spam:明顯的促銷、無關或惡意內容possibly_spam:可疑內容,可能是垃圾留言not_spam:合法、相關的留言unsure:無法有信心地判斷
動作類型
delete:永久刪除垃圾留言hide:隱藏留言不讓公眾看見report:向 Facebook 檢舉留言none:僅偵測,不執行自動化動作
增強式日誌功能
本工具提供清晰易讀的增強式日誌輸出,包含以下特色:
控制台日誌
- 📅 精確時間戳記:包含日期時間到毫秒級精度
- 🎨 彩色輸出:不同類型的訊息使用不同顏色標示
- 😀 表情符號:使用 emoji 快速識別訊息類型和狀態
- 📋 階段分隔:清楚劃分不同處理階段
- 📊 分析結果格式:結構化顯示留言分析結果
檔案日誌(選用)
設定 LOG_FILE_PATH 環境變數即可將日誌同時寫入檔案:
# 啟用檔案日誌
export LOG_FILE_PATH=./logs/fb-blocker.log
npm run hide-comments "https://facebook.com/post-url"檔案日誌特色:
- 自動建立日誌目錄
- 純文字格式(無 ANSI 色彩代碼)
- 包含完整時間戳記和 emoji
- 會話分隔標記方便查看
- 便於後續查詢和分析
範例日誌輸出:
[2024/9/16 18:25:30.270] 🚀 開始處理 URL: https://facebook.com/post/123
[2024/9/16 18:25:30.487] 🌐 已導航到 URL
[2024/9/16 18:25:30.488] ✅ 成功取得留言: 15 個
[2024/9/16 18:25:30.489] 🔬 開始分析留言,使用 API: 是
[2024/9/16 18:25:30.490] 🚫 偵測到垃圾留言,準備採取動作
[2024/9/16 18:25:30.491] ⚡ 準備執行動作: delete
[2024/9/16 18:25:30.492] 🎉 處理完成🔧 進階使用
自訂啟發式規則
工具包含當沒有提供 API 金鑰時的備援啟發式分析:
// 增加垃圾留言機率的啟發式因子:
// - 包含 URL 或促銷語言
// - 過多表情符號或符號(3+ 個表情符號)
// - 促銷關鍵字(免費、折扣、點擊這裡等)
// - 重複標點符號或字元
// - 與主貼文內容高度相似
// - 重複詞彙且詞彙多樣性低瀏覽器自動化配置
工具使用 Playwright 並採用以下預設設定:
const browser = await chromium.launch({
headless: process.env.HEADLESS_MODE === 'true' || process.env.HEADLESS_MODE === '1'
});
const context = await browser.newContext({
locale: 'zh-TW', // 支援繁體中文
storageState: 'storageState.json' // 已儲存的登入會話
});錯誤處理與監控
工具包含全面的錯誤處理與記錄:
// 結果會自動儲存到 analysis_results.json
{
"mainPost": "原始貼文內容...",
"results": [
{
"comment": "留言文字...",
"label": "spam",
"confidence": 0.92,
"reason": "包含可疑連結的促銷內容",
"raw": "原始 API 回應..."
}
]
}🛡️ 安全性與最佳實務
速率限制
- 注意 Facebook 的速率限制
- 在動作之間添加延遲以避免被偵測
- 使用
DRY_RUN=1進行測試
隱私與合規性
- 僅在您擁有或有權限管理的內容上使用
- 尊重使用者隱私和當地法規
- 考慮對邊緣案例進行人工審查
API 成本
- Google Gemini API 有使用成本
- 開發/測試時使用啟發式模式
- 在生產環境中監控 API 使用量
🔍 故障排除
常見問題:
腳本完成後停在 Playwright 視窗:
- 垃圾留言流程中會呼叫
page.pause()以便人工檢視結果與除錯。請在 Playwright Inspector 按下繼續,或移除/註解該行以取消暫停。
- 垃圾留言流程中會呼叫
測試模式未實際封鎖但有記錄:
- 當
DRY_RUN=1時不會對 UI 進行真實點擊封鎖,但仍會把候選目標寫入blocked-pages.json與blocked-pages.txt,方便後續批次封鎖。
- 當
其他常見問題
"fetch is not a function" 錯誤
npm install node-fetch@3Facebook 登入問題
- 確保
storageState.json存在且含有效會話 - 檢查 Facebook 是否需要額外驗證
- 嘗試先手動登入
- 確保
API 驗證錯誤
- 驗證
GEMINI_API_KEY是否正確 - 檢查 API 配額和計費狀態
- 確保 API 金鑰有適當權限
- 驗證
瀏覽器自動化中找不到元素
- Facebook UI 經常變更
- 需要時更新選擇器
- 使用
headless: false進行視覺化除錯
除錯模式
要進行詳細除錯,請使用詳細記錄執行:
DEBUG=1 npm run cli -- hide-spam "your-facebook-url"💡 快速取得封鎖連結的方式
開啟 Google Chrome 瀏覽器
搜尋不想要的粉絲專頁
https://www.facebook.com/search/pages/?q=%E7%95%B6%E6%B2%96
進入粉絲專頁後,按下
F12開啟開發者工具直接執行以下腳本就可以順利複製出命令到剪貼簿:
const links = Array.from( document.querySelectorAll('div[aria-label="搜尋結果"] a[href^="https://www.facebook.com/"]') ); const cleanedHrefs = links.map(link => { const url = new URL(link.href); // 粉絲專頁:有 profile.php?id if (url.pathname === '/profile.php' && url.searchParams.has('id')) { return `https://www.facebook.com/profile.php?id=${url.searchParams.get('id')}`; } // 個人帳號:path 長度大於 1 且沒有 query string if (url.pathname !== '/' && !url.search) { return `https://www.facebook.com${url.pathname}`; } // 其他狀況(例如粉絲團短網址、含 query string 的動態頁)就忽略 return null; }).filter(Boolean); const uniqueHrefs = [...new Set(cleanedHrefs)]; const data = `npm run cli -- block-page ${uniqueHrefs.join(' ')}`; copy(data);也可以用 AI assistant 快速取得命令:
Find all the links that start with "https://www.facebook.com/profile.php?id=" and then merge them into the following string: npm run cli -- block-page URL1 URL2 ... Remove duplicated links.執行命令
範例如下:
npm run cli -- block-page https://www.facebook.com/profile.php?id=100087996592961 https://www.facebook.com/dangchongxidangdie
🏗️ 重構後的架構
本專案已完成模組化重構,採用清晰的分層架構,提升程式碼品質、可維護性和可擴展性。
架構層級
src/
├── cli.js # CLI 主入口(使用 commander)
├── commands/ # 命令層 - CLI 命令入口點
│ ├── hide-spam-comments.js
│ ├── block-hidden-pages.js
│ └── block-page.js
├── core/ # 核心層 - 業務邏輯
│ ├── comment-processor.js
│ └── page-blocker.js
├── services/ # 服務層 - 外部服務整合
│ ├── browser.js
│ ├── gemini.js
│ └── logger.js
└── utils/ # 工具層 - 共用函式
├── url-parser.js
├── file-handler.js
└── blocked-pages.js設計原則
- 分層架構 (Layered Architecture): 程式碼按功能分層,職責明確
- 單一職責原則 (Single Responsibility Principle): 每個模組只負責一項功能
- 依賴注入 (Dependency Injection): 提升可測試性和靈活性
- 工廠模式 (Factory Pattern): BrowserService 統一管理瀏覽器實例
統一 CLI 工具
使用 commander 套件提供一致的命令列介面:
# 查看所有可用命令
npm run cli -- --help
# 隱藏垃圾留言
npm run cli -- hide-spam <url>
npm run cli -- hide-spam -f <file>
# 封鎖已被隱藏的留言者
npm run cli -- block-hidden <url>
# 封鎖頁面(支援並行處理)
npm run cli -- block-page <urls...>
npm run cli -- block-page -c 3 -f <file>安裝為全域命令
npm link
fb-ad-blocker --help
fb-ad-blocker hide-spam "https://facebook.com/post/123"CLI 命令
統一使用 CLI 介面執行各項功能:
# 隱藏垃圾留言
npm run cli -- hide-spam
# 封鎖已被隱藏的留言者
npm run cli -- block-hidden
# 封鎖頁面
npm run cli -- block-page重構成果
程式碼品質改進:
- ✅ 模組化架構 - 程式碼按功能分層
- ✅ 統一 CLI - 使用 commander 套件
- ✅ 程式碼重用 - 核心邏輯共用
- ✅ 關注點分離 - 每個模組職責單一
- ✅ 可測試性 - 便於撰寫單元測試
- ✅ 擴展性 - 易於新增功能
之前: 3 個主程式檔案(各約 300 行),utils.js 混合多種職責
之後: 清晰的分層架構,每個檔案平均約 150-200 行,單一職責原則
新增功能
統一 CLI 介面
- 使用
commander提供專業的命令列體驗 - 支援
--help查看詳細說明 - 支援全域安裝(
npm link)
- 使用
並行處理
block-page命令支援-c選項控制並行數- 提升大量封鎖作業的效率
改進的錯誤處理
- 統一的錯誤訊息格式
- 更清晰的日誌輸出
📚 其他資源
- API.md:詳細的 API 文件,包含範例和最佳實務
- examples/usage_example.js:您可以在本地執行的綜合使用範例
- CLI 命令:
npm run cli -- hide-spam、npm run cli -- block-hidden、npm run cli -- block-page - 測試與範例:
npm test、npm run examples、npm run analyze - GitHub Actions 設定指南:如何設定 CI/CD 的詳細說明
🚀 發佈流程
本專案使用 GitHub Actions 自動化 CI/CD 流程。
自動發佈
當程式碼推送到 main 分支時,會自動執行以下流程:
- ✅ CI 測試:在多個 Node.js 版本上執行測試
- 🔍 版本檢查:檢查
package.json中的版本是否已存在於 npm registry - 📦 發佈套件:如果是新版本,自動發佈到 npm
- 🏷️ 建立標籤:自動建立 Git tag(格式:
v{version}) - 📝 建立 Release:在 GitHub 上建立正式 Release,包含變更日誌
發佈新版本
更新版本號:
npm version patch # 1.0.0 -> 1.0.1(修補版本) npm version minor # 1.0.0 -> 1.1.0(次要版本) npm version major # 1.0.0 -> 2.0.0(主要版本)提交並推送:
git add package.json package-lock.json git commit -m "chore: bump version to x.x.x" git push origin main自動執行:GitHub Actions 會自動處理後續的發佈流程
詳細設定說明請參考 GitHub Actions 設定指南。
🤝 貢獻
歡迎貢獻!請遵循以下步驟:
- Fork 儲存庫
- 建立功能分支:
git checkout -b feature/amazing-feature - 進行您的更改
- 提交變更(遵循 Conventional Commits):
git commit -m "feat: 新增超棒的功能" - 推送到分支:
git push origin feature/amazing-feature - 建立 Pull Request
Commit 訊息規範
請使用 Conventional Commits 格式:
feat:新增功能fix:修正錯誤docs:文件更新style:程式碼格式調整refactor:重構test:測試相關chore:建構流程或輔助工具變動
程式碼審查
所有 Pull Request 都會經過以下檢查:
- ✅ CI 測試通過
- ✅ 程式碼品質檢查(如有設定 ESLint)
- ✅ 人工程式碼審查
� 延伸文件
- Playwright 最佳實踐指南 - 完整的 Playwright API 使用規範與範例
- Playwright 重構摘要 - 最新重構的詳細說明
- API 文件 - 詳細的 API 說明與函式文件
- 封鎖記錄格式 - 封鎖記錄檔案格式說明
�📄 授權
MIT 授權 - 詳見 LICENSE 檔案
⚠️ 免責聲明
此工具僅供教育和合法內容管理用途。使用者需負責:
- 遵守 Facebook 的服務條款
- 尊重適用的法律法規
- 以道德和負責任的方式使用工具
- 在管理內容前確保有適當權限
作者不對任何濫用或違反平台政策的行為負責。
