# Fb Upload

> Đăng NGAY hoặc HẸN GIỜ 1 video lên 1 Facebook PAGE (chọn theo TÊN — hỗ trợ nhiều page) qua Graph API + tự viết title/mô tả/hashtag tối ưu (kênh reup ăn uống VN kiểu a Phong). Dùng khi user muốn "up/đăng video lên facebook", "đăng reel FB", "hẹn giờ đăng", "post clip lên page X". Input = file video (.mp4) + TÊN PAGE (thiếu tên thì hỏi + gợi ý); hẹn giờ qua --schedule (giờ VN).

- Skill: `tiennguyen1203/fb-upload` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tiennguyen1203/fb-upload`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tiennguyen1203/fb-upload/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: tiennguyen1203 (https://skillmd.com/u/tiennguyen1203)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/tiennguyen1203/fb-upload

---


# FB Upload — đăng video + caption tự động

Nhận **1 file video** (đã edit trong CapCut) → **BẠN (Claude) viết caption** (title + mô tả + hashtag, tối ưu reup ăn uống VN) → đăng lên **Facebook Page**.
FB (từ 6/2025) **bỏ giới hạn độ dài** → clip dài mấy phút đăng nguyên cũng thành Reel, KHỎI cắt 90s.

## HAI đường đăng (ưu tiên BROWSER nếu đã login)
| | **Browser — Meta Business Suite** (ƯU TIÊN) | Graph API (`fb_upload.py`) |
|---|---|---|
| Setup | **KHỎI** — chỉ cần đã đăng nhập FB trong browser | Phải lấy Page token (dev app, rườm rà) |
| Hẹn giờ | ✅ Business Suite composer có sẵn | ✅ `--schedule` |
| Khi dùng | **Mặc định** — mở `business.facebook.com` là đăng được ngay | Chỉ khi có `fb_config.json` sẵn / chạy headless |
- ✅ **User đã chốt (2026-07-14): đi BROWSER** vì browser luôn login sẵn Page → khỏi token. Chỉ fallback API khi đã có token.
- **Quy trình browser (Playwright MCP)** — y như /youtube-upload:
  1. Copy clip vào `~/tony-programming/` (browser MCP chỉ up file trong đó); xoá sau.
  2. Mở `https://business.facebook.com/latest/reels_composer?asset_id=<PAGE_ID>` (Ăn Là Sập = `1148656548340200`). Nếu bị đá login → nhờ user tự đăng nhập.
  3. Xác nhận "Đăng lên: <Page>" đúng → **Thêm video** (file_chooser) → chờ upload 100%.
  4. Điền **Mô tả** (caption bên dưới). Bấm **Tiếp** (Chi tiết → Chỉnh sửa → **Tiếp** → Chia sẻ).
  5. Bước Chia sẻ: chọn **Lên lịch** → ô ngày (calendar) + ô giờ (gõ **từng ký tự**, `.fill()` KHÔNG ăn — múi giờ **Asia/Jakarta = GMT+7 = giờ VN**, khỏi quy đổi) → **Lên lịch** → "Xong".
  6. Tự chụp screenshot xác nhận "Đã lên lịch…". Dọn file tạm.

- Code: `~/.claude/skills/fb-upload/fb_upload.py`
- Venv: `~/DouyinReup/.dubvenv` (PY). Cần `requests` (đã cài).
- Config token: `~/DouyinReup/fb_config.json`

## SETUP (1 lần — lấy PAGE token; BẠN không làm hộ được vì cần login FB của user)
1. Phải có **Facebook PAGE** (fanpage), user là admin. (Graph API KHÔNG đăng lên profile cá nhân.)
2. Vào **developers.facebook.com** → **My Apps** → **Create App** (type "Business" hoặc "Other" → "None").
3. Mở **Graph API Explorer** (developers.facebook.com/tools/explorer):
   - Chọn app vừa tạo. Bấm **Generate/Get User Access Token**.
   - Tick quyền: `pages_show_list`, `pages_manage_posts`, `pages_read_engagement`, `publish_video`.
4. **Đổi sang token dài hạn** (token Explorer chỉ sống ~1-2h):
   - Lấy **App ID** + **App Secret** (Settings → Basic).
   - Chạy (thay chỗ `<...>`):
     `curl "https://graph.facebook.com/v21.0/oauth/access_token?grant_type=fb_exchange_token&client_id=<APP_ID>&client_secret=<APP_SECRET>&fb_exchange_token=<USER_TOKEN>"`
     → ra **long-lived user token** (60 ngày).
5. **Lấy PAGE token** (page token sinh từ long-lived user token thường **KHÔNG hết hạn**):
   `curl "https://graph.facebook.com/v21.0/me/accounts?access_token=<LONG_LIVED_USER_TOKEN>"`
   → trong kết quả có `id` (=page_id) và `access_token` (=PAGE token) của trang.
