Services

Cloudflare TMap worker

Backend tuỳ chọn gồm Cloudflare Worker và cơ sở dữ liệu D1 để sao lưu TMap (bản đồ ticket → vòng DCA) của GoldenRobber và bầu leader khi nhiều node chạy cùng tài khoản. Trang này mô tả endpoint, schema, cách deploy bằng wrangler và trạng thái hiện tại. An optional Cloudflare Worker + D1 backend that backs up GoldenRobber's TMap (ticket → DCA round map) and elects a leader when several nodes run the same account. This page covers the endpoints, schema, deploying with wrangler, and its current status.

  • Cập nhậtUpdated 18/09/2026
  • NguồnSource cloudflare-tmap-worker/README.md
  • cloudflare-tmap-worker/src/index.js · wrangler.toml · schema.sql · package.json
  • GoldenRobber-1.41.4.mq5 (Cloud sync inputs)

Trạng thái hiện tạiCurrent status

Tuỳ chọn, production không dùngOptional, not used in production

Trong cả hai config pass58 (v1.41.4-pass58-easupported-goldenrobber-29082026.set và v1.42.b7-pass58.set): InpCloudSyncEnable=true, InpCloudCfDomain để trống, InpCloudMyApiDomain=https://fxconsole.gamelau.uk/easupported/goldenrobber. Nghĩa là EA production chỉ đồng bộ TMap lên fxconsole (MyApi), không gọi Worker này.

In both pass58 configs (v1.41.4-pass58-easupported-goldenrobber-29082026.set and v1.42.b7-pass58.set): InpCloudSyncEnable=true, InpCloudCfDomain is empty, InpCloudMyApiDomain=https://fxconsole.gamelau.uk/easupported/goldenrobber. The production EA therefore syncs TMap only to fxconsole (MyApi) and never calls this Worker.

wrangler.toml trong repo vẫn giữ database_id = "REPLACE_WITH_YOUR_D1_DATABASE_ID", nên repo không cho thấy một bản Worker nào đang được deploy (chưa xác minh trên tài khoản Cloudflare).

wrangler.toml in the repo still holds database_id = "REPLACE_WITH_YOUR_D1_DATABASE_ID", so the repo shows no deployed Worker instance (not verified against the Cloudflare account).

EA dùng Worker thế nàoHow the EA uses it

Từ v1.38 EA chỉ nhận domain; EA tự nối đường dẫn: Worker dùng /tmap/{save,load,clear,heartbeat}, fxconsole (MyApi) dùng /api/tmap/{save,load,clear,heartbeat}. Hai backend có cùng hợp đồng API và dùng chung một Bearer token (InpCloudBearerToken).

  • Save: gửi toàn bộ TMap lên từng backend có domain (POST /save), theo chu kỳ InpCloudSyncIntervalSec.
  • Clear: khi không còn lệnh nào (nPos == 0), gọi DELETE /clear trên cả hai backend.
  • Load: khi cần khôi phục, EA có hàm đọc từ Worker (D1) và từ MyApi; chỉ chạy khi InpCloudSyncEnable=true và không ở Strategy Tester.
  • Heartbeat / leader: thử Worker trước, lỗi thì sang MyApi. Nếu cả hai lỗi quá 2 × InpCloudHeartbeatTimeoutSec, node tự nhận làm leader để không chặn giao dịch.

Since v1.38 the EA takes a domain only and appends the paths itself: the Worker uses /tmap/{save,load,clear,heartbeat}, fxconsole (MyApi) uses /api/tmap/{save,load,clear,heartbeat}. Both backends share the same API contract and the same Bearer token (InpCloudBearerToken).

  • Save: posts the whole TMap to every backend that has a domain (POST /save), every InpCloudSyncIntervalSec.
  • Clear: when no positions remain (nPos == 0), calls DELETE /clear on both backends.
  • Load: for recovery the EA has loaders for the Worker (D1) and for MyApi; they only run with InpCloudSyncEnable=true and never in the Strategy Tester.
  • Heartbeat / leader: tries the Worker first, falls back to MyApi. If both fail for longer than 2 × InpCloudHeartbeatTimeoutSec, the node declares itself leader so trading isn't blocked.
flowchart LR
  EA["GoldenRobber EA"] -- "HTTPS /tmap/* (nếu InpCloudCfDomain có giá trị)" --> CF["Cloudflare Worker gr-tmap"]
  CF --> D1[("D1: tmap_entries, tmap_nodes")]
  EA -- "HTTPS /api/tmap/* (production)" --> FX["fxconsole TmapApiController"]
  EA -. "heartbeat: Worker trước, MyApi dự phòng" .-> CF
