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:
- Copy clip vào
~/tony-programming/ (browser MCP chỉ up file trong đó); xoá sau.
- 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.
- Xác nhận "Đăng lên: " đúng → Thêm video (file_chooser) → chờ upload 100%.
- Điền Mô tả (caption bên dưới). Bấm Tiếp (Chi tiết → Chỉnh sửa → Tiếp → Chia sẻ).
- 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".
- 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)
- Phải có Facebook PAGE (fanpage), user là admin. (Graph API KHÔNG đăng lên profile cá nhân.)
- Vào developers.facebook.com → My Apps → Create App (type "Business" hoặc "Other" → "None").
- 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.
- Đổ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).
- 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.
- Lưu
~/DouyinReup/fb_config.json — ĐA PAGE (key = tên page user hay gọi):{
"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.
- 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
- 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.
- 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).
- Đă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.
- 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.
1---2name: fb-upload3description: Đă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).4---56# FB Upload — đăng video + caption tự động78Nhậ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**.9FB (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.1011## HAI đường đăng (ưu tiên BROWSER nếu đã login)12| | **Browser — Meta Business Suite** (ƯU TIÊN) | Graph API (`fb_upload.py`) |13|---|---|---|14| Setup | **KHỎI** — chỉ cần đã đăng nhập FB trong browser | Phải lấy Page token (dev app, rườm rà) |15| Hẹn giờ | ✅ Business Suite composer có sẵn | ✅ `--schedule` |16| 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 |17- ✅ **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.18- **Quy trình browser (Playwright MCP)** — y như /youtube-upload:19 1. Copy clip vào `~/tony-programming/` (browser MCP chỉ up file trong đó); xoá sau.20 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.21 3. Xác nhận "Đăng lên: <Page>" đúng → **Thêm video** (file_chooser) → chờ upload 100%.22 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ẻ).23 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".24 6. Tự chụp screenshot xác nhận "Đã lên lịch…". Dọn file tạm.2526- Code: `~/.claude/skills/fb-upload/fb_upload.py`27- Venv: `~/DouyinReup/.dubvenv` (PY). Cần `requests` (đã cài).28- Config token: `~/DouyinReup/fb_config.json`2930## SETUP (1 lần — lấy PAGE token; BẠN không làm hộ được vì cần login FB của user)311. Phải có **Facebook PAGE** (fanpage), user là admin. (Graph API KHÔNG đăng lên profile cá nhân.)322. Vào **developers.facebook.com** → **My Apps** → **Create App** (type "Business" hoặc "Other" → "None").333. Mở **Graph API Explorer** (developers.facebook.com/tools/explorer):34 - Chọn app vừa tạo. Bấm **Generate/Get User Access Token**.35 - Tick quyền: `pages_show_list`, `pages_manage_posts`, `pages_read_engagement`, `publish_video`.364. **Đổi sang token dài hạn** (token Explorer chỉ sống ~1-2h):37 - Lấy **App ID** + **App Secret** (Settings → Basic).38 - Chạy (thay chỗ `<...>`):39 `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>"`40 → ra **long-lived user token** (60 ngày).415. **Lấy PAGE token** (page token sinh từ long-lived user token thường **KHÔNG hết hạn**):42 `curl "https://graph.facebook.com/v21.0/me/accounts?access_token=<LONG_LIVED_USER_TOKEN>"`43 → trong kết quả có `id` (=page_id) và `access_token` (=PAGE token) của trang.446. Lưu `~/DouyinReup/fb_config.json` — **ĐA PAGE** (key = tên page user hay gọi):45 ```json46 {47 "graph_version": "v21.0",48 "pages": {49 "Ăn Là Sập": {"page_id": "<PAGE_ID>", "access_token": "<PAGE_TOKEN>"},50 "Deal Ơi": {"page_id": "<PAGE_ID_2>", "access_token": "<PAGE_TOKEN_2>"}51 }52 }53 ```54 > `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`.557. Kiểm tra: `curl "https://graph.facebook.com/v21.0/<PAGE_ID>?fields=name&access_token=<PAGE_TOKEN>"` → ra tên trang là OK.5657> 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ọ).5859## QUY TRÌNH (mỗi video) — `PY=~/DouyinReup/.dubvenv/bin/python`, `SK=~/.claude/skills/fb-upload`601. **XÁC ĐỊNH PAGE:**61 - User có nói tên page (vd "đăng lên Ăn Là Sập") → dùng luôn.62 - **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.632. **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).643. **Đăng NGAY:** `"$PY" "$SK/fb_upload.py" "<video.mp4>" "<caption.txt>" --page "<Tên Page>"`65 → in link video sau khi đăng. (Resumable, chịu file ~vài trăm MB.)66 - 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.67 **HOẶC HẸN GIỜ:** thêm `--schedule "19:00"` (hoặc `--schedule "2026-07-15 19:00"`).68 - 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).69 - `"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.70 - 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**.714. Báo user **link (hoặc giờ đã hẹn) + page + caption**.7273## CAPTION — BẠN tự quyết (tối ưu reup ăn uống VN, test view-money)74FB ưu tiên **hook chặn-lướt + tương tác (comment) + watch-time** hơn hashtag. Viết:75- **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 😳🥩".76- **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.77- **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 🔥".78- **Hashtag (8-14):** trộn RỘNG (reach) + NGÁCH. VD:79 `#mukbang #anuong #ansapquan #thanhan #dopsach #reviewdoan #monngon #amthuc #douyin #xuhuong #reels #fbreels #wagyu #foodie`80- **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).81- 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.8283### Mẫu bố cục84```85<HOOK 1 dòng + emoji>8687<2-3 dòng mô tả trend + gợi tò mò>8889<1 câu hỏi kéo comment> — Theo dõi để hóng tập sau nha! 🔥9091#hashtag1 #hashtag2 ...92```9394## Lưu ý / rủi ro (nói thật với user)95- **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.96- 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.97- Token là **bí mật** — đừng share/log ra ngoài.98- API đăng lên **Page**, không lên profile cá nhân / nhóm.