Tool Worker API#

Tool Worker là service Go độc lập, vừa là HTTP API server vừa là background worker. Chạy trên port 3500.

Base URL (internal): http://fbtool-socialking-vn:3500/api/v1

Auth: Không cần auth — service chỉ expose trong Docker network nội bộ.


Tổng quan chức năng#

EndpointMô tả
POST /fetchLấy name + avatar + type từ Facebook UID/URL
POST /check-accountKiểm tra tài khoản live/die
POST /check-proxyKiểm tra proxy alive, geo, latency
POST /resolvePhân tích 1 Facebook URL
POST /resolve-urlsPhân tích batch nhiều Facebook URL
GET /healthHealth check

1. Fetch Facebook Info#

POST /api/v1/fetch#

Lấy thông tin cơ bản: tên, avatar, loại tài khoản từ UID hoặc vanity username.

Request Body:

{
  "uids": ["100045678901", "minhngoc22052k3", "TrungScapBot"]
}
FieldTypeMô tả
uidsstring[]Danh sách UID số hoặc vanity username. Max 50000 items.

Response (200):

{
  "success": true,
  "total": 3,
  "results": [
    {
      "uid": "100045678901",
      "name": "Nguyễn Văn A",
      "avatar_url": "https://scontent-hkg4-2.xx.fbcdn.net/...",
      "type": "user",
      "exists": true
    },
    {
      "uid": "minhngoc22052k3",
      "name": "Minh Ngọc",
      "avatar_url": "https://scontent...",
      "type": "user",
      "exists": true
    },
    {
      "uid": "100099999999999",
      "name": "",
      "avatar_url": "",
      "type": "",
      "exists": false,
      "error": "uid_not_found"
    }
  ]
}

Trường response:

FieldTypeMô tả
uidstringUID đã nhập (numeric hoặc vanity)
namestringTên Facebook
avatar_urlstringURL avatar full-size
typestringuser | page | group
existsboolUID tồn tại trên Facebook
errorstringLý do nếu không lấy được: uid_not_found, rate_limited, network_error

Logic xử lý:

Vanity username (minhngoc22052k3):
  → GET facebook.com/{username} → đọc 300KB HTML
  → Extract og:title (name) + og:image (avatar)
  → Extract userID từ HTML ~254KB

Numeric UID (100045678901):
  → Graph API picture endpoint → kiểm tra tồn tại
  → GET facebook.com/profile.php?id={uid} → đọc 150KB HTML
  → Extract og:title + og:image

Type detection:
  → Graph API picture với vanity name:
    200 → page
    error → user (Graph không nhận vanity của user)
  → Group: nhận diện từ og:url chứa /groups/

Batch lớn: Request > 10.000 items sẽ được xử lý async. Response trả về job_id và kết quả ghi file.


2. Check Account#

POST /api/v1/check-account#

Kiểm tra tài khoản Facebook còn live hay đã die. Không cần cookie.

Request Body:

{
  "uids": ["100045678901", "100004549753790", "minhngoc22052k3"]
}

Response (200):

{
  "success": true,
  "total": 3,
  "summary": {
    "live": 1,
    "die": 1,
    "errors": 1
  },
  "results": [
    {
      "uid": "100045678901",
      "status": "live",
      "name": "Nguyễn Văn A",
      "has_avatar": true,
      "error": ""
    },
    {
      "uid": "100004549753790",
      "status": "die",
      "name": "",
      "has_avatar": false,
      "error": "account_deactivated"
    },
    {
      "uid": "minhngoc22052k3",
      "status": "live",
      "name": "Minh Ngọc",
      "has_avatar": true,
      "error": "private_profile"
    }
  ]
}

Giá trị status:

StatusÝ nghĩa
liveTài khoản tồn tại và active
dieTài khoản bị xóa hoặc vô hiệu hóa
errorKhông thể kiểm tra (mạng, rate limit)

Giá trị error field (khi status = live):

ErrorÝ nghĩa
private_profileProfile ẩn — không lấy được thông tin nhưng tài khoản vẫn live

Giá trị error field (khi status = die):

ErrorÝ nghĩa
account_deactivatedPhát hiện từ HTML: từ khóa “deactivat”/“unavailable”

Logic phát hiện die:

Private profile và die đều redirect về login page với Picture API
→ Không thể dùng Picture API để phân biệt

Giải pháp: Đọc 150KB HTML của profile page
  → "deactivat" hoặc "unavailable" trong body → die (account_deactivated)
  → Không có keywords trên → live (có thể private_profile)

3. Check Proxy#

POST /api/v1/check-proxy#

Kiểm tra proxy alive, IP thực, geo, latency. ZERO Facebook contact — tuyệt đối an toàn.

Request Body:

{
  "proxies": [
    {
      "id": "proxy-uuid-1",
      "host": "1.2.3.4",
      "port": 8080,
      "type": "http",
      "username": "user1",
      "password": "pass1"
    },
    {
      "id": "proxy-uuid-2",
      "host": "5.6.7.8",
      "port": 3128,
      "type": "http"
    }
  ]
}
FieldTypeRequiredMô tả
idstringNoID để map kết quả
hoststringYesIP hoặc hostname proxy
portintYesPort
typestringYeshttp | https | socks5
usernamestringNoAuth username
passwordstringNoAuth password

