Triển khai Ads

Bộ triển khai cho học viên

Dựng chiến dịch từ một đầu bài, tệp remarketing tự cập nhật

Trang này gom toàn bộ câu lệnh và các trường cần điền để bạn tự dựng hai phần trên tài khoản của chính mình. Bấm vào ô lệnh hoặc tên trường để chép.

Hai phần chạy thế nào

Đầu bài
bạn nói hoặc điền
Kiểm trước
chỉ đọc
Xem trước
bạn đồng ý
Facebook
tạm dừng
Bạn bật
Bảng khách đăng ký
Lark Base
GitHub
mỗi giờ
Tệp CHƯA MUA
để nhắm
vàTệp ĐÃ MUA
để loại trừ

Chuẩn bị

Cần cóDùng choKiểm tra
Business Manager mà bạn là quản trị viên, có tài khoản quảng cáo bên trongCả hai phầnCó mã dạng act_1234567890
Token System User của Meta, không hết hạnCả hai phầnXem cách tạo ngay dưới
Node.js 18 trở lênPhần 1node -v
Trang Facebook đứng tên quảng cáoPhần 1Bạn có quyền quản trị Trang
Pixel đã gắn trên trang đíchPhần 1, khi chạy chuyển đổiTrình quản lý sự kiện thấy sự kiện bắn về
Claude CodePhần 1, nếu muốn ra lệnh bằng lờiKhông có vẫn chạy tay được
Tài khoản GitHubPhần 2Tạo được kho Private
Tài khoản Lark và bảng Base chứa khách đăng kýPhần 2Có cột số điện thoại hoặc email

Tạo token System User của Meta

  1. Vào business.facebook.com/settings → Người dùng → Người dùng hệ thống → Thêm. Đặt tên, vai trò Quản trị viên.
  2. Chọn người dùng vừa tạo → Chỉ định tài sản → gán Tài khoản quảng cáo (Quản lý chiến dịch) và Trang (Nhà quảng cáo trở lên).
  3. Bấm Tạo mã mới → chọn app của doanh nghiệp → tick ads_management ads_read business_management pages_manage_ads pages_read_engagement → hết hạn: Không bao giờ → chép mã.
  4. Chấp nhận điều khoản danh sách khách hàng một lần: Trình quản lý quảng cáo → Đối tượng → Tạo đối tượng → Đối tượng tùy chỉnh → Danh sách khách hàng. Hiện màn hình điều khoản thì bấm Chấp nhận rồi thoát.

Token cá nhân hết hạn sau khoảng 60 ngày. Token của Trang bị Meta khoá với danh sách khách hàng (lỗi 1870090). Vì vậy cả hai phần đều dùng token System User.

Phần 1

Dựng chiến dịch từ một đầu bài

1

Tải gói và đặt vào dự án

Tải dung-chien-dich-meta.zip, giải nén. Dùng với Claude Code thì đặt thư mục dung-chien-dich-meta vào .claude/skills/ của dự án. Chạy tay thì để đâu cũng được.

Cửa sổ lệnh · vào thư mục vừa giải nén
cd dung-chien-dich-meta
cp config.env.example config.env
2

Điền config.env

BiếnĐiền gì
META_ACCESS_TOKENBắt buộcToken System User
META_AD_ACCOUNT_IDBắt buộcact_ cộng số tài khoản, ví dụ act_1234567890
META_PAGE_IDBắt buộcMã Trang Facebook đứng tên quảng cáo. Lấy ở bước 3
META_PIXEL_IDKhi chuyển đổiMã pixel mặc định. Lấy ở bước 3
META_IG_IDTuỳ chọnMã tài khoản Instagram nối với Trang, để quảng cáo hiện cả trên Instagram
META_ACCESS_TOKEN_PAGETuỳ chọnKhoá riêng của Trang. Chỉ cần khi System User không được gán Trang
META_API_VERSIONTuỳ chọnGiữ v25.0. Bị báo "deprecated version" thì đổi sang số Meta nhắc

Điền hai dòng đầu trước, chạy bước 3 để lấy mã Trang và mã pixel, rồi quay lại điền nốt.

3

Kiểm trước

