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: Bearer | quê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
| endpoint | là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ường | bắt buộc | giới hạn |
|---|---|---|
title | có | 10–120 ký tự |
body | có | 80–6000 ký tự |
tags | không | ≤ 5 phần tử, mỗi tag ≤ 24 ký tự; EAFC27 server tự thêm |
imageUrl | không | phải https://, ≤ 400 ký tự |
imageRatio | không | số, mặc định 1.91 |
authorName | không | ≤ 40 ký tự, mặc định ABFut News |
lang | không | en | vi | es | fr, mặc định en |
slugGoc | với bản dịch | slug 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 đậm | in đậm |
một dòng chỉ có Tiêu đề mục | một <h2> |
• gạch đầu dòng | một mục danh sách |
| link YouTube đứng riêng một dòng | video 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ĩa | làm gì |
|---|---|---|
400 | thiếu trường, quá ngắn, imageUrl không phải https | sửa payload |
409 | trù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ờ |
503 | không đọc được bài gần đây | khô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ường | bắt buộc | giới hạn |
|---|---|---|
slug | có | dùng chung cho mọi ngôn ngữ của cùng bài |
lang | có | en vi es fr |
loai | có | leak promo thi_truong meo canh_bao |
doTinCay | có | tin_don xac_nhan |
tieuDe | có | ≤ 90 |
tomTat | có | ≤ 160 — câu hiện ở danh sách |
than | có | — |
hetHan | có | ISO date, phải ở tương lai |
anh | không | https:// |
chiPremium | không | true / false |
hanhDong | không | mảng hành động, mức bài |
y | không | mả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ường | bắt buộc | giới hạn |
|---|---|---|
the.ten | có | tên thẻ đúng như futbin lưu |
viSao | có | một câu lý do |
huong | có | mua ban giu tranh theo_doi |
doChacChan | có | cao vua thap |
vungGia | không | { tu, den } — cả hai > 0 và tu ≤ den |
hanhDong | không | Deeplink |
{
"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.
Deeplink
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": "..." }
| kieu | dạng uri | điều kiện | ví dụ |
|---|---|---|---|
xem_gia | abfut://player?id=<eaId> | id > 0 | abfut://player?id=70726 |
them_filter | abfut://filter?player=<id>&buy=<price>&sell=<price> | player>0 | style>0 · buy>0 | bid>0 · sell>0 | abfut://filter?player=70726&buy=9500&sell=11000 |
mo_fodder | abfut://fodder?rating=<N> | 81 ≤ N ≤ 99 | abfut://fodder?rating=89 |
mo_market | abfut://market | — | abfut://market |
mo_sbc | abfut://sbc | abfut://sbc_solution | — | abfut://sbc |
mo_web | https://abfut.site/... | host = abfut.site | *.abfut.site | https://abfut.site/news/ |
mo_tab | abfut://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 định | nghĩa |
|---|---|---|
lang | tất cả | một trong các ngôn ngữ trên |
limit | 20 | tố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.