ABFut
🇻🇳VI

API đăng nội dung

Hợp đồng HTTP để đăng bài viết và bài tips của ABFut, kèm đầy đủ deeplink mà một bài tips có thể dùng. Sinh ra từ mã đang chạy trên server.

Sinh ra từ mã đang chạy trên server lúc . Mọi con số, enum và danh sách deeplink trên trang này đọc thẳng từ validator server đang chạy, không chép tay. Bản cho máy đọc: /api/contract.json.

Xác thực

Mọi lời gọi ghi đều cần bearer token trong header. Không có đăng ký tự động: xin khoá thì được cấp một khoá giới hạn đúng endpoint cần dùng.

Authorization: Bearer <key>
Content-Type: application/json

Khoá mang theo phạm vi. Khoá chỉ có post:tip không đăng được bài viết, và ngược lại — nên khoá rò rỉ thì thiệt hại giới hạn trong đúng việc nó được cấp. Khoá lưu dạng băm, nên chỉ hiện một lần lúc tạo, và thu hồi được riêng từng cái mà không làm chết người gọi nào khác.

Lỗi xác thực

mãnghĩa
401 thiếu Authorization: Bearerquên header
401 chứng thực không hợp lệkhoá sai hoặc đã bị thu hồi
401 khoá không có phạm vi "…"khoá đúng, nhưng không được phép gọi API này

Các endpoint

endpointlàm gìphạm vi
POST /postArticleĐăng bài viết — lên tường trong app ngay, lên website ở lần dựng kế tiếp.post:article
POST /postTipĐăng bài TIPS — hiện ngay trong tab Tips của app.post:tip
GET /newsFeedĐọc lại bài đã đăng. Công khai, không cần khoá.không
GET /sbcList?limit=50&sau=Cả bảng SBC, phân trang theo docId (tối đa 50/trang). Truyền `tiep` của trang trước vào `sau` để lấy trang kế.không
GET /sbcMeta?ten=Tra chi phí và thông tin một SBC theo tên. Bỏ trống `ten` thì liệt kê các tên đang có.không

endpoint: https://us-central1-ab-fut.cloudfunctions.net

postArticle — bài viết

Bài viết lên tường trong app ngay. Website là trang tĩnh nên bài xuất hiện ở đó từ lần dựng kế tiếp.

trườngbắt buộcgiới hạn
titlecó10–120 ký tự
bodycó80–6000 ký tự
tagskhông≤ 5 phần tử, mỗi tag ≤ 24 ký tự; EAFC27 server tự thêm
imageUrlkhôngphải https://, ≤ 400 ký tự
imageRatiokhôngsố, mặc định 1.91
authorNamekhông≤ 40 ký tự, mặc định ABFut News
langkhôngen | vi | es | fr, mặc định en
slugGocvới bản dịchslug của bản tiếng Anh
curl -X POST https://us-central1-ab-fut.cloudfunctions.net/postArticle \
  -H "Authorization: Bearer $ABFUT_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "title": "EA confirms TOTW 3 release time",
    "body":  "...",
    "tags":  ["Promo", "TOTW"],
    "imageUrl": "https://..."
  }'

Viết thân bài

Cùng một chuỗi vừa là bài trên website vừa là bài trên tường trong app. Viết cho tường, website tự ổn:

  • 200–350 từ. Dài hơn thì trên tường thành một khối chữ không ai đọc.
  • Hai ba câu đầu phải đứng độc lập được — người lướt tường chỉ đọc đến đó.
  • Kết bằng một câu hành động cụ thể, không phải lời chúc.

Cú pháp website dựng được

ví dụnghĩa
in đậmin đậm
một dòng chỉ có Tiêu đề mụcmột <h2>
• gạch đầu dòngmột mục danh sách
link YouTube đứng riêng một dòngvideo nhúng

Ngôn ngữ

App và website lọc theo ngôn ngữ và KHÔNG rơi về tiếng Anh. Bài chỉ có en thì với người đọc ngôn ngữ khác là bài không tồn tại.

Đăng bản tiếng Anh trước, giữ slug nó trả về, rồi mỗi bản dịch gửi slug đó làm slugGoc. Cặp đó là thứ ghép các bản thành một bài và gắn hreflang đúng; thiếu nó thì máy tìm kiếm đọc thành mấy trang rời nhau, trùng nội dung.

Bản dịch không bị luật chặn trùng chủ đề chặn — nó cố ý cùng chủ đề.

-d '{ "title": "...", "body": "...", "lang": "vi",
      "slugGoc": "<slug bản tiếng Anh>" }'

Server chặn những gì