Cửa sổ lệnh · chỉ đọc, không tạo gì
node scripts/kiem-truoc.mjs
node scripts/kiem-truoc.mjs --vung "Hà Nội, Đà Nẵng"    # tra thêm tên tỉnh, thành phố

Lệnh in ra sáu mục. Có dấu ❌ thì sửa xong mới đi tiếp.

MụcCho bạn biếtChép vào đâu
1. KhoáKhoá còn dùng được không, loại gì, đủ quyền chưa
2. Tài khoản quảng cáoTài khoản có đang hoạt động, đã chấp nhận điều khoản tệp khách hàng chưa
3. Trang FacebookCác Trang khoá dùng được, kèm mã InstagramMETA_PAGE_ID META_IG_ID
4. PixelCác pixel và sự kiện bắn trong 7 ngàyMETA_PIXEL_ID và ô su_kien của đầu bài
5. Tệp đối tượngMọi tệp kèm mã và quy môÔ tep_nham tep_loai_tru của đầu bài
6. Chiến dịch đang chạyĐể khỏi dựng trùng
4

Viết đầu bài

Mỗi chiến dịch là một thư mục chứa video hoặc ảnh và một tệp dau-bai.json.

Cách 1. Nói với Claude Code

Gõ vào Claude Code · thay nội dung bằng việc của bạn
Setup quảng cáo chuyển đổi cho video video-quang-cao.mp4.
Trang đích https://example.com/dang-ky, sự kiện LEAD.
Ngân sách 100000 một ngày. Chạy Hồ Chí Minh và Bình Dương, tuổi 28 đến 45.
Bài viết: (dán bài của bạn vào đây)

Claude kiểm trước, hỏi lại những ô còn thiếu, viết đầu bài, cho bạn xem trước rồi mới dựng.

Cách 2. Tự chép mẫu rồi sửa

Cửa sổ lệnh
mkdir -p viec/khoa-hoc-thang-12
cp mau/chuyen-doi.json viec/khoa-hoc-thang-12/dau-bai.json
# đặt video hoặc ảnh vào cùng thư mục, rồi mở dau-bai.json để sửa

Ba mẫu có sẵn: mau/chuyen-doi.json, mau/nhan-tin.json, mau/remarketing.json. Ý nghĩa từng ô ở mục Trường của đầu bài.

5

Xem trước

Cửa sổ lệnh · chỉ đọc
node scripts/dung-chien-dich.mjs viec/khoa-hoc-thang-12/dau-bai.json

Máy soát đầu bài, tra mã vùng, đọc tên các tệp, rồi in bản kế hoạch: tên chiến dịch, trang đích kèm UTM, pixel và sự kiện, ngân sách, vùng, tuổi, tệp nhắm, tệp loại trừ, media. Đầu bài thiếu ô nào máy nói rõ ô đó.

6

Dựng thật, tất cả tạm dừng

Cửa sổ lệnh
node scripts/dung-chien-dich.mjs viec/khoa-hoc-thang-12/dau-bai.json --tao

Thứ tự: tải media, tạo bài quảng cáo, chiến dịch, nhóm quảng cáo, quảng cáo. Mỗi bước xong được ghi vào sổ dau-bai.da-tao.json cạnh đầu bài.

Đứt giữa chừng thì sửa lỗi rồi chạy lại đúng lệnh này. Máy làm tiếp từ bước dở, không tạo trùng. Đầu bài đã dựng xong thì máy không tạo lần hai.

7

Kiểm sau, soát rồi bật

Cửa sổ lệnh · chỉ đọc
node scripts/kiem-sau.mjs viec/khoa-hoc-thang-12/dau-bai.json

Lệnh in trạng thái ba tầng, lý do nếu Meta từ chối, và link mở thẳng chiến dịch trong Ads Manager. Bạn soát lại rồi tự bật. Máy không bao giờ bật thay bạn.

Cửa sổ lệnh · gỡ một chiến dịch dựng nhầm
node scripts/dung-chien-dich.mjs viec/khoa-hoc-thang-12/dau-bai.json --go

Trường của đầu bài

Bắt buộc thiếu là máy không dựng Khi chuyển đổi bắt buộc với loại chuyển đổi Tuỳ chọn để trống thì dùng mặc định