flowchart LR
  EA["GoldenRobber EA"] -- "HTTPS /tmap/* (when InpCloudCfDomain is set)" --> CF["Cloudflare Worker gr-tmap"]
  CF --> D1[("D1: tmap_entries, tmap_nodes")]
  EA -- "HTTPS /api/tmap/* (production)" --> FX["fxconsole TmapApiController"]
  EA -. "heartbeat: Worker first, MyApi fallback" .-> CF

Quy trình khôi phục chi tiết: Khôi phục TMap.Full recovery procedure: TMap disaster recovery.

Input Cloud sync trong EACloud sync inputs in the EA

InputMặc định EAEA defaultpass58Ý nghĩaMeaning
InpCloudSyncEnablefalsetrueBật đồng bộ TMap lên cloud (chỉ live)Enable TMap cloud sync (live only)
InpCloudBearerTokentrốngempty<secret>Bearer token, dùng chung cho cả hai backendBearer token, shared by both backends
InpCloudCfDomaintrốngemptytrốngemptyDomain Worker, ví dụ https://gr-tmap.your-account.workers.devWorker domain, e.g. https://gr-tmap.your-account.workers.dev
InpCloudMyApiDomaintrốngemptyhttps://fxconsole.gamelau.uk/easupported/goldenrobberDomain fxconsole (không thêm /api/tmap)fxconsole domain (do not add /api/tmap)
InpCloudSyncIntervalSec3010Chu kỳ đồng bộ (giây)Sync interval (seconds)
InpCloudWebTimeoutMs5000—Timeout WebRequest (ms)WebRequest timeout (ms)
InpCloudNodePriority100100Ưu tiên node, số nhỏ ưu tiên cao (1–999)Node priority, lower wins (1–999)
InpCloudNodeIdtrốngemptytrốngemptyID node duy nhất; trống = tự lấy từ terminalUnique node ID; empty = derived from the terminal
InpCloudHeartbeatTimeoutSec9090Node bị coi là chết nếu không heartbeat trong N giâyA node counts as dead after N seconds without a heartbeat
Tên input cũ trong README WorkerOld input names in the Worker README

cloudflare-tmap-worker/README.md còn nhắc InpCloudSecretKey và InpCloudCfUrl. Từ v1.38 URL đổi thành InpCloudCfDomain (chỉ domain) và token nằm ở InpCloudBearerToken. Config cũ còn đuôi /tmap hoặc /api/tmap sẽ tạo URL sai, phải bỏ đuôi đó trong .set.

cloudflare-tmap-worker/README.md still mentions InpCloudSecretKey and InpCloudCfUrl. Since v1.38 the URL input is InpCloudCfDomain (domain only) and the token is InpCloudBearerToken. Old configs that keep a /tmap or /api/tmap suffix build wrong URLs; remove the suffix in the .set.

API endpointAPI endpoints

Mọi request (trừ preflight OPTIONS) phải có header Authorization: Bearer <secret> khớp với secret TMAP_SECRET_KEY của Worker; nếu Worker chưa có secret hoặc token sai → 401 {"message":"Unauthorized"}. Worker trả CORS * cho GET, POST, DELETE, OPTIONS.

Every request (except the OPTIONS preflight) needs Authorization: Bearer <secret> matching the Worker's TMAP_SECRET_KEY secret; a missing secret on the Worker or a wrong token → 401 {"message":"Unauthorized"}. The Worker answers CORS * for GET, POST, DELETE, OPTIONS.

MethodPathHành viBehaviourKết quảResponse
POST/tmap/saveThay toàn bộ map của magic+account: xoá rồi insert batchReplaces the whole map for magic+account: delete, then batch insert{ok, count}
GET/tmap/load?magic=…&account=…Đọc mapReads the map{ok, magic, account, entries}
DELETE/tmap/clear?magic=…&account=…Xoá mapDeletes the map{ok, deleted}
POST/tmap/heartbeatUpsert heartbeat của node rồi bầu leader trong các node còn sống (priority tăng dần, rồi node_id)Upserts the node heartbeat, then elects a leader among live nodes (priority ascending, then node_id){ok, is_leader, current_leader_id, current_leader_priority, alive_count, alive_nodes}

