14 KiB
Tài Liệu API
Dịch vụ: mkt-whatsapp-service-net
Phiên bản: v1.0
URL Cơ sở: /api/v1/whatsapp
Xác Thực
Tất cả endpoints (trừ webhooks) yêu cầu xác thực qua JWT token.
Authorization: Bearer <jwt_token>
Định Dạng Phản Hồi
Tất cả phản hồi tuân theo cấu trúc này:
{
"success": true | false,
"data": { ... },
"error": "Thông báo lỗi" | null,
"pagination": { ... } | null
}
Webhooks
Xác Minh Webhook
GET /webhooks
Xác minh thách thức từ WhatsApp.
Tham Số Truy Vấn:
hub.mode(string) - Phải là "subscribe"hub.verify_token(string) - Token xác minh của bạnhub.challenge(string) - Chuỗi ngẫu nhiên để phản hồi lại
Phản Hồi:
(Plain text) giá trị hub.challenge
Nhận Sự Kiện
POST /webhooks
Nhận sự kiện tin nhắn từ WhatsApp.
Headers:
X-Hub-Signature-256- Chữ ký HMAC-SHA256
Request Body:
{
"object": "whatsapp_business_account",
"entry": [{
"id": "123456",
"changes": [{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"phone_number_id": "123456789"
},
"messages": [{
"from": "84901234567",
"id": "wamid.xxx",
"timestamp": "1704000000",
"type": "text",
"text": {
"body": "Xin chào"
}
}]
}
}]
}]
}
Phản Hồi:
{
"success": true
}
Tài Khoản WhatsApp
Kết Nối Tài Khoản
POST /accounts
Kết nối Tài Khoản Doanh Nghiệp WhatsApp.
Request:
{
"shopId": "550e8400-e29b-41d4-a716-446655440000",
"phoneNumberId": "123456789",
"accessToken": "EAAxxxxx",
"webhookUrl": "https://yourdomain.com/api/v1/whatsapp/webhooks"
}
Phản Hồi:
{
"success": true,
"data": {
"accountId": "660e8400-e29b-41d4-a716-446655440000",
"shopId": "550e8400-e29b-41d4-a716-446655440000",
"phoneNumberId": "123456789",
"status": "active",
"messageTier": "tier_1",
"connectedAt": "2026-01-18T10:00:00Z"
}
}
Lấy Thông Tin Tài Khoản
GET /accounts/{shopId}
Lấy thông tin tài khoản của cửa hàng.
Phản Hồi:
{
"success": true,
"data": {
"accountId": "660e8400-e29b-41d4-a716-446655440000",
"shopId": "550e8400-e29b-41d4-a716-446655440000",
"phoneNumberId": "123456789",
"webhookUrl": "https://yourdomain.com/api/v1/whatsapp/webhooks",
"status": "active",
"messageTier": "tier_2",
"dailyLimit": 10000,
"messagesUsedToday": 1523,
"connectedAt": "2026-01-15T10:00:00Z"
}
}
Ngắt Kết Nối Tài Khoản
DELETE /accounts/{shopId}
Ngắt kết nối Tài Khoản Doanh Nghiệp WhatsApp.
Phản Hồi:
{
"success": true,
"data": {
"message": "Ngắt kết nối tài khoản thành công"
}
}
Hội Thoại
Danh Sách Hội Thoại
GET /conversations
Lấy danh sách hội thoại có phân trang.
Tham Số Truy Vấn:
shopId(bắt buộc) - ID cửa hàngstatus(tùy chọn) - Lọc:active,closed,expiredassignedAgentId(tùy chọn) - Lọc theo nhân viênskip(mặc định: 0) - Vị trí phân trangtake(mặc định: 20, tối đa: 100) - Kích thước trang
Phản Hồi:
{
"success": true,
"data": {
"conversations": [
{
"id": "conv-001",
"shopId": "shop-001",
"customerWaId": "84901234567",
"customerName": "Nguyễn Văn A",
"status": "active",
"assignedAgentId": null,
"lastMessageAt": "2026-01-18T10:30:00Z",
"messageCount": 5,
"tags": ["new-customer"],
"createdAt": "2026-01-18T10:00:00Z"
}
],
"totalCount": 42
},
"pagination": {
"page": 1,
"limit": 20,
"total": 42,
"totalPages": 3
}
}
Lấy Thông Tin Hội Thoại
GET /conversations/{conversationId}
Lấy chi tiết hội thoại với tin nhắn.
Phản Hồi:
{
"success": true,
"data": {
"id": "conv-001",
"shopId": "shop-001",
"customer": {
"waId": "84901234567",
"name": "Nguyễn Văn A",
"tags": ["vip"]
},
"status": "active",
"messages": [
{
"id": "msg-001",
"whatsAppMessageId": "wamid.xxx",
"direction": "inbound",
"content": {
"type": "text",
"text": "Xin chào"
},
"status": "read",
"timestamp": "2026-01-18T10:00:00Z"
},
{
"id": "msg-002",
"whatsAppMessageId": "wamid.yyy",
"direction": "outbound",
"content": {
"type": "text",
"text": "Xin chào! Chúng tôi có thể giúp gì cho bạn?"
},
"status": "delivered",
"timestamp": "2026-01-18T10:00:15Z"
}
],
"createdAt": "2026-01-18T10:00:00Z",
"expiresAt": "2026-01-19T10:00:00Z"
}
}
Gửi Tin Nhắn
POST /conversations/{conversationId}/messages
Gửi tin nhắn trong hội thoại.
Request:
{
"content": {
"type": "text",
"text": "Cảm ơn bạn đã liên hệ!"
}
}
Phản Hồi:
{
"success": true,
"data": {
"messageId": "msg-003",
"whatsAppMessageId": "wamid.zzz",
"status": "sent",
"timestamp": "2026-01-18T10:05:00Z"
}
}
Tin Nhắn Media:
{
"content": {
"type": "image",
"url": "https://example.com/product.jpg",
"caption": "Xem sản phẩm này!"
}
}
Tin Nhắn Tương Tác:
{
"content": {
"type": "interactive",
"interactive": {
"type": "button",
"body": {
"text": "Chọn một tùy chọn:"
},
"action": {
"buttons": [
{"id": "yes", "title": "Có"},
{"id": "no", "title": "Không"}
]
}
}
}
}
Gán Hội Thoại
POST /conversations/{conversationId}/assign
Gán hội thoại cho nhân viên.
Request:
{
"agentId": "agent-001"
}
Phản Hồi:
{
"success": true,
"data": {
"conversationId": "conv-001",
"assignedAgentId": "agent-001",
"assignedAt": "2026-01-18T10:10:00Z"
}
}
Đóng Hội Thoại
POST /conversations/{conversationId}/close
Đóng hội thoại.
Phản Hồi:
{
"success": true,
"data": {
"conversationId": "conv-001",
"status": "closed",
"closedAt": "2026-01-18T10:15:00Z"
}
}
Khách Hàng
Danh Sách Khách Hàng
GET /customers
Lấy danh sách khách hàng có phân trang.
Tham Số Truy Vấn:
shopId(bắt buộc)search(tùy chọn) - Tìm kiếm theo tên/số điện thoạitags(tùy chọn) - Lọc theo tags (phân cách bằng dấu phẩy)skip/take(phân trang)
Phản Hồi:
{
"success": true,
"data": {
"customers": [
{
"id": "cust-001",
"waId": "84901234567",
"name": "Nguyễn Văn A",
"tags": ["vip", "frequent-buyer"],
"optInStatus": "opted_in",
"conversationCount": 12,
"lastContactedAt": "2026-01-18T10:00:00Z",
"createdAt": "2026-01-01T00:00:00Z"
}
],
"totalCount": 150
}
}
Lấy Thông Tin Khách Hàng
GET /customers/{waId}
Lấy hồ sơ khách hàng.
Tham Số Truy Vấn:
shopId(bắt buộc)
Phản Hồi:
{
"success": true,
"data": {
"id": "cust-001",
"waId": "84901234567",
"shopId": "shop-001",
"name": "Nguyễn Văn A",
"profilePictureUrl": "https://...",
"consent": {
"status": "opted_in",
"timestamp": "2026-01-01T10:00:00Z",
"source": "whatsapp"
},
"tags": ["vip"],
"customFields": {
"city": "Hanoi",
"preferredLanguage": "vi"
},
"stats": {
"conversationCount": 12,
"averageResponseTime": "5m",
"lastPurchaseDate": "2026-01-15"
}
}
}
Cập Nhật Tags Khách Hàng
PUT /customers/{waId}/tags
Thêm hoặc xóa tags khách hàng.
Tham Số Truy Vấn:
shopId(bắt buộc)
Request:
{
"addTags": ["vip", "electronics-buyer"],
"removeTags": ["new-customer"]
}
Phản Hồi:
{
"success": true,
"data": {
"waId": "84901234567",
"tags": ["vip", "electronics-buyer"]
}
}
Cập Nhật Trạng Thái Opt-In
PUT /customers/{waId}/opt-in
Cập nhật sự đồng ý của khách hàng.
Request:
{
"status": "opted_in",
"source": "web"
}
Phản Hồi:
{
"success": true,
"data": {
"waId": "84901234567",
"consent": {
"status": "opted_in",
"timestamp": "2026-01-18T10:20:00Z",
"source": "web"
}
}
}
Luồng Tự Động
Danh Sách Luồng
GET /flows
Lấy danh sách luồng tự động.
Tham Số Truy Vấn:
shopId(bắt buộc)isActive(tùy chọn) - Lọc theo trạng thái
Phản Hồi:
{
"success": true,
"data": {
"flows": [
{
"id": "flow-001",
"flowName": "Chào Mừng Khách Hàng Mới",
"triggerType": "keyword",
"isActive": true,
"executionCount": 523,
"createdAt": "2026-01-10T00:00:00Z"
}
]
}
}
Tạo Luồng
POST /flows
Tạo luồng tự động.
Request: Xem Hướng Dẫn Tự Động
Phản Hồi:
{
"success": true,
"data": {
"flowId": "flow-002",
"flowName": "FAQ Bot",
"isActive": false
}
}
Cập Nhật Luồng
PUT /flows/{flowId}
Cập nhật cấu hình luồng.
Kích Hoạt Luồng
POST /flows/{flowId}/activate
Bật luồng tự động.
Vô Hiệu Hóa Luồng
POST /flows/{flowId}/deactivate
Tắt luồng tự động.
AI Agents
Tạo AI Agent
POST /ai-agents
Cấu hình chatbot AI.
Request: Xem Hướng Dẫn AI Chatbot
Cập Nhật AI Agent
PUT /ai-agents/{agentId}
Cập nhật tính cách/prompts.
Kích Hoạt AI Agent
POST /ai-agents/{agentId}/activate
Bật phản hồi AI.
Kiểm Tra AI Agent
POST /ai-agents/{agentId}/test
Mô phỏng phản hồi AI.
Request:
{
"conversationHistory": [
{"role": "user", "content": "Bạn có laptop nào tốt?"}
],
"customerContext": {
"name": "Nguyễn Văn A",
"tags": ["vip"]
}
}
Phản Hồi:
{
"success": true,
"data": {
"generatedResponse": "Chúng tôi có nhiều laptop tuyệt vời! Bạn đang tìm laptop cho mục đích gì ạ? Gaming hay làm việc văn phòng?",
"tokensUsed": {"prompt": 450, "completion": 120, "total": 570},
"estimatedCost": 0.0154,
"latencyMs": 1850
}
}
Phân Tích
Thống Kê Tin Nhắn
GET /analytics/messages
Lấy số liệu về lượng tin nhắn.
Tham Số Truy Vấn:
shopId(bắt buộc)startDate/endDate(ISO 8601)groupBy-hour,day,week
Phản Hồi:
{
"success": true,
"data": {
"metrics": [
{
"date": "2026-01-18",
"inboundCount": 245,
"outboundCount": 298,
"totalCount": 543
}
],
"summary": {
"totalInbound": 2450,
"totalOutbound": 2980,
"averagePerDay": 543
}
}
}
Số Liệu Hội Thoại
GET /analytics/conversations
Lấy số liệu hiệu suất hội thoại.
Phản Hồi:
{
"success": true,
"data": {
"averageResponseTime": "2m 30s",
"averageResolutionTime": "15m 45s",
"automationResolutionRate": 0.65,
"aiResolutionRate": 0.78,
"humanHandoffRate": 0.22
}
}
Hiệu Suất Tự Động
GET /analytics/automations
Lấy thống kê thực thi luồng tự động.
Phản Hồi:
{
"success": true,
"data": {
"flows": [
{
"flowId": "flow-001",
"flowName": "Welcome Bot",
"executionCount": 523,
"completionRate": 0.89,
"averageSteps": 3.2,
"fallbackRate": 0.11
}
]
}
}
Mã Lỗi
| Mã | Thông Báo | Mô Tả |
|---|---|---|
| 400 | Bad Request | Định dạng request không hợp lệ |
| 401 | Unauthorized | Thiếu hoặc token xác thực không hợp lệ |
| 404 | Not Found | Tài nguyên không tồn tại |
| 409 | Conflict | Tài nguyên trùng lặp |
| 422 | Validation Error | Vi phạm quy tắc nghiệp vụ |
| 429 | Rate Limit Exceeded | Quá nhiều yêu cầu |
| 500 | Internal Server Error | Lỗi máy chủ |
Định Dạng Phản Hồi Lỗi:
{
"success": false,
"error": "Validation failed: Phone number is required",
"details": {
"field": "phoneNumberId",
"code": "REQUIRED_FIELD"
}
}
Giới Hạn Tốc Độ
- Public APIs: 60 yêu cầu/phút mỗi cửa hàng
- Webhooks: Không giới hạn (nhưng phải phản hồi < 5s)
- Analytics: 10 yêu cầu/phút mỗi cửa hàng
Xác Minh Chữ Ký Webhooks
Xác minh header X-Hub-Signature-256:
const crypto = require('crypto');
const signature = req.headers['x-hub-signature-256'];
const payload = JSON.stringify(req.body);
const expectedSignature = 'sha256=' +
crypto.createHmac('sha256', APP_SECRET)
.update(payload)
.digest('hex');
if (signature !== expectedSignature) {
throw new Error('Invalid signature');
}
Phân Trang
Tất cả endpoints danh sách đều hỗ trợ phân trang:
Request:
GET /conversations?skip=20&take=20
Phản Hồi:
{
"pagination": {
"page": 2,
"limit": 20,
"total": 150,
"totalPages": 8
}
}
Changelog
v1.0 (2026-01-18)
- Phát hành ban đầu
- Tích hợp WhatsApp Cloud API
- Luồng tự động
- AI chatbot
- Quản lý khách hàng