diff --git a/.agent/skills/documentation/SKILL.md b/.agent/skills/documentation/SKILL.md index e13c4c60..4b2c61a8 100644 --- a/.agent/skills/documentation/SKILL.md +++ b/.agent/skills/documentation/SKILL.md @@ -67,9 +67,78 @@ services/my-service-net/ **Key Rules:** - `docs/en/` and `docs/vi/` MUST mirror each other (same files, same structure) - Each language folder is MONOLINGUAL (no bilingual mixing) +- **Filenames**: EN uses English (UPPERCASE), VI uses Vietnamese (kebab-case) - Service root `README.md` links to both EN/VI documentation - Mermaid diagrams MUST use dark color palette (see [Mermaid Diagrams Skill](../mermaid-diagrams/SKILL.md)) -- `ARCHITECTURE.md` is MANDATORY, `README.md` is MANDATORY, other files optional +- `ARCHITECTURE.md`/`kien-truc.md` is MANDATORY, `README.md`/`gioi-thieu.md` is MANDATORY, other files optional + +### Vietnamese Filename Conventions / Quy Ước Đặt Tên Tiếng Việt + +**Standard EN/VI Filename Mapping:** + +| English (docs/en/) | Vietnamese (docs/vi/) | Description | +|-------------------|----------------------|-------------| +| `README.md` | `gioi-thieu.md` | Service introduction, quick start | +| `ARCHITECTURE.md` | `kien-truc.md` | Architecture documentation | +| `API.md` | `api.md` | API reference (technical term) | +| `DEPLOYMENT.md` | `trien-khai.md` | Deployment guide | +| `CONFIGURATION.md` | `cau-hinh.md` | Configuration guide | +| `TESTING.md` | `kiem-thu.md` | Testing guide | +| `TROUBLESHOOTING.md` | `khac-phuc-su-co.md` | Troubleshooting | +| `MIGRATION.md` | `di-chuyen-du-lieu.md` | Migration guide | +| `PERFORMANCE.md` | `hieu-nang.md` | Performance optimization | +| `SECURITY.md` | `bao-mat.md` | Security guidelines | + +**Service-Specific Examples:** + +| Service Type | EN Filename | VI Filename | +|-------------|------------|-------------| +| WhatsApp | `WHATSAPP_SETUP.md` | `cai-dat-whatsapp.md` | +| WhatsApp | `AI_CHATBOT_GUIDE.md` | `huong-dan-chatbot-ai.md` | +| WhatsApp | `AUTOMATION_GUIDE.md` | `huong-dan-tu-dong-hoa.md` | +| Facebook | `FACEBOOK_SETUP.md` | `cai-dat-facebook.md` | +| Twitter/X | `TWITTER_SETUP.md` | `cai-dat-twitter.md` | +| Zalo | `ZALO_SETUP.md` | `cai-dat-zalo.md` | + +**Naming Rules for Vietnamese Files:** + +1. **Kebab-case**: All lowercase, words separated by hyphens (`-`) + - ✅ `kien-truc.md`, `huong-dan-chatbot-ai.md` + - ❌ `KIEN-TRUC.md`, `Kien_Truc.md`, `KienTruc.md` + +2. **Vietnamese without diacritics**: Use non-accented Vietnamese + - ✅ `kien-truc` (not `kiến-trúc`) + - ✅ `cau-hinh` (not `cấu-hình`) + - ✅ `trien-khai` (not `triển-khai`) + +3. **Descriptive and clear**: Use full words, avoid abbreviations + - ✅ `huong-dan-chatbot-ai.md` (clear) + - ❌ `hd-chatbot.md` (abbreviated) + +4. **Technical terms**: Keep English for technical/API terms + - ✅ `api.md` (lowercase) + - ✅ `webhook.md` + - ✅ `oauth.md` + +**Directory Structure Example:** + +``` +services/mkt-whatsapp-service-net/docs/ +├── en/ +│ ├── README.md +│ ├── ARCHITECTURE.md +│ ├── API.md +│ ├── WHATSAPP_SETUP.md +│ ├── AI_CHATBOT_GUIDE.md +│ └── AUTOMATION_GUIDE.md +└── vi/ + ├── gioi-thieu.md + ├── kien-truc.md + ├── api.md + ├── cai-dat-whatsapp.md + ├── huong-dan-chatbot-ai.md + └── huong-dan-tu-dong-hoa.md +``` ## Key Patterns / Mẫu Chính @@ -104,32 +173,100 @@ Nội dung bằng tiếng Việt... ### Service README Template +**For service root `README.md` (bilingual with links to language-specific docs):** + ```markdown -# Service Name / Tên Dịch Vụ +# Service Name -> **EN**: Brief description in English -> **VI**: Mô tả ngắn gọn bằng tiếng Việt +> **EN**: [English Documentation](docs/en/README.md) +> **VI**: [Tài liệu Tiếng Việt](docs/vi/gioi-thieu.md) -## Features / Tính Năng -- Feature 1 / Tính năng 1 +## Quick Links -## Prerequisites / Yêu Cầu -- Node.js 20+ -- PostgreSQL (Neon) +- 📖 [Architecture](docs/en/ARCHITECTURE.md) / [Kiến trúc](docs/vi/kien-truc.md) +- 🚀 [API Reference](docs/en/API.md) / [Tài liệu API](docs/vi/api.md) +- ⚙️ [Configuration](docs/en/README.md#configuration) / [Cấu hình](docs/vi/gioi-thieu.md#cấu-hình) + +## Tech Stack + +- .NET 8 / Node.js 20 +- PostgreSQL +- Redis +- RabbitMQ + +## Development -## Quick Start / Bắt Đầu Nhanh ```bash +dotnet build && dotnet run +# or pnpm install && pnpm dev ``` -## Configuration / Cấu Hình +See detailed documentation: +- **English**: [docs/en/](docs/en/) +- **Tiếng Việt**: [docs/vi/](docs/vi/) +``` -| Variable | Description / Mô Tả | Default | -|----------|---------------------|---------| -| PORT | Server port / Cổng server | 5000 | +**For `docs/en/README.md` (English only, detailed):** + +```markdown +# Service Name + +Brief description in English. + +## Features +- Feature 1 +- Feature 2 + +## Prerequisites +- .NET 8 / Node.js 20+ +- PostgreSQL 15+ + +## Quick Start +```bash +dotnet run +``` + +## Configuration + +| Variable | Description | Default | +|----------|-------------|---------| +| PORT | Server port | 5000 | +| DATABASE_URL | PostgreSQL connection | - | ## API Endpoints -See [API Documentation](../../docs/api/openapi/service-name.yaml) +See [API Documentation](API.md) +``` + +**For `docs/vi/gioi-thieu.md` (Vietnamese only, mirrors EN content):** + +```markdown +# Tên Dịch Vụ + +Mô tả ngắn gọn bằng tiếng Việt. + +## Tính Năng +- Tính năng 1 +- Tính năng 2 + +## Yêu Cầu +- .NET 8 / Node.js 20+ +- PostgreSQL 15+ + +## Bắt Đầu Nhanh +```bash +dotnet run +``` + +## Cấu Hình + +| Biến | Mô Tả | Mặc Định | +|------|-------|---------| +| PORT | Cổng server | 5000 | +| DATABASE_URL | Kết nối PostgreSQL | - | + +## API Endpoints +Xem [Tài liệu API](api.md) ``` ### Guide Template diff --git a/services/mkt-facebook-service-net/docs/en/ARCHITECTURE.md b/services/mkt-facebook-service-net/docs/en/ARCHITECTURE.md index 303e70ab..806cbba4 100644 --- a/services/mkt-facebook-service-net/docs/en/ARCHITECTURE.md +++ b/services/mkt-facebook-service-net/docs/en/ARCHITECTURE.md @@ -76,6 +76,27 @@ graph TB Handlers -->|Send Message| FBClient Handlers -->|AI Completion| AIClient + + style EndUser fill:#2C3E50,color:#ECF0F1,stroke:#34495E,stroke-width:2px + style MessengerApp fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px + style Webhook fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px + style API fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px + style Commands fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style Queries fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style Handlers fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style Conversation fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px + style Customer fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px + style ChatbotFlow fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px + style AIChatbot fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px + style FBClient fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style AIClient fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style Repos fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style DbContext fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style PostgreSQL fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style Redis fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style RabbitMQ fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style FacebookAPI fill:#7F8C8D,color:#ECF0F1,stroke:#5D6D7E,stroke-width:2px + style OpenAI fill:#7F8C8D,color:#ECF0F1,stroke:#5D6D7E,stroke-width:2px ``` ## Domain Model @@ -129,6 +150,11 @@ classDiagram Conversation "1" *-- "many" Message Conversation --> ConversationStatus Message --> MessageDirection + + style Conversation fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style Message fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px + style ConversationStatus fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px + style MessageDirection fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px ``` The Conversation aggregate manages the lifecycle of a customer conversation, including all messages exchanged. @@ -161,6 +187,8 @@ classDiagram +RemoveTag(string tag) void +SetCustomField(string key, string value) void } + + style Customer fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px ``` The Customer aggregate represents a Facebook user who interacts with the chatbot. @@ -211,6 +239,10 @@ classDiagram ChatbotFlow "1" *-- "many" FlowNode FlowNode --> NodeType + + style ChatbotFlow fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style FlowNode fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px + style NodeType fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px ``` The ChatbotFlow aggregate defines automation rules and conversation flows. @@ -249,6 +281,9 @@ classDiagram } AIChatbotConfig --> AIProvider + + style AIChatbotConfig fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style AIProvider fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px ``` The AIChatbotConfig aggregate configures AI-powered chatbot behavior. diff --git a/services/mkt-facebook-service-net/docs/en/README.md b/services/mkt-facebook-service-net/docs/en/README.md index 18301b34..0666c543 100644 --- a/services/mkt-facebook-service-net/docs/en/README.md +++ b/services/mkt-facebook-service-net/docs/en/README.md @@ -130,6 +130,18 @@ graph TD INFRA -->|API Call| FB APP -->|AI Completion| INFRA INFRA -->|API Call| OAI + + style User fill:#2C3E50,color:#ECF0F1,stroke:#34495E,stroke-width:2px + style FB fill:#7F8C8D,color:#ECF0F1,stroke:#5D6D7E,stroke-width:2px + style OAI fill:#7F8C8D,color:#ECF0F1,stroke:#5D6D7E,stroke-width:2px + style WH fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px + style API fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px + style APP fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style DOM fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px + style INFRA fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style PG fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style RD fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style RMQ fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px ``` ### Technology Stack diff --git a/services/mkt-facebook-service-net/docs/vi/ARCHITECTURE.md b/services/mkt-facebook-service-net/docs/vi/ARCHITECTURE.md index d3932596..dd88a2ae 100644 --- a/services/mkt-facebook-service-net/docs/vi/ARCHITECTURE.md +++ b/services/mkt-facebook-service-net/docs/vi/ARCHITECTURE.md @@ -76,6 +76,27 @@ graph TB Handlers -->|Gửi Message| FBClient Handlers -->|AI Completion| AIClient + + style EndUser fill:#2C3E50,color:#ECF0F1,stroke:#34495E,stroke-width:2px + style MessengerApp fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px + style Webhook fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px + style API fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px + style Commands fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style Queries fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style Handlers fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style Conversation fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px + style Customer fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px + style ChatbotFlow fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px + style AIChatbot fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px + style FBClient fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style AIClient fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style Repos fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style DbContext fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style PostgreSQL fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style Redis fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style RabbitMQ fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style FacebookAPI fill:#7F8C8D,color:#ECF0F1,stroke:#5D6D7E,stroke-width:2px + style OpenAI fill:#7F8C8D,color:#ECF0F1,stroke:#5D6D7E,stroke-width:2px ``` ## Mô Hình Domain @@ -129,6 +150,11 @@ classDiagram Conversation "1" *-- "many" Message Conversation --> ConversationStatus Message --> MessageDirection + + style Conversation fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style Message fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px + style ConversationStatus fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px + style MessageDirection fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px ``` Aggregate Conversation quản lý vòng đời của một cuộc hội thoại khách hàng, bao gồm tất cả tin nhắn trao đổi. @@ -161,6 +187,8 @@ classDiagram +RemoveTag(string tag) void +SetCustomField(string key, string value) void } + + style Customer fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px ``` Aggregate Customer đại diện cho một Facebook user tương tác với chatbot. @@ -211,6 +239,10 @@ classDiagram ChatbotFlow "1" *-- "many" FlowNode FlowNode --> NodeType + + style ChatbotFlow fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style FlowNode fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px + style NodeType fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px ``` Aggregate ChatbotFlow định nghĩa quy tắc tự động và luồng hội thoại. @@ -249,6 +281,9 @@ classDiagram } AIChatbotConfig --> AIProvider + + style AIChatbotConfig fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style AIProvider fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px ``` Aggregate AIChatbotConfig cấu hình hành vi chatbot AI. diff --git a/services/mkt-facebook-service-net/docs/vi/README.md b/services/mkt-facebook-service-net/docs/vi/README.md index d29b6946..f52ca26d 100644 --- a/services/mkt-facebook-service-net/docs/vi/README.md +++ b/services/mkt-facebook-service-net/docs/vi/README.md @@ -130,6 +130,18 @@ graph TD INFRA -->|API Call| FB APP -->|AI Completion| INFRA INFRA -->|API Call| OAI + + style User fill:#2C3E50,color:#ECF0F1,stroke:#34495E,stroke-width:2px + style FB fill:#7F8C8D,color:#ECF0F1,stroke:#5D6D7E,stroke-width:2px + style OAI fill:#7F8C8D,color:#ECF0F1,stroke:#5D6D7E,stroke-width:2px + style WH fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px + style API fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px + style APP fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style DOM fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px + style INFRA fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style PG fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style RD fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style RMQ fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px ``` ### Công Nghệ diff --git a/services/mkt-whatsapp-service-net/docs/en/ARCHITECTURE.md b/services/mkt-whatsapp-service-net/docs/en/ARCHITECTURE.md index b9e8849c..58de950a 100644 --- a/services/mkt-whatsapp-service-net/docs/en/ARCHITECTURE.md +++ b/services/mkt-whatsapp-service-net/docs/en/ARCHITECTURE.md @@ -55,6 +55,20 @@ graph TB INFRA --> RABBIT RABBIT --> MERCHANT RABBIT --> ANALYTICS + + style Customer fill:#2C3E50,color:#ECF0F1,stroke:#34495E,stroke-width:3px + style WA fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px + style OPENAI fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px + style GATEWAY fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px + style API fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style APP fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style DOMAIN fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style INFRA fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style PG fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style REDIS fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style RABBIT fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style MERCHANT fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px + style ANALYTICS fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px ``` ## Clean Architecture Layers diff --git a/services/mkt-whatsapp-service-net/docs/vi/AI_CHATBOT_GUIDE.md b/services/mkt-whatsapp-service-net/docs/vi/AI_CHATBOT_GUIDE.md new file mode 100644 index 00000000..24f8b4f6 --- /dev/null +++ b/services/mkt-whatsapp-service-net/docs/vi/AI_CHATBOT_GUIDE.md @@ -0,0 +1,547 @@ +# Hướng Dẫn AI Chatbot + +**Cập nhật lần cuối**: 2026-01-18 + +Tìm hiểu cách cấu hình và tối ưu hóa chatbot AI cho hội thoại WhatsApp. + +## Tổng Quan + +AI Chatbot sử dụng Mô Hình Ngôn Ngữ Lớn (LLM) để cung cấp phản hồi thông minh, nhận biết ngữ cảnh. Không giống như tự động hóa dựa trên quy tắc, AI có thể: + +- Hiểu ngôn ngữ tự nhiên và ý định +- Duy trì ngữ cảnh qua các lượt hội thoại +- Tạo phản hồi động +- Xử lý các câu hỏi bất ngờ +- Học từ các mẫu hội thoại + +## Các Nhà Cung Cấp LLM Được Hỗ Trợ + +| Nhà Cung Cấp | Model | Chi Phí (mỗi 1M tokens) | Độ Trễ | +|--------------|-------|-------------------------|--------| +| **OpenAI** | GPT-4-Turbo | $10 input / $30 output | ~2s | +| **OpenAI** | GPT-3.5-Turbo | $0.50 input / $1.50 output | ~1s | +| **Azure OpenAI** | GPT-4 | Giá tùy chỉnh | ~2s | +| **Google Gemini** | Gemini Pro | $0.50 input / $1.50 output | ~1.5s | + +**Khuyến Nghị**: Bắt đầu với GPT-4-Turbo cho chất lượng, tối ưu hóa sang GPT-3.5 cho các truy vấn đơn giản. + +## Tạo AI Agent + +### Qua API + +```bash +POST /api/v1/whatsapp/ai-agents +Content-Type: application/json + +{ + "shopId": "shop-guid", + "agentName": "AI Hỗ Trợ Khách Hàng", + "personality": { + "tone": "friendly", + "language": "vietnamese", + "constraints": [ + "KHÔNG cung cấp giá mà không kiểm tra catalog hiện tại", + "KHÔNG xử lý đơn hàng trực tiếp", + "Luôn đề nghị kết nối với nhân viên cho các vấn đề phức tạp" + ], + "promptTemplate": "Bạn là trợ lý hỗ trợ khách hàng hữu ích cho {shop_name}." + }, + "knowledgeBaseId": "kb-guid", + "isActive": false +} +``` + +### Phản Hồi + +```json +{ + "success": true, + "data": { + "agentId": "agent-guid", + "agentName": "AI Hỗ Trợ Khách Hàng", + "createdAt": "2026-01-18T10:00:00Z" + } +} +``` + +## Cấu Hình Tính Cách + +### Các Tùy Chọn Tone + +**Friendly** (Khuyến nghị cho bán lẻ) +``` +"Bạn là trợ lý ấm áp và nhiệt tình. Sử dụng emoji thỉnh thoảng. +Xưng hô khách hàng một cách thân thiện nhưng tôn trọng." +``` + +**Professional** (Khuyến nghị cho B2B) +``` +"Bạn là trợ lý doanh nghiệp chuyên nghiệp. Sử dụng ngôn ngữ trang trọng. +Cung cấp thông tin chi tiết, chính xác. Tránh emoji." +``` + +**Casual** (Khuyến nghị cho đối tượng trẻ tuổi) +``` +"Bạn là trợ lý thân thiện và dễ gần. Sử dụng ngôn ngữ không trang trọng. +Giữ phản hồi ngắn gọn. Sử dụng slang thịnh hành khi thích hợp." +``` + +### Ngôn Ngữ + +Đặt ngôn ngữ chính: +```json +{ + "language": "vietnamese", + "fallbackLanguage": "english" +} +``` + +AI sẽ: +1. Phản hồi bằng tiếng Việt mặc định +2. Chuyển sang tiếng Anh nếu khách hàng sử dụng tiếng Anh +3. Xử lý ngôn ngữ hỗn hợp (Vienglish) + +### Ràng Buộc + +Định nghĩa những gì AI KHÔNG nên làm: + +```json +{ + "constraints": [ + "Không bao giờ chia sẻ thông tin cá nhân của khách hàng khác", + "Không hứa giảm giá hoặc hoàn tiền mà không có sự chấp thuận", + "Không xử lý giao dịch tài chính", + "Luôn xác minh mã đơn hàng trước khi cung cấp trạng thái", + "Chuyển các vấn đề nhạy cảm cho nhân viên" + ] +} +``` + +## Prompt Template + +### Template Cơ Bản + +``` +Bạn là nhân viên hỗ trợ khách hàng cho {shop_name}. + +Vai trò: Hỗ trợ khách hàng về thông tin sản phẩm, theo dõi đơn hàng và các câu hỏi chung. + +Ngữ Cảnh: +- Tên khách hàng: {customer_name} +- Tags khách hàng: {customer_tags} +- Lần mua hàng trước: {purchase_count} + +Cơ Sở Kiến Thức: +{knowledge_base_content} + +Hướng Dẫn: +- Hữu ích và ngắn gọn +- Nếu không chắc chắn, hãy nói và đề nghị kết nối với nhân viên +- Không bao giờ bịa thông tin +- Luôn xác nhận trước khi thực hiện hành động + +Ngày hiện tại: {current_date} +Thời gian hiện tại: {current_time} +``` + +### Template Nâng Cao với Few-Shot Examples + +``` +Bạn là nhân viên hỗ trợ khách hàng cho {shop_name}. + +Dưới đây là các ví dụ về phản hồi tốt: + +Khách hàng: "Bạn có iPhone 15 không?" +Nhân Viên: "Để tôi kiểm tra hàng tồn kho cho bạn! 📱 Bạn có thể cho biết màu sắc và dung lượng bộ nhớ bạn đang tìm kiếm không? Chúng tôi thường có Đen, Xanh và Hồng với dung lượng 128GB, 256GB và 512GB." + +Khách hàng: "Đơn hàng của tôi đâu?" +Nhân Viên: "Tôi sẽ giúp bạn theo dõi! Bạn có thể chia sẻ mã đơn hàng không? Nó trông giống như #12345. Bạn có thể tìm thấy trong email xác nhận." + +Khách hàng: "Sản phẩm này bị hỏng" +Nhân Viên: "Tôi rất tiếc khi nghe điều này! 😞 Để giúp bạn nhanh chóng, tôi sẽ kết nối bạn với đội hỗ trợ của chúng tôi, họ có thể xử lý đổi trả hoặc thay thế. Vui lòng chờ một chút." + +Bây giờ phản hồi tin nhắn của khách hàng: +{customer_message} +``` + +## Tích Hợp Cơ Sở Kiến Thức + +### Tạo Knowledge Base + +Tải lên tài liệu (FAQ, catalog sản phẩm, chính sách): + +```bash +POST /api/v1/whatsapp/knowledge-bases +Content-Type: application/json + +{ + "shopId": "shop-guid", + "name": "KB Hỗ Trợ Khách Hàng", + "documents": [ + { + "title": "Chính Sách Vận Chuyển", + "content": "Chúng tôi cung cấp vận chuyển miễn phí cho đơn hàng trên 500.000 VNĐ..." + }, + { + "title": "Chính Sách Đổi Trả", + "content": "Bạn có thể đổi trả hàng trong vòng 30 ngày..." + } + ] +} +``` + +### Liên Kết với AI Agent + +```bash +PUT /api/v1/whatsapp/ai-agents/{agentId} +Content-Type: application/json + +{ + "knowledgeBaseId": "kb-guid" +} +``` + +AI sẽ tự động tham chiếu KB khi phản hồi. + +## Quản Lý Ngữ Cảnh + +### Lịch Sử Hội Thoại + +AI tự động bao gồm 10 tin nhắn cuối cùng cho ngữ cảnh: + +```json +{ + "messages": [ + {"role": "user", "content": "Bạn có bán laptop không?"}, + {"role": "assistant", "content": "Có! Chúng tôi có nhiều mẫu laptop..."}, + {"role": "user", "content": "Còn laptop gaming thì sao?"} + ] +} +``` + +AI hiểu "laptop gaming" đề cập đến cuộc thảo luận về laptop. + +### Biến Ngữ Cảnh Tùy Chỉnh + +Chèn ngữ cảnh động: + +```json +{ + "contextVariables": { + "customer_tier": "vip", + "cart_value": "2500000", + "last_purchase_date": "2026-01-10", + "preferred_category": "electronics" + } +} +``` + +Sử dụng trong prompt: +``` +Cấp độ khách hàng: {customer_tier} +Giá trị giỏ hàng: {cart_value} VNĐ + +Cung cấp đề xuất cá nhân hóa dựa trên sở thích của họ về {preferred_category}. +``` + +## Tạo Phản Hồi + +### API Request + +Khi khách hàng gửi tin nhắn, AI agent tự động tạo phản hồi: + +``` +Khách hàng: "Tôi muốn mua áo thun size L" + +[Pipeline AI Nội Bộ] +1. Tải lịch sử hội thoại +2. Lấy hồ sơ khách hàng (tags, trường tùy chỉnh) +3. Truy vấn cơ sở kiến thức cho thông tin liên quan +4. Xây dựng prompt với ngữ cảnh +5. Gọi OpenAI API +6. Phân tích phản hồi +7. Áp dụng bộ lọc an toàn +8. Gửi cho khách hàng +``` + +### Phản Hồi Streaming + +Đối với phản hồi dài, bật streaming: + +```bash +PUT /api/v1/whatsapp/ai-agents/{agentId} +Content-Type: application/json + +{ + "streamingEnabled": true, + "streamingChunkSize": 500 +} +``` + +Gửi tin nhắn theo từng đoạn (UX mượt mà hơn cho câu trả lời dài). + +## Xử Lý Fallback + +### Khi AI Nên Chuyển Tiếp + +Cấu hình điều kiện để chuyển cho người: + +```json +{ + "fallbackConditions": [ + {"type": "low_confidence", "threshold": 0.7}, + {"type": "contains_keywords", "keywords": ["khiếu nại", "hoàn tiền", "gặp quản lý"]}, + {"type": "conversation_length", "maxTurns": 10}, + {"type": "sentiment", "value": "negative"} + ] +} +``` + +### Tin Nhắn Fallback + +Tin nhắn chuyển giao tùy chỉnh: + +```json +{ + "fallbackMessage": "Tôi muốn đảm bảo bạn nhận được sự giúp đỡ tốt nhất! Để tôi kết nối bạn với một trong những chuyên gia của chúng tôi, họ có thể hỗ trợ bạn thêm. Vui lòng chờ... 👨‍💼" +} +``` + +## Tối Ưu Hóa Chi Phí + +### 1. Phân Loại Ý Định + +Trước khi gọi GPT-4 đắt tiền, sử dụng bộ phân loại rẻ: + +```json +{ + "intentClassifier": { + "enabled": true, + "model": "gpt-3.5-turbo", + "categories": ["faq", "product_inquiry", "order_tracking", "complaint", "other"] + } +} +``` + +Định tuyến đến GPT-3.5 cho FAQs, GPT-4 cho truy vấn phức tạp. + +### 2. Response Caching + +Lưu cache câu hỏi phổ biến: + +```json +{ + "caching": { + "enabled": true, + "ttl": 3600, + "similarityThreshold": 0.95 + } +} +``` + +Nếu khách hàng hỏi "Bạn có giao hàng đến Hà Nội?" và cache có câu trả lời cho câu hỏi tương tự → trả về phản hồi đã cache (không gọi API = $0). + +### 3. Giới Hạn Token + +Đặt token tối đa để tránh chi phí tăng cao: + +```json +{ + "tokenLimits": { + "maxPromptTokens": 2000, + "maxCompletionTokens": 500 + } +} +``` + +### 4. Cảnh Báo Ngân Sách + +Đặt giới hạn chi tiêu: + +```bash +POST /api/v1/whatsapp/ai-agents/{agentId}/budget +Content-Type: application/json + +{ + "dailyBudgetUsd": 10.00, + "monthlyBudgetUsd": 200.00, + "alertThreshold": 0.8 +} +``` + +Nhận cảnh báo khi sử dụng 80% ngân sách. + +## An Toàn & Kiểm Duyệt + +### Lọc Nội Dung + +Bật kiểm duyệt OpenAI: + +```json +{ + "moderation": { + "enabled": true, + "blockCategories": ["hate", "harassment", "violence", "self-harm"] + } +} +``` + +Nội dung đáng ngờ bị chặn trước khi phản hồi. + +### Bảo Vệ PII + +Tự động che giấu dữ liệu nhạy cảm: + +```json +{ + "piiProtection": { + "enabled": true, + "redactTypes": ["credit_card", "ssn", "email", "phone"] + } +} +``` + +Logs sẽ hiển thị `[REDACTED]` thay vì giá trị thực tế. + +## Kiểm Tra + +### Chế Độ Kiểm Tra + +Mô phỏng phản hồi AI mà không gửi cho khách hàng: + +```bash +POST /api/v1/whatsapp/ai-agents/{agentId}/test +Content-Type: application/json + +{ + "conversationHistory": [ + {"role": "user", "content": "Laptop nào tốt nhất?"} + ], + "customerContext": { + "name": "Nguyễn Văn A", + "tags": ["vip"] + } +} +``` + +**Phản Hồi**: +```json +{ + "generatedResponse": "Xin chào Nguyễn Văn A! 👋 ...", + "tokensUsed": { + "prompt": 450, + "completion": 120, + "total": 570 + }, + "estimatedCost": 0.0154, + "latencyMs": 1850 +} +``` + +### Kiểm Thử A/B + +So sánh prompts: + +- Agent A: Personality = "friendly" +- Agent B: Personality = "professional" + +Định tuyến 50% lưu lượng cho mỗi agent, đo lường: +- Sự hài lòng của khách hàng (ngầm từ độ dài hội thoại) +- Tỷ lệ giải quyết +- Chi phí mỗi hội thoại + +## Theo Dõi + +### Dashboard Số Liệu + +Theo dõi: +- **Token usage** (hàng ngày/hàng tháng) +- **Chi phí** (mỗi hội thoại, tổng cộng) +- **Độ trễ** (p50, p95, p99) +- **Tỷ lệ fallback** (AI chuyển tiếp bao nhiêu lần) +- **Sự hài lòng của khách hàng** (thumbs up/down) + +### Chất Lượng Hội Thoại + +Xem xét mẫu ngẫu nhiên: + +```bash +GET /api/v1/whatsapp/ai-agents/{agentId}/conversations/sample?count=10 +``` + +Tìm: +- Ảo giác (AI bịa thông tin) +- Tone không phù hợp với thương hiệu +- Không chuyển tiếp khi cần + +## Cách Tiếp Cận Lai + +Kết hợp tự động + AI cho kết quả tốt nhất: + +### Chiến Lược 1: Tự Động Trước + +1. Tin nhắn đến → Kiểm tra luồng tự động +2. Nếu không khớp → Định tuyến đến AI +3. Phản hồi AI → Gửi cho khách hàng + +### Chiến Lược 2: AI Để Phân Loại + +1. AI phân loại ý định +2. Định tuyến đến luồng tự động phù hợp +3. Fallback đến AI nếu không có luồng nào khớp + +### Chiến Lược 3: Dựa Trên Thời Gian + +- Giờ làm việc (9 AM - 6 PM): AI bật +- Sau giờ: Chỉ tự động (FAQ đơn giản) + +## Thực Hành Tốt Nhất + +1. **Bắt đầu với phạm vi hẹp** - Huấn luyện AI về các danh mục cụ thể trước +2. **Xem xét thường xuyên** - Lấy mẫu hội thoại hàng tuần +3. **Cập nhật cơ sở kiến thức** - Giữ thông tin sản phẩm/chính sách cập nhật +4. **Đặt ràng buộc rõ ràng** - Định nghĩa AI có thể/không thể làm gì +5. **Theo dõi chi phí** - Đặt ngân sách và cảnh báo +6. **Con người trong vòng lặp** - Luôn cung cấp đường chuyển tiếp +7. **Tối ưu hóa prompts** - Lặp lại dựa trên hiệu suất +8. **Sử dụng ví dụ** - Few-shot learning cải thiện chất lượng + +## Khắc Phục Sự Cố + +### Phản Hồi AI Chung Chung + +**Giải Pháp**: Thêm ngữ cảnh và ví dụ vào prompt template. + +### AI Cung Cấp Thông Tin Sai + +**Giải Pháp**: +1. Cập nhật cơ sở kiến thức +2. Thêm ràng buộc trong prompt +3. Xem xét và huấn luyện lại + +### Chi Phí Cao + +**Giải Pháp**: +1. Bật phân loại ý định +2. Giảm token tối đa +3. Sử dụng GPT-3.5 khi có thể +4. Triển khai caching + +### Phản Hồi Chậm + +**Giải Pháp**: +1. Giảm cửa sổ ngữ cảnh (ít tin nhắn lịch sử hơn) +2. Bật streaming +3. Sử dụng mô hình nhanh hơn (GPT-3.5) + +## Bước Tiếp Theo + +- [Tài Liệu API](API.md) - Tham chiếu API AI agent +- [Hướng Dẫn Automation](AUTOMATION_GUIDE.md) - Kết hợp với tự động +- [Kiến Trúc](ARCHITECTURE.md) - Hiểu pipeline AI + +## Tài Nguyên + +- [OpenAI Best Practices](https://platform.openai.com/docs/guides/prompt-engineering) +- [Hướng Dẫn Prompt Engineering](https://www.promptingguide.ai/) +- [Công Cụ Tính Chi Phí LLM](https://docsbot.ai/tools/gpt-openai-api-pricing-calculator) diff --git a/services/mkt-whatsapp-service-net/docs/vi/API.md b/services/mkt-whatsapp-service-net/docs/vi/API.md new file mode 100644 index 00000000..426319f5 --- /dev/null +++ b/services/mkt-whatsapp-service-net/docs/vi/API.md @@ -0,0 +1,790 @@ +# 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. + +```bash +Authorization: Bearer +``` + +## Định Dạng Phản Hồi + +Tất cả phản hồi tuân theo cấu trúc này: + +```json +{ + "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ạn +- `hub.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**: +```json +{ + "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**: +```json +{ + "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**: +```json +{ + "shopId": "550e8400-e29b-41d4-a716-446655440000", + "phoneNumberId": "123456789", + "accessToken": "EAAxxxxx", + "webhookUrl": "https://yourdomain.com/api/v1/whatsapp/webhooks" +} +``` + +**Phản Hồi**: +```json +{ + "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**: +```json +{ + "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**: +```json +{ + "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àng +- `status` (tùy chọn) - Lọc: `active`, `closed`, `expired` +- `assignedAgentId` (tùy chọn) - Lọc theo nhân viên +- `skip` (mặc định: 0) - Vị trí phân trang +- `take` (mặc định: 20, tối đa: 100) - Kích thước trang + +**Phản Hồi**: +```json +{ + "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**: +```json +{ + "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**: +```json +{ + "content": { + "type": "text", + "text": "Cảm ơn bạn đã liên hệ!" + } +} +``` + +**Phản Hồi**: +```json +{ + "success": true, + "data": { + "messageId": "msg-003", + "whatsAppMessageId": "wamid.zzz", + "status": "sent", + "timestamp": "2026-01-18T10:05:00Z" + } +} +``` + +**Tin Nhắn Media**: +```json +{ + "content": { + "type": "image", + "url": "https://example.com/product.jpg", + "caption": "Xem sản phẩm này!" + } +} +``` + +**Tin Nhắn Tương Tác**: +```json +{ + "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**: +```json +{ + "agentId": "agent-001" +} +``` + +**Phản Hồi**: +```json +{ + "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**: +```json +{ + "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ại +- `tags` (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**: +```json +{ + "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**: +```json +{ + "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**: +```json +{ + "addTags": ["vip", "electronics-buyer"], + "removeTags": ["new-customer"] +} +``` + +**Phản Hồi**: +```json +{ + "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**: +```json +{ + "status": "opted_in", + "source": "web" +} +``` + +**Phản Hồi**: +```json +{ + "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**: +```json +{ + "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](AUTOMATION_GUIDE.md#tạo-luồng) + +**Phản Hồi**: +```json +{ + "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](AI_CHATBOT_GUIDE.md#tạo-ai-agent) + +### 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**: +```json +{ + "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**: +```json +{ + "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**: +```json +{ + "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**: +```json +{ + "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**: +```json +{ + "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**: +```json +{ + "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`: + +```javascript +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**: +```json +{ + "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 diff --git a/services/mkt-whatsapp-service-net/docs/vi/ARCHITECTURE.md b/services/mkt-whatsapp-service-net/docs/vi/ARCHITECTURE.md index 5846b890..1ec3cdaf 100644 --- a/services/mkt-whatsapp-service-net/docs/vi/ARCHITECTURE.md +++ b/services/mkt-whatsapp-service-net/docs/vi/ARCHITECTURE.md @@ -12,17 +12,535 @@ MKT WhatsApp Service là một microservice toàn diện được xây dựng tr 2. **AI Chatbot**: Phản hồi thông minh được hỗ trợ bởi LLM 3. **Quản Lý Khách Hàng**: CRM thống nhất cho tương tác WhatsApp -_(Nội dung tương tự phiên bản English, với các mô tả và text được dịch sang tiếng Việt)_ +### Kiến Trúc Cấp Cao + +```mermaid +graph TB + subgraph External["Bên Ngoài"] + WA[WhatsApp Cloud API] + OPENAI[OpenAI GPT-4] + Customer[Người Dùng Cuối] + end + + subgraph "GoodGo Platform" + GATEWAY[Traefik Gateway] + + subgraph "mkt-whatsapp-service-net" + API[API Layer] + APP[Application Layer] + DOMAIN[Domain Layer] + INFRA[Infrastructure Layer] + end + + PG[(PostgreSQL)] + REDIS[(Redis)] + RABBIT[RabbitMQ] + end + + subgraph "Other Services"["Dịch Vụ Khác"] + MERCHANT[merchant-service] + ANALYTICS[analytics-service] + end + + Customer -->|Tin nhắn| WA + WA -->|Webhooks| GATEWAY + GATEWAY --> API + API --> APP + APP --> DOMAIN + APP --> INFRA + INFRA --> PG + INFRA --> REDIS + INFRA --> WA + INFRA --> OPENAI + INFRA --> RABBIT + RABBIT --> MERCHANT + RABBIT --> ANALYTICS + + style Customer fill:#2C3E50,color:#ECF0F1,stroke:#34495E,stroke-width:3px + style WA fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px + style OPENAI fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px + style GATEWAY fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px + style API fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style APP fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style DOMAIN fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style INFRA fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px + style PG fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style REDIS fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style RABBIT fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px + style MERCHANT fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px + style ANALYTICS fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px +``` ## Các Tầng Clean Architecture -### 1. Tầng API -### 2. Tầng Application -### 3. Tầng Domain -### 4. Tầng Infrastructure +### 1. Tầng API (`MktWhatsAppService.API`) -_(Xem file English để tham khảo nội dung chi tiết - đã được dịch)_ +**Trách Nhiệm**: Giao diện HTTP, xử lý request/response + +#### Controllers +- `WebhooksController` - Xác minh webhook WhatsApp và sự kiện tin nhắn +- `WhatsAppAccountsController` - Quản lý kết nối tài khoản +- `ConversationsController` - Endpoints hội thoại và tin nhắn +- `CustomersController` - Quản lý hồ sơ khách hàng +- `AutomationFlowsController` - CRUD luồng tự động +- `AIAgentsController` - Cấu hình AI agent +- `AnalyticsController` - Số liệu và báo cáo + +#### Background Jobs +- `ConversationExpiryJob` - Đóng hội thoại hết hạn 24h +- `MessageStatusSyncJob` - Đồng bộ trạng thái gửi/đã đọc từ WhatsApp +- `FlowSchedulerJob` - Kích hoạt luồng tự động theo thời gian + +### 2. Tầng Application (`MktWhatsAppService.API/Application`) + +**Trách Nhiệm**: Use cases, điều phối, CQRS + +#### Commands (Ghi) + +**Tài Khoản WhatsApp** +- `ConnectWhatsAppAccountCommand` - Đăng ký tài khoản mới +- `UpdateWebhookCommand` - Cập nhật cấu hình webhook +- `DisconnectWhatsAppAccountCommand` - Vô hiệu hóa tài khoản + +**Tin Nhắn** +- `ProcessIncomingMessageCommand` - Xử lý tin nhắn WhatsApp đến +- `SendMessageCommand` - Gửi tin nhắn đi +- `SendTemplateMessageCommand` - Gửi template đã phê duyệt + +**Tự Động** +- `CreateAutomationFlowCommand` - Định nghĩa luồng mới +- `UpdateFlowStepCommand` - Sửa logic luồng +- `ActivateFlowCommand` - Bật tự động +- `DeactivateFlowCommand` - Tắt tự động + +**AI Agent** +- `CreateAIAgentCommand` - Cấu hình chatbot AI +- `UpdateAgentPersonalityCommand` - Sửa hành vi AI +- `GenerateAIResponseCommand` - Lấy trả lời AI + +**Khách Hàng** +- `CreateCustomerCommand` - Đăng ký khách hàng mới +- `UpdateCustomerOptInCommand` - Quản lý đồng ý opt-in +- `TagCustomerCommand` - Thêm/xóa tags + +#### Queries (Đọc) + +**Hội Thoại** +- `GetConversationQuery` - Một hội thoại với tin nhắn +- `GetActiveConversationsQuery` - Liệt kê hội thoại đang diễn ra +- `SearchConversationsQuery` - Tìm kiếm toàn văn bản + +**Khách Hàng** +- `GetCustomerQuery` - Hồ sơ khách hàng theo WaId +- `GetCustomersQuery` - Danh sách khách hàng có phân trang +- `GetCustomerConversationHistoryQuery` - Tất cả hội thoại trong quá khứ + +**Phân Tích** +- `GetMessageStatsQuery` - Số liệu lượng tin nhắn +- `GetConversationMetricsQuery` - Thời gian phản hồi, tỷ lệ giải quyết +- `GetAutomationPerformanceQuery` - Thống kê thực thi luồng + +#### MediatR Pipeline Behaviors +1. **Logging Behavior** - Ghi log tất cả commands/queries +2. **Validation Behavior** - Tích hợp FluentValidation +3. **Transaction Behavior** - Unit of Work cho commands + +### 3. Tầng Domain (`MktWhatsAppService.Domain`) + +**Trách Nhiệm**: Logic nghiệp vụ, entities, quy tắc nghiệp vụ + +#### Aggregates + +##### WhatsAppAccount Aggregate +**Aggregate Root**: `WhatsAppAccount` + +Thuộc Tính: +- `Id` (Guid) +- `ShopId` (Guid) +- `PhoneNumberId` (string) - ID số điện thoại WhatsApp +- `AccessToken` (string, mã hóa) +- `WebhookUrl` (string) +- `Status` (Active/Suspended) +- `MessageTier` (1K/10K/100K/Unlimited) + +Phương Thức Nghiệp Vụ: +- `Activate()` - Kích hoạt tài khoản +- `UpdateWebhook(url)` - Thay đổi URL webhook +- `Suspend()` - Tạm ngừng tài khoản + +Domain Events: +- `WhatsAppAccountConnectedEvent` +- `WebhookVerifiedEvent` + +##### Conversation Aggregate +**Aggregate Root**: `Conversation` + +Thuộc Tính: +- `Id` (Guid) +- `ShopId` (Guid) +- `CustomerWaId` (string) +- `Status` (Active/Closed/Expired) +- `AssignedAgentId` (Guid, nullable) +- `LastMessageAt` (DateTime) +- `Tags` (List) + +Entities: +- `Message` + - `Id` (Guid) + - `WhatsAppMessageId` (string) + - `Direction` (Inbound/Outbound) + - `Content` (MessageContent value object) + - `Status` (Sent/Delivered/Read/Failed) + - `Timestamp` (DateTime) + +Phương Thức Nghiệp Vụ: +- `AddMessage(content, direction)` - Thêm tin nhắn vào hội thoại +- `AssignToAgent(agentId)` - Gán hội thoại +- `Close()` - Đóng hội thoại +- `CheckExpiry()` - Kiểm tra cửa sổ 24h + +Domain Events: +- `ConversationStartedEvent` +- `MessageReceivedEvent` +- `MessageSentEvent` +- `ConversationClosedEvent` + +##### AutomationFlow Aggregate +**Aggregate Root**: `AutomationFlow` + +Thuộc Tính: +- `Id` (Guid) +- `ShopId` (Guid) +- `FlowName` (string) +- `TriggerType` (Keyword/Event/Schedule) +- `TriggerConfig` (JSON) +- `IsActive` (bool) + +Entities: +- `FlowStep` + - `Order` (int) + - `Action` (SendMessage/TagCustomer/CallWebhook/Delay) + - `ActionConfig` (JSON) + - `Conditions` (JSON, optional) + - `NextStepId` (int, nullable) + +Phương Thức Nghiệp Vụ: +- `AddStep(action, config, conditions)` - Thêm bước luồng +- `ValidateFlow()` - Kiểm tra chu trình, xác thực cấu trúc +- `Activate()` - Bật luồng +- `Deactivate()` - Tắt luồng + +##### AIAgent Aggregate +**Aggregate Root**: `AIAgent` + +Thuộc Tính: +- `Id` (Guid) +- `ShopId` (Guid) +- `AgentName` (string) +- `Personality` (AgentPersonality value object) +- `KnowledgeBaseId` (Guid, nullable) +- `IsActive` (bool) + +Value Objects: +- `AgentPersonality` + - `Tone` (Friendly/Professional/Casual) + - `Language` (Vietnamese/English) + - `Constraints` (List) + - `PromptTemplate` (string) + +Phương Thức Nghiệp Vụ: +- `UpdatePersonality(personality)` - Thay đổi hành vi AI +- `Activate()` - Bật phản hồi AI +- `Deactivate()` - Tắt AI + +##### Customer Aggregate +**Aggregate Root**: `Customer` + +Thuộc Tính: +- `Id` (Guid) +- `WaId` (string) - ID WhatsApp (số điện thoại) +- `ShopId` (Guid) +- `Name` (string) +- `ProfilePictureUrl` (string, nullable) +- `Consent` (OptInConsent value object) +- `Tags` (List) +- `CustomFields` (Dictionary) +- `FirstContactedAt` (DateTime) + +Value Objects: +- `OptInConsent` + - `Status` (OptedIn/OptedOut/Pending) + - `Timestamp` (DateTime) + - `Source` (Web/WhatsApp/Manual) + +Phương Thức Nghiệp Vụ: +- `UpdateOptIn(status, source)` - Quản lý đồng ý +- `AddTag(tag)` - Thêm tag khách hàng +- `RemoveTag(tag)` - Xóa tag +- `UpdateCustomField(key, value)` - Đặt trường tùy chỉnh + +### 4. Tầng Infrastructure (`MktWhatsAppService.Infrastructure`) + +**Trách Nhiệm**: Mối quan tâm bên ngoài, lưu trữ, API clients + +#### Truy Cập Dữ Liệu +- `MktWhatsAppServiceContext` - EF Core DbContext +- Cấu hình Entity sử dụng Fluent API +- Repositories triển khai interfaces domain + +#### Dịch Vụ Bên Ngoài + +##### WhatsAppCloudApiClient +HTTP client cho WhatsApp Cloud API với chính sách resilience Polly: + +Phương Thức: +- `SendMessageAsync()` - Gửi tin nhắn văn bản/media/tương tác +- `SendTemplateMessageAsync()` - Gửi templates đã phê duyệt +- `MarkMessageAsReadAsync()` - Gửi biên nhận đã đọc +- `GetMediaAsync()` - Tải xuống file media + +Resilience: +- **Retry**: 3 lần thử, backoff mũ (500ms, 1.5s, 4.5s) +- **Circuit Breaker**: Tỷ lệ lỗi 50%, lấy mẫu 30s, ngắt 30s +- **Timeout**: 10s mỗi request + +##### LlmService +Trừu tượng hóa nhà cung cấp LLM (triển khai OpenAI): + +Phương Thức: +- `GenerateResponseAsync()` - Lấy phản hồi AI với ngữ cảnh +- `ExtractIntentAsync()` - Phân loại ý định người dùng +- `StreamResponseAsync()` - Streaming cho phản hồi dài + +Tính Năng: +- Theo dõi sử dụng token +- Tính toán chi phí +- Quản lý cửa sổ ngữ cảnh (10 tin nhắn cuối) +- Bộ lọc an toàn + +## Luồng Xử Lý Tin Nhắn + +### Luồng Tin Nhắn Đến + +```mermaid +sequenceDiagram + participant WA as WhatsApp + participant Webhook as WebhooksController + participant Cmd as ProcessIncomingMessageHandler + participant AutoEngine as AutomationEngine + participant AIEngine as AIEngine + participant DB as Database + + WA->>Webhook: POST /webhooks (sự kiện tin nhắn) + Webhook->>Webhook: Xác minh chữ ký + Webhook->>Cmd: ProcessIncomingMessageCommand + Webhook-->>WA: 200 OK (ngay lập tức) + + Cmd->>DB: Lấy/Tạo Hội Thoại + Cmd->>DB: Lưu Tin Nhắn + + alt Luồng Tự Động Hoạt Động + Cmd->>AutoEngine: Kiểm tra triggers + AutoEngine->>AutoEngine: Khớp từ khóa/điều kiện + AutoEngine->>WA: Gửi phản hồi tự động + else AI Agent Hoạt Động + Cmd->>AIEngine: GenerateAIResponseCommand + AIEngine->>DB: Lấy lịch sử (10 tin nhắn cuối) + AIEngine->>AIEngine: Xây dựng prompt + AIEngine->>OpenAI: Chat completion + OpenAI-->>AIEngine: Phản hồi AI + AIEngine->>WA: Gửi tin nhắn AI + else Phản Hồi Thủ Công + Cmd->>DB: Đánh dấu hội thoại chờ xử lý + Cmd->>RabbitMQ: Phát hành event + end +``` + +### Luồng Tin Nhắn Đi + +```mermaid +sequenceDiagram + participant API as ConversationsController + participant Cmd as SendMessageHandler + participant Domain as Conversation Aggregate + participant WA as WhatsAppCloudApiClient + participant DB as Database + + API->>Cmd: SendMessageCommand + Cmd->>DB: Lấy Hội Thoại + Cmd->>Domain: CheckExpiry() + + alt Trong Cửa Sổ 24h + Domain-->>Cmd: Cửa sổ hợp lệ + Cmd->>WA: SendMessageAsync() + WA-->>Cmd: ID tin nhắn WhatsApp + Cmd->>Domain: AddMessage() + Cmd->>DB: Lưu + else Ngoài Cửa Sổ 24h + Domain-->>Cmd: Cửa sổ hết hạn + Cmd->>WA: SendTemplateMessageAsync() + WA-->>Cmd: ID tin nhắn (cửa sổ mới) + Cmd->>Domain: AddMessage() + Cmd->>DB: Lưu + end +``` + +## Mô Hình Dữ Liệu + +### Database Schema + +Xem [Tài Liệu Database Schema](DATABASE_SCHEMA.md) để biết cấu trúc bảng chi tiết và indexes. + +Các bảng chính: +- `whatsapp_accounts` - Kết nối tài khoản doanh nghiệp +- `conversations` - Hội thoại khách hàng +- `messages` - Tin nhắn riêng lẻ (thuộc sở hữu của hội thoại) +- `customers` - Hồ sơ khách hàng +- `automation_flows` - Định nghĩa luồng tự động +- `flow_steps` - Cấu hình bước luồng +- `ai_agents` - Cấu hình AI agent + +### Indexes Quan Trọng + +```sql +-- Truy vấn lưu lượng cao +CREATE INDEX idx_conversations_shop_status ON conversations(shop_id, status); +CREATE INDEX idx_messages_conversation_timestamp ON messages(conversation_id, timestamp DESC); +CREATE INDEX idx_customers_shop_waid ON customers(shop_id, wa_id); + +-- Tra cứu tự động +CREATE INDEX idx_flows_shop_active ON automation_flows(shop_id, is_active); +``` + +## Integration Events + +Dịch vụ phát hành events đến RabbitMQ để các dịch vụ khác tiêu thụ: + +### Published Events + +**WhatsAppMessageReceivedEvent** +- Phát ra khi: Khách hàng gửi tin nhắn đến shop +- Người tiêu thụ: analytics-service (số liệu), merchant-service (thông báo) + +**ConversationClosedEvent** +- Phát ra khi: Hội thoại được đóng hoặc hết hạn +- Người tiêu thụ: analytics-service (thời lượng hội thoại), merchant-service + +**AITokenUsageEvent** +- Phát ra khi: AI agent tạo phản hồi +- Người tiêu thụ: wallet-service (thanh toán), analytics-service (theo dõi chi phí) + +**CustomerOptInChangedEvent** +- Phát ra khi: Trạng thái opt-in khách hàng thay đổi +- Người tiêu thụ: dịch vụ marketing (cập nhật quyền) + +## Cân Nhắc Bảo Mật + +### Xác Minh Chữ Ký Webhook + +Tất cả webhooks đến từ WhatsApp được xác minh sử dụng HMAC-SHA256: + +```csharp +var signature = Request.Headers["X-Hub-Signature-256"]; +var payload = await ReadBodyAsStringAsync(); +var computedSignature = ComputeHmacSha256(payload, _appSecret); + +if (!SecureCompare(signature, computedSignature)) + return Unauthorized(); +``` + +### Mã Hóa Access Token + +WhatsApp access tokens được mã hóa khi lưu trữ sử dụng AES-256-GCM: + +```csharp +// Lưu trong database dưới dạng bytes đã mã hóa +public string AccessToken +{ + get => _encryption.Decrypt(_encryptedToken); + private set => _encryptedToken = _encryption.Encrypt(value); +} +``` + +### Rate Limiting + +Bộ rate limiter phân tán dựa trên Redis: +- 60 requests/phút mỗi shop +- 1000 requests/phút mỗi service instance + +### Tuân Thủ GDPR + +- Dữ liệu khách hàng có thể được xuất qua API +- Quyền bị lãng quên: xóa mềm với ẩn danh hóa dữ liệu +- Theo dõi đồng ý opt-in với timestamps +- Áp dụng chính sách lưu giữ dữ liệu + +## Tối Ưu Hóa Hiệu Suất + +### Chiến Lược Caching + +**Sử Dụng Redis Cache:** +1. **Ngữ Cảnh Hội Thoại** - 10 tin nhắn cuối (TTL: 1 giờ) +2. **Hồ Sơ Khách Hàng** - Khách hàng được truy cập thường xuyên (TTL: 30 phút) +3. **Luồng Hoạt Động** - Luồng tự động (TTL: 5 phút) +4. **Bộ Đếm Rate Limit** - Số lượng request mỗi shop (TTL: 1 phút) + +### Tối Ưu Hóa Truy Vấn + +- Sử dụng Dapper cho truy vấn đọc nhiều (bỏ qua EF Core) +- Triển khai phân trang cho tất cả list endpoints +- Index trên foreign keys và cột được lọc thường xuyên +- Không có truy vấn N+1 (sử dụng `Include()` hoặc projections) + +### Xử Lý Nền + +- Xử lý webhook trả về 200 ngay lập tức +- Gửi tin nhắn được xếp hàng đến background job +- Thực thi luồng chạy không đồng bộ + +## Monitoring & Observability + +### Health Checks + +```csharp +builder.Services.AddHealthChecks() + .AddNpgSql(connectionString, name: "postgres") + .AddRedis(redisConnection, name: "redis") + .AddRabbitMQ(rabbitConnection, name: "rabbitmq") + .AddCheck("whatsapp-api") + .AddCheck("openai-api"); +``` + +### Metrics (Prometheus) + +- `whatsapp_messages_received_total` - Counter +- `whatsapp_messages_sent_total` - Counter +- `whatsapp_conversation_duration_seconds` - Histogram +- `whatsapp_ai_tokens_used_total` - Counter +- `whatsapp_webhook_processing_duration_ms` - Histogram + +### Logging (Loki) + +Structured logging với Serilog: +- Correlation IDs Request/response +- Làm giàu với `ShopId`, `ConversationId` +- Dữ liệu nhạy cảm (tokens, messages) được che giấu + +## Kiến Trúc Triển Khai + +Xem [Hướng Dẫn Triển Khai](DEPLOYMENT.md) để biết Kubernetes manifests và chiến lược scaling. + +**Triggers Scaling:** +- CPU > 70% → Scale up pods +- Webhook queue > 1000 messages → Scale up +- Memory > 80% → Điều tra + scale + +**Giới Hạn Tài Nguyên:** +- Requests: 256Mi memory, 250m CPU +- Limits: 512Mi memory, 500m CPU ## Tài Liệu Tham Khảo - [WhatsApp Cloud API Docs](https://developers.facebook.com/docs/whatsapp/cloud-api) +- [Đặc Tả OpenAPI](../openapi.yaml) +- [Chi Tiết Domain Model](DOMAIN_MODELS.md) diff --git a/services/mkt-whatsapp-service-net/docs/vi/AUTOMATION_GUIDE.md b/services/mkt-whatsapp-service-net/docs/vi/AUTOMATION_GUIDE.md new file mode 100644 index 00000000..a27bc39d --- /dev/null +++ b/services/mkt-whatsapp-service-net/docs/vi/AUTOMATION_GUIDE.md @@ -0,0 +1,429 @@ +# Hướng Dẫn Automation + +**Cập nhật lần cuối**: 2026-01-18 + +Tìm hiểu cách tạo và quản lý luồng tự động cho hội thoại WhatsApp. + +## Tổng Quan + +Luồng tự động cho phép bạn định nghĩa logic chatbot dựa trên quy tắc mà không cần AI. Các trường hợp sử dụng bao gồm: + +- Tin nhắn chào mừng khách hàng mới +- Tự động trả lời FAQ +- Luồng xác nhận đơn hàng +- Khảo sát tiềm năng khách hàng +- Đặt lịch hẹn +- Định tuyến hỗ trợ khách hàng + +## Khái Niệm Cốt Lõi + +### Các Loại Trigger + +| Trigger | Mô Tả | Ví dụ | +|---------|-------|-------| +| **Keyword** | Tin nhắn chứa văn bản cụ thể | "hi", "help", "price" | +| **Event** | Sự kiện hệ thống xảy ra | Khách hàng opt in, đơn hàng được tạo | +| **Schedule** | Kích hoạt dựa trên thời gian | Hàng ngày lúc 9 giờ sáng, mỗi thứ Hai | + +### Các Bước Luồng + +Mỗi luồng bao gồm các bước theo thứ tự. Các loại bước: + +**1. Gửi Tin Nhắn** +- Gửi tin nhắn văn bản hoặc media +- Hỗ trợ biến: `{customer_name}`, `{shop_name}` + +**2. Trả Lời Nhanh** +- Hiển thị nút để khách hàng nhấn +- Phân nhánh đến các bước khác nhau dựa trên lựa chọn + +**3. Gắn Tag Khách Hàng** +- Thêm/xóa tags khách hàng +- Sử dụng để phân khúc + +**4. Gọi Webhook** +- POST dữ liệu đến URL bên ngoài +- Tích hợp với CRM, hệ thống kho + +**5. Gán Cho Nhân Viên** +- Chuyển hội thoại đến nhân viên +- Thoát tự động + +**6. Trì Hoãn** +- Chờ trước bước tiếp theo +- Thời gian tính bằng giây/phút/giờ + +**7. Phân Nhánh Có Điều Kiện** +- Logic if/else +- Điều kiện: tag tồn tại, giá trị trường tùy chỉnh, giờ trong ngày + +## Tạo Luồng + +### Qua API + +```bash +POST /api/v1/whatsapp/flows +Content-Type: application/json + +{ + "shopId": "shop-guid", + "flowName": "Chào Mừng Khách Hàng Mới", + "triggerType": "keyword", + "triggerConfig": { + "keywords": ["hi", "hello", "start", "chào", "xin chào"] + }, + "steps": [ + { + "order": 1, + "action": "send_message", + "actionConfig": { + "text": "Chào mừng đến {shop_name}! 👋\\n\\nChúng tôi có thể giúp gì cho bạn hôm nay?" + } + }, + { + "order": 2, + "action": "quick_reply", + "actionConfig": { + "text": "Chọn một tùy chọn:", + "buttons": [ + {"id": "browse", "title": "Xem Sản Phẩm"}, + {"id": "track", "title": "Tra Đơn Hàng"}, + {"id": "support", "title": "Hỗ Trợ"} + ] + }, + "nextStepMapping": { + "browse": 3, + "track": 5, + "support": 7 + } + }, + { + "order": 3, + "action": "send_message", + "actionConfig": { + "text": "Truy cập catalog của chúng tôi: https://shop.example.com" + } + } + ] +} +``` + +### Phản Hồi + +```json +{ + "success": true, + "data": { + "flowId": "flow-guid", + "flowName": "Chào Mừng Khách Hàng Mới", + "isActive": false, + "createdAt": "2026-01-18T10:00:00Z" + } +} +``` + +## Ví Dụ Luồng + +### Ví Dụ 1: FAQ Bot + +**Trigger**: Từ khóa "giá", "bao nhiêu", "price", "cost" + +**Luồng**: +1. Gửi: "Giá của chúng tôi phụ thuộc vào sản phẩm. Bạn quan tâm đến sản phẩm nào?" +2. Trả Lời Nhanh: ["Thời Trang", "Điện Tử", "Thực Phẩm"] +3. Điều Kiện: + - Nếu "Thời Trang" → Gửi bảng giá thời trang + - Nếu "Điện Tử" → Gửi bảng giá điện tử + - Nếu "Thực Phẩm" → Gửi bảng giá thực phẩm + +### Ví Dụ 2: Đặt Lịch Hẹn + +**Trigger**: Từ khóa "lịch hẹn", "đặt lịch", "appointment" + +**Luồng**: +1. Gửi: "Tôi có thể giúp bạn đặt lịch hẹn! 📅" +2. Gửi: "Bạn cần dịch vụ gì?" +3. Trả Lời Nhanh: ["Tư Vấn", "Kiểm Tra", "Tái Khám"] +4. Gắn Tag Khách Hàng: "appointment-pending" +5. Gọi Webhook: POST đến hệ thống đặt lịch +6. Trì Hoãn: 2 giây (chờ phản hồi webhook) +7. Gửi: "Lịch hẹn của bạn đã được xác nhận! Bạn sẽ nhận được nhắc nhở." + +### Ví Dụ 3: Tra Cứu Đơn Hàng + +**Trigger**: Từ khóa "tra", "đơn hàng", "track", "order status" + +**Luồng**: +1. Gửi: "Vui lòng gửi mã đơn hàng của bạn (ví dụ: #12345)" +2. (Khách hàng trả lời với mã đơn hàng) +3. Gọi Webhook: GET trạng thái đơn hàng từ backend +4. Điều Kiện: + - Nếu tìm thấy đơn → Gửi trạng thái + link theo dõi + - Nếu không tìm thấy → Gửi "Không tìm thấy đơn hàng. Vui lòng kiểm tra lại mã." + +## Biến + +Sử dụng biến trong văn bản tin nhắn để cá nhân hóa: + +### Biến Khách Hàng + +- `{customer_name}` - Tên khách hàng +- `{customer_phone}` - Số WhatsApp của khách hàng +- `{customer_tags}` - Tags phân cách bằng dấu phẩy + +### Biến Cửa Hàng + +- `{shop_name}` - Tên cửa hàng +- `{shop_url}` - URL website cửa hàng + +### Biến Hội Thoại + +- `{conversation_id}` - UUID hội thoại +- `{message_count}` - Số lượng tin nhắn trong hội thoại + +### Biến Tùy Chỉnh (từ phản hồi webhook) + +Webhook có thể trả về biến: + +```json +{ + "variables": { + "order_status": "Đã Gửi", + "tracking_number": "ABC123XYZ" + } +} +``` + +Sử dụng trong bước tiếp theo: +``` +Đơn hàng của bạn đang {order_status}. Theo dõi tại đây: {tracking_number} +``` + +## Điều Kiện + +### Các Điều Kiện Được Hỗ Trợ + +**Tag Tồn Tại** +```json +{ + "type": "tag_exists", + "tag": "vip-customer" +} +``` + +**Trường Tùy Chỉnh Bằng** +```json +{ + "type": "custom_field_equals", + "field": "city", + "value": "Hanoi" +} +``` + +**Giờ Trong Ngày** +```json +{ + "type": "time_of_day", + "start": "09:00", + "end": "17:00", + "timezone": "Asia/Ho_Chi_Minh" +} +``` + +**Ngày Trong Tuần** +```json +{ + "type": "day_of_week", + "days": ["monday", "tuesday", "wednesday"] +} +``` + +**Tin Nhắn Chứa** +```json +{ + "type": "message_contains", + "text": "khẩn cấp", + "case_sensitive": false +} +``` + +### Kết Hợp Điều Kiện + +Sử dụng logic AND/OR: + +```json +{ + "type": "and", + "conditions": [ + {"type": "tag_exists", "tag": "vip-customer"}, + {"type": "time_of_day", "start": "00:00", "end": "23:59"} + ] +} +``` + +## Kích Hoạt Luồng + +```bash +POST /api/v1/whatsapp/flows/{flowId}/activate +``` + +**Phản Hồi**: +```json +{ + "success": true, + "data": { + "flowId": "flow-guid", + "isActive": true, + "activatedAt": "2026-01-18T10:05:00Z" + } +} +``` + +## Ưu Tiên + +Khi nhiều luồng khớp, ưu tiên xác định luồng nào thực thi: + +1. **Khớp từ khóa chính xác** (ưu tiên cao nhất) +2. **Event triggers** +3. **Scheduled triggers** (ưu tiên thấp nhất) + +Đặt ưu tiên khi tạo luồng: + +```json +{ + "flowName": "Chào Mừng Khách Hàng VIP", + "priority": 100, + ... +} +``` + +Số lớn hơn = ưu tiên cao hơn (mặc định: 50) + +## Kiểm Tra Luồng + +### Chế Độ Kiểm Tra + +Bật chế độ kiểm tra để xem quá trình thực thi mà không gửi tin nhắn thực tế: + +```bash +POST /api/v1/whatsapp/flows/{flowId}/test +Content-Type: application/json + +{ + "shopId": "shop-guid", + "customerWaId": "84901234567", + "simulatedMessage": "xin chào" +} +``` + +**Phản Hồi**: +```json +{ + "success": true, + "data": { + "matched": true, + "executedSteps": [ + {"step": 1, "action": "send_message", "result": "Sẽ gửi: Chào mừng..."}, + {"step": 2, "action": "quick_reply", "result": "Sẽ hiển thị nút"} + ] + } +} +``` + +### Nhật Ký Debug + +Xem lịch sử thực thi luồng: + +```bash +GET /api/v1/whatsapp/flows/{flowId}/executions?limit=20 +``` + +## Thực Hành Tốt Nhất + +### 1. Giữ Luồng Đơn Giản + +- Tối đa 10 bước mỗi luồng +- Tránh lồng sâu các điều kiện +- Chia luồng phức tạp thành nhiều luồng nhỏ hơn + +### 2. Cung Cấp Điểm Thoát + +Luôn cho khách hàng cách để: +- Nói chuyện với nhân viên ("support", "help", "hỗ trợ") +- Bắt đầu lại ("restart", "menu", "khởi động lại") +- Hủy đăng ký ("stop", "unsubscribe", "dừng") + +### 3. Xử Lý Đầu Vào Không Xác Định + +Thêm bước dự phòng: +```json +{ + "order": 99, + "action": "send_message", + "actionConfig": { + "text": "Tôi không hiểu. Trả lời 'menu' để xem tùy chọn hoặc 'hỗ trợ' để nói chuyện với nhân viên." + } +} +``` + +### 4. Sử Dụng Trì Hoãn Khôn Ngoan + +- Sau lời gọi webhook: 2-5 giây +- Giữa các tin nhắn: 1-2 giây (tự nhiên hơn) +- Tránh trì hoãn > 10 giây (khách hàng có thể rời đi) + +### 5. Kiểm Thử A/B + +Tạo hai phiên bản của luồng: + +- Luồng A: Gửi biến thể tin nhắn A +- Luồng B: Gửi biến thể tin nhắn B + +Định tuyến 50% lưu lượng cho mỗi luồng, đo lường: +- Tỷ lệ phản hồi +- Tỷ lệ chuyển đổi +- Thời gian giải quyết + +## Giới Hạn + +- Tối đa 50 luồng hoạt động mỗi cửa hàng +- Tối đa 20 bước mỗi luồng +- Tối đa 10 nút trả lời nhanh mỗi tin nhắn +- Timeout webhook: 10 giây +- Không có vòng lặp (xác thực chống chu trình) + +## Khắc Phục Sự Cố + +### Luồng Không Kích Hoạt + +**Kiểm Tra**: +1. Luồng đã được kích hoạt (`isActive: true`) +2. Từ khóa trigger khớp chính xác (không phân biệt chữ hoa/thường) +3. Không có luồng ưu tiên cao hơn khớp trước +4. Khách hàng chưa hủy đăng ký + +### Webhook Thất Bại + +**Kiểm Tra**: +1. URL webhook có thể truy cập (yêu cầu HTTPS) +2. Webhook phản hồi trong vòng 10 giây +3. Mã trạng thái phản hồi là 200 +4. JSON phản hồi hợp lệ + +### Biến Không Được Thay Thế + +**Kiểm Tra**: +1. Cú pháp biến đúng: `{variable_name}` +2. Biến được định nghĩa (customer_name tồn tại cho khách hàng) +3. Webhook trả về các biến mong đợi + +## Bước Tiếp Theo + +- [Hướng Dẫn AI Chatbot](AI_CHATBOT_GUIDE.md) - Kết hợp với AI cho cách tiếp cận lai +- [Tài Liệu API](API.md) - Tham chiếu API đầy đủ +- [Kiến Trúc](ARCHITECTURE.md) - Hiểu về công cụ tự động + +## Tài Nguyên + +- [Giao Diện Flow Builder](https://platform.goodgo.com/whatsapp/flows) (nếu có) +- [Hướng Dẫn Tích Hợp Webhook](WEBHOOK_INTEGRATION.md) diff --git a/services/mkt-whatsapp-service-net/docs/vi/WHATSAPP_SETUP.md b/services/mkt-whatsapp-service-net/docs/vi/WHATSAPP_SETUP.md new file mode 100644 index 00000000..af16c7d7 --- /dev/null +++ b/services/mkt-whatsapp-service-net/docs/vi/WHATSAPP_SETUP.md @@ -0,0 +1,296 @@ +# Hướng Dẫn Thiết Lập WhatsApp + +**Cập nhật lần cuối**: 2026-01-18 + +Hướng dẫn này hướng dẫn bạn thiết lập quyền truy cập WhatsApp Business API cho MKT WhatsApp Service. + +## Yêu Cầu Tiên Quyết + +- Tài khoản Meta Business +- Quyền truy cập Facebook Business Manager +- Doanh nghiệp đã xác minh (cho giới hạn tier cao hơn) +- Domain với HTTPS (cho webhook) + +## Bước 1: Tạo Tài Khoản Meta Business + +1. Truy cập [Meta Business Suite](https://business.facebook.com/) +2. Nhấp "Create Account" +3. Nhập tên doanh nghiệp và thông tin chi tiết +4. Xác minh email doanh nghiệp của bạn + +## Bước 2: Truy Cập WhatsApp API + +### Tùy Chọn A: Cloud API (Khuyến Nghị) + +1. Truy cập [Meta for Developers](https://developers.facebook.com/) +2. Nhấp "My Apps" → "Create App" +3. Chọn "Business" làm loại app +4. Điền thông tin app (tên, email liên hệ, tài khoản doanh nghiệp) +5. Sau khi tạo, nhấp "Add Product" +6. Chọn "WhatsApp" → "Set Up" + +### Tùy Chọn B: On-Premise API + +Không được khuyến nghị cho hầu hết các trường hợp sử dụng. Yêu cầu cơ sở hạ tầng máy chủ chuyên dụng và hợp tác BSP. + +## Bước 3: Lấy Số Điện Thoại + +### Số Điện Thoại Thử Nghiệm (Development) + +Meta cung cấp số thử nghiệm cho phát triển: + +1. Trong cài đặt sản phẩm WhatsApp, bạn sẽ thấy một số điện thoại thử nghiệm +2. Sao chép `Phone Number ID` +3. Thêm người nhận thử nghiệm (tối đa 5) trong tab Configuration + +### Số Điện Thoại Production + +1. Nhấp "Add Phone Number" +2. Chọn một trong hai: + - **Use existing**: Di chuyển số WhatsApp Business hiện có + - **Register new**: Lấy số mới từ Meta +3. Xác minh số điện thoại qua SMS/cuộc gọi +4. Hoàn tất xác minh doanh nghiệp + +**Quan Trọng**: Sau khi kết nối với API, bạn không thể sử dụng Ứng dụng WhatsApp Business trên số này. + +## Bước 4: Tạo Access Token + +### Token Tạm Thời (24 giờ) + +1. Truy cập WhatsApp → API Setup +2. Sao chép access token tạm thời +3. Chỉ sử dụng để thử nghiệm + +### Token Vĩnh Viễn + +1. Truy cập Meta Business Suite → Settings → System Users +2. Nhấp "Add" → Tạo system user (tên: "WhatsApp API") +3. Gán vai trò "Admin" +4. Nhấp "Generate Token" +5. Chọn app của bạn +6. Chọn quyền: + - `whatsapp_business_management` + - `whatsapp_business_messaging` +7. Sao chép token (lưu trữ an toàn, chỉ hiển thị một lần) + +## Bước 5: Cấu Hình Webhook + +### Lấy Webhook URL + +Từ dịch vụ đã triển khai của bạn: +``` +https://yourdomain.com/api/v1/whatsapp/webhooks +``` + +### Tạo Verify Token + +Tạo chuỗi ngẫu nhiên để xác minh webhook: + +```bash +# Tạo token ngẫu nhiên +openssl rand -hex 32 +``` + +Lưu điều này dưới dạng `WHATSAPP_WEBHOOK_VERIFY_TOKEN` trong `.env` của bạn + +### Thiết Lập Trong Meta + +1. Truy cập WhatsApp → Configuration → Webhook +2. Nhấp "Edit" +3. Nhập: + - **Callback URL**: `https://yourdomain.com/api/v1/whatsapp/webhooks` + - **Verify Token**: Token bạn đã tạo +4. Nhấp "Verify and Save" + +### Đăng Ký Sự Kiện + +Sau khi xác minh, đăng ký: +- ✅ `messages` - Tin nhắn khách hàng đến +- ✅ `message_status` (tùy chọn) - Cập nhật trạng thái gửi/đã đọc +- ✅ `messaging_postbacks` (tùy chọn) - Tương tác nút + +## Bước 6: Lấy App Secret + +Để xác minh chữ ký webhook: + +1. Truy cập App Dashboard → Settings → Basic +2. Nhấp "Show" bên cạnh "App Secret" +3. Sao chép và lưu dưới dạng `WHATSAPP_APP_SECRET` + +## Bước 7: Cấu Hình Dịch Vụ + +Cập nhật file `.env` của bạn: + +```bash +# WhatsApp Configuration +WHATSAPP_PHONE_NUMBER_ID=123456789012345 +WHATSAPP_ACCESS_TOKEN=your_permanent_token_here +WHATSAPP_WEBHOOK_VERIFY_TOKEN=your_verify_token_here +WHATSAPP_APP_SECRET=your_app_secret_here +WHATSAPP_API_VERSION=v21.0 +``` + +## Bước 8: Kiểm Tra Tích Hợp + +### Xác Minh Webhook + +Dịch vụ sẽ tự động xử lý xác minh webhook. Kiểm tra logs: + +```bash +docker-compose logs -f mkt-whatsapp-service-net +``` + +Bạn nên thấy: +``` +[INFO] Webhook verification successful +``` + +### Gửi Tin Nhắn Thử Nghiệm + +1. Lấy số WhatsApp của khách hàng thử nghiệm +2. Sử dụng API để gửi tin nhắn: + +```bash +curl -X POST http://localhost/api/v1/whatsapp/conversations/{conversationId}/messages \ + -H "Content-Type: application/json" \ + -d '{ + "content": { + "type": "text", + "text": "Xin chào từ MKT WhatsApp Service!" + } + }' +``` + +### Nhận Tin Nhắn Thử Nghiệm + +1. Gửi tin nhắn từ WhatsApp của khách hàng thử nghiệm đến số doanh nghiệp của bạn +2. Kiểm tra service logs cho webhook đến +3. Xác minh tin nhắn được lưu trữ trong database + +## Bước 9: Message Templates + +Đối với tin nhắn ngoài cửa sổ 24 giờ, bạn cần templates đã phê duyệt. + +### Tạo Template + +1. Truy cập WhatsApp → Message Templates +2. Nhấp "Create Template" +3. Điền: + - **Name**: `order_confirmation` (chữ thường, chỉ dấu gạch dưới) + - **Category**: Utility/Marketing/Authentication + - **Language**: Vietnamese, English, v.v. + - **Content**: Sử dụng placeholders như `{{1}}`, `{{2}}` + +Ví dụ template: +``` +Xin chào {{1}}! + +Đơn hàng #{{2}} của bạn đã được xác nhận. +Tổng tiền: {{3}} VNĐ + +Cảm ơn bạn đã mua hàng! +``` + +4. Gửi để xem xét (phê duyệt mất 1-3 ngày) + +### Sử Dụng Template Trong Dịch Vụ + +Sau khi được phê duyệt, cập nhật `.env`: +```bash +WHATSAPP_TEMPLATE_ORDER_CONFIRMATION=order_confirmation +``` + +## Bước 10: Nâng Cấp Giới Hạn Tier + +### Tier Ban Đầu + +Số điện thoại mới bắt đầu ở **Tier 1** (1.000 cuộc hội thoại/ngày). + +### Quy Trình Nâng Cấp + +Tier tự động nâng cấp dựa trên: +1. **Chất lượng số điện thoại** (tỷ lệ chặn thấp) +2. **Khối lượng gửi** +3. **Thời gian** (tối thiểu 7 ngày ở tier hiện tại) + +### Các Mức Tier + +| Tier | Giới Hạn Hàng Ngày | Tiêu Chí Nâng Cấp | +|------|-------------------|-------------------| +| Tier 1 | 1.000 | Tier khởi đầu | +| Tier 2 | 10.000 | 7 ngày + chất lượng tốt | +| Tier 3 | 100.000 | 7 ngày + khối lượng cao | +| Unlimited | Không giới hạn | Yêu cầu từ Meta | + +## Khắc Phục Sự Cố + +### Xác Minh Webhook Thất Bại + +**Vấn Đề**: "Verification token mismatch" + +**Giải Pháp**: +1. Kiểm tra `WHATSAPP_WEBHOOK_VERIFY_TOKEN` khớp chính xác +2. Đảm bảo dịch vụ đang chạy và có thể truy cập +3. Kiểm tra HTTPS hoạt động (WhatsApp yêu cầu HTTPS) + +### Tin Nhắn Không Gửi Được + +**Vấn Đề**: API trả về lỗi `(#131030) Recipient phone number not valid` + +**Giải Pháp**: +1. Đảm bảo số bao gồm mã quốc gia không có + hoặc 0 +2. Định dạng: `84901234567` (Vietnam), không phải `+84901234567` + +**Vấn Đề**: `(#368) Template not found` + +**Giải Pháp**: +1. Xác minh template đã được phê duyệt trong Meta dashboard +2. Kiểm tra tên template khớp chính xác +3. Đảm bảo mã ngôn ngữ đúng + +### Vượt Giới Hạn Tốc Độ + +**Vấn Đề**: `(#130429) Rate limit exceeded` + +**Giải Pháp**: +1. Kiểm tra tier hiện tại trong Meta dashboard +2. Triển khai exponential backoff +3. Yêu cầu nâng cấp tier nếu cần + +### Access Token Không Hợp Lệ + +**Vấn Đề**: `(#190) Invalid OAuth access token` + +**Giải Pháp**: +1. Token có thể đã hết hạn - tạo token vĩnh viễn mới +2. Kiểm tra token có quyền đúng +3. Xác minh token thuộc về app đúng + +## Thực Hành Bảo Mật Tốt Nhất + +1. **Không bao giờ commit tokens** - Sử dụng biến môi trường +2. **Xoay tokens thường xuyên** - Tạo tokens mới mỗi 6 tháng +3. **Xác minh chữ ký webhook** - Luôn xác thực `X-Hub-Signature-256` +4. **Chỉ sử dụng HTTPS** - WhatsApp sẽ từ chối webhooks HTTP +5. **Hạn chế truy cập IP** - Whitelist dải IP của Meta nếu có thể + +## Tối Ưu Hóa Chi Phí + +1. **Sử dụng utility templates** - Rẻ hơn marketing +2. **Tận dụng cửa sổ 24 giờ** - Tin nhắn miễn phí trong cửa sổ +3. **Tránh spam** - Tỷ lệ chặn cao có thể giới hạn tài khoản của bạn +4. **Theo dõi hội thoại** - Theo dõi loại nào mở/đóng cửa sổ + +## Bước Tiếp Theo + +- [Tài Liệu API](API.md) - Tìm hiểu các endpoints có sẵn +- [Hướng Dẫn Automation](AUTOMATION_GUIDE.md) - Thiết lập luồng tự động +- [Hướng Dẫn AI Chatbot](AI_CHATBOT_GUIDE.md) - Cấu hình AI agent + +## Tài Nguyên + +- [WhatsApp Cloud API Docs](https://developers.facebook.com/docs/whatsapp/cloud-api) +- [Business Verification](https://www.facebook.com/business/help/2058515294227817) +- [Hướng Dẫn Message Templates](https://developers.facebook.com/docs/whatsapp/business-management-api/message-templates) +- [Tham Chiếu Webhook](https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks) diff --git a/services/mkt-x-service-net/README.md b/services/mkt-x-service-net/README.md index c22bb318..c6823328 100644 --- a/services/mkt-x-service-net/README.md +++ b/services/mkt-x-service-net/README.md @@ -1,8 +1,9 @@ # MKT X/Twitter Service -## Twitter Marketing Service / Dịch Vụ Marketing Twitter -> **EN**: Comprehensive marketing automation and customer engagement service for X/Twitter -> **VI**: Dịch vụ tự động hóa marketing và tương tác khách hàng toàn diện cho X/Twitter +> **EN**: [English Documentation](docs/en/README.md) +> **VI**: [Tài liệu Tiếng Việt](docs/vi/README.md) + +Comprehensive marketing automation and customer engagement service for X/Twitter. [![.NET](https://img.shields.io/badge/.NET-8.0-512BD4)](https://dotnet.microsoft.com/) [![PostgreSQL](https://img.shields.io/badge/PostgreSQL-15+-336791)](https://www.postgresql.org/) @@ -10,67 +11,61 @@ --- -## Overview / Tổng Quan +## Overview -**EN**: The Twitter Marketing Service provides three core capabilities for social media marketing through X/Twitter: +The Twitter Marketing Service provides three core capabilities for social media marketing through X/Twitter: - **CHATBOT Automation** - Template-based messaging with workflows and scheduling - **CHATBOT AI** - AI-powered conversations using OpenAI integration - **Customer Management** - Contact database, segmentation, and analytics -**VI**: Dịch vụ Twitter Marketing cung cấp ba khả năng cốt lõi cho marketing trên X/Twitter: - -- **CHATBOT Tự Động** - Gửi tin nhắn dựa trên template với workflows và lịch trình -- **CHATBOT AI** - Trò chuyện thông minh sử dụng OpenAI -- **Quản Lý Khách Hàng** - Cơ sở dữ liệu liên hệ, phân khúc, và phân tích - --- -## Features / Tính Năng +## Features ### 🤖 Automation Messenger -- ✅ Message template library / Thư viện mẫu tin nhắn -- ✅ Visual workflow designer / Thiết kế workflow trực quan -- ✅ Event-triggered messaging / Tin nhắn kích hoạt sự kiện -- ✅ Scheduled campaigns / Chiến dịch theo lịch -- ✅ A/B testing / Kiểm thử A/B -- ✅ Rate limiting compliance / Tuân thủ giới hạn tốc độ +- ✅ Message template library +- ✅ Visual workflow designer +- ✅ Event-triggered messaging +- ✅ Scheduled campaigns +- ✅ A/B testing +- ✅ Rate limiting compliance ### 🧠 AI Messenger -- ✅ Natural language understanding / Hiểu ngôn ngữ tự nhiên -- ✅ Context-aware conversations / Trò chuyện theo ngữ cảnh -- ✅ Intent detection / Phát hiện ý định -- ✅ Integration with merchant data / Tích hợp dữ liệu merchant -- ✅ Auto escalation to human / Tự động chuyển cho người -- ✅ Sentiment analysis / Phân tích cảm xúc +- ✅ Natural language understanding +- ✅ Context-aware conversations +- ✅ Intent detection +- ✅ Integration with merchant data +- ✅ Auto escalation to human +- ✅ Sentiment analysis ### 👥 Customer Management -- ✅ Contact profile management / Quản lý hồ sơ liên hệ -- ✅ Conversation history / Lịch sử trò chuyện -- ✅ Customer segmentation / Phân khúc khách hàng -- ✅ Tag management / Quản lý nhãn -- ✅ Custom attributes / Thuộc tính tùy chỉnh -- ✅ Engagement analytics / Phân tích tương tác +- ✅ Contact profile management +- ✅ Conversation history +- ✅ Customer segmentation +- ✅ Tag management +- ✅ Custom attributes +- ✅ Engagement analytics --- -## Prerequisites / Yêu Cầu +## Prerequisites | Requirement | Version | Notes | |-------------|---------|-------| | **.NET SDK** | 8.0+ | [Download](https://dotnet.microsoft.com/download) | -| **PostgreSQL** | 15+ | For data storage / Lưu trữ dữ liệu | -| **Redis** | 7+ | For caching / Cache | -| **RabbitMQ** | 3.12+ | For message bus / Message bus | -| **Twitter Developer Account** | - | Required for API / Cần cho API | -| **OpenAI API Key** | - | Optional for AI / Tùy chọn cho AI | +| **PostgreSQL** | 15+ | For data storage | +| **Redis** | 7+ | For caching | +| **RabbitMQ** | 3.12+ | For message bus | +| **Twitter Developer Account** | - | Required for API | +| **OpenAI API Key** | - | Optional for AI | --- -## Quick Start / Bắt Đầu Nhanh +## Quick Start ### 1. Clone Repository @@ -78,7 +73,7 @@ cd services/mkt-x-service-net ``` -### 2. Configure Environment / Cấu Hình +### 2. Configure Environment Create `appsettings.Development.json`: @@ -108,13 +103,13 @@ Create `appsettings.Development.json`: } ``` -### 3. Run Migrations / Chạy Migrations +### 3. Run Migrations ```bash dotnet ef database update --project src/MktXService.Infrastructure ``` -### 4. Run Service / Chạy Service +### 4. Run Service ```bash dotnet run --project src/MktXService.API @@ -126,19 +121,22 @@ dotnet run --project src/MktXService.API --- -## Documentation / Tài Liệu +## Documentation + +> **EN**: [English Documentation](docs/en/README.md) +> **VI**: [Tài liu Tiếng Việt](docs/vi/README.md) ### English Documentation -- **[Architecture](docs/ARCHITECTURE.md)** - System architecture and domain model -- **[API Reference](docs/API.md)** - Complete API documentation with examples -- **[Twitter Setup Guide](docs/TWITTER_SETUP.md)** - Step-by-step Twitter API setup +- **[Architecture](docs/en/ARCHITECTURE.md)** - System architecture and domain model +- **[API Reference](docs/en/API.md)** - Complete API documentation with examples +- **[Twitter Setup Guide](docs/en/TWITTER_SETUP.md)** - Step-by-step Twitter API setup -### Vietnamese Documentation / Tài Liệu Tiếng Việt +### Vietnamese Documentation -- **[Kiến Trúc](docs/vi/ARCHITECTURE.md)** - Kiến trúc hệ thống và mô hình domain +- **[Kiến Trúc](docs/vi/KIEN-TRUC.md)** - Kiến trúc hệ thống và mô hình domain - **[Tài Liệu API](docs/vi/API.md)** - Tài liệu API đầy đủ với ví dụ -- **[Hướng Dẫn Thiết Lập Twitter](docs/vi/TWITTER_SETUP.md)** - Hướng dẫn thiết lập Twitter API +- **[Hướng Dẫn Thiết Lập Twitter](docs/vi/CAI-DAT-TWITTER.md)** - Hướng dẫn thiết lập Twitter API từng bước --- @@ -179,7 +177,7 @@ GET /api/v1/mkt-x/analytics/overview # Dashboard analytics --- -## Project Structure / Cấu Trúc +## Project Structure ``` mkt-x-service-net/ @@ -206,7 +204,7 @@ mkt-x-service-net/ --- -## Development / Phát Triển +## Development ### Build @@ -241,7 +239,7 @@ docker-compose -f deployments/local/docker-compose.yml logs -f mkt-x-service-net --- -## Architecture / Kiến Trúc +## Architecture ### Clean Architecture Layers @@ -264,11 +262,11 @@ docker-compose -f deployments/local/docker-compose.yml logs -f mkt-x-service-net - **Repository Pattern** for data access - **Event-Driven** with RabbitMQ -**Details**: See [ARCHITECTURE.md](docs/ARCHITECTURE.md) +**Details**: See [ARCHITECTURE.md](docs/en/ARCHITECTURE.md) --- -## Configuration / Cấu Hình +## Configuration ### Environment Variables @@ -294,7 +292,7 @@ Redis__ConnectionString="localhost:6379" --- -## Monitoring / Giám Sát +## Monitoring ### Health Check @@ -325,9 +323,9 @@ Structured logging with Serilog, sent to Loki: --- -##Troubleshooting / Xử Lý Sự Cố +##Troubleshooting -### Common Issues / Vấn Đề Thường Gặp +### Common Issues #### 1. Twitter API 401 Unauthorized @@ -351,11 +349,11 @@ Structured logging with Serilog, sent to Loki: - Ensure firewall allows inbound traffic - Review webhook signature validation -**Details**: See [TWITTER_SETUP.md](docs/TWITTER_SETUP.md) +**Details**: See [TWITTER_SETUP.md](docs/en/TWITTER_SETUP.md) --- -## Performance / Hiệu Năng +## Performance ### Targets @@ -376,7 +374,7 @@ Segments: 5 minutes TTL --- -## Security / Bảo Mật +## Security - ✅ OAuth tokens encrypted at rest - ✅ JWT authentication for API @@ -386,27 +384,27 @@ Segments: 5 minutes TTL --- -## Contributing / Đóng Góp +## Contributing See [GoodGo Contributing Guide](../../docs/CONTRIBUTING.md) --- -## Support / Hỗ Trợ +## Support - **Documentation Issues**: Open issue on GitHub - **API Support**: api-support@goodgo.com -- **Twitter Integration**: See [TWITTER_SETUP.md](docs/TWITTER_SETUP.md) +- **Twitter Integration**: See [TWITTER_SETUP.md](docs/en/TWITTER_SETUP.md) --- -## License / Giấy Phép +## License MIT License - See LICENSE file for details --- -## Related Services / Dịch Vụ Liên Quan +## Related Services - [MKT Facebook Service](../mkt-facebook-service-net) - Facebook Messenger marketing - [MKT Zalo Service](../mkt-zalo-service-net) - Zalo OA marketing @@ -414,7 +412,7 @@ MIT License - See LICENSE file for details --- -## Technology Stack / Công Nghệ +## Technology Stack | Component | Technology | Version | |-----------|-----------|---------| @@ -430,7 +428,7 @@ MIT License - See LICENSE file for details --- -##References / Tham Khảo +##References - [Twitter API v2 Documentation](https://developer.twitter.com/en/docs/twitter-api) - [OpenAI API Documentation](https://platform.openai.com/docs) diff --git a/services/mkt-x-service-net/docs/vi/API.md b/services/mkt-x-service-net/docs/vi/API.md new file mode 100644 index 00000000..cad3877d --- /dev/null +++ b/services/mkt-x-service-net/docs/vi/API.md @@ -0,0 +1,1435 @@ +# 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 diff --git a/services/mkt-x-service-net/docs/vi/README.md b/services/mkt-x-service-net/docs/vi/README.md new file mode 100644 index 00000000..53ea5d2f --- /dev/null +++ b/services/mkt-x-service-net/docs/vi/README.md @@ -0,0 +1,422 @@ +# Dịch Vụ MKT X/Twitter + +## Tổng Quan + +Dịch Vụ Marketing X/Twitter cung cấp ba khả năng cốt lõi cho marketing trên mạng xã hội X/Twitter: + +- **CHATBOT Tự Động** - Gửi tin nhắn dựa trên template với workflows và lịch trình +- **CHATBOT AI** - Trò chuyện được hỗ trợ AI sử dụng tích hợp OpenAI +- **Quản Lý Khách Hàng** - CRM hoàn chỉnh cho liên hệ Twitter với phân khúc và phân tích + +--- + +## Tính Năng + +### 🤖 Automation Messenger + +- ✅ Thư viện mẫu tin nhắn +- ✅ Thiết kế workflow trực quan +- ✅ Tin nhắn kích hoạt sự kiện +- ✅ Chiến dịch theo lịch +- ✅ Kiểm thử A/B +- ✅ Tuân thủ giới hạn tốc độ + +### 🧠 AI Messenger + +- ✅ Hiểu ngôn ngữ tự nhiên +- ✅ Trò chuyện theo ngữ cảnh +- ✅ Phát hiện ý định +- ✅ Tích hợp dữ liệu merchant +- ✅ Tự động chuyển cho người +- ✅ Phân tích cảm xúc + +### 👥 Customer Management + +- ✅ Quản lý hồ sơ liên hệ +- ✅ Lịch sử trò chuyện +- ✅ Phân khúc khách hàng +- ✅ Quản lý nhãn +- ✅ Thuộc tính tùy chỉnh +- ✅ Phân tích tương tác + +--- + +## Yêu Cầu + +| Yêu Cầu | Phiên Bản | Ghi Chú | +|----------|-----------|---------| +| **.NET SDK** | 8.0+ | [Tải xuống](https://dotnet.microsoft.com/download) | +| **PostgreSQL** | 15+ | Để lưu trữ dữ liệu | +| **Redis** | 7+ | Để cache | +| **RabbitMQ** | 3.12+ | Để message bus | +| **Tài Khoản Twitter Developer** | - | Cần cho API | +| **OpenAI API Key** | - | Tùy chọn cho AI | + +--- + +## Bắt Đầu Nhanh + +### 1. Clone Repository + +```bash +cd services/mkt-x-service-net +``` + +### 2. Cấu Hình + +Tạo `appsettings.Development.json`: + +```json +{ + "ConnectionStrings": { + "DefaultConnection": "Host=localhost;Database=mkt_x_service;Username=postgres;Password=postgres" + }, + "Twitter": { + "ApiKey": "your_twitter_api_key", + "ApiKeySecret": "your_twitter_api_secret", + "BearerToken": "your_bearer_token", + "WebhookUrl": "https://your-domain.com/api/v1/mkt-x/webhooks/twitter" + }, + "OpenAI": { + "ApiKey": "your_openai_api_key", + "Model": "gpt-4" + }, + "RabbitMQ": { + "Host": "localhost", + "Username": "guest", + "Password": "guest" + }, + "Redis": { + "ConnectionString": "localhost:6379" + } +} +``` + +### 3. Chạy Migrations + +```bash +dotnet ef database update --project src/MktXService.Infrastructure +``` + +### 4. Chạy Service + +```bash +dotnet run --project src/MktXService.API +``` + +**Điểm Truy Cập**: +- API: http://localhost:5000 +- Swagger: http://localhost:5000/swagger + +--- + +## Tài Liệu + +### Tài Liệu Tiếng Việt + +- **[Kiến Trúc](KIEN-TRUC.md)** - Kiến trúc hệ thống và mô hình domain +- **[Tài Liệu API](API.md)** - Tài liệu API đầy đủ với ví dụ +- **[Hướng Dẫn Thiết Lập Twitter](CAI-DAT-TWITTER.md)** - Hướng dẫn thiết lập Twitter API từng bước + +### English Documentation + +- **[Architecture](../en/ARCHITECTURE.md)** - System architecture and domain model +- **[API Reference](../en/API.md)** - Complete API documentation with examples +- **[Twitter Setup Guide](../en/TWITTER_SETUP.md)** - Step-by-step Twitter API setup + +--- + +## API Endpoints + +### Core Endpoints + +``` +# Quản Lý Tài Khoản +POST /api/v1/mkt-x/accounts # Kết nối tài khoản Twitter +GET /api/v1/mkt-x/accounts # Danh sách tài khoản +DELETE /api/v1/mkt-x/accounts/{id} # Ngắt kết nối + +# Quản Lý Liên Hệ +GET /api/v1/mkt-x/contacts # Danh sách liên hệ +POST /api/v1/mkt-x/contacts/{id}/tags # Thêm nhãn +PUT /api/v1/mkt-x/contacts/{id}/attributes # Cập nhật thuộc tính + +# Hội Thoại +GET /api/v1/mkt-x/conversations # Danh sách hội thoại +POST /api/v1/mkt-x/conversations/{id}/messages # Gửi tin nhắn + +# Chiến Dịch +POST /api/v1/mkt-x/campaigns # Tạo chiến dịch +POST /api/v1/mkt-x/campaigns/{id}/start # Bắt đầu chiến dịch +GET /api/v1/mkt-x/campaigns/{id}/metrics # Xem số liệu + +# Tự Động Hóa +POST /api/v1/mkt-x/automation/flows # Tạo workflow +POST /api/v1/mkt-x/automation/flows/{id}/activate # Kích hoạt + +# AI Chatbot +POST /api/v1/mkt-x/ai/conversations/{id}/message # Trò chuyện AI +GET /api/v1/mkt-x/analytics/overview # Phân tích dashboard +``` + +**Tài liệu API đầy đủ**: Xem [API.md](API.md) + +--- + +## Cấu Trúc Dự Án + +``` +mkt-x-service-net/ +├── src/ +│ ├── MktXService.API/ # Controllers, Swagger +│ │ ├── Controllers/ # API Controllers +│ │ └── Application/ # Commands, Queries, DTOs +│ ├── MktXService.Domain/ # Mô hình domain +│ │ ├── AggregatesModel/ # Aggregates +│ │ ├── Events/ # Domain events +│ │ └── SeedWork/ # Base classes +│ └── MktXService.Infrastructure/ # EF Core, Repositories +│ ├── Data/ # DbContext +│ ├── Repositories/ # Truy cập dữ liệu +│ ├── Services/ # External clients +│ └── BackgroundJobs/ # Background workers +├── tests/ +│ ├── MktXService.UnitTests/ +│ └── MktXService.IntegrationTests/ +├── docs/ # Tài liệu +├── Dockerfile +└── docker-compose.yml +``` + +--- + +## Phát Triển + +### Build + +```bash +dotnet build +``` + +### Chạy Tests + +```bash +dotnet test +``` + +### Tạo Migration + +```bash +dotnet ef migrations add MigrationName --project src/MktXService.Infrastructure +``` + +### Triển Khai Docker + +```bash +# Build +docker-compose -f deployments/local/docker-compose.yml build mkt-x-service-net + +# Chạy +docker-compose -f deployments/local/docker-compose.yml up -d mkt-x-service-net + +# Logs +docker-compose -f deployments/local/docker-compose.yml logs -f mkt-x-service-net +``` + +--- + +## Kiến Trúc + +### Các Tầng Clean Architecture + +``` +┌─────────────────────────────────────┐ +│ Tầng API (Controllers) │ +├─────────────────────────────────────┤ +│ Tầng Application (CQRS + MediatR) │ +├─────────────────────────────────────┤ +│ Tầng Domain (Aggregates) │ +├─────────────────────────────────────┤ +│ Infrastructure (EF Core, Twitter) │ +└─────────────────────────────────────┘ +``` + +### Patterns Chính + +- **CQRS** với MediatR để tách command/query +- **DDD** với 9 aggregate roots +- **Repository Pattern** cho truy cập dữ liệu +- **Event-Driven** với RabbitMQ + +**Chi tiết**: Xem [KIEN-TRUC.md](KIEN-TRUC.md) + +--- + +## Cấu Hình + +### Biến Môi Trường + +```bash +# Database +ConnectionStrings__DefaultConnection="Host=localhost;Database=mkt_x_service" + +# Twitter API +Twitter__ApiKey="your_api_key" +Twitter__ApiKeySecret="your_api_secret" +Twitter__WebhookUrl="https://your-domain.com/api/v1/mkt-x/webhooks/twitter" + +# OpenAI +OpenAI__ApiKey="sk-..." +OpenAI__Model="gpt-4" + +# RabbitMQ +RabbitMQ__Host="localhost" + +# Redis +Redis__ConnectionString="localhost:6379" +``` + +--- + +## Giám Sát + +### Health Check + +```bash +curl http://localhost:5000/health +``` + +### Metrics + +- **Prometheus**: `http://localhost:5000/metrics` +- **Grafana Dashboard**: Có sẵn trong production + +### Logging + +Structured logging với Serilog, gửi đến Loki: + +```json +{ + "timestamp": "2026-01-18T10:00:00Z", + "level": "Information", + "message": "Chiến dịch đã bắt đầu", + "properties": { + "campaignId": "...", + "merchantId": "..." + } +} +``` + +--- + +## Xử Lý Sự Cố + +### Vấn Đề Thường Gặp + +#### 1. Twitter API 401 Unauthorized + +**Giải pháp**: +- Xác minh API credentials trong cấu hình +- Kiểm tra OAuth token expiration +- Đảm bảo app có quyền Direct Messages + +#### 2. Lỗi Kết Nối Database + +**Giải pháp**: +- Kiểm tra PostgreSQL đang chạy +- Xác minh connection string +- Đảm bảo database tồn tại: `createdb mkt_x_service` + +#### 3. Không Nhận Được Webhook Events + +**Giải pháp**: +- Xác minh webhook đã đăng ký trong Twitter +- Kiểm tra HTTPS certificate hợp lệ +- Đảm bảo firewall cho phép inbound traffic +- Xem xét webhook signature validation + +**Chi tiết**: Xem [CAI-DAT-TWITTER.md](CAI-DAT-TWITTER.md) + +--- + +## Hiệu Năng + +### Mục Tiêu + +| Chỉ Số | Mục Tiêu | +|--------|----------| +| API Response (P95) | < 500ms | +| Xử Lý Tin Nhắn | 100 msg/giây | +| Thông Lượng Campaign | 10,000 liên hệ/phút | +| Database Query (P95) | < 100ms | + +### Caching + +``` +Hồ Sơ Liên Hệ: 1 giờ TTL +Templates: 10 phút TTL +Segments: 5 phút TTL +``` + +--- + +## Bảo Mật + +- ✅ OAuth tokens được mã hóa khi lưu trữ +- ✅ JWT authentication cho API +- ✅ RBAC cho cô lập merchant +- ✅ Xác thực đầu vào với FluentValidation +- ✅ Tuân thủ GDPR (lưu trữ dữ liệu, xóa dữ liệu) + +--- + +## Đóng Góp + +Xem [GoodGo Contributing Guide](../../docs/CONTRIBUTING.md) + +--- + +## Hỗ Trợ + +- **Vấn Đề Tài Liệu**: Mở issue trên GitHub +- **Hỗ Trợ API**: api-support@goodgo.com +- **Tích Hợp Twitter**: Xem [CAI-DAT-TWITTER.md](CAI-DAT-TWITTER.md) + +--- + +## Giấy Phép + +MIT License - Xem file LICENSE để biết chi tiết + +--- + +## Dịch Vụ Liên Quan + +- [MKT Facebook Service](../../mkt-facebook-service-net) - Facebook Messenger marketing +- [MKT Zalo Service](../../mkt-zalo-service-net) - Zalo OA marketing +- [MKT WhatsApp Service](../../mkt-whatsapp-service-net) - WhatsApp Business marketing + +--- + +## Công Nghệ + +| Component | Technology | Version | +|-----------|-----------|---------| +| Runtime | .NET | 8.0+ | +| Framework | ASP.NET Core | 8.0+ | +| ORM | Entity Framework Core | 8.0+ | +| Database | PostgreSQL | 15+ | +| Cache | Redis | 7+ | +| Message Broker | RabbitMQ | 3.12+ | +| Mediator | MediatR | 12+ | +| API Gateway | Traefik | 2.10+ | +| Monitoring | Prometheus + Grafana | - | + +--- + +## Tham Khảo + +- [Twitter API v2 Documentation](https://developer.twitter.com/en/docs/twitter-api) +- [OpenAI API Documentation](https://platform.openai.com/docs) +- [Clean Architecture](https://docs.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/common-web-application-architectures) +- [Domain-Driven Design](https://domainlanguage.com/ddd/)