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#
| Endpoint | Mô tả |
|---|---|
POST /fetch | Lấy name + avatar + type từ Facebook UID/URL |
POST /check-account | Kiểm tra tài khoản live/die |
POST /check-proxy | Kiểm tra proxy alive, geo, latency |
POST /resolve | Phân tích 1 Facebook URL |
POST /resolve-urls | Phân tích batch nhiều Facebook URL |
GET /health | Health 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"]
}| Field | Type | Mô tả |
|---|---|---|
uids | string[] | 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:
| Field | Type | Mô tả |
|---|---|---|
uid | string | UID đã nhập (numeric hoặc vanity) |
name | string | Tên Facebook |
avatar_url | string | URL avatar full-size |
type | string | user | page | group |
exists | bool | UID tồn tại trên Facebook |
error | string | Lý 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 |
|---|---|
live | Tài khoản tồn tại và active |
die | Tài khoản bị xóa hoặc vô hiệu hóa |
error | Không thể kiểm tra (mạng, rate limit) |
Giá trị error field (khi status = live):
| Error | Ý nghĩa |
|---|---|
private_profile | Profile ẩ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_deactivated | Phá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"
}
]
}| Field | Type | Required | Mô tả |
|---|---|---|---|
id | string | No | ID để map kết quả |
host | string | Yes | IP hoặc hostname proxy |
port | int | Yes | Port |
type | string | Yes | http | https | socks5 |
username | string | No | Auth username |
password | string | No | Auth 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 |
|---|---|
alive | Proxy hoạt động, IP thực đã xác định |
fb_unreachable | Proxy alive nhưng block Facebook (chỉ allow FB-only traffic) |
slow | Alive nhưng latency > 3000ms |
dead | Khô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ùngPerformance:
| Metric | Kết quả |
|---|---|
| 609 proxies | ~21 giây |
| 10.000 proxies | < 10 phút |
| Max concurrent | 500 goroutines |
| Accuracy | 100% (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:
| Type | URL 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 database5. Health Check#
GET /health#
{
"status": "ok",
"version": "1.0.0",
"uptime": "2h34m12s"
}