TrườngĐiền gìĐể trống thì
tenBắt buộcTên sản phẩm hoặc chương trình. Thành tên chiến dịch
loaiBắt buộcchuyen-doi hoặc nhan-tin
ngan_sach_ngayBắt buộcSố tiền mỗi ngày, đơn vị đồng, không dấu chấm: 100000
mediaBắt buộcTên tệp video (mp4, mov) hoặc ảnh (jpg, png) nằm cạnh đầu bài
noi_dungBắt buộcBài viết. Một chuỗi, hoặc danh sách các dòng; dòng trống để ngắt đoạn
trang_dichKhi chuyển đổiLink trang đăng ký hoặc bán hàng, bắt đầu bằng https://
su_kienKhi chuyển đổiLEAD COMPLETE_REGISTRATION PURCHASE CONTACT SCHEDULELEAD
utmTuỳ chọnNên có. Ví dụ utm_source=facebook&utm_content=ten-chien-dichMáy nhắc
pixel_idTuỳ chọnDùng pixel khác với pixel trong config.envPixel trong config.env
tieu_deTuỳ chọnDòng tiêu đề đậm dưới video hoặc ảnhKhông có tiêu đề
nutTuỳ chọnSIGN_UP LEARN_MORE SHOP_NOW DOWNLOAD CONTACT_USSIGN_UP. Nhắn tin là nút nhắn tin
vungTuỳ chọnDanh sách: "VN" cho cả nước, hoặc tên tỉnh, thành phốCả nước
tuoi_tu tuoi_denTuỳ chọnTừ 18 đến 6522 và 55
gioi_tinhTuỳ chọntat-ca nam nuTất cả
tep_nhamTuỳ chọnDanh sách mã tệp đối tượng để nhắmKhông nhắm tệp
tep_loai_truTuỳ chọnDanh sách mã tệp loại trừ, ví dụ tệp đã muaKhông loại trừ
khoa_tepTuỳ chọntrue = không cho Meta phát ra ngoài tệp nhắmBật khi có tệp nhắm
nham_chi_tietTuỳ chọnSở thích, hành vi, chức danh theo định dạng flexible_spec của MetaKhông nhắm chi tiết
vi_triTuỳ chọnbang-tin-va-reels hoặc tu-dongBảng tin, Reels, video trong luồng
nhan_tenTuỳ chọnTự đặt tên chiến dịchNGÀY | LOẠI | TÊN

Mẫu chuyển đổi trên web

dau-bai.json
{
  "ten": "Khoá học mẫu tháng 12",
  "loai": "chuyen-doi",
  "trang_dich": "https://example.com/dang-ky",
  "utm": "utm_source=facebook&utm_content=khoa-hoc-mau-t12",
  "su_kien": "LEAD",
  "ngan_sach_ngay": 100000,
  "media": "video-quang-cao.mp4",
  "tieu_de": "Đăng ký nhận tư vấn",
  "noi_dung": [
    "Dòng mở đầu nói thẳng vào vấn đề của khách.",
    "",
    "Đoạn giữa nói vì sao vấn đề đó xảy ra và bạn giúp được gì.",
    "",
    "Dòng cuối mời khách để lại thông tin."
  ],
  "vung": ["Hồ Chí Minh", "Bình Dương", "Đồng Nai"],
  "tuoi_tu": 28,
  "tuoi_den": 45,
  "gioi_tinh": "tat-ca"
}

Mẫu nhắn tin Messenger

dau-bai.json
{
  "ten": "Tư vấn dịch vụ mẫu",
  "loai": "nhan-tin",
  "ngan_sach_ngay": 100000,
  "media": "video-quang-cao.mp4",
  "noi_dung": [
    "Dòng mở đầu nói thẳng vào vấn đề của khách.",
    "",
    "Nhắn tin để được tư vấn riêng cho trường hợp của bạn."
  ],
  "vung": ["Hà Nội"],
  "tuoi_tu": 25,
  "tuoi_den": 50,
  "gioi_tinh": "nu"
}

Những việc máy luôn làm

