{
  "layLuc": "2026-10-08T07:31:42.280Z",
  "base": "https://us-central1-ab-fut.cloudfunctions.net",
  "ghiChu": "Sinh ra bởi abfut_function/scripts/xuat_hop_dong.js — đừng sửa tay.",
  "api": [
    {
      "ten": "postArticle",
      "method": "POST",
      "duong": "/postArticle",
      "pham": "post:article",
      "doc": false,
      "viec_vi": "Đăng bài viết — lên tường trong app ngay, lên website ở lần dựng kế tiếp.",
      "viec_en": "Publish an article — on the in-app wall at once, on the website at the next build."
    },
    {
      "ten": "postTip",
      "method": "POST",
      "duong": "/postTip",
      "pham": "post:tip",
      "doc": false,
      "viec_vi": "Đăng bài TIPS — hiện ngay trong tab Tips của app.",
      "viec_en": "Publish a TIPS post — shows up in the app's Tips tab immediately."
    },
    {
      "ten": "newsFeed",
      "method": "GET",
      "duong": "/newsFeed",
      "pham": null,
      "doc": true,
      "viec_vi": "Đọc lại bài đã đăng. Công khai, không cần khoá.",
      "viec_en": "Read published articles back. Public, no key needed."
    },
    {
      "ten": "sbcList",
      "method": "GET",
      "duong": "/sbcList?limit=50&sau=",
      "pham": null,
      "doc": true,
      "viec_vi": "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ế.",
      "viec_en": "The whole SBC table, paginated by docId (50 per page max). Pass the previous page's `tiep` as `sau` for the next one."
    },
    {
      "ten": "sbcMeta",
      "method": "GET",
      "duong": "/sbcMeta?ten=",
      "pham": null,
      "doc": true,
      "viec_vi": "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ó.",
      "viec_en": "Look up one SBC's cost and details by name. Omit `ten` to list the available names."
    }
  ],
  "baiViet": {
    "ngonNgu": [
      "en",
      "vi",
      "es",
      "fr"
    ],
    "truong": [
      {
        "ten": "title",
        "bat_buoc": true,
        "vi": "10–120 ký tự",
        "en": "10–120 characters"
      },
      {
        "ten": "body",
        "bat_buoc": true,
        "vi": "80–6000 ký tự",
        "en": "80–6000 characters"
      },
      {
        "ten": "tags",
        "bat_buoc": false,
        "vi": "≤ 5 phần tử, mỗi tag ≤ 24 ký tự; EAFC27 server tự thêm",
        "en": "≤ 5 items, ≤ 24 characters each; EAFC27 is added by the server"
      },
      {
        "ten": "imageUrl",
        "bat_buoc": false,
        "vi": "phải https://, ≤ 400 ký tự",
        "en": "must be https://, ≤ 400 characters"
      },
      {
        "ten": "imageRatio",
        "bat_buoc": false,
        "vi": "số, mặc định 1.91",
        "en": "number, defaults to 1.91"
      },
      {
        "ten": "authorName",
        "bat_buoc": false,
        "vi": "≤ 40 ký tự, mặc định ABFut News",
        "en": "≤ 40 characters, defaults to ABFut News"
      },
      {
        "ten": "lang",
        "bat_buoc": false,
        "vi": "en | vi | es | fr, mặc định en",
        "en": "en | vi | es | fr, defaults to en"
      },
      {
        "ten": "slugGoc",
        "bat_buoc": "với bản dịch",
        "vi": "slug của bản tiếng Anh",
        "en": "the slug of the English version"
      }
    ],
    "chanTrungNgay": 7,
    "toiDaMoiNgay": 10
  },
  "tip": {
    "ngonNgu": [
      "en",
      "vi",
      "es",
      "fr"
    ],
    "loai": [
      "leak",
      "promo",
      "thi_truong",
      "meo",
      "canh_bao"
    ],
    "doTinCay": [
      "tin_don",
      "xac_nhan"
    ],
    "huong": [
      "mua",
      "ban",
      "giu",
      "tranh",
      "theo_doi"
    ],
    "doChacChan": [
      "cao",
      "vua",
      "thap"
    ],
    "toiDaTieuDe": 90,
    "toiDaTomTat": 160
  },
  "hanhDong": [
    {
      "kieu": "xem_gia",
      "dang": "abfut://player?id=<eaId>",
      "dieuKien": "id > 0",
      "viDu": "abfut://player?id=70726",
      "vi": "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.",
      "en": "Opens the card page: price chart plus a button to add it straight to autobuy. `id` is the **eaId**, not the futbin id. If you do not have it, leave this action out — the server fills it in from `y[].the.ten` at publish time."
    },
    {
      "kieu": "them_filter",
      "dang": "abfut://filter?player=<id>&buy=<price>&sell=<price>",
      "dieuKien": "`player`>0 | `style`>0 · `buy`>0 | `bid`>0 · `sell`>0",
      "viDu": "abfut://filter?player=70726&buy=9500&sell=11000",
      "vi": "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.",
      "en": "Adds a filter straight into autobuy — **the strongest action here**: one tap and the bot starts buying. So `buy`/`sell` must be real numbers from the source, and `sell` must clear `buy` by enough to survive EA's 5% tax; under ~8% the engine lowers or skips it. Use `style=<id>` instead of `player=<id>` when the advice is about a chem style, and `bid` instead of `buy` to bid rather than buy now."
    },
    {
      "kieu": "mo_fodder",
      "dang": "abfut://fodder?rating=<N>",
      "dieuKien": "81 ≤ N ≤ 99",
      "viDu": "abfut://fodder?rating=89",
      "vi": "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.",
      "en": "Opens the fodder screen at that rating. **If the post mentions fodder ratings, it needs one of these per rating** — mention 89 and 90 and that is two separate buttons."
    },
    {
      "kieu": "mo_market",
      "dang": "abfut://market",
      "dieuKien": "—",
      "viDu": "abfut://market",
      "vi": "Mở màn giá thị trường. Dùng cho bài về xu hướng giá chung.",
      "en": "Opens the market price screen. For posts about overall price trends."
    },
    {
      "kieu": "mo_sbc",
      "dang": "abfut://sbc | abfut://sbc_solution",
      "dieuKien": "—",
      "viDu": "abfut://sbc",
      "vi": "Mở màn SBC / lời giải SBC. Dùng cho bài về SBC mới ra.",
      "en": "Opens the SBC screen or SBC solutions. For posts about a new SBC."
    },
    {
      "kieu": "mo_web",
      "dang": "https://abfut.site/...",
      "dieuKien": "host = `abfut.site` | `*.abfut.site`",
      "viDu": "https://abfut.site/news/",
      "vi": "**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ữ.",
      "en": "**`abfut.site` only.** futbin, YouTube and every other host is rejected. To point somewhere else, put the link in `than` as text."
    },
    {
      "kieu": "mo_tab",
      "dang": "abfut://player_tab?ten=<tab name>",
      "dieuKien": "`ten` ≠ \"\"",
      "viDu": "abfut://player_tab?ten=TOTW",
      "vi": "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.",
      "en": "Opens one tab of the Players screen. `ten` is matched against the tab title, **case-insensitively**, trimmed. The tab set lives in Firestore (`config/player_tabs`) so it can change — the current list is in the table below. A name that matches no tab leaves the app on **the tab it is already showing**: the button reports no error, it simply does nothing. The server cannot catch this one, so it is on you to check."
    }
  ],
  "playerTabs": [
    "Market",
    "<50K",
    "Fastest",
    "Icon",
    "50-100K",
    "Most Expensive",
    "Meta",
    "TOTW"
  ]
}
