1436 lines
24 KiB
Markdown
1436 lines
24 KiB
Markdown
# Dịch Vụ MKT X/Twitter - Tài Liệu API
|
|
|
|
## Mục Lục
|
|
|
|
1. [Tổng Quan API](#tổng-quan-api)
|
|
2. [Xác Thực](#xác-thực)
|
|
3. [Quản Lý Tài Khoản](#quản-lý-tài-khoản)
|
|
4. [Quản Lý Liên Hệ](#quản-lý-liên-hệ)
|
|
5. [Quản Lý Hội Thoại](#quản-lý-hội-thoại)
|
|
6. [Quản Lý Template](#quản-lý-template)
|
|
7. [Quản Lý Chiến Dịch](#quản-lý-chiến-dịch)
|
|
8. [Quản Lý Segment](#quản-lý-segment)
|
|
9. [Automation Flows](#automation-flows)
|
|
10. [AI Chatbot](#ai-chatbot)
|
|
11. [Phân Tích](#phân-tích)
|
|
12. [Webhooks](#webhooks)
|
|
13. [Xử Lý Lỗi](#xử-lý-lỗi)
|
|
|
|
---
|
|
|
|
## Tổng Quan API
|
|
|
|
### Base URL
|
|
|
|
```
|
|
Development: http://localhost:5000/api/v1/mkt-x
|
|
Production: https://api.goodgo.com/api/v1/mkt-x
|
|
```
|
|
|
|
### Versioning
|
|
|
|
API versioning được xử lý thông qua URL path (`/api/v1/`).
|
|
|
|
### Định Dạng Request
|
|
|
|
Tất cả requests với body nên sử dụng:
|
|
```
|
|
Content-Type: application/json
|
|
```
|
|
|
|
### Định Dạng Response
|
|
|
|
Tất cả responses tuân theo cấu trúc này:
|
|
|
|
**Success Response**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": { ... },
|
|
"pagination": {
|
|
"page": 1,
|
|
"limit": 20,
|
|
"total": 100,
|
|
"totalPages": 5
|
|
}
|
|
}
|
|
```
|
|
|
|
**Error Response**
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": "Mô tả lỗi"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Xác Thực
|
|
|
|
### JWT Bearer Token
|
|
|
|
Tất cả API endpoints (ngoại trừ webhooks) yêu cầu xác thực qua JWT bearer token.
|
|
|
|
**Request Header**
|
|
```
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
```
|
|
|
|
### Lấy Token
|
|
|
|
Tokens được lấy từ IAM service:
|
|
|
|
```bash
|
|
POST /api/v1/auth/login
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"email": "user@example.com",
|
|
"password": "password"
|
|
}
|
|
```
|
|
|
|
**Response**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"accessToken": "eyJhbGci...",
|
|
"refreshToken": "refresh...",
|
|
"expiresIn": 3600
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Quản Lý Tài Khoản
|
|
|
|
### Kết Nối Tài Khoản Twitter
|
|
|
|
Kết nối tài khoản Twitter sử dụng OAuth 1.0a credentials.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /accounts
|
|
```
|
|
|
|
**Request Body**
|
|
```json
|
|
{
|
|
"oauthToken": "oauth_token_từ_twitter",
|
|
"oauthTokenSecret": "oauth_token_secret_từ_twitter"
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"id": "550e8400-e29b-41d4-a716-446655440000",
|
|
"merchantId": "merchant-uuid",
|
|
"twitterUserId": "123456789",
|
|
"username": "goodgo_shop",
|
|
"displayName": "GoodGo Official",
|
|
"status": "active",
|
|
"connectedAt": "2026-01-18T10:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Mã Lỗi**
|
|
- `400` - OAuth credentials không hợp lệ
|
|
- `401` - Unauthorized
|
|
- `409` - Tài khoản đã được kết nối
|
|
|
|
---
|
|
|
|
### Danh Sách Tài Khoản Đã Kết Nối
|
|
|
|
Lấy tất cả tài khoản Twitter đã kết nối bởi merchant.
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /accounts
|
|
```
|
|
|
|
**Query Parameters**
|
|
- `status` (tùy chọn) - Lọc theo trạng thái: `active`, `inactive`, `error`
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [
|
|
{
|
|
"id": "uuid",
|
|
"merchantId": "uuid",
|
|
"twitterUserId": "123456789",
|
|
"username": "goodgo_shop",
|
|
"displayName": "GoodGo Official",
|
|
"status": "active",
|
|
"connectedAt": "2026-01-18T10:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Lấy Chi Tiết Tài Khoản
|
|
|
|
Lấy thông tin chi tiết về tài khoản Twitter cụ thể.
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /accounts/{accountId}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"id": "uuid",
|
|
"merchantId": "uuid",
|
|
"twitterUserId": "123456789",
|
|
"username": "goodgo_shop",
|
|
"displayName": "GoodGo Official",
|
|
"profileImageUrl": "https://pbs.twimg.com/profile_images/...",
|
|
"status": "active",
|
|
"webhookId": "webhook-id",
|
|
"connectedAt": "2026-01-18T10:00:00Z",
|
|
"statistics": {
|
|
"totalContacts": 1234,
|
|
"totalConversations": 567,
|
|
"messagesThisMonth": 890
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Mã Lỗi**
|
|
- `404` - Không tìm thấy tài khoản
|
|
|
|
---
|
|
|
|
### Ngắt Kết Nối Tài Khoản
|
|
|
|
Ngắt kết nối tài khoản Twitter và thu hồi OAuth tokens.
|
|
|
|
**Endpoint**
|
|
```
|
|
DELETE /accounts/{accountId}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": null
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Cập Nhật Cài Đặt Tài Khoản
|
|
|
|
Cập nhật cài đặt cấu hình tài khoản.
|
|
|
|
**Endpoint**
|
|
```
|
|
PUT /accounts/{accountId}
|
|
```
|
|
|
|
**Request Body**
|
|
```json
|
|
{
|
|
"autoReplyEnabled": true,
|
|
"businessHours": {
|
|
"enabled": true,
|
|
"timezone": "Asia/Ho_Chi_Minh",
|
|
"schedule": {
|
|
"monday": { "start": "09:00", "end": "18:00" },
|
|
"tuesday": { "start": "09:00", "end": "18:00" }
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
## Quản Lý Liên Hệ
|
|
|
|
### Danh Sách Liên Hệ
|
|
|
|
Lấy danh sách liên hệ có phân trang với filtering.
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /contacts
|
|
```
|
|
|
|
**Query Parameters**
|
|
- `accountId` (tùy chọn) - Lọc theo tài khoản Twitter
|
|
- `tags` (tùy chọn) - Tags phân cách bằng dấu phẩy: `vip,customer`
|
|
- `search` (tùy chọn) - Tìm kiếm trong username/display name
|
|
- `skip` (tùy chọn, mặc định: 0) - Pagination offset
|
|
- `take` (tùy chọn, mặc định: 20, tối đa: 100) - Items per page
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [
|
|
{
|
|
"id": "uuid",
|
|
"accountId": "uuid",
|
|
"twitterUserId": "987654321",
|
|
"username": "customer_john",
|
|
"displayName": "John Doe",
|
|
"profileImageUrl": "https://...",
|
|
"tags": ["vip", "customer"],
|
|
"attributes": {
|
|
"purchaseCount": 5,
|
|
"totalSpent": 1250000,
|
|
"lastPurchaseDate": "2026-01-15"
|
|
},
|
|
"conversationCount": 3,
|
|
"firstInteractionAt": "2025-12-01T10:00:00Z",
|
|
"lastInteractionAt": "2026-01-18T09:30:00Z"
|
|
}
|
|
],
|
|
"pagination": {
|
|
"page": 1,
|
|
"limit": 20,
|
|
"total": 1234,
|
|
"totalPages": 62
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Lấy Chi Tiết Liên Hệ
|
|
|
|
Lấy thông tin chi tiết về liên hệ cụ thể.
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /contacts/{contactId}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"id": "uuid",
|
|
"accountId": "uuid",
|
|
"twitterUserId": "987654321",
|
|
"username": "customer_john",
|
|
"displayName": "John Doe",
|
|
"profileImageUrl": "https://...",
|
|
"tags": ["vip", "customer"],
|
|
"attributes": {
|
|
"purchaseCount": 5,
|
|
"totalSpent": 1250000,
|
|
"lastPurchaseDate": "2026-01-15",
|
|
"preferredLanguage": "vi"
|
|
},
|
|
"source": "inbound_message",
|
|
"conversationCount": 3,
|
|
"firstInteractionAt": "2025-12-01T10:00:00Z",
|
|
"lastInteractionAt": "2026-01-18T09:30:00Z",
|
|
"engagement": {
|
|
"messagesSent": 15,
|
|
"messagesReceived": 18,
|
|
"averageResponseTime": "5m 30s"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Cập Nhật Liên Hệ
|
|
|
|
Cập nhật thông tin liên hệ.
|
|
|
|
**Endpoint**
|
|
```
|
|
PUT /contacts/{contactId}
|
|
```
|
|
|
|
**Request Body**
|
|
```json
|
|
{
|
|
"displayName": "John Doe (VIP)",
|
|
"attributes": {
|
|
"preferredLanguage": "vi",
|
|
"notes": "Khách hàng cao cấp"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Thêm Tags vào Liên Hệ
|
|
|
|
Thêm một hoặc nhiều tags vào liên hệ.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /contacts/{contactId}/tags
|
|
```
|
|
|
|
**Request Body**
|
|
```json
|
|
{
|
|
"tags": ["vip", "premium"]
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Xóa Tag khỏi Liên Hệ
|
|
|
|
Xóa tag cụ thể khỏi liên hệ.
|
|
|
|
**Endpoint**
|
|
```
|
|
DELETE /contacts/{contactId}/tags/{tagName}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Cập Nhật Thuộc Tính Liên Hệ
|
|
|
|
Cập nhật hàng loạt thuộc tính tùy chỉnh cho liên hệ.
|
|
|
|
**Endpoint**
|
|
```
|
|
PUT /contacts/{contactId}/attributes
|
|
```
|
|
|
|
**Request Body**
|
|
```json
|
|
{
|
|
"attributes": {
|
|
"purchaseCount": 6,
|
|
"totalSpent": 1500000,
|
|
"lastPurchaseDate": "2026-01-18",
|
|
"membershipTier": "gold"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Lấy Hội Thoại của Liên Hệ
|
|
|
|
Lấy tất cả hội thoại cho liên hệ cụ thể.
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /contacts/{contactId}/conversations
|
|
```
|
|
|
|
**Query Parameters**
|
|
- `status` (tùy chọn) - Lọc theo trạng thái: `open`, `closed`
|
|
- `skip` (tùy chọn) - Pagination offset
|
|
- `take` (tùy chọn) - Items per page
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [
|
|
{
|
|
"id": "uuid",
|
|
"contactId": "uuid",
|
|
"status": "open",
|
|
"messageCount": 5,
|
|
"startedAt": "2026-01-18T09:00:00Z",
|
|
"lastMessageAt": "2026-01-18T09:30:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Xóa Liên Hệ
|
|
|
|
Xóa liên hệ và tất cả dữ liệu liên quan (tuân thủ GDPR).
|
|
|
|
**Endpoint**
|
|
```
|
|
DELETE /contacts/{contactId}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
## Quản Lý Hội Thoại
|
|
|
|
### Danh Sách Hội Thoại
|
|
|
|
Lấy danh sách hội thoại có phân trang.
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /conversations
|
|
```
|
|
|
|
**Query Parameters**
|
|
- `accountId` (tùy chọn) - Lọc theo tài khoản
|
|
- `status` (tùy chọn) - Lọc theo trạng thái: `open`, `closed`
|
|
- `assignedTo` (tùy chọn) - Lọc theo user ID được gán
|
|
- `skip` (tùy chọn) - Pagination offset
|
|
- `take` (tùy chọn) - Items per page
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [
|
|
{
|
|
"id": "uuid",
|
|
"contactId": "uuid",
|
|
"accountId": "uuid",
|
|
"status": "open",
|
|
"channel": "direct_message",
|
|
"assignedToUserId": "uuid",
|
|
"messageCount": 12,
|
|
"startedAt": "2026-01-18T09:00:00Z",
|
|
"lastMessageAt": "2026-01-18T10:15:00Z",
|
|
"contact": {
|
|
"username": "customer_john",
|
|
"displayName": "John Doe"
|
|
}
|
|
}
|
|
],
|
|
"pagination": { ... }
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Lấy Hội Thoại với Tin Nhắn
|
|
|
|
Lấy chi tiết hội thoại bao gồm tất cả tin nhắn.
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /conversations/{conversationId}
|
|
```
|
|
|
|
**Query Parameters**
|
|
- `includeMessages` (tùy chọn, mặc định: true) - Bao gồm lịch sử tin nhắn
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"id": "uuid",
|
|
"contactId": "uuid",
|
|
"accountId": "uuid",
|
|
"status": "open",
|
|
"channel": "direct_message",
|
|
"assignedToUserId": "uuid",
|
|
"startedAt": "2026-01-18T09:00:00Z",
|
|
"messages": [
|
|
{
|
|
"id": "uuid",
|
|
"conversationId": "uuid",
|
|
"direction": "inbound",
|
|
"type": "text",
|
|
"content": "Xin chào, tôi có câu hỏi về đơn hàng",
|
|
"attachments": [],
|
|
"isFromBot": false,
|
|
"sentAt": "2026-01-18T09:00:00Z"
|
|
},
|
|
{
|
|
"id": "uuid",
|
|
"conversationId": "uuid",
|
|
"direction": "outbound",
|
|
"type": "text",
|
|
"content": "Chào bạn! Tôi rất vui được hỗ trợ. Mã đơn hàng của bạn là gì?",
|
|
"attachments": [],
|
|
"isFromBot": false,
|
|
"sentAt": "2026-01-18T09:02:00Z"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Gửi Tin Nhắn
|
|
|
|
Gửi tin nhắn trong hội thoại.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /conversations/{conversationId}/messages
|
|
```
|
|
|
|
**Request Body**
|
|
```json
|
|
{
|
|
"content": "Đơn hàng #12345 của bạn đã được gửi đi!",
|
|
"type": "text",
|
|
"attachments": [
|
|
{
|
|
"type": "image",
|
|
"url": "https://example.com/tracking.png"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"id": "uuid",
|
|
"conversationId": "uuid",
|
|
"twitterMessageId": "123456789",
|
|
"direction": "outbound",
|
|
"type": "text",
|
|
"content": "Đơn hàng #12345 của bạn đã được gửi đi!",
|
|
"sentAt": "2026-01-18T10:30:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Mã Lỗi**
|
|
- `400` - Nội dung tin nhắn vượt quá giới hạn Twitter (10,000 ký tự)
|
|
- `429` - Vượt quá rate limit
|
|
|
|
---
|
|
|
|
### Đóng Hội Thoại
|
|
|
|
Đóng hội thoại đang hoạt động.
|
|
|
|
**Endpoint**
|
|
```
|
|
PUT /conversations/{conversationId}/close
|
|
```
|
|
|
|
**Request Body** (tùy chọn)
|
|
```json
|
|
{
|
|
"reason": "resolved"
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Gán Hội Thoại
|
|
|
|
Gán hội thoại cho user/agent cụ thể.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /conversations/{conversationId}/assign
|
|
```
|
|
|
|
**Request Body**
|
|
```json
|
|
{
|
|
"userId": "user-uuid"
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
## Quản Lý Template
|
|
|
|
### Tạo Template
|
|
|
|
Tạo template tin nhắn mới.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /templates
|
|
```
|
|
|
|
**Request Body**
|
|
```json
|
|
{
|
|
"name": "Tin Nhắn Chào Mừng",
|
|
"type": "text",
|
|
"content": "Chào {{name}}, chào mừng đến {{shop_name}}! Sử dụng mã {{discount_code}} để được giảm giá 10% cho đơn hàng đầu tiên.",
|
|
"variables": ["name", "shop_name", "discount_code"]
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"id": "uuid",
|
|
"merchantId": "uuid",
|
|
"name": "Tin Nhắn Chào Mừng",
|
|
"type": "text",
|
|
"content": "Chào {{name}}, chào mừng đến...",
|
|
"variables": ["name", "shop_name", "discount_code"],
|
|
"createdAt": "2026-01-18T10:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Danh Sách Templates
|
|
|
|
Lấy tất cả templates của merchant.
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /templates
|
|
```
|
|
|
|
**Query Parameters**
|
|
- `type` (tùy chọn) - Lọc theo loại: `text`, `quick_reply`, `card`
|
|
- `search` (tùy chọn) - Tìm kiếm trong tên template
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Lấy Template
|
|
|
|
Lấy chi tiết template.
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /templates/{templateId}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Cập Nhật Template
|
|
|
|
Cập nhật template hiện có.
|
|
|
|
**Endpoint**
|
|
```
|
|
PUT /templates/{templateId}
|
|
```
|
|
|
|
**Request Body**
|
|
```json
|
|
{
|
|
"name": "Tin Nhắn Chào Mừng Đã Cập Nhật",
|
|
"content": "Xin chào {{name}}!..."
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Xóa Template
|
|
|
|
Xóa template.
|
|
|
|
**Endpoint**
|
|
```
|
|
DELETE /templates/{templateId}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
**Mã Lỗi**
|
|
- `409` - Template đang được sử dụng bởi chiến dịch đang hoạt động
|
|
|
|
---
|
|
|
|
### Xem Trước Template
|
|
|
|
Xem trước template đã render với dữ liệu mẫu.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /templates/{templateId}/preview
|
|
```
|
|
|
|
**Request Body**
|
|
```json
|
|
{
|
|
"variables": {
|
|
"name": "John",
|
|
"shop_name": "GoodGo Shop",
|
|
"discount_code": "WELCOME10"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"rendered": "Chào John, chào mừng đến GoodGo Shop! Sử dụng mã WELCOME10 để được giảm giá 10% cho đơn hàng đầu tiên."
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Quản Lý Chiến Dịch
|
|
|
|
### Tạo Chiến Dịch
|
|
|
|
Tạo chiến dịch tin nhắn mới.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /campaigns
|
|
```
|
|
|
|
**Request Body**
|
|
```json
|
|
{
|
|
"name": "Khuyến Mãi Tết 2026",
|
|
"templateId": "template-uuid",
|
|
"segmentIds": ["segment-uuid-1", "segment-uuid-2"],
|
|
"schedule": {
|
|
"startAt": "2026-01-25T09:00:00Z",
|
|
"endAt": "2026-01-31T23:59:59Z"
|
|
},
|
|
"variables": {
|
|
"discount_code": "TET2026"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"id": "uuid",
|
|
"merchantId": "uuid",
|
|
"name": "Khuyến Mãi Tết 2026",
|
|
"status": "scheduled",
|
|
"targetContactCount": 1500,
|
|
"createdAt": "2026-01-18T10:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Danh Sách Chiến Dịch
|
|
|
|
Lấy tất cả chiến dịch.
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /campaigns
|
|
```
|
|
|
|
**Query Parameters**
|
|
- `status` (tùy chọn) - Lọc theo trạng thái: `draft`, `scheduled`, `running`, `paused`, `completed`
|
|
- `skip` (tùy chọn) - Pagination offset
|
|
- `take` (tùy chọn) - Items per page
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Lấy Chi Tiết Chiến Dịch
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /campaigns/{campaignId}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"id": "uuid",
|
|
"name": "Khuyến Mãi Tết 2026",
|
|
"status": "running",
|
|
"templateId": "uuid",
|
|
"segmentIds": ["uuid"],
|
|
"schedule": {
|
|
"startAt": "2026-01-25T09:00:00Z",
|
|
"endAt": "2026-01-31T23:59:59Z"
|
|
},
|
|
"metrics": {
|
|
"totalSent": 1200,
|
|
"delivered": 1180,
|
|
"opened": 850,
|
|
"clicked": 320,
|
|
"replied": 45,
|
|
"failed": 20
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Bắt Đầu Chiến Dịch
|
|
|
|
Bắt đầu thực thi chiến dịch.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /campaigns/{campaignId}/start
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Tạm Dừng Chiến Dịch
|
|
|
|
Tạm dừng chiến dịch đang chạy.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /campaigns/{campaignId}/pause
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Tiếp Tục Chiến Dịch
|
|
|
|
Tiếp tục chiến dịch đã tạm dừng.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /campaigns/{campaignId}/resume
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Lấy Số Liệu Chiến Dịch
|
|
|
|
Lấy số liệu chi tiết cho chiến dịch.
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /campaigns/{campaignId}/metrics
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"totalSent": 1200,
|
|
"delivered": 1180,
|
|
"deliveryRate": 98.3,
|
|
"opened": 850,
|
|
"openRate": 72.0,
|
|
"clicked": 320,
|
|
"clickRate": 37.6,
|
|
"replied": 45,
|
|
"replyRate": 5.3,
|
|
"failed": 20,
|
|
"failureRate": 1.7
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Quản Lý Segment
|
|
|
|
### Tạo Segment
|
|
|
|
Tạo phân khúc khách hàng mới.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /segments
|
|
```
|
|
|
|
**Request Body**
|
|
```json
|
|
{
|
|
"name": "Khách Hàng VIP",
|
|
"conditions": [
|
|
{
|
|
"field": "attributes.purchaseCount",
|
|
"operator": "gte",
|
|
"value": 5
|
|
},
|
|
{
|
|
"field": "tags",
|
|
"operator": "contains",
|
|
"value": "vip"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Danh Sách Segments
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /segments
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Đánh Giá Segment
|
|
|
|
Lấy số lượng liên hệ khớp với điều kiện segment.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /segments/{segmentId}/evaluate
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"segmentId": "uuid",
|
|
"contactCount": 345,
|
|
"sampleContacts": [
|
|
{
|
|
"id": "uuid",
|
|
"username": "customer_1",
|
|
"displayName": "Customer 1"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Automation Flows
|
|
|
|
### Tạo Automation Flow
|
|
|
|
Tạo workflow tự động hóa.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /automation/flows
|
|
```
|
|
|
|
**Request Body**
|
|
```json
|
|
{
|
|
"name": "Chào Mừng Khách Hàng Mới",
|
|
"trigger": {
|
|
"type": "contact_created",
|
|
"config": {}
|
|
},
|
|
"nodes": [
|
|
{
|
|
"type": "send_message",
|
|
"templateId": "welcome-template-uuid",
|
|
"delay": 0
|
|
},
|
|
{
|
|
"type": "wait",
|
|
"duration": 86400
|
|
},
|
|
{
|
|
"type": "send_message",
|
|
"templateId": "followup-template-uuid",
|
|
"delay": 0
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Kích Hoạt Flow
|
|
|
|
Kích hoạt automation flow.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /automation/flows/{flowId}/activate
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Hủy Kích Hoạt Flow
|
|
|
|
Hủy kích hoạt automation flow.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /automation/flows/{flowId}/deactivate
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
## AI Chatbot
|
|
|
|
### Gửi Tin Nhắn AI
|
|
|
|
Gửi tin nhắn và nhận phản hồi AI.
|
|
|
|
**Endpoint**
|
|
```
|
|
POST /ai/conversations/{conversationId}/message
|
|
```
|
|
|
|
**Request Body**
|
|
```json
|
|
{
|
|
"message": "Tôi muốn kiểm tra đơn hàng của tôi"
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"message": "Dạ, tôi có thể giúp bạn kiểm tra đơn hàng. Vui lòng cho tôi biết mã đơn hàng của bạn.",
|
|
"intent": "check_order",
|
|
"confidence": 0.95,
|
|
"needsHumanEscalation": false
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Cấu Hình AI Chatbot
|
|
|
|
Cập nhật cài đặt AI chatbot cho tài khoản.
|
|
|
|
**Endpoint**
|
|
```
|
|
PUT /ai/accounts/{accountId}/config
|
|
```
|
|
|
|
**Request Body**
|
|
```json
|
|
{
|
|
"enabled": true,
|
|
"model": "gpt-4",
|
|
"systemPrompt": "Bạn là trợ lý ảo của GoodGo Shop...",
|
|
"temperature": 0.7,
|
|
"escalationThreshold": 0.6
|
|
}
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
## Phân Tích
|
|
|
|
### Tổng Quan Analytics
|
|
|
|
Lấy số liệu tổng quan cho merchant.
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /analytics/overview
|
|
```
|
|
|
|
**Query Parameters**
|
|
- `startDate` (bắt buộc) - Ngày bắt đầu (YYYY-MM-DD)
|
|
- `endDate` (bắt buộc) - Ngày kết thúc (YYYY-MM-DD)
|
|
- `accountId` (tùy chọn) - Lọc theo tài khoản
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"period": {
|
|
"startDate": "2026-01-01",
|
|
"endDate": "2026-01-18"
|
|
},
|
|
"summary": {
|
|
"totalContacts": 1234,
|
|
"newContacts": 145,
|
|
"totalConversations": 567,
|
|
"activeConversations": 89,
|
|
"messagesSent": 2340,
|
|
"messagesReceived": 1890,
|
|
"campaignsCompleted": 12,
|
|
"averageResponseTime": "3m 45s"
|
|
},
|
|
"trends": {
|
|
"contactsGrowth": 12.5,
|
|
"conversationsGrowth": 8.3,
|
|
"messagesGrowth": -2.1
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Phân Tích Liên Hệ
|
|
|
|
Lấy thống kê về liên hệ.
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /analytics/contacts
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Phân Tích Hội Thoại
|
|
|
|
Lấy số liệu về hội thoại.
|
|
|
|
**Endpoint**
|
|
```
|
|
GET /analytics/conversations
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
### Phân Tích Chiến Dịch
|
|
|
|
Lấy hiệu suất chiến dịch.
|
|
|
|
**Endpoint```
|
|
GET /analytics/campaigns
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
|
|
---
|
|
|
|
## Webhooks
|
|
|
|
### Endpoint Webhook
|
|
|
|
Twitter sẽ gửi events đến:
|
|
|
|
```
|
|
POST /webhooks/twitter
|
|
```
|
|
|
|
### Xác Minh CRC
|
|
|
|
Twitter gửi challenge để xác minh webhook:
|
|
|
|
```
|
|
GET /webhooks/verify?crc_token=xxx
|
|
```
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
{
|
|
"response_token": "sha256=..."
|
|
}
|
|
```
|
|
|
|
### Sự Kiện Webhook
|
|
|
|
#### Direct Message Event
|
|
```json
|
|
{
|
|
"direct_message_events": [
|
|
{
|
|
"type": "message_create",
|
|
"id": "123456789",
|
|
"created_timestamp": "1642000000000",
|
|
"message_create": {
|
|
"sender_id": "987654321",
|
|
"message_data": {
|
|
"text": "Xin chào!"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Xử Lý Lỗi
|
|
|
|
### Mã Lỗi HTTP
|
|
|
|
| Mã | Ý Nghĩa | Mô Tả |
|
|
|----|---------|-------|
|
|
| `400` | Bad Request | Request không hợp lệ hoặc thiếu tham số |
|
|
| `401` | Unauthorized | Token xác thực không hợp lệ hoặc thiếu |
|
|
| `403` | Forbidden | Không có quyền truy cập tài nguyên |
|
|
| `404` | Not Found | Không tìm thấy tài nguyên |
|
|
| `409` | Conflict | Xung đột với trạng thái hiện tại |
|
|
| `422` | Unprocessable Entity | Validation failed |
|
|
| `429` | Too Many Requests | Vượt quá rate limit |
|
|
| `500` | Internal Server Error | Lỗi server |
|
|
|
|
### Error Response Structure
|
|
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": "Mô tả lỗi",
|
|
"errorCode": "ERROR_CODE",
|
|
"details": {
|
|
"field": "fieldName",
|
|
"message": "Chi tiết lỗi"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Validation Errors
|
|
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": "Validation failed",
|
|
"errorCode": "VALIDATION_ERROR",
|
|
"details": [
|
|
{
|
|
"field": "templateId",
|
|
"message": "Template ID là bắt buộc"
|
|
},
|
|
{
|
|
"field": "segmentIds",
|
|
"message": "Cần ít nhất một segment"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Rate Limiting
|
|
|
|
Service thực thi các giới hạn sau:
|
|
|
|
- **API Calls**: 100 requests/phút mỗi merchant
|
|
- **Message Sending**: 500 tin nhắn/24 giờ mỗi tài khoản Twitter
|
|
- **Webhook Processing**: 1000 events/phút
|
|
|
|
**Rate Limit Headers**:
|
|
```
|
|
X-RateLimit-Limit: 100
|
|
X-RateLimit-Remaining: 95
|
|
X-RateLimit-Reset: 1642000000
|
|
```
|
|
|
|
---
|
|
|
|
## Pagination
|
|
|
|
Tất cả list endpoints hỗ trợ pagination:
|
|
|
|
**Query Parameters**:
|
|
- `skip` - Offset (mặc định: 0)
|
|
- `take` - Limit (mặc định: 20, tối đa: 100)
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"pagination": {
|
|
"page": 1,
|
|
"limit": 20,
|
|
"total": 1234,
|
|
"totalPages": 62
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Best Practices
|
|
|
|
### 1. Sử Dụng Pagination
|
|
|
|
Luôn sử dụng pagination cho list endpoints để tránh timeout.
|
|
|
|
### 2. Xử Lý Rate Limits
|
|
|
|
Implement exponential backoff khi nhận `429` errors.
|
|
|
|
### 3. Validate Input
|
|
|
|
Validate dữ liệu trước khi gửi để giảm lỗi validation.
|
|
|
|
### 4. Sử Dụng Webhooks
|
|
|
|
Sử dụng webhooks thay vì polling để nhận real-time updates.
|
|
|
|
### 5. Cache Responses
|
|
|
|
Cache responses khi phù hợp để giảm API calls.
|
|
|
|
---
|
|
|
|
## Tài Nguyên Bổ Sung
|
|
|
|
- [Twitter API Documentation](https://developer.twitter.com/en/docs/twitter-api)
|
|
- [OpenAI API Documentation](https://platform.openai.com/docs)
|
|
- [Tài Liệu Kiến Trúc](KIEN-TRUC.md)
|
|
- [Hướng Dẫn Thiết Lập Twitter](CAI-DAT-TWITTER.md)
|
|
|
|
---
|
|
|
|
## Hỗ Trợ
|
|
|
|
Để được hỗ trợ về API:
|
|
|
|
- **Email**: api-support@goodgo.com
|
|
- **Documentation Issues**: Mở issue trên GitHub
|
|
- **Emergency Support**: support-priority@goodgo.com
|