Việc máy luôn làmVì sao
Tạo mọi thứ ở trạng thái tạm dừngChỉ bạn quyết định lúc nào tiêu tiền
Đặt ngân sách ở nhóm quảng cáoNhắn tin Messenger bắt buộc như vậy, và dễ kiểm soát từng nhóm
Tắt Advantage+ đối tượngĐể bật thì Meta coi độ tuổi và tệp nhắm chỉ là gợi ý
Khoá trong tệp khi remarketingKhông khoá thì Meta phát ra người ngoài tệp
Gắn UTM vào trang đíchĐể biết đơn nào đến từ quảng cáo nào
Tải video theo khúc, lấy ảnh bìa từ videoVideo lớn tải một phát dễ đứt; bài video bắt buộc có ảnh bìa
Ghi sổ sau mỗi bướcChạy lại không tạo trùng

Phần 2

Tệp remarketing tự cập nhật

1

Tạo kho GitHub của bạn từ gói

Tải dong-bo-tep-remarketing.zip, giải nén.

  1. github.com → New repository → đặt tên, chọn Private → Create repository.
  2. Trên trang kho trống bấm "uploading an existing file", kéo toàn bộ nội dung thư mục vừa giải nén vào, kể cả hai thư mục .github và .claude → Commit changes.
  3. Kiểm tra: trong kho phải thấy tệp .github/workflows/dong-bo-tep.yml.

Trên Mac, bấm Cmd + Shift + . trong Finder để hiện thư mục có dấu chấm ở đầu.

2

Tạo app Lark và cho app đọc bảng

  1. open.larksuite.com → Developer Console → Create Custom App.
  2. Credentials & Basic Info → chép App ID và App Secret.
  3. Permissions & Scopes → thêm bitable:app:readonly → Create version → phát hành.
  4. Mở Base chứa khách đăng ký → nút … góc phải trên → Add document app → chọn app vừa tạo → quyền Can view.
  5. Chép hai mã từ link Base: phần sau /base/ là mã Base, phần sau ?table= là mã bảng.

Lỗi 91403 Forbidden về sau gần như luôn do quên bước thêm app vào Base.

3

Điền Secrets và Variables trên GitHub

Kho → Settings → Secrets and variables → Actions.

Tab Secrets (bí mật)

TênGiá trị
LARK_APP_SECRETApp Secret của app Lark
META_ACCESS_TOKENToken System User của Meta

Tab Variables (không bí mật)

TênGiá trị
LARK_APP_IDApp ID của app Lark
LARK_BASE_TOKENMã Base
LARK_TABLE_IDMã bảng khách đăng ký
META_AD_ACCOUNT_IDact_ cộng số tài khoản
DONG_BO_BATfalse lúc này, bật ở bước 7
META_AUD_CHUA_MUA META_AUD_DA_MUAMã hai tệp, có sau bước 4

Token và App Secret chỉ dán vào tab Secrets. Không gửi qua chat, không chụp màn hình.

4

Tạo hai tệp trên Meta

  1. Tab Actions → nếu được hỏi thì bấm "I understand my workflows, go ahead and enable them".
  2. Chọn "Tạo tệp trên Meta" → Run workflow → giữ tiền tố AUTO → tick "Tạo thật" → Run workflow.
  3. Đợi dấu tích xanh → mở lượt chạy → Summary → chép hai dòng META_AUD_CHUA_MUA = … và META_AUD_DA_MUA = ….
  4. Thêm hai Variables đó như ở bước 3.
5

Khai tên cột nếu bảng của bạn đặt khác

Bảng dùng đúng tên mặc định thì bỏ qua bước này. Đặt khác thì thêm Variable tương ứng. Bảng không có cột nào thì đặt giá trị là dấu gạch -.

