---
name: scrape-facebook-to-sheet
description: Tự động quét bài viết Facebook, tải ảnh, lọc chủ đề AI bằng API và ghi vào Google Sheet.
---

## Mục Đích

Script này dùng Selenium để:

- đọc danh sách nguồn từ tab `Link_KOL`
- quét bài viết Facebook
- tải ảnh về `images/`
- lọc bài theo chủ đề AI bằng API
- ghi bài hợp lệ sang tab `Posts`
- backfill `Tên Facebook` và câu nguồn cho các bài cũ còn thiếu

## Quy Trình Bắt Buộc

Thứ tự thực hiện phải là:

1. cài đặt dependencies
2. kiểm tra file `.env`
3. chỉ sau đó mới được chạy script

Không bỏ qua bước 1 và bước 2.

## Bước 1: Cài Đặt Dependencies

Luôn chạy lệnh này trước:

```powershell
py -m pip install -r requirements.txt
```

Thư viện chính:

```text
selenium
requests
google-api-python-client
google-auth
python-dotenv
```

Nếu thiếu package thì phải cài xong rồi mới chạy script.

## Bước 2: Kiểm Tra `.env`

File `.env` phải có đầy đủ các key sau:

```env
FACEBOOK_URL=https://www.facebook.com/
SPREADSHEET_ID=your_google_sheet_id
SOURCE_SHEET_NAME=Link_KOL
POSTS_SHEET_NAME=Posts
SERVICE_ACCOUNT_FILE=your_service_account.json
CHROME_PROFILE_DIR=facebook-chrome-profile
LOGIN_WAIT_SECONDS=180
SCROLL_TIMES=12
SCROLL_PAUSE_SECONDS=2
MAX_POSTS=20
MAX_POSTS_PER_SOURCE=5
ENABLE_TOPIC_FILTER=true
TOPIC_FILTER_API_URL=https://api.deepseek.com/chat/completions
TOPIC_FILTER_MODEL=deepseek-chat
TOPIC_FILTER_TIMEOUT_SECONDS=30
DEEPSEEK_API_KEY=your_deepseek_api_key_here
HEADLESS=false
```

Checklist:

- không thiếu key nào so với `.env.example`
- không để trống `SPREADSHEET_ID`
- không để trống `SERVICE_ACCOUNT_FILE`
- nếu `ENABLE_TOPIC_FILTER=true` thì phải có `DEEPSEEK_API_KEY`

## Lệnh Chính

Chạy mặc định:

```powershell
py script\scrape_facebook_to_sheet.py
```

Chạy thử, không ghi Google Sheet:

```powershell
py script\scrape_facebook_to_sheet.py --dry-run
```

Chỉ dùng khi cần mở Chrome để đăng nhập Facebook thủ công:

```powershell
py script\scrape_facebook_to_sheet.py --login-only
```

Chỉ dùng khi muốn ép chạy riêng phần backfill:

```powershell
py script\scrape_facebook_to_sheet.py --backfill-existing
```

## File Chính

```text
script/scrape_facebook_to_sheet.py
```

## Cấu Trúc Google Sheet

### Tab nguồn

```text
Link_KOL
```

Header:

```text
Link_KOL
```

### Tab bài viết

```text
Posts
```

Header:

```text
Bài Viết
Hình Ảnh
Trạng thái
Link bài viết
Tên Facebook KOL
Ngày đăng
Tên Facebook
```

## Logic Hiện Tại

1. Đọc toàn bộ source từ `Link_KOL`.
2. Mở từng link bằng Chrome profile `facebook-chrome-profile`.
3. Nếu đã login sẵn thì quét luôn.
4. Nếu gặp login/checkpoint thì chờ tối đa `LOGIN_WAIT_SECONDS`.
5. Nếu vẫn chưa vào được Facebook thì dừng source đó.
6. Lấy tối đa `MAX_POSTS_PER_SOURCE` bài mỗi nguồn.
7. Lọc bài bằng API nếu `ENABLE_TOPIC_FILTER=true`.
8. Deduplicate theo `Link bài viết` đã có trong `Posts`.
9. Ghi bài mới sang `Posts` với `Trạng thái = UNVERIFIED`.
10. Cuối mỗi bài tự thêm:

```text
Tham khảo từ Nguồn Facebook: <Tên Facebook>
```

11. Sau khi scrape xong, script tự rà lại `Posts` để backfill các dòng cũ còn thiếu `Tên Facebook` hoặc thiếu câu nguồn.
12. Dropdown và màu của cột `Trạng thái` được quản lý trên Google Sheet. Script không được tự ý sửa logic này nếu chưa được yêu cầu.

## Tên Facebook

Script cố gắng lấy `Tên Facebook` hiển thị thật từ profile/page bằng Selenium.

Nếu không lấy được thì fallback về slug từ link nguồn, ví dụ:

```text
https://www.facebook.com/vuduchongdotcom -> vuduchongdotcom
```

## Ảnh

Ảnh được lưu trong:

```text
images/
```

Cột `Hình Ảnh` chỉ lưu tên file, không lưu full path.

Thư mục `images/` không push lên git, chỉ giữ:

```text
images/.gitkeep
```

## Lọc Chủ Đề

Khi bật:

```env
ENABLE_TOPIC_FILTER=true
```

Prompt hiện tại ưu tiên giữ các bài liên quan đến:

- AI tools
- AI automation
- workflow automation
- AI agent
- LLM
- chatbot AI
- AI coding
- prompting
- API use case
- n8n / Make / Zapier
- DeepSeek / Claude / Claude Code / OpenAI / ChatGPT / Gemini / Copilot
- Cursor / Cline / Windsurf / Bolt / Lovable

Nếu bài bị loại, log sẽ có dạng:

```text
Skip not AI Automation: <link hoặc đoạn text> | reason: <lý do từ API>
```

## Git Ignore

Các thư mục local không push lên git:

```text
facebook-chrome-profile/
images/
tests/
```

Riêng `images/.gitkeep` vẫn giữ trong repo.

## Troubleshooting

Nếu chạy lệnh mặc định mà Facebook chưa login:

```powershell
py script\scrape_facebook_to_sheet.py --login-only
```

Đăng nhập xong rồi chạy lại lệnh chính.

Nếu quét được ít bài:

- tăng `SCROLL_TIMES`
- kiểm tra `MAX_POSTS_PER_SOURCE`
- kiểm tra `DEEPSEEK_API_KEY`
- chạy `--dry-run` để xem trước dữ liệu

Nếu script báo:

```text
No KOL source rows found in Link_KOL sheet.
```

hãy kiểm tra tab `Link_KOL` đã có dữ liệu ở cột `Link_KOL` chưa.