mãnghĩalàm gì
400thiếu trường, quá ngắn, imageUrl không phải httpssửa payload
409trùng chủ đề trong 7 ngày (trả về cả bài cũ để đối chiếu)đổi góc viết, hoặc bỏ
429đã đăng 10 bài trong 24 giờchờ
503không đọc được bài gần đâykhông đăng, thử lại sau

postTip — bài tips

Bài tips hiện ngay trong tab Tips của app, không cần dựng website. Đăng lại cùng cặp (slug, lang) thì ghi đè, không tạo bài thứ hai.

trườngbắt buộcgiới hạn
slugcódùng chung cho mọi ngôn ngữ của cùng bài
langcóen vi es fr
loaicóleak promo thi_truong meo canh_bao
doTinCaycótin_don xac_nhan
tieuDecó≤ 90
tomTatcó≤ 160 — câu hiện ở danh sách
thancó—
hetHancóISO date, phải ở tương lai
anhkhônghttps://
chiPremiumkhôngtrue / false
hanhDongkhôngmảng hành động, mức bài
ykhôngmảng ý

Mảng y[] là nơi giá trị nằm

than là văn bản người đọc lướt qua. Mỗi phần tử y[] là một thẻ bấm được: một hướng, một vùng giá, một câu lý do, và các nút.

trườngbắt buộcgiới hạn
the.tencótên thẻ đúng như futbin lưu
viSaocómột câu lý do
huongcómua ban giu tranh theo_doi
doChacChancócao vua thap
vungGiakhông{ tu, den } — cả hai > 0 và tu ≤ den
hanhDongkhôngDeeplink
{
  "the": { "ten": "Hadj Moussa" },
  "huong": "mua",
  "doChacChan": "vua",
  "viSao": "TOTW price dipped once packs dried up; floor around 9.5K.",
  "vungGia": { "tu": 9500, "den": 11000 },
  "hanhDong": [
    { "kieu": "xem_gia", "nhan": "Price", "uri": "abfut://player?id=70726" },
    { "kieu": "them_filter", "nhan": "Add to autobuy",
      "uri": "abfut://filter?player=70726&buy=9500&sell=11000" }
  ]
}

Tên thẻ viết đúng như futbin lưu — Groß chứ không phải Gross. Viết đúng thì server tra được eaId ngay lúc đăng và nút giá có sẵn; viết sai thì app phải tra theo tên lúc người đọc bấm, chậm hơn và có thể trượt hẳn.

Hướng tranh cũng là một ý. Bài về một thẻ đang bị thổi giá mà chỉ có ý mua là đang đẩy người đọc vào đúng chỗ nguy hiểm.

Nút trong bài tips mở app qua các URI này. Danh sách là đóng: kieu không có dưới đây, hoặc uri không khớp dạng của nó, bị trả 400 lúc đăng — và nếu có cái nào lọt qua thì app im lặng không dựng nút.

Mỗi hành động là một object:

{ "kieu": "...", "nhan": "button label", "uri": "..." }
kieudạng uriđiều kiệnví dụ
xem_giaabfut://player?id=<eaId>id > 0abfut://player?id=70726
them_filterabfut://filter?player=<id>&buy=<price>&sell=<price>player>0 | style>0 · buy>0 | bid>0 · sell>0abfut://filter?player=70726&buy=9500&sell=11000
mo_fodderabfut://fodder?rating=<N>81 ≤ N ≤ 99abfut://fodder?rating=89
mo_marketabfut://market—abfut://market
mo_sbcabfut://sbc | abfut://sbc_solution—abfut://sbc
mo_webhttps://abfut.site/...host = abfut.site | *.abfut.sitehttps://abfut.site/news/
mo_tababfut://player_tab?ten=<tab name>ten ≠ ""abfut://player_tab?ten=TOTW

xem_gia Mở trang thẻ: chart giá, và nút thêm thẳng vào autobuy. id là eaId, không phải futbinId. Không biết eaId thì cứ bỏ trống hành động này — server tự tra từ y[].the.ten lúc đăng.

them_filter Thêm thẳng một filter vào autobuy — hành động mạnh nhất: người đọc bấm một lần là bot bắt đầu mua. Nên buy/sell phải là số thật có trong nguồn, và sell cao hơn buy đủ để còn lãi sau 5% thuế EA; chênh dưới ~8% thì engine tự hạ hoặc bỏ qua. Dùng style=<id> thay player=<id> khi lời khuyên nói về một chem style; bid thay buy khi muốn đấu giá thay vì mua ngay.