6. Lưu `~/DouyinReup/fb_config.json` — **ĐA PAGE** (key = tên page user hay gọi):
   ```json
   {
     "graph_version": "v21.0",
     "pages": {
       "Ăn Là Sập": {"page_id": "<PAGE_ID>", "access_token": "<PAGE_TOKEN>"},
       "Deal Ơi":   {"page_id": "<PAGE_ID_2>", "access_token": "<PAGE_TOKEN_2>"}
     }
   }
   ```
   > `me/accounts` trả về HẾT các page user admin (kèm id + token mỗi page) → thêm bao nhiêu page tuỳ ý. Có page mới sau này chỉ cần thêm 1 mục vào `pages`.
7. Kiểm tra: `curl "https://graph.facebook.com/v21.0/<PAGE_ID>?fields=name&access_token=<PAGE_TOKEN>"` → ra tên trang là OK.

> Token hỏng/hết hạn → làm lại bước 3-6. Báo user tự làm (cần login FB của họ).

## QUY TRÌNH (mỗi video) — `PY=~/DouyinReup/.dubvenv/bin/python`, `SK=~/.claude/skills/fb-upload`
1. **XÁC ĐỊNH PAGE:**
   - User có nói tên page (vd "đăng lên Ăn Là Sập") → dùng luôn.
   - **Không nói tên** → chạy `"$PY" "$SK/fb_upload.py" --list` để lấy danh sách page, rồi **HỎI user chọn** (AskUserQuestion) — **gợi ý** page hợp nhất theo LOẠI video (vd clip ăn uống → "Ăn Là Sập"; clip đồ gia dụng/deal → page deal…). Chỉ có 1 page thì dùng luôn khỏi hỏi.
2. **BẠN viết caption** theo mục "CAPTION", lưu `caption.txt` (dựa NỘI DUNG clip — clip vừa dub thì đã biết từ segs_vi). Giọng/hashtag có thể chỉnh theo từng page (page khác chủ đề → hashtag khác).
3. **Đăng NGAY:** `"$PY" "$SK/fb_upload.py" "<video.mp4>" "<caption.txt>" --page "<Tên Page>"`
   → in link video sau khi đăng. (Resumable, chịu file ~vài trăm MB.)
   - Nếu script in `❌ ... Chọn 1 trong:` + `PAGES_AVAILABLE:[...]` → tên page chưa khớp → hỏi lại user rồi chạy lại với `--page` đúng.
   **HOẶC HẸN GIỜ:** thêm `--schedule "19:00"` (hoặc `--schedule "2026-07-15 19:00"`).
   - Giờ nhập là **GIỜ VIỆT NAM (UTC+7)** — script tự đổi sang timestamp UTC cho API (`scheduled_publish_time`), **KHÔNG lệ thuộc múi giờ Page** (khỏi lệch như khi hẹn tay trên web).
   - `"HH:MM"` = hôm nay (đã qua/sát quá thì tự dời sang mai); `"YYYY-MM-DD HH:MM"` / `"DD/MM HH:MM"` = đúng ngày giờ đó. FB cho hẹn 10 phút → 6 tháng.
   - Lên lịch xong video **chưa công khai** tới giờ hẹn; kiểm ở **Meta Business Suite → Công cụ lập kế hoạch**.
4. Báo user **link (hoặc giờ đã hẹn) + page + caption**.

## CAPTION — BẠN tự quyết (tối ưu reup ăn uống VN, test view-money)
FB ưu tiên **hook chặn-lướt + tương tác (comment) + watch-time** hơn hashtag. Viết:
- **Dòng 1 = HOOK** (hiện trước "Xem thêm", ~125 ký tự đầu): sốc/tò mò + emoji. VD: "Gọi NGUYÊN CUỐN menu bò Wagyu, nhân viên há hốc mồm 😳🥩".
- **2-3 dòng mô tả** giọng đời/trend (dùng slang **đớp / phê / thánh đớp / chốt đơn / xỉu ngang**). Kể cái hay, gợi tò mò tới cuối.
- **CTA tương tác:** hỏi 1 câu để kéo comment ("Ai đoán được hết bao nhiêu tệ?") + "Theo dõi hóng tập sau 🔥".
- **Hashtag (8-14):** trộn RỘNG (reach) + NGÁCH. VD:
  `#mukbang #anuong #ansapquan #thanhan #dopsach #reviewdoan #monngon #amthuc #douyin #xuhuong #reels #fbreels #wagyu #foodie`
- **KHÔNG bịa** (giá, số liệu) — nói chung chung nếu không chắc. Tránh caption spam/nhồi hashtag đầu bài (nhét cuối).
- Giọng: hào hứng, ngắn gọn, xuống dòng thoáng. 1-2 emoji/đoạn, đừng lạm dụng.

### Mẫu bố cục
```
<HOOK 1 dòng + emoji>

<2-3 dòng mô tả trend + gợi tò mò>

<1 câu hỏi kéo comment> — Theo dõi để hóng tập sau nha! 🔥

#hashtag1 #hashtag2 ...
```

## Lưu ý / rủi ro (nói thật với user)
- **Reup + bản quyền + ToS Facebook:** rủi ro bị hạ/khoá reach hoặc gậy bản quyền — của người vận hành.
- Video reup thuần thường **khó bật kiếm tiền** (FB phạt nội dung tái sử dụng) — đăng để TEST view.
- Token là **bí mật** — đừng share/log ra ngoài.
- API đăng lên **Page**, không lên profile cá nhân / nhóm.

