================================================================================ TÀI LIỆU HƯỚNG DẪN TÍCH HỢP API VOICESERVER ================================================================================ Phiên bản API: 2.0.0 Định dạng dữ liệu: JSON (UTF-8) Giao thức hỗ trợ: HTTP / HTTPS -------------------------------------------------------------------------------- 1. TỔNG QUAN & CƠ CHẾ XÁC THỰC (AUTHENTICATION & SECURITY) -------------------------------------------------------------------------------- Hệ thống VoiceServer cung cấp dịch vụ chuyển văn bản thành giọng nói (Text-To-Speech) tiếng Việt chất lượng cao, độ trễ thấp (<1-2s), hỗ trợ sinh file đồng bộ hoặc sinh file ngầm thông qua hàng đợi và Webhook Callback. Tất cả các yêu cầu từ Client / Đối tác tới API đều phải xác thực thông qua: - Header: "X-API-Key: vs_live_xxxxxxxxxxxxxxxxxxxxxxxx" (hoặc tham số query URL: ?api_key=vs_live_xxxxxxxxxxxxxxxxxxxxxxxx) - Bảo mật IP Whitelist: Địa chỉ IP của máy chủ gọi API phải nằm trong danh sách IP Whitelist đã được Admin cấp phép cho API Key tương ứng. Nếu gọi từ IP lạ ngoài danh sách, hệ thống sẽ trả về mã lỗi 403 Forbidden. Base URL mặc định (khi triển khai nội bộ hoặc qua IIS): http://localhost:8000 (hoặc domain/IP máy chủ triển khai IIS: http://your-voice-server.com) -------------------------------------------------------------------------------- 2. DANH SÁCH GIỌNG ĐỌC NGUỒN CÓ SẴN (VOICE CATALOG) -------------------------------------------------------------------------------- ID Giọng Giới Tính Đặc Trưng / Phong Cách -------------------------------------------------------------------------------- edge_female Nữ Nữ 1: Tự nhiên, truyền cảm, phổ biến edge_male Nam Nam 1: Trầm ấm, dõng dạc, chuyên nghiệp edge_female_fast Nữ Nữ 2: Nhịp nhanh, hoạt bát (thích hợp tin ngắn) edge_male_fast Nam Nam 2: Nhịp nhanh, dứt khoát edge_female_deep Nữ Nữ 3: Trầm, êm dịu, dẫn chuyện edge_male_deep Nam Nam 3: Trầm sâu, thuyết minh phim / tài liệu gtts_vietnam Nữ Giọng chuẩn quen thuộc (Google) -------------------------------------------------------------------------------- 3. CHI TIẾT CÁC ENDPOINT API CLIENT -------------------------------------------------------------------------------- ================================================================================ API 1: LẤY DANH SÁCH GIỌNG ĐỌC ================================================================================ Phương thức: GET Đường dẫn: /api/v1/voices Xác thực: Không bắt buộc (Công khai) * Ví dụ cURL: curl -X GET "http://localhost:8000/api/v1/voices" * Phản hồi thành công (HTTP 200 OK): { "status": "success", "total": 7, "data": [ { "id": "edge_female", "name": "Nữ 1: Tự nhiên, truyền cảm", "gender": "female", "style": "Tự nhiên, mềm mại, truyền cảm" }, { "id": "edge_male", "name": "Nam 1: Trầm ấm, dõng dạc", "gender": "male", "style": "Trầm ấm, nam tính, giọng chuẩn" } ... ] } ================================================================================ API 2: TẠO MP3 ĐỒNG BỘ (SYNCHRONOUS GENERATE) ================================================================================ Mô tả: Tạo âm thanh ngay lập tức trong 1 - 2 giây và trả về link file MP3 trực tiếp. Thích hợp cho các luồng cần phát audio ngay lập tức cho người dùng. Phương thức: POST Đường dẫn: /api/v1/tts/generate Header bắt buộc: - Content-Type: application/json - X-API-Key: vs_live_YOUR_API_KEY * Tham số Request Body (JSON): - text (String, bắt buộc) : Đoạn văn bản tiếng Việt cần đọc. - voice_id (String, tuỳ chọn) : Mã giọng đọc (mặc định "edge_female"). - title (String, tuỳ chọn) : Tiêu đề gợi nhớ cho bản ghi. * Ví dụ cURL: curl -X POST "http://localhost:8000/api/v1/tts/generate" \ -H "Content-Type: application/json" \ -H "X-API-Key: vs_live_YOUR_API_KEY" \ -d '{ "text": "Xin chào quý khách, đơn hàng của quý khách đã được đóng gói thành công.", "voice_id": "edge_female", "title": "Thông báo đơn hàng #12345" }' * Phản hồi thành công (HTTP 200 OK): { "status": "success", "task_id": "84a7e9f3b120", "audio_url": "http://localhost:8000/audio/2026/10/84a7e9f3b120.mp3", "duration": 3.85, "cost_seconds": 1.42 } ================================================================================ API 3: TẠO MP3 BẤT ĐỒNG BỘ (ASYNC QUEUE + WEBHOOK CALLBACK) ================================================================================ Mô tả: Tiếp nhận yêu cầu vào hàng đợi xử lý ngầm trong PostgreSQL, phản hồi kết quả ngay trong 0.05 giây. Worker ngầm quét mẻ 10 yêu cầu/lần, sinh file MP3 và tự động gửi HTTP POST Webhook tới callback_url của Client. Phương thức: POST Đường dẫn: /api/v1/tts/generate-async Header bắt buộc: - Content-Type: application/json - X-API-Key: vs_live_YOUR_API_KEY * Tham số Request Body (JSON): - text (String, bắt buộc) : Đoạn văn bản tiếng Việt cần đọc. - voice_id (String, tuỳ chọn) : Mã giọng đọc (mặc định "edge_female"). - title (String, tuỳ chọn) : Tiêu đề hoặc ghi chú task. - callback_url (String, tuỳ chọn) : URL máy chủ của Client để nhận Webhook kết quả. - callback_key (String, tuỳ chọn) : Token bảo mật do Client tự định nghĩa. Lưu ý: Callback Key KHÔNG lưu trong thông tin đối tác mà gắn liền với từng tác vụ ngầm (task). Khi hoàn tất, Worker sẽ dùng chính token này để gửi trong Header xác thực. - custom_data (String, tuỳ chọn) : Dữ liệu tùy biến (ví dụ: order_id, user_id...) hệ thống sẽ gửi trả nguyên vẹn trong payload Webhook. * Ví dụ cURL: curl -X POST "http://localhost:8000/api/v1/tts/generate-async" \ -H "Content-Type: application/json" \ -H "X-API-Key: vs_live_YOUR_API_KEY" \ -d '{ "text": "Hệ thống đang tiến hành đối soát dữ liệu cuối ngày cho quý khách.", "voice_id": "edge_male", "callback_url": "https://client-api.com/webhooks/voice-tts", "callback_key": "my_secure_client_token_999", "custom_data": "batch_session_20261026" }' * Phản hồi thành công ngay lập tức (HTTP 200 OK): { "status": "queued", "task_id": "9c8b7a6d5e4f", "message": "Yêu cầu đã được tiếp nhận vào hàng đợi xử lý", "callback_url": "https://client-api.com/webhooks/voice-tts", "has_callback_key": true } ================================================================================ QUY CHUẨN WEBHOOK CALLBACK (VOICESERVER -> CLIENT) ================================================================================ Khi tiến trình ngầm hoàn thành tạo file MP3 (hoặc gặp lỗi), VoiceServer sẽ gửi HTTP POST tới `callback_url` của Client. * Các Headers xác thực được gửi kèm theo Webhook: Content-Type: application/json User-Agent: VoiceServer-Webhook/1.0 X-Callback-Key: Authorization: Bearer * Payload JSON khi tạo âm thanh thành công: { "event": "tts_completed", "task_id": "9c8b7a6d5e4f", "status": "success", "audio_url": "http://localhost:8000/audio/2026/10/9c8b7a6d5e4f.mp3", "duration": 4.15, "custom_data": "batch_session_20261026" } * Payload JSON nếu gặp lỗi: { "event": "tts_failed", "task_id": "9c8b7a6d5e4f", "status": "failed", "error": "Chi tiết nguyên nhân lỗi...", "custom_data": "batch_session_20261026" } * Cơ chế Retry & Lưu kết quả phản hồi (Callback Result): - VoiceServer chờ tối đa 10s cho mỗi lần gọi callback. - Nếu máy chủ client không trả về mã 200..204 hoặc rớt mạng, VoiceServer sẽ tự động thử lại tối đa 5 lần (Retry), mỗi lần cách nhau đúng 2 phút (120 giây). - Toàn bộ kết quả (Mã HTTP response, số lần thử, nội dung phản hồi từ server client) được lưu vĩnh viễn trong Database để phục vụ tra cứu, đối soát. ================================================================================ API 4: KIỂM TRA TRẠNG THÁI TASK (POLLING STATUS) ================================================================================ Mô tả: Chủ động kiểm tra trạng thái và lấy link audio theo Task ID. Phương thức: GET Đường dẫn: /api/v1/tts/status/{task_id} Header bắt buộc: - X-API-Key: vs_live_YOUR_API_KEY * Ví dụ cURL: curl -X GET "http://localhost:8000/api/v1/tts/status/9c8b7a6d5e4f" \ -H "X-API-Key: vs_live_YOUR_API_KEY" * Phản hồi mẫu (HTTP 200 OK): { "status": "completed", "task_id": "9c8b7a6d5e4f", "audio_url": "http://localhost:8000/audio/2026/10/9c8b7a6d5e4f.mp3", "duration": 4.15, "created_at": "2026-10-26 10:45:12", "completed_at": "2026-10-26 10:45:14", "error": null, "callback_status_code": 200, "callback_attempts": 1, "is_expired": false } (Các giá trị status có thể có: "pending", "processing", "completed", "failed") -------------------------------------------------------------------------------- 4. CHÍNH SÁCH LƯU TRỮ FILE MP3 (FILE RETENTION) -------------------------------------------------------------------------------- - Mỗi đối tác được thiết lập thời gian lưu trữ file MP3 riêng (retention_days). - Giá trị mặc định là 30 ngày. Nếu thiết lập 0 = lưu trữ vĩnh viễn không bao giờ xóa. - Hệ thống chạy ngầm định kỳ quét và thu hồi dung lượng ổ cứng đối với các file MP3 đã hết hạn. Khi file đã bị xóa, trường `is_expired` sẽ trả về `true` và `audio_url` là null. -------------------------------------------------------------------------------- 5. BẢNG MÃ LỖI HTTP CHUẨN (ERROR CODES) -------------------------------------------------------------------------------- Mã HTTP Ý Nghĩa Mô Tả & Cách Khắc Phục -------------------------------------------------------------------------------- 200 OK Thành công Yêu cầu xử lý hoàn tất hoặc đã đưa vào queue. 400 Bad Req Dữ liệu không hợp lệ Thiếu tham số 'text' hoặc văn bản rỗng. 401 Unauth Chưa xác thực Thiếu Header X-API-Key hoặc API Key sai. 403 Forbid Bị từ chối truy cập IP của client không nằm trong IP Whitelist hoặc tài khoản đối tác đang bị tạm khóa. 404 Not Fnd Không tìm thấy Task ID không tồn tại trên hệ thống. 500 Err Lỗi máy chủ nội bộ Lỗi kết nối cơ sở dữ liệu hoặc xử lý âm thanh. -------------------------------------------------------------------------------- 6. CODE MẪU TÍCH HỢP CHO CÁC NGÔN NGỮ -------------------------------------------------------------------------------- [PYTHON] -------------------------------------------------------------------------------- import requests API_KEY = "vs_live_YOUR_API_KEY" URL = "http://localhost:8000/api/v1/tts/generate" headers = { "Content-Type": "application/json", "X-API-Key": API_KEY } payload = { "text": "Chào bạn, đây là kiểm tra giọng đọc từ Python.", "voice_id": "edge_female" } response = requests.post(URL, json=payload, headers=headers) if response.status_code == 200: data = response.json() print("Link file MP3:", data["audio_url"]) print("Thời lượng:", data["duration"], "giây") else: print("Lỗi:", response.status_code, response.text) [NODE.JS / JAVASCRIPT] -------------------------------------------------------------------------------- const axios = require('axios'); async function generateVoice() { const apiKey = 'vs_live_YOUR_API_KEY'; const url = 'http://localhost:8000/api/v1/tts/generate-async'; try { const res = await axios.post(url, { text: 'Đơn hàng 12345 đã được thanh toán thành công.', voice_id: 'edge_male', callback_url: 'https://my-backend.com/api/voice-callback', callback_key: 'secret_token_abc' }, { headers: { 'Content-Type': 'application/json', 'X-API-Key': apiKey } }); console.log('Đã đưa vào hàng đợi, Task ID:', res.data.task_id); } catch (error) { console.error('Lỗi API:', error.response ? error.response.data : error.message); } } generateVoice(); [PHP] -------------------------------------------------------------------------------- "Chào mừng quý khách đến với dịch vụ của chúng tôi.", "voice_id" => "edge_female" ]; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Content-Type: application/json", "X-API-Key: " . $apiKey ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode == 200) { $result = json_decode($response, true); echo "Audio URL: " . $result["audio_url"]; } else { echo "Lỗi ($httpCode): " . $response; } ?> [C# / .NET] -------------------------------------------------------------------------------- using System; using System.Net.Http; using System.Text; using System.Threading.Tasks; class Program { static async Task Main() { using var client = new HttpClient(); client.DefaultRequestHeaders.Add("X-API-Key", "vs_live_YOUR_API_KEY"); var json = "{\"text\": \"Xin chào từ C# .NET\", \"voice_id\": \"edge_female\"}"; var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await client.PostAsync("http://localhost:8000/api/v1/tts/generate", content); var result = await response.Content.ReadAsStringAsync(); Console.WriteLine(result); } } ================================================================================ HẾT TÀI LIỆU ================================================================================