mo_fodder Mở màn fodder đúng mức rating. Bài nhắc tới mức rating fodder thì phải có nút này cho TỪNG mức — nhắc 89 và 90 thì hai nút riêng.

mo_market Mở màn giá thị trường. Dùng cho bài về xu hướng giá chung.

mo_sbc Mở màn SBC / lời giải SBC. Dùng cho bài về SBC mới ra.

mo_web Chỉ abfut.site. Link futbin, YouTube hay host nào khác đều bị chặn. Muốn dẫn ra ngoài thì đặt link trong than dạng chữ.

mo_tab Mở một tab của màn Players. ten so với tiêu đề tab, không phân biệt hoa thường, bỏ khoảng trắng hai đầu. Bộ tab nằm trên Firestore (config/player_tabs) nên có thể đã đổi — danh sách đang có ở bảng dưới. Tên không khớp tab nào thì app giữ nguyên tab đang xem: nút không báo lỗi, chỉ là không có gì xảy ra. Server không bắt được lỗi này, nên đây là chỗ phải tự cẩn thận.

Tab màn Players

Các tên mà mo_tab nhận. So với tiêu đề tab, không phân biệt hoa thường. Bộ tab này nằm trên Firestore nên có thể đổi — danh sách dưới đây đọc lúc dựng trang.

tên
Market
<50K
Fastest
Icon
50-100K
Most Expensive
Meta
TOTW

newsFeed — đọc lại

Công khai, không cần khoá. Dùng để kiểm bài đã lên chưa và để tránh lặp chủ đề.

curl "https://us-central1-ab-fut.cloudfunctions.net/newsFeed?lang=vi&limit=20"
curl "https://us-central1-ab-fut.cloudfunctions.net/newsFeed?slug=<slug>"
tham sốmặc địnhnghĩa
langtất cảmột trong các ngôn ngữ trên
limit20tối đa 50
slug—khớp slug hoặc slugGoc

Trả { ok, lang, soBai, bai: [...] }. Cache biên 5 phút nên bài vừa đăng có thể chưa thấy ngay.

sbcMeta — chi phí SBC

Công khai, không cần khoá. Trả về số liệu crawl từ futbin của một SBC: chi phí trên console và PC, có lặp lại không, còn bao lâu, và lượt bình chọn của cộng đồng.

curl --get "https://us-central1-ab-fut.cloudfunctions.net/sbcMeta" --data-urlencode "ten=83+ Upgrade"
curl "https://us-central1-ab-fut.cloudfunctions.net/sbcMeta"      # liệt kê tên

Tên được khớp theo ba bậc, chặt trước lỏng sau: đúng khoá tài liệu, rồi bỏ qua hoa thường, rồi bỏ qua mọi thứ không phải chữ hay số (nên 83 upgrade vẫn ra 83+ Upgrade).

Tên không khớp bậc nào thì trả 404 kèm danh sách goiY các tên gần giống — không bao giờ tự chọn cái giống nhất. Đây là chi phí tính bằng coin: trả lời về một SBC khác còn tệ hơn là không trả lời. Gọi mà bỏ trống ten thì được danh sách mọi tên đang có.

Cần gắn nhãn cho NHIỀU SBC một lúc — ví dụ overlay trên màn SBC của EA — thì dùng sbcList rồi khớp tại chỗ: một request cho cả bảng thay vì mỗi tên một request, và các lần EA dựng lại DOM sau đó không tốn thêm gì. Lật trang bằng cách truyền tiep của lần trả về trước vào sau; tiep: null là đã hết. Hãy khớp tại chỗ theo đúng ba bậc ở trên, để một cái tên không ra kết quả này ở đây mà kết quả khác ở kia.

curl "https://us-central1-ab-fut.cloudfunctions.net/sbcList?limit=50"
curl --get "https://us-central1-ab-fut.cloudfunctions.net/sbcList" -d limit=50 \
     --data-urlencode "sau=<tiep>"

Luật

  • Không bịa số. Mọi mức giá, phần trăm, tên thẻ phải có trong nguồn. Sai một con số giá là người đọc mất coin thật.
  • Không hứa lợi nhuận. Không "chắc chắn lãi", không "x2 coin". FAQ của chính ABFut trả lời "ABFut có đảm bảo lợi nhuận không? Không" — viết ngược lại là tự mâu thuẫn, và các store soi rất kỹ khẳng định về thu nhập.
  • Bài tips bắt buộc có hạn. Gợi ý "mua trước thứ Sáu" còn nằm trên feed thứ Hai tuần sau là một gợi ý đã sai.

Trang guide và tactics nằm trong repo, không có API — soạn nội dung rồi bàn giao.