Hướng Dẫn Sử Dụng Chi Tiết
Sử Dụng Giao Diện Web của Tool Việt Nam (Tool.vn)
Giao diện web của Tool Việt Nam cung cấp một cách trực quan để bạn khởi tạo và theo dõi quá trình quét toàn bộ bài viết từ một Fanpage Facebook.
-
Đăng Nhập (Nếu Chưa):
Để sử dụng công cụ và quản lý credit, bạn cần đăng nhập vào tài khoản Tool Việt Nam của mình.
-
Nhập ID Fanpage:
Trong ô "ID Fanpage Facebook", hãy điền ID dạng số của Fanpage bạn muốn quét. Ví dụ: 61565985206441.
Nếu bạn chỉ có link Fanpage (ví dụ: https://www.facebook.com/ToolvnOfficial), hãy sử dụng công cụ tìm ID từ link của chúng tôi để lấy ID số trước.
-
Thiết Lập Số Lượng Bài Viết:
- Trong ô "Số Lượng Bài Viết Tối Đa Cần Quét", nhập số lượng bài bạn muốn hệ thống cố gắng lấy.
- Để quét một lượng nhỏ (ví dụ, vài trăm bài mới nhất): Nhập
100, 500.
- Để quét toàn bộ (hoặc nhiều nhất có thể): Nhập một số rất lớn, ví dụ:
200000. Hệ thống sẽ cố gắng lấy hết các bài viết công khai cho đến khi đạt giới hạn này hoặc không còn bài nào nữa.
- Nếu để trống, hệ thống sẽ quét mặc định 50 bài viết.
-
Kiểm Tra Chi Phí Ước Tính:
Khi bạn thay đổi "Số Lượng Bài Viết", dòng chữ "Chi phí dự kiến..." bên dưới sẽ tự động cập nhật, cho bạn biết số credit sẽ bị trừ ban đầu. Hệ thống sẽ hoàn lại credit tự động nếu số bài viết thực tế quét được ít hơn số lượng đã trừ phí.
-
Bắt Đầu Quá Trình Quét:
Nhấn nút "Bắt Đầu Quét".
- Hệ thống sẽ xác nhận yêu cầu, trừ credit và tạo một mã phiên quét duy nhất. Mã này sẽ hiển thị trong khu vực tiến trình. Bạn nên lưu mã ở nơi an toàn và không chia sẻ cho người khác.
- Một thông báo sẽ xuất hiện cho biết yêu cầu của bạn đã được đưa vào hàng đợi và quá trình quét sẽ chạy ngầm. Bạn không cần phải treo tab trình duyệt.
- Khu vực "Tiến Trình Quét" sẽ tự động cập nhật định kỳ để hiển thị trạng thái (Đang chờ, Đang xử lý, Hoàn tất, Thất bại), số bài đã quét được, và thanh tiến trình.
-
Theo Dõi và Nhận Kết Quả:
- Bạn có thể rời khỏi trang và quay lại sau. Trang tự khôi phục phiên gần nhất trên thiết bị; bạn cũng có thể nhập mã phiên vào mục “Tiếp tục theo dõi một phiên đã tạo”.
- Khi trạng thái chuyển thành "completed" (hoàn tất), một đường dẫn để Tải Xuống File JSON Kết Quả sẽ xuất hiện. File này chứa toàn bộ dữ liệu các bài viết đã quét được.
- Đường dẫn file JSON cũng sẽ được hiển thị để bạn có thể copy và sử dụng nếu cần.
Mẹo Quan Trọng:
Quét toàn bộ: Để quét nhiều bài viết nhất, hãy nhập một giá trị "Số Lượng Bài Viết" lớn (ví dụ: 200000). Quá trình này có thể mất nhiều thời gian (vài phút đến vài giờ) tùy thuộc vào số lượng bài viết của Fanpage.
Không cần treo máy: Sau khi khởi tạo thành công và nhận được mã phiên, bạn có thể đóng trình duyệt. Hệ thống sẽ tiếp tục xử lý.
Kiểm tra định kỳ: Quay lại trang để tự động tiếp tục phiên gần nhất hoặc nhập mã phiên đã lưu. Khi hoàn tất, nút tải file JSON sẽ xuất hiện trong khu vực tiến độ.
Tài Liệu API Cho Nhà Phát Triển
Tích hợp chức năng quét toàn bộ bài viết Fanpage vào ứng dụng hoặc quy trình tự động hóa của bạn bằng API của Tool Việt Nam. Cơ chế hoạt động bao gồm việc khởi tạo một phiên quét, sau đó polling để kiểm tra trạng thái và nhận kết quả.
Luồng Hoạt Động Chính Của API
-
Bước 1: Khởi Tạo Phiên Quét
- Client gửi request
POST đến endpoint chính với body application/x-www-form-urlencoded.
- Request dùng header
Authorization: Bearer YOUR_API_KEY, tham số id và tùy chọn limit.
- API xác thực thông tin, ghi nhận chi phí dự kiến và phản hồi HTTP 202 cùng
scan_session_token, trạng thái queued và thời gian nên chờ trước lần kiểm tra tiếp theo.
- Client cần lưu lại
scan_session_token này để sử dụng ở các bước sau.
-
Bước 2: Kiểm Tra Trạng Thái Phiên Quét (Polling)
- Sau khi có
scan_session_token, client gửi request POST đến cùng endpoint.
- Request tiếp tục dùng header Bearer, đồng thời gửi
action=status và scan_token trong body.
- API trả về trạng thái hiện tại của phiên quét:
- Nếu
status: "queued": Phiên quét đang chờ xử lý. Client nên đợi và request lại sau delay_seconds.
- Nếu
status: "processing": Phiên quét đang được xử lý. Phản hồi sẽ chứa total_posts_fetched_so_far.
- Nếu
status: "completed": Phiên quét đã hoàn tất. Phản hồi sẽ chứa total_posts_fetched_so_far và log_file là URL HTTPS dùng để tải kết quả.
- Nếu
status: "failed": Phiên quét không hoàn tất. Đọc thông báo trả về để biết hướng xử lý phù hợp.
- Client lặp lại việc polling này cho đến khi nhận được trạng thái
completed hoặc failed.
-
Bước 3: Tải File Kết Quả
Khi trạng thái là completed và có log_file, client sử dụng URL HTTPS do API trả về để tải file JSON kết quả. Không tự xây dựng đường dẫn tải xuống từ ID hoặc mã phiên.
Endpoint Chính
POST https://tool.vn/api/facebook/get-all-post-fanpage
Xác Thực (Authentication)
Mọi yêu cầu đến API đều cần header Authorization: Bearer YOUR_API_KEY. Không đặt API key trong URL hoặc query string.
Bạn có thể tạo và quản lý API Key tại Khu vực Quản lý API Key.
Tham Số Yêu Cầu (Request Parameters)
1. Khởi Tạo Phiên Quét Mới (action=init hoặc không có `scan_token`):
| Tham Số | Bắt Buộc? | Mô Tả | Ví Dụ |
action | Không | Đặt init hoặc bỏ trống khi khởi tạo. | init |
id | Có | ID dạng số của Fanpage Facebook. | 61565985206441 |
limit | Không | Số lượng bài viết tối đa muốn quét. Mặc định: 50. Tối đa: 200000. | 1000 |
Ví dụ cURL khởi tạo:
curl -X POST 'https://tool.vn/api/facebook/get-all-post-fanpage' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'action=init' \
--data-urlencode 'id=1000PAGEID' \
--data-urlencode 'limit=500'
2. Kiểm Tra Trạng Thái Phiên Quét (action=status hoặc có `scan_token`):
| Tham Số | Bắt Buộc? | Mô Tả | Ví Dụ |
action | Có | Hành động kiểm tra trạng thái. | status |
scan_token | Có | Mã phiên nhận được từ request khởi tạo. Hãy giữ kín giá trị này. | ssapi_xxxxxxxxxx |
Ví dụ cURL kiểm tra trạng thái:
curl -X POST 'https://tool.vn/api/facebook/get-all-post-fanpage' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'action=status' \
--data-urlencode 'scan_token=ssapi_xxxxxxxxxxxxxx'
Phản Hồi (API Responses)
Tất cả phản hồi từ API đều ở định dạng JSON được sử dụng.
Response Khi Khởi Tạo Phiên Quét Thành Công (HTTP 202 Accepted):
{
"status": "queued",
"message": "Yêu cầu quét đã được tiếp nhận và đưa vào hàng đợi xử lý.",
"scan_session_token": "ssapi_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"page_id": "1000PAGEID",
"target_limit": 500,
"message_from_api": "Sử dụng mã phiên này để kiểm tra tiến trình.",
"delay_seconds": 20
}
Response Khi Kiểm Tra Tiến Trình (status: "processing"):
{
"status": "processing",
"message": "Lấy thông tin phiên quét thành công.",
"scan_session_token": "ssapi_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"page_id": "1000PAGEID",
"target_limit": 500,
"total_posts_fetched_so_far": 75,
"created_at": "2026-08-09 10:00:00",
"processing_started_at": "2026-08-09 10:00:05",
"last_progress_update_at": "2026-08-09 10:05:30",
"completed_at": null,
"message_from_api": "Đang xử lý... Bài viết đã lấy: 75/500.",
"log_file": null,
"delay_seconds": 15
}
Response Khi Hoàn Tất Quét Thành Công (status: "completed"):
{
"status": "completed",
"message": "Lấy thông tin phiên quét thành công.",
"scan_session_token": "ssapi_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"page_id": "1000PAGEID",
"target_limit": 500,
"total_posts_fetched_so_far": 500,
"created_at": "2026-08-09 10:00:00",
"processing_started_at": "2026-08-09 10:00:05",
"last_progress_update_at": "2026-08-09 10:25:00",
"completed_at": "2026-08-09 10:25:00",
"message_from_api": "Hoàn tất. Tổng bài viết: 500.",
"log_file": "https://tool.vn/download/facebook-posts/temporary-result.json",
"delay_seconds": 3600
}
log_file là URL HTTPS đầy đủ do API cấp khi có file kết quả. Client cần dùng nguyên giá trị trả về thay vì suy đoán cấu trúc URL.
Response Khi Phiên Quét Thất Bại (status: "failed"):
{
"status": "failed",
"message": "Lấy thông tin phiên quét thành công.",
"scan_session_token": "ssapi_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"page_id": "1000PAGEID",
"target_limit": 500,
"total_posts_fetched_so_far": 150,
"created_at": "2026-08-09 10:00:00",
"processing_started_at": "2026-08-09 10:00:05",
"last_progress_update_at": "2026-08-09 10:15:00",
"completed_at": "2026-08-09 10:15:00",
"message_from_api": "Phiên quét đã dừng trước khi hoàn tất.",
"log_file": "https://tool.vn/download/facebook-posts/temporary-result.json",
"delay_seconds": 3600
}
Các Mã Lỗi HTTP Thường Gặp (API Endpoint Call)
| Mã Lỗi | Tên Lỗi | Mô Tả & Cách Xử Lý |
400 Bad Request | Lỗi Tham Số | Thiếu id khi khởi tạo, thiếu scan_token khi kiểm tra trạng thái hoặc giá trị tham số không hợp lệ. |
401 Unauthorized | Xác Thực Thất Bại | Header Bearer bị thiếu, API key không hợp lệ hoặc đã bị vô hiệu hóa. |
402 Payment Required | Yêu Cầu Thanh Toán | Không đủ credit để khởi tạo phiên quét mới. Vui lòng nạp thêm credit. |
403 Forbidden | Truy Cập Bị Từ Chối | Tài khoản đang xác thực không có quyền truy cập phiên quét này. |
404 Not Found | Không Tìm Thấy | Mã phiên không khả dụng cho tài khoản đang xác thực hoặc ID Facebook không tồn tại. Kiểm tra lại dữ liệu đầu vào rồi thử lại. |
500 Internal Server Error | Lỗi Máy Chủ (API Endpoint) | Yêu cầu chưa thể xử lý do lỗi tạm thời. Vui lòng thử lại sau. Nếu lỗi kéo dài, liên hệ hỗ trợ. |
503 Service Unavailable | Dịch Vụ Tạm Thời Không Khả Dụng | Dịch vụ đang bận hoặc tạm thời gián đoạn. Hãy thử lại sau. |
Ngay cả khi request kiểm tra trạng thái trả về HTTP 200, phiên quét vẫn có thể ở status: "failed". Luôn kiểm tra trường status cấp cao nhất.
Tích Hợp Với Công Cụ Tự Động Hóa (n8n, Make, etc.)
Với cơ chế polling và mã phiên quét, bạn có thể dễ dàng tích hợp API này vào các nền tảng No-Code/Low-Code. Dưới đây là hướng dẫn chi tiết cho n8n, bạn có thể áp dụng tương tự cho Make.com (Integromat) hoặc các công cụ khác.
-
1. Trigger Node: Bắt đầu workflow. Có thể là "Manual", "Schedule", "Webhook", hoặc từ một ứng dụng khác (ví dụ: Google Sheets).
-
2. Set Node (
SetInitialParams): Thiết lập các thông số ban đầu.
Output của node này (ví dụ):
{
"apiKey": "YOUR_API_KEY",
"fanpageId": "123456789012345",
"limit": 250
}
-
3. HTTP Request Node (
InitScanSession): Khởi tạo phiên quét.
- Request Method:
POST.
- URL:
https://tool.vn/api/facebook/get-all-post-fanpage
- Header:
Authorization = Bearer {{ $('SetInitialParams').item.json.apiKey }}
- Body Content Type:
Form URL Encoded
action: init
id: {{ $('SetInitialParams').item.json.fanpageId }}
limit: {{ $('SetInitialParams').item.json.limit }}
- Options: Bật "Continue on Fail" để có thể xử lý lỗi API.
- Node này trả về
scan_session_token trong {{ $json.scan_session_token }}.
-
4. Set Node (
SetScanToken): Trích xuất và lưu scan_token.
Đặt biến currentScanToken với giá trị {{ $('InitScanSession').item.json.scan_session_token }}.
-
5. Loop Over Items Node (
PollingLoop): Tạo vòng lặp để poll trạng thái.
- Mode: "Run Fixed Number of Times" (ví dụ: 240 lần, tương đương 2 giờ nếu mỗi lần chờ 30s) hoặc bạn có thể xây dựng logic phức tạp hơn với "Run Until True/False".
- Iterations: Đặt một số lần lặp tối đa hợp lý.
-
6. HTTP Request Node (
CheckStatus - bên trong PollingLoop): Kiểm tra trạng thái.
- Request Method:
POST.
- URL:
https://tool.vn/api/facebook/get-all-post-fanpage
- Header:
Authorization = Bearer {{ $('SetInitialParams').item.json.apiKey }}
- Body Content Type:
Form URL Encoded
action: status
scan_token: {{ $('SetScanToken').item.json.currentScanToken }}
- Options: Bật "Continue on Fail".
- Output của node này chứa trạng thái hiện tại, ví dụ
{{ $json.status }} và {{ $json.log_file }}.
-
7. If Node (
IsScanComplete - bên trong PollingLoop): Kiểm tra xem quét đã xong chưa.
- Condition 1:
{{ $('CheckStatus').item.json.status }} - String - Equals - completed
- Condition 2 (OR):
{{ $('CheckStatus').item.json.status }} - String - Equals - failed
- Nếu một trong hai điều kiện đúng, đi đến output "true" (để dừng vòng lặp). Ngược lại, đi đến output "false".
-
8. Wait Node (
PollingDelay - nối từ output "false" của IsScanComplete):
- Wait Time:
{{ $('CheckStatus').item.json.delay_seconds || 30 }} giây.
- Node này sẽ nối lại vào đầu
PollingLoop hoặc vào CheckStatus của lần lặp tiếp theo.
-
9. Break Loop Node (Nối từ output "true" của
IsScanComplete): Để thoát khỏi vòng lặp polling khi hoàn tất hoặc thất bại.
-
10. Set Node (
FinalStatus - sau PollingLoop): Lấy kết quả cuối cùng từ lần CheckStatus cuối cùng.
Ví dụ: finalStatus = {{ $('CheckStatus').item.json.status }}, logFileUrl = {{ $('CheckStatus').item.json.log_file }}.
-
11. If Node (
ProcessResult): Xử lý kết quả cuối cùng.
- Nếu
finalStatus == 'completed' và logFileUrl tồn tại:
- HTTP Request Node (
DownloadFile): Tải file từ logFileUrl. Lưu ý đặt "Response Format" là "File".
- Sau đó, bạn có thể dùng các node khác để đọc JSON từ file (Read Binary File -> Move Binary Data -> JSON), xử lý dữ liệu, lưu vào Google Sheets, database, etc.
- Nếu
finalStatus == 'failed':
- Error Handling Node: Gửi thông báo lỗi (Email, Slack, Discord).
Lưu ý quan trọng: Trong n8n, để tham chiếu dữ liệu từ các node trước đó trong một vòng lặp, bạn có thể cần sử dụng "Merge Node" hoặc cách tiếp cận "Split in Batches" nếu vòng lặp xử lý nhiều item. Với polling một session duy nhất, việc tham chiếu trực tiếp thường hoạt động, nhưng hãy kiểm tra kỹ cú pháp biểu thức của n8n.
Tương tự, bạn có thể áp dụng logic polling này cho Make.com (Integromat) sử dụng module "HTTP > Make a request", "Router" để kiểm tra điều kiện, "Sleep" để chờ, và các module lặp (Repeater hoặc Iterator kết hợp với Array Aggregator nếu cần xử lý nhiều session).
Ví Dụ Code Tích Hợp (PHP cURL)
Dưới đây là ví dụ cơ bản bằng PHP để minh họa cách gọi API, khởi tạo phiên quét và thực hiện polling để lấy kết quả.
<?php
$apiKey = 'YOUR_API_KEY';
$fanpageId = '1000PAGEID';
$limit = 100;
$baseUrl = 'https://tool.vn/api/facebook/get-all-post-fanpage';
$maxPolls = 240;
$defaultPollDelay = 30;
function callScanApi(string $url, string $apiKey, array $params = []) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($params, '', '&', PHP_QUERY_RFC3986),
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/x-www-form-urlencoded',
'Accept: application/json'
],
CURLOPT_TIMEOUT => 60
]);
$responseJson = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError) {
echo "cURL Error: " . $curlError . "\n";
return null;
}
$responseData = json_decode($responseJson, true);
if (json_last_error() !== JSON_ERROR_NONE) {
echo "JSON Decode Error: " . json_last_error_msg() . "\n";
return null;
}
echo "HTTP Status: {$httpCode}\n";
if (!in_array($httpCode, [200, 202])) {
echo "API Error (HTTP {$httpCode}): " . ($responseData['message'] ?? 'Unknown error') . "\n";
return null;
}
return $responseData;
}
echo "--- Bước 1: Khởi tạo phiên quét ---\n";
$initParams = [
'action' => 'init',
'id' => $fanpageId,
'limit' => $limit
];
$initResponse = callScanApi($baseUrl, $apiKey, $initParams);
if (!$initResponse || !isset($initResponse['scan_session_token'])) {
echo "Lỗi nghiêm trọng: Không thể khởi tạo phiên quét hoặc không nhận được scan_session_token.\n";
exit;
}
$scanToken = $initResponse['scan_session_token'];
echo "Phiên quét đã được tạo: {$scanToken}\n";
echo "Trạng thái ban đầu: " . ($initResponse['status'] ?? 'N/A') . "\n";
echo "Thông điệp: " . ($initResponse['message_from_api'] ?? $initResponse['message'] ?? 'N/A') . "\n\n";
echo "--- Bước 2: Bắt đầu Polling kiểm tra tiến trình ---\n";
$isCompleted = false;
$pollCount = 0;
$logFileUrl = null;
$currentPollDelay = $initResponse['delay_seconds'] ?? $defaultPollDelay;
while (!$isCompleted && $pollCount < $maxPolls) {
$pollCount++;
echo "Đang chờ {$currentPollDelay} giây trước khi poll lần #{$pollCount}...\n";
sleep($currentPollDelay);
$statusParams = [
'action' => 'status',
'scan_token' => $scanToken
];
$statusResponse = callScanApi($baseUrl, $apiKey, $statusParams);
if (!$statusResponse || !isset($statusResponse['status'])) {
echo "Lỗi khi poll trạng thái, dừng lại.\n";
break;
}
$sessionData = $statusResponse;
$sessionStatus = $sessionData['status'] ?? 'unknown';
$currentPollDelay = $sessionData['delay_seconds'] ?? $defaultPollDelay;
echo "-------------------------------------\n";
echo "Kết quả poll lần {$pollCount}:\n";
echo "Thông điệp API: " . ($statusResponse['message'] ?? 'N/A') . "\n";
echo "Trạng thái phiên: " . strtoupper($sessionStatus) . "\n";
echo "Bài viết đã xử lý: " . ($sessionData['total_posts_fetched_so_far'] ?? 'N/A') . " / " . ($sessionData['target_limit'] ?? 'N/A') . "\n";
if (isset($sessionData['last_progress_update_at'])) {
echo "Cập nhật tiến độ lần cuối: " . $sessionData['last_progress_update_at'] . "\n";
}
if ($sessionStatus === 'completed') {
echo "Quá trình quét đã HOÀN TẤT!\n";
$logFileUrl = $sessionData['log_file'] ?? null;
$isCompleted = true;
} elseif ($sessionStatus === 'failed') {
echo "Quá trình quét đã THẤT BẠI.\n";
if (isset($sessionData['message_from_api'])) echo "Lý do: " . $sessionData['message_from_api'] . "\n";
else echo "Phiên quét không thể hoàn tất. Vui lòng thử lại sau.\n";
$logFileUrl = $sessionData['log_file'] ?? null;
$isCompleted = true;
} else if ($sessionStatus === 'queued' || $sessionStatus === 'processing') {
echo "Trạng thái: Đang chờ hoặc đang xử lý...\n";
} else {
echo "Trạng thái không xác định: {$sessionStatus}. Dừng polling.\n";
$isCompleted = true;
}
echo "-------------------------------------\n\n";
}
echo "--- Bước 3: Kết thúc Polling ---\n";
if ($pollCount >= $maxPolls && !$isCompleted) {
echo "Đã đạt giới hạn số lần poll ({$maxPolls} lần). Phiên quét có thể vẫn đang chạy nhưng do số lượng file lớn nên dữ liệu chưa cập nhật chính xác.\n";
echo "Vui lòng kiểm tra lại sau bằng Scan Token: {$scanToken}\n";
}
if ($logFileUrl) {
echo "Đường dẫn file kết quả JSON: " . $logFileUrl . "\n";
echo "Bạn có thể sử dụng URL này để tải file dữ liệu.\n";
} else {
echo "Không tìm thấy đường dẫn file kết quả cuối cùng.\n";
}
echo "Script kết thúc.\n";
?>