VariableMặc địnhCột chứa gì
COT_SDTSố điện thoạiSố điện thoại khách. Nhận các dạng 0912…, +84912…, 84912…, 912…
COT_EMAILEmailEmail khách
COT_TRANG_THAITrạng thái TTTrạng thái thanh toán
GIA_TRI_DA_MUAĐã thanh toánGiá trị trong cột trạng thái nghĩa là đã trả tiền
COT_SO_TIENSố tiềnSố tiền đơn. Người đã mua phải có số tiền lớn hơn 0
DA_MUA_CAN_SO_TIEN1Đặt 0 nếu chỉ cần trạng thái, không cần số tiền
COT_CHAT_LUONGChất lượng dataKhông bắt buộc
GIA_TRI_RACRácDòng mang giá trị này bị bỏ qua
COT_HUY_NHAN-Cột đánh dấu khách từ chối nhận quảng cáo. Ô có giá trị thì người đó bị rút khỏi tệp
LARK_VIEW_ID(trống)Chỉ đọc một view đã lọc, mã dạng vew… trong link
MA_QUOC_GIA84Mã quốc gia thay số 0 đầu số điện thoại
6

Chạy kiểm tra, xem trước, rồi chạy thật lần đầu

  1. Actions → "Đồng bộ tệp remarketing" → Run workflow → giữ hai ô đã tick (Chỉ xem trước, Chạy kiểm tra cấu hình) → Run workflow.
  2. Bước "Kiểm tra cấu hình" phải ra "Kết quả: không có lỗi". Bước "Đồng bộ" cho biết sẽ đẩy bao nhiêu người.
  3. Run workflow lần nữa, bỏ tick "Chỉ xem trước". Kết quả đúng có dòng "Xong, đã ghi sổ ghi nhớ".
  4. Chạy thật thêm một lần. Phải ra "Không có thay đổi. Nghỉ." Đó là bằng chứng máy nhớ lần trước và không đẩy trùng.
7

Bật lịch tự động

Settings → Variables → sửa DONG_BO_BAT thành true. Từ đây máy tự chạy mỗi giờ vào phút 23, có thể trễ vài phút khi GitHub đông.

ViệcLàm ở đâu
Xem máy có chạy khôngTab Actions: dấu tích xanh mỗi giờ
Tạm dừngVariable DONG_BO_BAT = false
Chạy ngay không chờ giờActions → Run workflow, bỏ tick xem trước
Đổi token MetaSettings → Secrets → META_ACCESS_TOKEN → Update

Mỗi lượt chạy khoảng 20 giây, GitHub tính tròn 1 phút, tức khoảng 720 phút mỗi tháng. Gói miễn phí có 2.000 phút mỗi tháng cho kho Private.

Chạy trên máy (không bắt buộc)

Cửa sổ lệnh · chạy trên máy thay vì GitHub, cần Node.js 18 trở lên
cp config.env.example config.env        # rồi điền
node scripts/kiem-tra.mjs
node scripts/dong-bo.mjs --dry-run
node scripts/dong-bo.mjs --confirm

Chỉ nên chạy một nơi, hoặc GitHub hoặc máy.

Nối hai phần: remarketing cho người đã đăng ký

Phần 2 nuôi hai tệp. Phần 1 dùng hai tệp đó trong một chiến dịch remarketing: nhắm người chưa mua, loại trừ người đã mua, khoá không cho Meta phát ra ngoài.

  1. Chạy node scripts/kiem-truoc.mjs ở Phần 1. Mục 5 liệt kê hai tệp AUTO kèm mã.
  2. Chép mẫu remarketing, dán mã tệp chưa mua vào tep_nham, mã tệp đã mua vào tep_loai_tru.
  3. Xem trước rồi dựng như bước 5 và 6 của Phần 1.