Lỗi: thiếu trường → 422; đường dẫn khác → 404 Not found; exception → 500 {"message":"Server error","error":…}. README Worker chỉ liệt kê ba endpoint đầu; /tmap/heartbeat có trong src/index.js.

Errors: missing fields → 422; any other path → 404 Not found; an exception → 500 {"message":"Server error","error":…}. The Worker README lists only the first three endpoints; /tmap/heartbeat exists in src/index.js.

Body của saveSave body

{
  "magic": "21478308",
  "account": "12345",
  "entries": [
    {
      "ticket": 100,
      "round_id": 5,
      "add_num": 2,
      "is_dca_pos": true,
      "pos_type": 0,
      "comment": "DCAPos R5 B#2 |add_minpips"
    }
  ]
}

Body của heartbeatHeartbeat body

Bắt buộc magic, account, node_id, priority; tuỳ chọn timeout_sec (mặc định 90). Node được coi là sống nếu last_heartbeat trong vòng timeout_sec giây.

Requires magic, account, node_id, priority; optional timeout_sec (default 90). A node is alive if its last_heartbeat is within timeout_sec seconds.

{"magic":"21478308","account":"12345","node_id":"vps-tokyo","priority":100,"timeout_sec":90}

Schema D1D1 schema

BảngTableCộtColumnsKhoáKeys
tmap_entriesid, magic, account, ticket, round_id, add_num, is_dca_pos, pos_type, comment, updated_atUNIQUE(magic, account, ticket), indexindex (magic, account)
tmap_nodesid, magic, account, node_id, priority, last_heartbeat (unix timestamp)(unix timestamp)UNIQUE(magic, account, node_id), indexindex (magic, account)

Deploy bằng wranglerDeploy with wrangler

  1. Cài Wrangler CLI (trong cloudflare-tmap-worker/):Install the Wrangler CLI (in cloudflare-tmap-worker/):
    npm install
    npm install -g wrangler
    wrangler login
  2. Tạo database D1:Create the D1 database:
    npm run db:create
    Output có dạng dưới đây. Copy database_id dán vào wrangler.toml thay cho REPLACE_WITH_YOUR_D1_DATABASE_ID.The output looks like this. Copy database_id into wrangler.toml in place of REPLACE_WITH_YOUR_D1_DATABASE_ID.
    ✅ Successfully created DB 'gr-tmap'
    [[d1_databases]]
    binding = "DB"
    database_name = "gr-tmap"
    database_id = "abc123-def456-..."
  3. Áp schema:Apply the schema:
    npm run db:migrate
  4. Đặt secret: lệnh hỏi giá trị secret; nhập trực tiếp, không lưu vào file.Set the secret: the command prompts for the value; type it there, never save it in a file.
    npm run secret:set
    Secret này phải giống token trong EA (InpCloudBearerToken, tên cũ trong README là InpCloudSecretKey) và TMAP_SECRET_KEY trong .env của fxconsole.This secret must be identical to the EA token (InpCloudBearerToken; the README's old name is InpCloudSecretKey) and to TMAP_SECRET_KEY in fxconsole's .env.
  5. Deploy:Deploy:
    npm run deploy
    ✨ Deployed gr-tmap triggers (1 sec)
      https://gr-tmap.your-account.workers.dev
    URL này dùng làm InpCloudCfDomain trong EA (chỉ domain; README ghi tên cũ InpCloudCfUrl). Nhớ thêm domain vào danh sách WebRequest được phép của MT5.Use this URL as the EA's InpCloudCfDomain (domain only; the README uses the old name InpCloudCfUrl). Remember to add the domain to MT5's allowed WebRequest URLs.

Script npmnpm scripts

ScriptLệnhCommand
devwrangler dev
deploywrangler deploy
db:createwrangler d1 create gr-tmap
db:migratewrangler d1 execute gr-tmap --file=schema.sql --remote
db:migrate-localwrangler d1 execute gr-tmap --file=schema.sql --local
secret:setwrangler secret put TMAP_SECRET_KEY

Kiểm traTest

curl -X POST https://gr-tmap.your-account.workers.dev/tmap/save \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <secret>" \
  -d '{"magic":"123","account":"test","entries":[]}'

Kết quả mong đợi: {"ok":true,"count":0}. Nhận 401 nghĩa là secret chưa đặt hoặc token sai.

Expected: {"ok":true,"count":0}. A 401 means the secret isn't set or the token is wrong.