Response (200):

{
  "success": true,
  "total": 2,
  "summary": {
    "alive": 1,
    "dead": 1,
    "fb_unreachable": 0,
    "slow": 0
  },
  "results": [
    {
      "id": "proxy-uuid-1",
      "host": "1.2.3.4",
      "port": 8080,
      "status": "alive",
      "latency_ms": 245,
      "real_ip": "203.x.x.x",
      "country": "VN",
      "country_name": "Vietnam",
      "city": "Ho Chi Minh City",
      "isp": "Viettel Group",
      "facebook_accessible": true,
      "error": ""
    },
    {
      "id": "proxy-uuid-2",
      "status": "dead",
      "error": "timeout"
    }
  ]
}

Giá trị status:

StatusÝ nghĩa
aliveProxy hoạt động, IP thực đã xác định
fb_unreachableProxy alive nhưng block Facebook (chỉ allow FB-only traffic)
slowAlive nhưng latency > 3000ms
deadKhông kết nối được

Design: ZERO Facebook Contact

Vấn đề: Kiểm tra proxy qua Facebook → lộ proxy với Facebook → risk bị ban

Giải pháp: Dùng ipify.org (neutral domain) để check

Flow:
  1. HTTP request qua proxy đến ipify.org
     → 200 + trả về IP → proxy ALIVE, lấy real IP
     → 407 → auth fail → DEAD
     → Timeout → DEAD
     → 502 từ proxy → proxy ALIVE (proxy chặn ipify nhưng vẫn hoạt động)

Insight quan trọng:
  Proxy FB-only chặn ipify.org → trả về 502 chính TỪ proxy
  → 502 = proxy đang hoạt động = ALIVE (fb_unreachable)
  → Đây là điểm then chốt cho độ chính xác 100%

Geo lookup: ip-api.com batch API (100 IPs/request)
  → Chỉ 1 request lấy geo cho cả batch
  → Cache kết quả (sync.Map) tránh lookup trùng

Performance:

MetricKết quả
609 proxies~21 giây
10.000 proxies< 10 phút
Max concurrent500 goroutines
Accuracy100% (match GoLogin)

4. Resolve URL#

POST /api/v1/resolve#

Phân tích 1 Facebook URL bất kỳ — profile, page, group, post, reel, share link.

Request Body:

{
  "url": "https://www.facebook.com/groups/vinfastlimogreenclubvn"
}

Response (200):

{
  "success": true,
  "type": "group",
  "id": "1134806278152617",
  "name": "Hội VinFast Limo Green Việt Nam™ (LimoGreenClubVN)",
  "thumbnail": "https://scontent...",
  "exists": true
}

POST /api/v1/resolve-urls#

Phân tích batch nhiều URL.

Request Body:

{
  "urls": [
    "https://www.facebook.com/minhngoc22052k3",
    "https://www.facebook.com/groups/vinfastlimogreenclubvn",
    "https://www.facebook.com/share/v/1B3ayY77GT/",
    "https://www.facebook.com/100045678901"
  ]
}

Response (200):

{
  "success": true,
  "total": 4,
  "results": [
    {
      "url": "https://www.facebook.com/minhngoc22052k3",
      "type": "user",
      "id": "100072XXXXXXX",
      "name": "Minh Ngọc",
      "thumbnail": "https://scontent...",
      "exists": true
    },
    {
      "url": "https://www.facebook.com/groups/vinfastlimogreenclubvn",
      "type": "group",
      "id": "1134806278152617",
      "name": "Hội VinFast Limo Green Việt Nam™ (LimoGreenClubVN)",
      "thumbnail": "https://scontent...",
      "exists": true
    },
    {
      "url": "https://www.facebook.com/share/v/1B3ayY77GT/",
      "type": "video",
      "id": "1234567890123456",
      "name": "",
      "thumbnail": "",
      "exists": true
    },
    {
      "url": "https://www.facebook.com/100045678901",
      "type": "user",
      "id": "100045678901",
      "name": "Nguyễn Văn A",
      "thumbnail": "https://scontent...",
      "exists": true
    }
  ]
}

Giá trị type:

TypeURL pattern
user/profile.php?id=, /{username} (person)
page/{pagename} (page)
group/groups/{id}
post/permalink/, /{page}/posts/, /photo?fbid=
video/reel/, /videos/, /watch?v=
share/share/v/, /share/p/ → tự động follow redirect

Logic xử lý group:

Vanity URL (/groups/vinfastlimogreenclubvn):
  → og:url chỉ trả vanity, không có numeric ID
  → Đọc 300KB HTML, extract "groupID":"1134806278152617"
  → Dùng ID số để map với database

5. Health Check#

GET /health#

{
  "status": "ok",
  "version": "1.0.0",
  "uptime": "2h34m12s"
}