viec/remarketing/dau-bai.json
{
  "ten": "Remarketing khách đã đăng ký chưa mua",
  "loai": "chuyen-doi",
  "trang_dich": "https://example.com/dang-ky",
  "utm": "utm_source=facebook&utm_content=remarketing-chua-mua",
  "su_kien": "LEAD",
  "ngan_sach_ngay": 100000,
  "media": "video-quang-cao.mp4",
  "noi_dung": [
    "Bạn đã để lại thông tin nhưng chưa quay lại.",
    "",
    "Video này trả lời đúng điều khiến nhiều người còn lưỡng lự.",
    "",
    "Xem xong, để lại thông tin một lần nữa để được tư vấn riêng."
  ],
  "vung": ["VN"],
  "tuoi_tu": 25,
  "tuoi_den": 60,
  "tep_nham": ["DAN_MA_TEP_CHUA_MUA"],
  "tep_loai_tru": ["DAN_MA_TEP_DA_MUA"],
  "khoa_tep": true
}
Điều nên biếtChi tiết
Loại trừ ở mọi chiến dịch bánThêm mã tệp đã mua vào tep_loai_tru của mọi đầu bài bán sản phẩm đó, không riêng remarketing
Nội dung cho khách ấmNgười đã đăng ký cần bằng chứng và lời giải đáp: video phản hồi, câu chuyện khách hàng, nhắc hạn. Đừng dùng lại bài chạy cho người lạ
Tệp nhỏMeta khuyên danh sách từ 1.000 người. Nhỏ hơn thì bị cảnh báo khi dùng làm đối tượng nhắm; dùng làm tệp loại trừ thì không ảnh hưởng. Ads Manager luôn hiện quy mô tối thiểu 1.000 với tệp nhỏ, đó không phải số thật
Không khớp 100%Meta chỉ khớp người có tài khoản trùng số điện thoại hoặc email. Người đã mua vẫn có thể thấy quảng cáo
Độ trễThay đổi tệp mất tới 24 giờ mới có hiệu lực và không làm chiến dịch học lại từ đầu
Người từ chối nhận quảng cáoPhải được rút khỏi tệp theo điều khoản Meta. Khai cột đánh dấu ở COT_HUY_NHAN để máy tự rút
Dữ liệu gửi điSố điện thoại và email được băm SHA-256 trước khi gửi. Sổ ghi nhớ chỉ chứa mã băm

Gỡ lỗi

Phần 1

Thấy gìLàm gì
deprecated version of the Ads APIĐổi META_API_VERSION sang số Meta nhắc trong câu lỗi
Dừng ở "tạo bài quảng cáo", lỗi quyền Trang (code 10)Gán Trang cho System User với quyền Nhà quảng cáo trở lên, hoặc điền META_ACCESS_TOKEN_PAGE
Dừng ở "tạo nhóm quảng cáo", nhắc điều khoản đối tượng tùy chỉnhAds Manager → Đối tượng → Tạo đối tượng → Danh sách khách hàng → Chấp nhận
Meta không xử lý được videoVideo mã HEVC (thường quay bằng iPhone). Chuyển sang MP4 H.264: ffmpeg -i vao.mov -c:v libx264 -pix_fmt yuv420p -c:a aac ra.mp4
Please reduce the amount of data, rate limitTài khoản bị siết tần suất tạm thời. Máy tự nghỉ rồi thử lại 5 lần; vẫn lỗi thì đợi 15 phút
Không tìm thấy vùngnode scripts/kiem-truoc.mjs --vung "tên" để xem Meta ghi tên thế nào
Trùng vùngVừa nhắm cả nước vừa nhắm tỉnh trong nước đó. Chọn một trong hai
Quảng cáo bị từ chối sau khi dựngnode scripts/kiem-sau.mjs … in lý do. Sửa bài, đổi tên tệp đầu bài rồi dựng bản mới
Chạy rồi mà không ghi nhận chuyển đổiPixel không bắn sự kiện đã chọn. Xem mục 4 của kiểm trước, đổi su_kien cho khớp
"Đầu bài này đã dựng xong từ trước"Muốn bản mới thì đổi tên tệp đầu bài. Muốn bỏ bản cũ thì chạy với --go

Phần 2

Thấy gìLàm gì
deprecated version of the Ads APIThêm Variable META_API_VERSION bằng số Meta nhắc trong câu lỗi
91403 ForbiddenApp Lark chưa được thêm vào Base (Phần 2, bước 2)
1870090Đang dùng token của Trang. Đổi sang token System User
1254024 InvalidFieldNamesTên cột khai ở Variables không khớp tên cột trong bảng
Không thấy mục "Tạo tệp trên Meta" ở tab ActionsThư mục .github chưa lên kho. Tải lại, nhớ hiện thư mục ẩn
Lịch không chạy đúng phút 23GitHub có thể trễ 5 đến 30 phút. Đợi 1 đến 2 giờ rồi mới kết luận
Nhận email "Run failed"Mở lượt chạy đó, đọc dòng lỗi ở bước Đồng bộ

An toàn