From 7578ece5207845f66064225a5ef0b4d1c18adc71 Mon Sep 17 00:00:00 2001 From: Ho Ngoc Hai Date: Sun, 18 Jan 2026 17:31:06 +0700 Subject: [PATCH] refactor: Restructure documentation by moving files into language-specific directories and consolidating others. --- .../docs/AI_CHATBOT.md | 559 ---------- services/mkt-facebook-service-net/docs/API.md | 703 ------------- .../docs/FACEBOOK_SETUP.md | 381 ------- .../docs/{ => en}/ARCHITECTURE.md | 203 ++-- .../docs/{en => }/AI_CHATBOT_GUIDE.md | 0 .../docs/{en => }/API.md | 0 .../docs/{en => }/ARCHITECTURE.md | 0 .../docs/{en => }/AUTOMATION_GUIDE.md | 0 .../docs/{en => }/WHATSAPP_SETUP.md | 0 .../docs/en/README.md | 36 + .../docs/vi/AI_CHATBOT_GUIDE.md | 416 -------- .../mkt-whatsapp-service-net/docs/vi/API.md | 390 ------- .../docs/vi/ARCHITECTURE.md | 238 ----- .../docs/vi/AUTOMATION_GUIDE.md | 262 ----- .../docs/vi/README.md | 36 + .../docs/vi/WHATSAPP_SETUP.md | 261 ----- .../mkt-x-service-net/docs/{ => en}/API.md | 0 .../docs/{ => en}/ARCHITECTURE.md | 0 .../docs/{ => en}/TWITTER_SETUP.md | 0 .../docs/vi/CAI-DAT-TWITTER.md | 346 +++++++ .../mkt-x-service-net/docs/vi/KIEN-TRUC.md | 467 +++++++++ services/mkt-zalo-service-net/README.md | 350 +------ .../mkt-zalo-service-net/docs/API_DESIGN.md | 971 ------------------ .../docs/DATABASE_SCHEMA.md | 562 ---------- .../docs/DOMAIN_MODELS.md | 733 ------------- .../mkt-zalo-service-net/docs/INTEGRATION.md | 579 ----------- .../mkt-zalo-service-net/docs/SOLUTION.md | 779 -------------- .../docs/en/ARCHITECTURE.md | 437 ++++++++ 28 files changed, 1434 insertions(+), 7275 deletions(-) delete mode 100644 services/mkt-facebook-service-net/docs/AI_CHATBOT.md delete mode 100644 services/mkt-facebook-service-net/docs/API.md delete mode 100644 services/mkt-facebook-service-net/docs/FACEBOOK_SETUP.md rename services/mkt-facebook-service-net/docs/{ => en}/ARCHITECTURE.md (60%) rename services/mkt-whatsapp-service-net/docs/{en => }/AI_CHATBOT_GUIDE.md (100%) rename services/mkt-whatsapp-service-net/docs/{en => }/API.md (100%) rename services/mkt-whatsapp-service-net/docs/{en => }/ARCHITECTURE.md (100%) rename services/mkt-whatsapp-service-net/docs/{en => }/AUTOMATION_GUIDE.md (100%) rename services/mkt-whatsapp-service-net/docs/{en => }/WHATSAPP_SETUP.md (100%) create mode 100644 services/mkt-whatsapp-service-net/docs/en/README.md delete mode 100644 services/mkt-whatsapp-service-net/docs/vi/AI_CHATBOT_GUIDE.md delete mode 100644 services/mkt-whatsapp-service-net/docs/vi/API.md delete mode 100644 services/mkt-whatsapp-service-net/docs/vi/ARCHITECTURE.md delete mode 100644 services/mkt-whatsapp-service-net/docs/vi/AUTOMATION_GUIDE.md create mode 100644 services/mkt-whatsapp-service-net/docs/vi/README.md delete mode 100644 services/mkt-whatsapp-service-net/docs/vi/WHATSAPP_SETUP.md rename services/mkt-x-service-net/docs/{ => en}/API.md (100%) rename services/mkt-x-service-net/docs/{ => en}/ARCHITECTURE.md (100%) rename services/mkt-x-service-net/docs/{ => en}/TWITTER_SETUP.md (100%) create mode 100644 services/mkt-x-service-net/docs/vi/CAI-DAT-TWITTER.md create mode 100644 services/mkt-x-service-net/docs/vi/KIEN-TRUC.md delete mode 100644 services/mkt-zalo-service-net/docs/API_DESIGN.md delete mode 100644 services/mkt-zalo-service-net/docs/DATABASE_SCHEMA.md delete mode 100644 services/mkt-zalo-service-net/docs/DOMAIN_MODELS.md delete mode 100644 services/mkt-zalo-service-net/docs/INTEGRATION.md delete mode 100644 services/mkt-zalo-service-net/docs/SOLUTION.md create mode 100644 services/mkt-zalo-service-net/docs/en/ARCHITECTURE.md diff --git a/services/mkt-facebook-service-net/docs/AI_CHATBOT.md b/services/mkt-facebook-service-net/docs/AI_CHATBOT.md deleted file mode 100644 index cb96c9b6..00000000 --- a/services/mkt-facebook-service-net/docs/AI_CHATBOT.md +++ /dev/null @@ -1,559 +0,0 @@ -# AI Chatbot Configuration Guide - Hướng Dẫn Cấu Hình AI Chatbot - -**EN**: Guide to configure and optimize AI-powered chatbot using OpenAI or Azure OpenAI. - -**VI**: Hướng dẫn cấu hình và tối ưu chatbot AI sử dụng OpenAI hoặc Azure OpenAI. - -## Overview / Tổng Quan - -**EN**: The AI Chatbot uses GPT-4 or GPT-3.5 to provide intelligent, context-aware responses to customer messages. It can understand natural language, maintain conversation context, and provide helpful information. - -**VI**: AI Chatbot sử dụng GPT-4 hoặc GPT-3.5 để cung cấp phản hồi thông minh, theo ngữ cảnh cho tin nhắn khách hàng. Nó có thể hiểu ngôn ngữ tự nhiên, duy trì ngữ cảnh hội thoại, và cung cấp thông tin hữu ích. - -## Choosing AI Provider / Chọn AI Provider - -### Option 1: OpenAI - -**Pros / Ưu điểm**: -- ✅ Easy setup / Dễ dàng setup -- ✅ Pay-as-you-go pricing -- ✅ Latest models (GPT-4 Turbo) -- ✅ Good for global deployment - -**Cons / Nhược điểm**: -- ❌ External API (latency) -- ❌ Data processed outside your region - -**Setup**: -1. Create account at [platform.openai.com](https://platform.openai.com/) -2. Generate API key from **API Keys** page -3. Add credits to billing account - -```bash -# .env configuration -OPENAI_API_KEY="sk-proj-xxxxxxxxxxxxxxxxx" -OPENAI_MODEL="gpt-4-turbo" -``` - -### Option 2: Azure OpenAI - -**Pros / Ưu điểm**: -- ✅ Enterprise security \u0026 compliance -- ✅ Data residency control -- ✅ SLA guarantees -- ✅ VNET integration - -**Cons / Nhược điểm**: -- ❌ More complex setup -- ❌ Requires Azure subscription -- ❌ Slower model updates - -**Setup**: -1. Create Azure OpenAI resource in Azure Portal -2. Deploy model (e.g., `gpt-4`) -3. Copy endpoint và key - -```bash -# .env configuration -AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/" -AZURE_OPENAI_KEY="your-key-here" -AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4" -``` - ---- - -## Model Selection / Lựa Chọn Model - -| Model | Best For / Phù Hợp Cho | Cost / Chi Phí | Speed / Tốc Độ | -|-------|------------------------|----------------|----------------| -| **GPT-4 Turbo** | Complex reasoning, accurate responses | $$ | Medium | -| **GPT-4** | High quality, nuanced understanding | $$$ | Slow | -| **GPT-3.5 Turbo** | Fast responses, simple queries | $ | Fast | - -**Recommendation / Đề Nghị**: -- **E-commerce Support**: `gpt-3.5-turbo` (fast \u0026 cost-effective) -- **Technical Support**: `gpt-4-turbo` (better accuracy) -- **Multilingual Support**: `gpt-4-turbo` (better language handling) - ---- - -## System Prompt Best Practices / Thực Hành Tốt Nhất System Prompt - -### Basic Template / Mẫu Cơ Bản - -``` -You are a helpful customer service assistant for [BUSINESS_NAME], an e-commerce platform selling [PRODUCTS]. - -Your responsibilities: -- Answer questions about products, orders, and policies -- Provide friendly and professional customer service -- If you don't know something, be honest and offer to connect the customer with a human agent - -Important guidelines: -- Always be polite and respectful -- Keep responses concise (under 200 words) -- Use emojis sparingly -- Do not make up information -- Do not discuss competitor products -``` - -### E-commerce Example / Ví Dụ E-commerce - -``` -You are the AI assistant for "GoodGo Shop", a multi-category e-commerce platform in Vietnam. - -PRODUCTS: -- Electronics (phones, laptops, accessories) -- Fashion (clothing, shoes, bags) -- Home \u0026 Living (furniture, kitchenware) - -CAPABILITIES: -- Check order status (ask for order ID) -- Provide product information -- Explain shipping \u0026 return policies -- Help with account issues - -TONE: -- Friendly and conversational -- Use Vietnamese when customer uses Vietnamese -- Use simple language, avoid jargon - -LIMITATIONS: -- Cannot process refunds (refer to human agent) -- Cannot modify orders (refer to customer service) -- Cannot access payment information - -When you cannot help, say: "Let me connect you with our customer service team for this request." -``` - -### Restaurant/Food Delivery Example - -``` -You are the AI chatbot for "Taste of Vietnam", a Vietnamese restaurant in Ho Chi Minh City. - -MENU CATEGORIES: -- Appetizers (spring rolls, salads) -- Main courses (pho, banh mi, rice dishes) -- Beverages (Vietnamese coffee, smoothies) - -SERVICES: -- Dine-in (10AM - 10PM daily) -- Delivery (via our website only, 30-45 min) -- Reservation (ask for date, time, number of guests) - -COMMON QUESTIONS: -- Menu recommendations → Suggest based on preferences -- Allergies → Inform ingredients, recommend alternatives -- Delivery → Available within 5km radius -- Payment → Cash or card accepted - -Always end with: "Would you like to place an order or make a reservation?" -``` - ---- - -## Configuration Parameters / Tham Số Cấu Hình - -### Temperature - -**EN**: Controls randomness (0.0 - 2.0) - -**VI**: Kiểm soát độ ngẫu nhiên (0.0 - 2.0) - -| Value | Behavior / Hành Vi | Use Case | -|-------|-------------------|----------| -| **0.0 - 0.3** | Deterministic, focused | FAQ, policy questions | -| **0.4 - 0.7** | Balanced creativity | General customer service | -| **0.8 - 1.0** | More creative | Marketing, engagement | -| **1.1+** | Very random (not recommended) | - | - -**Recommendation**: `0.7` for customer service - -### Max Tokens - -**EN**: Maximum length of response - -**VI**: Độ dài tối đa của phản hồi - -| Tokens | Words / Từ | Use Case | -|--------|-----------|----------| -| 150 | ~100 | Quick answers | -| 300 | ~200 | Standard responses | -| 500 | ~350 | Detailed explanations | -| 1000+ | 700+ | Long-form content | - -**Recommendation**: `300-500` tokens for most cases - -### Top P (Nucleus Sampling) - -**EN**: Alternative to temperature (0.0 - 1.0) - -**VI**: Thay thế cho temperature (0.0 - 1.0) - -- **0.9**: Recommended default -- Use either `temperature` OR `top_p`, not both - -### Presence Penalty / Frequency Penalty - -**EN**: Reduce repetition (-2.0 to 2.0) - -**VI**: Giảm sự lặp lại (-2.0 đến 2.0) - -- **Presence Penalty**: `0.6` - Encourage topic variety -- **Frequency Penalty**: `0.3` - Reduce word repetition - ---- - -## Context Management / Quản Lý Ngữ Cảnh - -### Conversation History - -**EN**: Include recent messages for context: - -**VI**: Bao gồm tin nhắn gần đây cho ngữ cảnh: - -```csharp -var messages = new List -{ - new ChatMessage(ChatRole.System, systemPrompt), - new ChatMessage(ChatRole.User, "What are your opening hours?"), - new ChatMessage(ChatRole.Assistant, "We're open 10AM - 10PM daily."), - new ChatMessage(ChatRole.User, "Can I order delivery now?"), -}; -``` - -**Best Practice**: -- Keep last **5-10 messages** for context -- Trim old messages to save tokens -- Always include System message - -### Token Budget - -**EN**: Managing token costs: - -**VI**: Quản lý chi phí tokens: - -| Component | Tokens | Note | -|-----------|--------|------| -| System Prompt | 100-200 | Fixed | -| Conversation History | 50-100 per message | Variable | -| Max Response | 300-500 | Configurable | -| **Total per request** | ~500-1500 | Estimate | - -**Cost Estimation** (GPT-4 Turbo): -- Input: $0.01 / 1K tokens -- Output: $0.03 / 1K tokens -- **Average cost per conversation**: $0.02 - $0.05 - ---- - -## Fallback Strategies / Chiến Lược Dự Phòng - -### 1. Fallback to Automation - -**EN**: When AI confidence is low, fallback to automation rules: - -**VI**: Khi độ tin cậy AI thấp, fallback về automation rules: - -```csharp -if (aiResponse.Confidence < 0.7) -{ - // Fallback to keyword matching - return await _automationEngine.GetResponseAsync(message); -} -``` - -### 2. Human Handoff - -**EN**: Escalate to human agent for complex issues: - -**VI**: Chuyển sang agent người khi vấn đề phức tạp: - -**Trigger Phrases** (in AI response): -- "I'm not sure" -- "Let me connect you" -- "human agent" - -**Action**: Update conversation status to `NeedsHumanAgent` - -### 3. Timeout Handling - -**EN**: If OpenAI API times out: - -**VI**: Nếu OpenAI API timeout: - -```csharp -try -{ - var response = await _openAIClient.GetCompletionAsync(prompt, ct); -} -catch (TaskCanceledException) -{ - // Fallback response - return "I apologize for the delay. Let me connect you with our team."; -} -``` - ---- - -## Multilingual Support / Hỗ Trợ Đa Ngôn Ngữ - -### Auto-detect Language - -**EN**: GPT-4 can auto-detect and respond in the customer's language: - -**VI**: GPT-4 có thể tự động phát hiện và phản hồi bằng ngôn ngữ khách hàng: - -**System Prompt**: -``` -You are a multilingual customer service assistant. -- Detect the customer's language -- Respond in the same language -- Support: English, Vietnamese, Thai, Chinese -``` - -### Language-specific Prompts - -**Vietnamese**: -``` -Bạn là trợ lý AI cho "GoodGo Shop", nền tảng thương mại điện tử tại Việt Nam. - -NHIỆM VỤ: -- Trả lời câu hỏi về sản phẩm, đơn hàng, chính sách -- Hỗ trợ khách hàng thân thiện và chuyên nghiệp -- Nếu không biết, hãy thành thật và đề nghị kết nối với nhân viên - -NGUYÊN TẮC: -- Luôn lịch sự, tôn trọng -- Phản hồi ngắn gọn (dưới 200 từ) -- Không bịa đặt thông tin -``` - ---- - -## Testing \u0026 Optimization / Kiểm Thử \u0026 Tối Ưu - -### A/B Testing System Prompts - -**EN**: Test different prompts to find best performance: - -**VI**: Test các prompts khác nhau để tìm hiệu suất tốt nhất: - -| Metric | Target / Mục Tiêu | Measurement | -|--------|-------------------|-------------| -| **Response Quality** | User satisfaction \u003e 80% | Thumbs up/down | -| **Resolution Rate** | \u003e 70% without human | Track escalations | -| **Response Time** | \u003c 3 seconds | API latency | -| **Cost per Conversation** | \u003c $0.05 | Token usage | - -### Monitoring Dashboard - -**Key Metrics / Chỉ Số Chính**: -- Total conversations handled by AI -- Average tokens per conversation -- Total cost (daily/monthly) -- Fallback rate (AI → Automation) -- Human handoff rate -- Customer satisfaction score - ---- - -## Security \u0026 Privacy / Bảo Mật \u0026 Quyền Riêng Tư - -### PII Protection - -**EN**: Do NOT send sensitive data to OpenAI: - -**VI**: KHÔNG gửi dữ liệu nhạy cảm đến OpenAI: - -❌ **Never Include**: -- Credit card numbers -- Passwords -- Social security numbers -- Full addresses (unless necessary) - -✅ **Safe to Include**: -- Product names -- Order IDs (hashed) -- General questions -- Preferences - -### Data Retention - -**OpenAI Policy**: -- API data NOT used for training (as of Dec 2023) -- Data retained for 30 days for abuse monitoring -- Can opt-out of retention (contact OpenAI) - -**Azure OpenAI Policy**: -- Data stays in your Azure region -- Full control over data retention -- Enterprise compliance (SOC 2, ISO 27001) - ---- - -## Cost Optimization / Tối Ưu Chi Phí - -### 1. Use Shorter System Prompts - -```diff -- You are a helpful customer service assistant for GoodGo Shop, an e-commerce platform selling electronics, fashion, home \u0026 living... -+ You are a customer service AI for GoodGo, an e-commerce platform. -``` - -**Savings**: ~50 tokens per request - -### 2. Limit Conversation History - -```csharp -// Only keep recent 5 messages -var contextMessages = conversation.Messages - .OrderByDescending(m =\u003e m.SentAt) - .Take(5) - .Reverse(); -``` - -**Savings**: ~200-400 tokens per request - -### 3. Use GPT-3.5 for Simple Queries - -```csharp -if (IsSimpleQuery(message)) // FAQ, product lookup -{ - model = "gpt-3.5-turbo"; // 10x cheaper -} -else -{ - model = "gpt-4-turbo"; -} -``` - -### 4. Cache Common Responses - -**EN**: Cache responses for FAQs in Redis: - -**VI**: Cache responses cho FAQs trong Redis: - -```csharp -var cacheKey = $"faq:{messageHash}"; -var cachedResponse = await _redis.GetAsync(cacheKey); -if (cachedResponse != null) - return cachedResponse; // No API call -``` - ---- - -## Example Configurations / Ví Dụ Cấu Hình - -### Configuration 1: High-Quality Support - -```json -{ - "provider": "OpenAI", - "model": "gpt-4-turbo", - "systemPrompt": "Detailed customer service prompt...", - "temperature": 0.6, - "maxTokens": 500, - "topP": 0.9, - "presencePenalty": 0.5, - "frequencyPenalty": 0.3 -} -``` - -**Use Case**: Premium brands, complex products -**Cost**: ~$0.04 per conversation - -### Configuration 2: Fast \u0026 Cost-Effective - -```json -{ - "provider": "OpenAI", - "model": "gpt-3.5-turbo", - "systemPrompt": "Concise customer service prompt...", - "temperature": 0.7, - "maxTokens": 300, - "topP": 0.9 -} -``` - -**Use Case**: High-volume, simple queries -**Cost**: ~$0.005 per conversation - -### Configuration 3: Enterprise (Azure OpenAI) - -```json -{ - "provider": "AzureOpenAI", - "model": "gpt-4", - "endpoint": "https://your-resource.openai.azure.com/", - "deploymentName": "gpt-4-deployment", - "systemPrompt": "Enterprise-grade prompt...", - "temperature": 0.7, - "maxTokens": 400 -} -``` - -**Use Case**: Enterprise with compliance requirements -**Cost**: Based on Azure pricing - ---- - -## Troubleshooting / Xử Lý Sự Cố - -### Issue 1: Responses Too Generic - -**Problem**: AI gives vague, unhelpful answers - -**Solution**: -- ✅ Add more context to system prompt (products, policies) -- ✅ Include conversation history -- ✅ Lower temperature (0.5) - -### Issue 2: High Costs - -**Problem**: Token usage too high - -**Solution**: -- ✅ Shorten system prompt -- ✅ Limit conversation history -- ✅ Use GPT-3.5 for simple queries -- ✅ Cache common FAQs - -### Issue 3: Slow Responses - -**Problem**: Latency \u003e 5 seconds - -**Solution**: -- ✅ Use GPT-3.5 Turbo (faster) -- ✅ Reduce max_tokens -- ✅ Enable streaming (show typing indicator) -- ✅ Use Azure OpenAI (regional deployment) - -### Issue 4: AI Hallucinates - -**Problem**: AI makes up information - -**Solution**: -- ✅ Add explicit instructions: "Do not make up information" -- ✅ Lower temperature (0.3-0.5) -- ✅ Provide factual context in system prompt -- ✅ Use function calling for structured data (future enhancement) - ---- - -## Resources / Tài Nguyên - -### Official Documentation -- [OpenAI API Reference](https://platform.openai.com/docs/api-reference) -- [Azure OpenAI Documentation](https://learn.microsoft.com/en-us/azure/ai-services/openai/) -- [GPT Best Practices](https://platform.openai.com/docs/guides/prompt-engineering) - -### Tools -- [OpenAI Playground](https://platform.openai.com/playground) - Test prompts -- [Tokenizer](https://platform.openai.com/tokenizer) - Count tokens -- [Azure OpenAI Studio](https://oai.azure.com/) - Manage deployments - -### Internal Docs -- [API Documentation](./API.md) -- [Architecture Documentation](./ARCHITECTURE.md) -- [Facebook Setup Guide](./FACEBOOK_SETUP.md) diff --git a/services/mkt-facebook-service-net/docs/API.md b/services/mkt-facebook-service-net/docs/API.md deleted file mode 100644 index b0fb0c05..00000000 --- a/services/mkt-facebook-service-net/docs/API.md +++ /dev/null @@ -1,703 +0,0 @@ -# API Documentation - Tài Liệu API - -**Service**: mkt-facebook-service-net -**Base URL**: `http://localhost/api/v1/mkt-facebook` -**API Version**: v1.0 - -## Authentication / Xác Thực - -**EN**: All REST API endpoints (except webhooks) require JWT Bearer token. - -**VI**: Tất cả REST API endpoints (trừ webhooks) yêu cầu JWT Bearer token. - -```http -Authorization: Bearer {jwt_token} -``` - -## Webhooks API - -### Verify Facebook Webhook - -**EN**: Facebook uses this endpoint to verify webhook ownership during setup. - -**VI**: Facebook dùng endpoint này để verify webhook trong quá trình setup. - -```http -GET /api/v1/webhooks/facebook -``` - -**Query Parameters**: -| Parameter | Type | Description | -|-----------|------|-------------| -| `hub.mode` | string | Must be "subscribe" | -| `hub.verify_token` | string | Token configured in Facebook App | -| `hub.challenge` | string | Random string from Facebook | - -**Response** (200 OK): -``` -{hub.challenge} -``` - -**Example**: -```bash -curl "http://localhost/api/v1/webhooks/facebook?hub.mode=subscribe\u0026hub.verify_token=my_verify_token\u0026hub.challenge=1234567890" -``` - ---- - -### Receive Facebook Messenger Events - -**EN**: Receives messages, postbacks, and other events from Facebook Messenger Platform. - -**VI**: Nhận messages, postbacks, và các events khác từ Facebook Messenger Platform. - -```http -POST /api/v1/webhooks/facebook -``` - -**Headers**: -``` -X-Hub-Signature-256: sha256={signature} -Content-Type: application/json -``` - -**Request Body** (Message Event): -```json -{ - "object": "page", - "entry": [{ - "id": "PAGE_ID", - "time": 1234567890, - "messaging": [{ - "sender": { "id": "USER_ID" }, - "recipient": { "id": "PAGE_ID" }, - "timestamp": 1234567890, - "message": { - "mid": "MESSAGE_ID", - "text": "Hello chatbot!", - "quick_reply": { - "payload": "QUICK_REPLY_PAYLOAD" - } - } - }] - }] -} -``` - -**Request Body** (Postback Event): -```json -{ - "object": "page", - "entry": [{ - "messaging": [{ - "sender": { "id": "USER_ID" }, - "recipient": { "id": "PAGE_ID" }, - "timestamp": 1234567890, - "postback": { - "title": "Get Started", - "payload": "GET_STARTED" - } - }] - }] -} -``` - -**Response** (200 OK): -```json -{ - "success": true -} -``` - ---- - -## Conversations API - -### List Conversations - -**EN**: Retrieve a paginated list of conversations. - -**VI**: Lấy danh sách conversations có phân trang. - -```http -GET /api/v1/conversations -``` - -**Query Parameters**: -| Parameter | Type | Required | Default | Description | -|-----------|------|----------|---------|-------------| -| `shopId` | guid | Yes | - | Shop/Business ID | -| `status` | string | No | - | Filter by status (Active, Closed) | -| `skip` | int | No | 0 | Number of records to skip | -| `take` | int | No | 20 | Number of records to return | - -**Response** (200 OK): -```json -{ - "success": true, - "data": { - "conversations": [ - { - "id": "550e8400-e29b-41d4-a716-446655440000", - "customerId": "650e8400-e29b-41d4-a716-446655440001", - "customerName": "John Doe", - "pageId": "123456789", - "status": "Active", - "channel": "FacebookMessenger", - "lastMessageText": "Thank you!", - "lastMessageAt": "2026-01-18T10:30:00Z", - "createdAt": "2026-01-18T09:00:00Z" - } - ], - "totalCount": 150 - }, - "pagination": { - "page": 1, - "limit": 20, - "total": 150, - "totalPages": 8 - } -} -``` - -**Example**: -```bash -curl -H "Authorization: Bearer {token}" \ - "http://localhost/api/v1/conversations?shopId=abc123\u0026status=Active\u0026skip=0\u0026take=20" -``` - ---- - -### Get Conversation by ID - -**EN**: Retrieve a specific conversation with full message history. - -**VI**: Lấy một conversation với toàn bộ lịch sử tin nhắn. - -```http -GET /api/v1/conversations/{id} -``` - -**Path Parameters**: -| Parameter | Type | Description | -|-----------|------|-------------| -| `id` | guid | Conversation ID | - -**Response** (200 OK): -```json -{ - "success": true, - "data": { - "id": "550e8400-e29b-41d4-a716-446655440000", - "customerId": "650e8400-e29b-41d4-a716-446655440001", - "customer": { - "id": "650e8400-e29b-41d4-a716-446655440001", - "name": "John Doe", - "facebookUserId": "1234567890", - "profilePicUrl": "https://...", - "tags": ["VIP", "Returning Customer"] - }, - "pageId": "123456789", - "status": "Active", - "channel": "FacebookMessenger", - "messages": [ - { - "id": "msg-001", - "senderId": "1234567890", - "content": "Hello, I need help", - "messageType": "Text", - "direction": "Incoming", - "sentAt": "2026-01-18T09:00:00Z" - }, - { - "id": "msg-002", - "senderId": "PAGE_ID", - "content": "Hi! How can I help you today?", - "messageType": "Text", - "direction": "Outgoing", - "sentAt": "2026-01-18T09:00:05Z" - } - ], - "createdAt": "2026-01-18T09:00:00Z", - "lastMessageAt": "2026-01-18T10:30:00Z" - } -} -``` - -**Response** (404 Not Found): -```json -{ - "success": false, - "error": "Conversation not found" -} -``` - ---- - -### Send Message in Conversation - -**EN**: Send a message to a customer in an active conversation. - -**VI**: Gửi tin nhắn đến khách hàng trong một conversation đang active. - -```http -POST /api/v1/conversations/{id}/messages -``` - -**Path Parameters**: -| Parameter | Type | Description | -|-----------|------|-------------| -| `id` | guid | Conversation ID | - -**Request Body**: -```json -{ - "messageText": "Thank you for contacting us!", - "quickReplies": [ - { - "contentType": "text", - "title": "Yes", - "payload": "YES" - }, - { - "contentType": "text", - "title": "No", - "payload": "NO" - } - ] -} -``` - -**Response** (200 OK): -```json -{ - "success": true, - "data": { - "messageId": "msg-003", - "sentAt": "2026-01-18T10:35:00Z" - } -} -``` - -**Example**: -```bash -curl -X POST -H "Authorization: Bearer {token}" \ - -H "Content-Type: application/json" \ - -d '{"messageText":"Hello from our team!"}' \ - "http://localhost/api/v1/conversations/550e8400-e29b-41d4-a716-446655440000/messages" -``` - ---- - -### Update Conversation Status - -**EN**: Update conversation status (assign, close, archive). - -**VI**: Cập nhật trạng thái conversation (assign, đóng, lưu trữ). - -```http -PUT /api/v1/conversations/{id}/status -``` - -**Request Body**: -```json -{ - "status": "Closed", - "reason": "Issue resolved" -} -``` - -**Response** (200 OK): -```json -{ - "success": true, - "data": { - "conversationId": "550e8400-e29b-41d4-a716-446655440000", - "status": "Closed", - "updatedAt": "2026-01-18T11:00:00Z" - } -} -``` - ---- - -## Customers API - -### List Customers - -**EN**: Retrieve a paginated list of customers. - -**VI**: Lấy danh sách khách hàng có phân trang. - -```http -GET /api/v1/customers -``` - -**Query Parameters**: -| Parameter | Type | Required | Default | Description | -|-----------|------|----------|---------|-------------| -| `shopId` | guid | Yes | - | Shop/Business ID | -| `tags` | string[] | No | - | Filter by tags (comma-separated) | -| `search` | string | No | - | Search by name or email | -| `skip` | int | No | 0 | Pagination offset | -| `take` | int | No | 20 | Page size | - -**Response** (200 OK): -```json -{ - "success": true, - "data": { - "customers": [ - { - "id": "650e8400-e29b-41d4-a716-446655440001", - "facebookUserId": "1234567890", - "name": "John Doe", - "email": "john@example.com", - "profilePicUrl": "https://...", - "locale": "en_US", - "timezone": 7, - "tags": ["VIP", "Returning"], - "firstSeenAt": "2026-01-15T08:00:00Z", - "lastInteractionAt": "2026-01-18T10:30:00Z" - } - ], - "totalCount": 450 - }, - "pagination": { - "page": 1, - "limit": 20, - "total": 450, - "totalPages": 23 - } -} -``` - ---- - -### Get Customer by ID - -**EN**: Retrieve detailed customer information. - -**VI**: Lấy thông tin chi tiết khách hàng. - -```http -GET /api/v1/customers/{id} -``` - -**Response** (200 OK): -```json -{ - "success": true, - "data": { - "id": "650e8400-e29b-41d4-a716-446655440001", - "facebookUserId": "1234567890", - "name": "John Doe", - "email": "john@example.com", - "phone": "+84901234567", - "profilePicUrl": "https://...", - "locale": "vi_VN", - "timezone": 7, - "tags": ["VIP", "Returning Customer"], - "customFields": { - "preferredLanguage": "Vietnamese", - "membershipTier": "Gold" - }, - "conversationCount": 15, - "firstSeenAt": "2026-01-15T08:00:00Z", - "lastInteractionAt": "2026-01-18T10:30:00Z" - } -} -``` - ---- - -### Update Customer - -**EN**: Update customer tags and custom fields. - -**VI**: Cập nhật tags và custom fields của khách hàng. - -```http -PUT /api/v1/customers/{id} -``` - -**Request Body**: -```json -{ - "tags": ["VIP", "Returning", "HighValue"], - "customFields": { - "preferredLanguage": "English", - "membershipTier": "Platinum" - } -} -``` - -**Response** (200 OK): -```json -{ - "success": true, - "data": { - "customerId": "650e8400-e29b-41d4-a716-446655440001", - "updatedAt": "2026-01-18T11:00:00Z" - } -} -``` - ---- - -## Chatbots API - -### List Automation Flows - -**EN**: Retrieve all chatbot automation flows for a shop. - -**VI**: Lấy tất cả automation flows của một shop. - -```http -GET /api/v1/chatbots/flows -``` - -**Query Parameters**: -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `shopId` | guid | Yes | Shop/Business ID | -| `isActive` | bool | No | Filter by active status | - -**Response** (200 OK): -```json -{ - "success": true, - "data": [ - { - "id": "flow-001", - "name": "Welcome Flow", - "shopId": "shop-123", - "triggerType": "GetStarted", - "triggerValue": "GET_STARTED", - "isActive": true, - "nodeCount": 8, - "createdAt": "2026-01-10T00:00:00Z" - }, - { - "id": "flow-002", - "name": "FAQ Flow", - "shopId": "shop-123", - "triggerType": "Keyword", - "triggerValue": "help|faq|question", - "isActive": true, - "nodeCount": 12, - "createdAt": "2026-01-12T00:00:00Z" - } - ] -} -``` - ---- - -### Create Chatbot Flow - -**EN**: Create a new automation chatbot flow. - -**VI**: Tạo automation chatbot flow mới. - -```http -POST /api/v1/chatbots/flows -``` - -**Request Body**: -```json -{ - "shopId": "shop-123", - "name": "Product Inquiry Flow", - "triggerType": "Keyword", - "triggerValue": "product|price|buy", - "nodes": [ - { - "type": "Start", - "content": null, - "config": {}, - "nextNodeIds": ["node-002"] - }, - { - "type": "Message", - "content": "Welcome! I can help you find products.", - "config": {}, - "nextNodeIds": ["node-003"] - }, - { - "type": "Question", - "content": "What category are you interested in?", - "config": { - "quickReplies": [ - { "title": "Electronics", "payload": "CAT_ELECTRONICS" }, - { "title": "Fashion", "payload": "CAT_FASHION" } - ] - }, - "nextNodeIds": ["node-004", "node-005"] - } - ] -} -``` - -**Response** (201 Created): -```json -{ - "success": true, - "data": { - "flowId": "flow-003", - "createdAt": "2026-01-18T12:00:00Z" - } -} -``` - ---- - -### Get AI Chatbot Config - -**EN**: Retrieve AI chatbot configuration for a shop. - -**VI**: Lấy cấu hình AI chatbot của shop. - -```http -GET /api/v1/chatbots/ai-config -``` - -**Query Parameters**: -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `shopId` | guid | Yes | Shop/Business ID | - -**Response** (200 OK): -```json -{ - "success": true, - "data": { - "id": "ai-config-001", - "shopId": "shop-123", - "provider": "OpenAI", - "model": "gpt-4-turbo", - "systemPrompt": "You are a helpful customer service assistant for our e-commerce store...", - "temperature": 0.7, - "maxTokens": 500, - "isEnabled": true, - "updatedAt": "2026-01-17T10:00:00Z" - } -} -``` - ---- - -### Update AI Chatbot Config - -**EN**: Update AI chatbot configuration. - -**VI**: Cập nhật cấu hình AI chatbot. - -```http -PUT /api/v1/chatbots/ai-config -``` - -**Request Body**: -```json -{ - "shopId": "shop-123", - "provider": "OpenAI", - "model": "gpt-4-turbo", - "systemPrompt": "You are a helpful and friendly customer service assistant...", - "temperature": 0.8, - "maxTokens": 500, - "isEnabled": true -} -``` - -**Response** (200 OK): -```json -{ - "success": true, - "data": { - "configId": "ai-config-001", - "updatedAt": "2026-01-18T12:30:00Z" - } -} -``` - ---- - -## Error Responses / Phản Hồi Lỗi - -### Standard Error Format - -```json -{ - "success": false, - "error": "Error message in English", - "errorCode": "ERROR_CODE", - "details": { - "field": "Field-specific error" - } -} -``` - -### Common Error Codes / Mã Lỗi Thường Gặp - -| Status Code | Error Code | Description | -|-------------|------------|-------------| -| 400 | `INVALID_REQUEST` | Invalid request parameters | -| 400 | `VALIDATION_ERROR` | Validation failed | -| 401 | `UNAUTHORIZED` | Missing or invalid token | -| 403 | `FORBIDDEN` | No permission | -| 403 | `INVALID_SIGNATURE` | Facebook webhook signature invalid | -| 404 | `NOT_FOUND` | Resource not found | -| 409 | `CONFLICT` | Duplicate resource | -| 429 | `RATE_LIMIT_EXCEEDED` | Too many requests | -| 500 | `INTERNAL_ERROR` | Server error | -| 503 | `SERVICE_UNAVAILABLE` | External service unavailable | - -**Example Error Response** (400): -```json -{ - "success": false, - "error": "Validation failed", - "errorCode": "VALIDATION_ERROR", - "details": { - "messageText": "Message text is required", - "conversationId": "Invalid GUID format" - } -} -``` - ---- - -## Rate Limiting / Giới Hạn Tỷ Lệ - -**EN**: API rate limits per API key: -- **100 requests/minute** for read operations (GET) -- **20 requests/minute** for write operations (POST, PUT, DELETE) - -**VI**: Giới hạn API mỗi API key: -- **100 requests/phút** cho read operations (GET) -- **20 requests/phút** cho write operations (POST, PUT, DELETE) - -**Rate Limit Headers**: -``` -X-RateLimit-Limit: 100 -X-RateLimit-Remaining: 95 -X-RateLimit-Reset: 1234567890 -``` - ---- - -## Webhooks Best Practices / Thực Hành Tốt Webhooks - -1. **Always return 200 immediately** / Luôn trả 200 ngay lập tức -2. **Process asynchronously** / Xử lý bất đồng bộ -3. **Verify signature** / Xác thực chữ ký -4. **Handle retries** / Xử lý retry (Facebook sẽ retry nếu không nhận 200) -5. **Use HTTPS** / Sử dụng HTTPS - -## Resources / Tài Nguyên - -- [Facebook Messenger Platform Webhooks](https://developers.facebook.com/docs/messenger-platform/webhooks) -- [Facebook Send API Reference](https://developers.facebook.com/docs/messenger-platform/send-messages) -- [Architecture Documentation](./ARCHITECTURE.md) -- [Facebook Setup Guide](./FACEBOOK_SETUP.md) diff --git a/services/mkt-facebook-service-net/docs/FACEBOOK_SETUP.md b/services/mkt-facebook-service-net/docs/FACEBOOK_SETUP.md deleted file mode 100644 index b46bd7d1..00000000 --- a/services/mkt-facebook-service-net/docs/FACEBOOK_SETUP.md +++ /dev/null @@ -1,381 +0,0 @@ -# Facebook Messenger Setup Guide - Hướng Dẫn Thiết Lập - -**EN**: Step-by-step guide to set up Facebook Messenger Platform integration. - -**VI**: Hướng dẫn từng bước để thiết lập tích hợp Facebook Messenger Platform. - -## Prerequisites / Yêu Cầu - -- Facebook account / Tài khoản Facebook -- Facebook Page (đã tạo sẵn) -- Developer account on Meta for Developers / Tài khoản developer trên Meta for Developers -- HTTPS endpoint for webhook / Endpoint HTTPS cho webhook (production) -- ngrok (cho local testing) - -## Step 1: Create Facebook App / Tạo Facebook App - -### 1.1 Access Meta for Developers - -**EN**: -1. Go to [developers.facebook.com](https://developers.facebook.com/) -2. Click "My Apps" → "Create App" -3. Select use case: **"Other"** -4. Select app type: **"Business"** - -**VI**: -1. Truy cập [developers.facebook.com](https://developers.facebook.com/) -2. Click "My Apps" → "Create App" -3. Chọn use case: **"Other"** -4. Chọn app type: **"Business"** - -### 1.2 App Configuration - -**EN**: -- **App Name**: e.g., "My Shop Chatbot" -- **App Contact Email**: your email -- **Business Account**: Select or create - -**VI**: -- **App Name**: ví dụ, "My Shop Chatbot" -- **App Contact Email**: email của bạn -- **Business Account**: Chọn hoặc tạo mới - -> [!NOTE] -> Copy your **App ID** and **App Secret** (Settings → Basic). You'll need these later. - ---- - -## Step 2: Add Messenger Product / Thêm Messenger Product - -### 2.1 Add Messenger - -**EN**: -1. In your app dashboard, click **"Add Product"** -2. Find **"Messenger"** and click **"Set Up"** - -**VI**: -1. Trong app dashboard, click **"Add Product"** -2. Tìm **"Messenger"** và click **"Set Up"** - -### 2.2 Generate Page Access Token - -**EN**: -1. In Messenger Settings, scroll to **"Access Tokens"** -2. Click **"Add or Remove Pages"** -3. Select your Facebook Page -4. Click **"Generate Token"** -5. **Copy and save** the Page Access Token - -**VI**: -1. Trong Messenger Settings, scroll đến **"Access Tokens"** -2. Click **"Add or Remove Pages"** -3. Chọn Facebook Page của bạn -4. Click **"Generate Token"** -5. **Copy và lưu** Page Access Token - -```bash -# EN: Save to .env file / VI: Lưu vào file .env -FACEBOOK_PAGE_ACCESS_TOKEN="EAAxxxxxxxxxx..." -``` - -> [!WARNING] -> Page Access Token is sensitive! Never commit to Git or expose publicly. - ---- - -## Step 3: Configure Webhook / Cấu Hình Webhook - -### 3.1 Deploy Service or Use ngrok - -**Option A: Local Development with ngrok** - -```bash -# EN: Install ngrok / VI: Cài đặt ngrok -brew install ngrok # macOS -# or download from ngrok.com - -# EN: Run service locally / VI: Chạy service local -dotnet run --project src/MktFacebookService.API - -# EN: Expose local service / VI: Expose service local -ngrok http 5000 - -# Copy HTTPS URL, e.g., https://abc123.ngrok.io -``` - -**Option B: Production Deployment** - -Deploy service to production server với HTTPS enabled. - -### 3.2 Add Webhook in Facebook App - -**EN**: -1. Go to Messenger → Settings → **"Webhooks"** -2. Click **"Add Callback URL"** -3. Enter: - - **Callback URL**: `https://your-domain.com/api/v1/webhooks/facebook` - - **Verify Token**: Create a random string (e.g., `my_verify_token_12345`) -4. Click **"Verify and Save"** - -**VI**: -1. Vào Messenger → Settings → **"Webhooks"** -2. Click **"Add Callback URL"** -3. Nhập: - - **Callback URL**: `https://your-domain.com/api/v1/webhooks/facebook` - - **Verify Token**: Tạo chuỗi random (ví dụ, `my_verify_token_12345`) -4. Click **"Verify and Save"** - -```bash -# EN: Save to .env / VI: Lưu vào .env -FACEBOOK_VERIFY_TOKEN="my_verify_token_12345" -``` - -> [!IMPORTANT] -> Verify Token phải match với giá trị trong service configuration! - -### 3.3 Subscribe to Webhook Events - -**EN**: After webhook is verified, select fields: - -**VI**: Sau khi webhook được verified, chọn các fields: - -- [x] **messages** - Receive customer messages -- [x] **messaging_postbacks** - Receive button clicks -- [x] **message_reads** - Receive read receipts (optional) -- [x] **messaging_optins** - Receive opt-in events - -Click **"Subscribe"**. - ---- - -## Step 4: Configure App Settings / Cấu Hình App Settings - -### 4.1 App Review (Production Only) - -**EN**: For production, you need to submit for app review: - -**VI**: Để production, cần submit app review: - -1. Go to **"App Review"** → **"Permissions and Features"** -2. Request **"pages_messaging"** permission -3. Provide: - - Screencast demo video - - Privacy Policy URL - - Terms of Service URL -4. Submit for review (takes 1-3 days) - -> [!NOTE] -> For testing, you can use Test Users without app review. - -### 4.2 Privacy Policy \u0026 Terms - -**EN**: Add Privacy Policy and Terms of Service URLs in **Settings → Basic**. - -**VI**: Thêm Privacy Policy và Terms of Service URLs trong **Settings → Basic**. - ---- - -## Step 5: Test Integration / Kiểm Tra Tích Hợp - -### 5.1 Send Test Message - -**EN**: -1. Go to your Facebook Page -2. Click **"Send Message"** (as a user, not admin) -3. Type: `Hello` -4. Check service logs for incoming webhook event - -**VI**: -1. Vào Facebook Page của bạn -2. Click **"Send Message"** (với tư cách user, không phải admin) -3. Gõ: `Hello` -4. Kiểm tra logs của service cho incoming webhook event - -**Expected Log**: -``` -[INFO] Received message event from user: 1234567890 -[INFO] Processing incoming message: "Hello" -[INFO] Sending response via Facebook Messenger -``` - -### 5.2 Test Get Started Button - -**EN**: Configure Get Started button to trigger welcome flow. - -**VI**: Cấu hình nút Get Started để trigger welcome flow. - -**cURL Command**: -```bash -curl -X POST "https://graph.facebook.com/v21.0/me/messenger_profile" \ - -H "Content-Type: application/json" \ - -d '{ - "get_started": { - "payload": "GET_STARTED" - } - }' \ - -d "access_token=YOUR_PAGE_ACCESS_TOKEN" -``` - -### 5.3 Test Quick Replies - -**Postman Request**: -```http -POST https://localhost/api/v1/conversations/{conversationId}/messages -Authorization: Bearer {jwt_token} -Content-Type: application/json - -{ - "messageText": "How can I help you?", - "quickReplies": [ - { "title": "Product Info", "payload": "PRODUCT_INFO" }, - { "title": "Contact Support", "payload": "SUPPORT" } - ] -} -``` - ---- - -## Step 6: Configure Persistent Menu (Optional) / Cấu Hình Menu Cố Định - -**EN**: Add a persistent menu for quick access to common actions. - -**VI**: Thêm menu cố định để truy cập nhanh các actions thường dùng. - -```bash -curl -X POST "https://graph.facebook.com/v21.0/me/messenger_profile" \ - -H "Content-Type: application/json" \ - -d '{ - "persistent_menu": [{ - "locale": "default", - "call_to_actions": [ - { - "type": "postback", - "title": "Shop Now", - "payload": "MENU_SHOP" - }, - { - "type": "postback", - "title": "My Orders", - "payload": "MENU_ORDERS" - }, - { - "type": "postback", - "title": "Help", - "payload": "MENU_HELP" - } - ] - }] - }' \ - -d "access_token=YOUR_PAGE_ACCESS_TOKEN" -``` - ---- - -## Environment Variables Summary / Tổng Hợp Biến Môi Trường - -```bash -# Facebook App Configuration -FACEBOOK_APP_ID="123456789012345" -FACEBOOK_APP_SECRET="abcdef1234567890abcdef1234567890" -FACEBOOK_VERIFY_TOKEN="my_verify_token_12345" - -# Facebook Page Access Token -FACEBOOK_PAGE_ACCESS_TOKEN="EAAxxxxxxxxxx..." - -# Facebook API Version -FACEBOOK_API_VERSION="v21.0" -``` - ---- - -## Troubleshooting / Xử Lý Sự Cố - -### Issue 1: Webhook Verification Failed - -**Problem / Vấn đề**: -``` -The URL couldn't be validated. Callback verification failed with the following errors: ... -``` - -**Solution / Giải pháp**: -1. Check service is running và accessible qua HTTPS -2. Verify `FACEBOOK_VERIFY_TOKEN` match exactly -3. Check logs for webhook GET request -4. Ensure returning hub.challenge as plain text (not JSON) - -### Issue 2: Not Receiving Messages - -**Problem / Vấn đề**: Service không nhận được messages - -**Solution / Giải pháp**: -1. Verify webhook subscriptions are active (messages, messaging_postbacks) -2. Check Page Access Token chưa expire -3. Test webhook manually: - ```bash - curl -X POST https://your-domain.com/api/v1/webhooks/facebook \ - -H "X-Hub-Signature-256: sha256=test" \ - -H "Content-Type: application/json" \ - -d '{...sample payload...}' - ``` - -### Issue 3: Cannot Send Messages - -**Problem / Vấn đề**: -``` -(#200) This user can't receive messages from this bot -``` - -**Solution / Giải pháp**: -- User must send a message first (GDPR compliance) -- Or user must opt-in via checkbox plugin -- Page Access Token phải có `pages_messaging` permission - -### Issue 4: Signature Verification Failed - -**Problem / Vấn đề**: `X-Hub-Signature-256 validation failed` - -**Solution / Giải pháp**: -1. Check `FACEBOOK_APP_SECRET` is correct -2. Verify signature calculation algorithm: -```csharp -var hash = HMACSHA256.HashData( - Encoding.UTF8.GetBytes(appSecret), - Encoding.UTF8.GetBytes(requestBody)); -var signature = "sha256=" + Convert.ToHexString(hash).ToLower(); -``` - ---- - -## Testing Checklist / Danh Sách Kiểm Tra - -- [ ] Facebook App created và Messenger product added -- [ ] Page Access Token generated và saved -- [ ] Webhook configured và verified -- [ ] Webhook events subscribed (messages, postbacks) -- [ ] Test message sent và received successfully -- [ ] Bot response sent back to user -- [ ] Get Started button triggers welcome flow -- [ ] Quick replies work correctly -- [ ] Persistent menu configured (if applicable) -- [ ] Signature verification working -- [ ] Error handling tested - ---- - -## Resources / Tài Nguyên - -### Official Facebook Documentation -- [Messenger Platform Overview](https://developers.facebook.com/docs/messenger-platform/) -- [Webhooks Reference](https://developers.facebook.com/docs/messenger-platform/webhooks) -- [Send API Reference](https://developers.facebook.com/docs/messenger-platform/send-messages) -- [Messenger Profile API](https://developers.facebook.com/docs/messenger-platform/messenger-profile) - -### Tools -- [Facebook Graph API Explorer](https://developers.facebook.com/tools/explorer/) -- [Webhook Tester](https://webhook.site/) - Test webhooks -- [ngrok](https://ngrok.com/) - Local HTTPS tunnel - -### Internal Docs -- [API Documentation](./API.md) -- [Architecture Documentation](./ARCHITECTURE.md) -- [AI Chatbot Configuration](./AI_CHATBOT.md) diff --git a/services/mkt-facebook-service-net/docs/ARCHITECTURE.md b/services/mkt-facebook-service-net/docs/en/ARCHITECTURE.md similarity index 60% rename from services/mkt-facebook-service-net/docs/ARCHITECTURE.md rename to services/mkt-facebook-service-net/docs/en/ARCHITECTURE.md index 46ae183e..303e70ab 100644 --- a/services/mkt-facebook-service-net/docs/ARCHITECTURE.md +++ b/services/mkt-facebook-service-net/docs/en/ARCHITECTURE.md @@ -1,17 +1,15 @@ -# Architecture Documentation - Tài Liệu Kiến Trúc +# Architecture Documentation **Service**: mkt-facebook-service-net **Last Updated**: 2026-01-18 -## Overview / Tổng Quan +## Overview -**EN**: The Facebook Marketing Service provides a comprehensive solution for businesses to engage with customers on Facebook Messenger through automated chatbots and AI-powered conversations. +The Facebook Marketing Service provides a comprehensive solution for businesses to engage with customers on Facebook Messenger through automated chatbots and AI-powered conversations. -**VI**: Dịch vụ Marketing Facebook cung cấp giải pháp toàn diện cho doanh nghiệp tương tác với khách hàng trên Facebook Messenger thông qua chatbots tự động và hội thoại AI. +## System Architecture -## System Architecture / Kiến Trúc Hệ Thống - -### High-Level Architecture / Kiến Trúc Tổng Quát +### High-Level Architecture ```mermaid graph TB @@ -48,7 +46,7 @@ graph TB end end - subgraph "Data \u0026 Messaging" + subgraph "Data & Messaging" PostgreSQL[(PostgreSQL)] Redis[(Redis)] RabbitMQ[RabbitMQ] @@ -80,9 +78,9 @@ graph TB Handlers -->|AI Completion| AIClient ``` -## Domain Model / Mô Hình Domain +## Domain Model -### Aggregates / Các Aggregate +### Aggregates #### 1. Conversation Aggregate @@ -133,14 +131,12 @@ classDiagram Message --> MessageDirection ``` -**EN**: The Conversation aggregate manages the lifecycle of a customer conversation, including all messages exchanged. +The Conversation aggregate manages the lifecycle of a customer conversation, including all messages exchanged. -**VI**: 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. - -**Business Rules / Quy Tắc Nghiệp Vụ**: -- Chỉ có thể thêm messages vào conversations Active -- Một conversation phải có ít nhất 1 message -- Messages không thể bị xóa, chỉ có thể archive conversation +**Business Rules**: +- Can only add messages to Active conversations +- A conversation must have at least 1 message +- Messages cannot be deleted, only archive conversation #### 2. Customer Aggregate @@ -167,15 +163,13 @@ classDiagram } ``` -**EN**: The Customer aggregate represents a Facebook user who interacts with the chatbot. +The Customer aggregate represents a Facebook user who interacts with the chatbot. -**VI**: Aggregate Customer đại diện cho một Facebook user tương tác với chatbot. - -**Business Rules / Quy Tắc Nghiệp Vụ**: -- FacebookUserId là unique identifier -- Tags phải là valid strings (không rỗng) -- Custom fields giới hạn 50 fields per customer -- Profile được sync từ Facebook Messenger Platform +**Business Rules**: +- `FacebookUserId` is unique identifier +- Tags must be valid non-empty strings +- Custom fields limited to 50 fields per customer +- Profile synced from Facebook Messenger Platform #### 3. ChatbotFlow Aggregate (Automation) @@ -219,15 +213,13 @@ classDiagram FlowNode --> NodeType ``` -**EN**: The ChatbotFlow aggregate defines automation rules and conversation flows. +The ChatbotFlow aggregate defines automation rules and conversation flows. -**VI**: Aggregate ChatbotFlow định nghĩa quy tắc tự động và luồng hội thoại. - -**Business Rules / Quy Tắc Nghiệp Vụ**: -- Mỗi flow phải có đúng 1 Start node -- Mỗi flow phải có ít nhất 1 End node -- Không được có circular references (vòng lặp vô hạn) -- TriggerValue phải unique trong cùng ShopId +**Business Rules**: +- Each flow must have exactly 1 Start node +- Each flow must have at least 1 End node +- No circular references (infinite loops) +- `TriggerValue` must be unique within ShopId #### 4. AIChatbotConfig Aggregate @@ -259,17 +251,15 @@ classDiagram AIChatbotConfig --> AIProvider ``` -**EN**: The AIChatbotConfig aggregate configures AI-powered chatbot behavior. +The AIChatbotConfig aggregate configures AI-powered chatbot behavior. -**VI**: Aggregate AIChatbotConfig cấu hình hành vi chatbot AI. +**Business Rules**: +- Temperature must be in range [0.0, 2.0] +- MaxTokens must be > 0 and <= 4096 +- SystemPrompt cannot be empty +- Only 1 active config per ShopId -**Business Rules / Quy Tắc Nghiệp Vụ**: -- Temperature phải trong khoảng [0.0, 2.0] -- MaxTokens phải \u003e 0 và \u003c= 4096 -- SystemPrompt không được rỗng -- Chỉ có 1 active config per ShopId - -## Message Processing Flow / Luồng Xử Lý Tin Nhắn +## Message Processing Flow ```mermaid sequenceDiagram @@ -315,47 +305,36 @@ sequenceDiagram Handler->>DB: Save changes ``` -**Key Steps / Các Bước Chính**: +**Key Steps**: -1. **Webhook Reception / Nhận Webhook**: Facebook gửi event đến service -2. **Signature Verification / Xác thực Chữ ký**: Verify Facebook request signature -3. **Customer \u0026 Conversation Management / Quản lý Khách hàng \u0026 Hội thoại**: Get hoặc tạo mới -4. **Strategy Selection / Lựa chọn Chiến lược**: Automation vs AI -5. **Response Generation / Tạo Phản hồi**: Dựa trên strategy -6. **Send Message / Gửi Tin nhắn**: Qua Facebook Messenger API -7. **Persistence / Lưu trữ**: Save message history +1. **Webhook Reception**: Facebook sends event to service +2. **Signature Verification**: Verify Facebook request signature +3. **Customer & Conversation Management**: Get or create +4. **Strategy Selection**: Automation vs AI +5. **Response Generation**: Based on strategy +6. **Send Message**: Via Facebook Messenger API +7. **Persistence**: Save message history -## Integration Patterns / Mẫu Tích Hợp +## Integration Patterns ### Facebook Messenger Platform Integration -**EN**: The service integrates with Facebook Messenger Platform via: +The service integrates with Facebook Messenger Platform via: - **Webhooks**: Receive messages, postbacks, read receipts - **Send API**: Send messages, quick replies, templates - **User Profile API**: Fetch user information -**VI**: Dịch vụ tích hợp với Facebook Messenger Platform qua: -- **Webhooks**: Nhận messages, postbacks, read receipts -- **Send API**: Gửi messages, quick replies, templates -- **User Profile API**: Lấy thông tin user - ### OpenAI Integration -**EN**: AI chatbot uses OpenAI Chat Completions API with: +AI chatbot uses OpenAI Chat Completions API with: - **Streaming**: Real-time response generation - **Context Management**: Multi-turn conversations - **Retry Logic**: Polly resilience policies - **Cost Tracking**: Monitor token usage -**VI**: AI chatbot sử dụng OpenAI Chat Completions API với: -- **Streaming**: Tạo phản hồi real-time -- **Context Management**: Hội thoại nhiều lượt -- **Retry Logic**: Polly resilience policies -- **Cost Tracking**: Theo dõi sử dụng tokens +## Data Model -## Data Model / Mô Hình Dữ Liệu - -### Database Schema / Lược Đồ Cơ Sở Dữ Liệu +### Database Schema ```mermaid erDiagram @@ -432,9 +411,9 @@ erDiagram } ``` -### Indexes / Chỉ Mục +### Indexes -**Performance Optimization / Tối Ưu Hiệu Năng**: +**Performance Optimization**: - `idx_conversations_customer_id` - Fast lookup by customer - `idx_conversations_page_id_status` - Filter active conversations by page - `idx_messages_conversation_id_sent_at` - Sort messages chronologically @@ -442,78 +421,58 @@ erDiagram - `idx_chatbot_flows_shop_id_trigger` - Match triggers - `idx_ai_configs_shop_id` - One config per shop -## Security / Bảo Mật +## Security ### Facebook Webhook Verification -**EN**: All incoming webhooks must: +All incoming webhooks must: 1. Include `X-Hub-Signature-256` header 2. Signature verified using App Secret 3. Invalid signatures rejected with 403 -**VI**: Tất cả webhooks phải: -1. Có header `X-Hub-Signature-256` -2. Signature được verify bằng App Secret -3. Signature không hợp lệ bị reject với 403 - ### API Authentication -**EN**: REST API endpoints require: +REST API endpoints require: - JWT Bearer token from IAM service - Role-based authorization (Admin, Agent, Viewer) -**VI**: REST API endpoints yêu cầu: -- JWT Bearer token từ IAM service -- Authorization theo role (Admin, Agent, Viewer) +### Data Privacy -### Data Privacy / Quyền Riêng Tư Dữ Liệu +- **GDPR Compliance**: Customer data export and deletion +- **Data Encryption**: At rest (PostgreSQL) and in transit (HTTPS) +- **PII Protection**: Customer info not logged to files -- **GDPR Compliance**: Customer data export và deletion -- **Data Encryption**: At rest (PostgreSQL) và in transit (HTTPS) -- **PII Protection**: Customer info không log ra files +## Scalability Considerations -## Scalability Considerations / Cân Nhắc Khả Năng Mở Rộng +### Horizontal Scaling -### Horizontal Scaling / Mở Rộng Ngang - -**EN**: Service supports horizontal scaling with: +Service supports horizontal scaling with: - **Stateless API**: No server-side sessions - **Redis Cache**: Shared cache across instances - **RabbitMQ**: Distributed message queue - **Load Balancer**: Traefik distributes traffic -**VI**: Service hỗ trợ mở rộng ngang với: -- **Stateless API**: Không có server-side sessions -- **Redis Cache**: Cache chia sẻ giữa các instances -- **RabbitMQ**: Message queue phân tán -- **Load Balancer**: Traefik phân phối traffic +### Rate Limiting -### Rate Limiting / Giới Hạn Tỷ Lệ - -**EN**: Facebook Messenger API limits: +Facebook Messenger API limits: - **100 messages/second** per app - **Burst tolerance**: Queue messages during spikes - **Retry with exponential backoff**: For 429 responses -**VI**: Giới hạn Facebook Messenger API: -- **100 tin nhắn/giây** mỗi app -- **Burst tolerance**: Queue messages khi tăng đột biến -- **Retry with exponential backoff**: Cho responses 429 +## Monitoring & Observability -## Monitoring \u0026 Observability / Giám Sát +### Key Metrics -### Key Metrics / Chỉ Số Chính - -| Metric | Description / Mô Tả | Target / Mục Tiêu | -|--------|---------------------|-------------------| -| **Webhook Latency** | Time to return 200 to Facebook | \u003c 500ms | -| **Message Processing Time** | Time to generate \u0026 send response | \u003c 2s | -| **AI Response Time** | OpenAI API latency | \u003c 5s | -| **Message Success Rate** | % messages sent successfully | \u003e 99% | +| Metric | Description | Target | +|--------|-------------|--------| +| **Webhook Latency** | Time to return 200 to Facebook | < 500ms | +| **Message Processing Time** | Time to generate & send response | < 2s | +| **AI Response Time** | OpenAI API latency | < 5s | +| **Message Success Rate** | % messages sent successfully | > 99% | | **Conversation Active Count** | Number of active conversations | - | | **AI Cost per Conversation** | Average OpenAI cost | Monitor | -### Health Checks / Kiểm Tra Sức Khỏe +### Health Checks - **Database**: PostgreSQL connection pooling - **Redis**: Cache availability @@ -521,33 +480,23 @@ erDiagram - **Facebook API**: API availability check - **OpenAI API**: Provider availability -## Design Decisions / Quyết Định Thiết Kế +## Design Decisions -### Why CQRS? / Tại Sao CQRS? +### Why CQRS? -**EN**: Separate read and write operations for: +Separate read and write operations for: - **Optimized Queries**: Use Dapper for fast reads - **Complex Commands**: Use EF Core with Domain Model -- **Scalability**: Scale reads và writes independently +- **Scalability**: Scale reads and writes independently -**VI**: Tách biệt operations đọc và ghi để: -- **Queries Tối Ưu**: Dùng Dapper cho reads nhanh -- **Commands Phức Tạp**: Dùng EF Core với Domain Model -- **Khả Năng Mở Rộng**: Scale reads và writes độc lập +### Why DDD? -### Why DDD? / Tại Sao DDD? - -**EN**: Complex business logic requires: +Complex business logic requires: - **Rich Domain Model**: Conversation, Customer aggregates -- **Encapsulation**: Business rules trong domain +- **Encapsulation**: Business rules in domain - **Domain Events**: Decouple side effects -**VI**: Logic nghiệp vụ phức tạp yêu cầu: -- **Rich Domain Model**: Conversation, Customer aggregates -- **Encapsulation**: Business rules trong domain -- **Domain Events**: Tách biệt side effects - -## Resources / Tài Nguyên +## Resources - [API Documentation](./API.md) - [Facebook Setup Guide](./FACEBOOK_SETUP.md) diff --git a/services/mkt-whatsapp-service-net/docs/en/AI_CHATBOT_GUIDE.md b/services/mkt-whatsapp-service-net/docs/AI_CHATBOT_GUIDE.md similarity index 100% rename from services/mkt-whatsapp-service-net/docs/en/AI_CHATBOT_GUIDE.md rename to services/mkt-whatsapp-service-net/docs/AI_CHATBOT_GUIDE.md diff --git a/services/mkt-whatsapp-service-net/docs/en/API.md b/services/mkt-whatsapp-service-net/docs/API.md similarity index 100% rename from services/mkt-whatsapp-service-net/docs/en/API.md rename to services/mkt-whatsapp-service-net/docs/API.md diff --git a/services/mkt-whatsapp-service-net/docs/en/ARCHITECTURE.md b/services/mkt-whatsapp-service-net/docs/ARCHITECTURE.md similarity index 100% rename from services/mkt-whatsapp-service-net/docs/en/ARCHITECTURE.md rename to services/mkt-whatsapp-service-net/docs/ARCHITECTURE.md diff --git a/services/mkt-whatsapp-service-net/docs/en/AUTOMATION_GUIDE.md b/services/mkt-whatsapp-service-net/docs/AUTOMATION_GUIDE.md similarity index 100% rename from services/mkt-whatsapp-service-net/docs/en/AUTOMATION_GUIDE.md rename to services/mkt-whatsapp-service-net/docs/AUTOMATION_GUIDE.md diff --git a/services/mkt-whatsapp-service-net/docs/en/WHATSAPP_SETUP.md b/services/mkt-whatsapp-service-net/docs/WHATSAPP_SETUP.md similarity index 100% rename from services/mkt-whatsapp-service-net/docs/en/WHATSAPP_SETUP.md rename to services/mkt-whatsapp-service-net/docs/WHATSAPP_SETUP.md diff --git a/services/mkt-whatsapp-service-net/docs/en/README.md b/services/mkt-whatsapp-service-net/docs/en/README.md new file mode 100644 index 00000000..ed4e992b --- /dev/null +++ b/services/mkt-whatsapp-service-net/docs/en/README.md @@ -0,0 +1,36 @@ +# MKT WhatsApp Service Documentation + +Welcome to the MKT WhatsApp Service documentation. + +## 📚 Documentation + +- **[Architecture](./ARCHITECTURE.md)** - System design, Clean Architecture layers, domain models, and integration patterns +- **[API Reference](./API.md)** - Complete API documentation with request/response examples +- **[WhatsApp Setup Guide](./WHATSAPP_SETUP.md)** - Step-by-step guide to setup Meta Business Account and WhatsApp API +- **[Automation Guide](./AUTOMATION_GUIDE.md)** - Creating automation flows with triggers, steps, and conditions +- **[AI Chatbot Guide](./AI_CHATBOT_GUIDE.md)** - Configuring AI agents with LLM, prompt engineering, and cost optimization + +## 🚀 Quick Links + +### Getting Started +1. [WhatsApp Setup Guide](./WHATSAPP_SETUP.md) - Setup WhatsApp Business API +2. [Architecture Overview](./ARCHITECTURE.md#system-overview) - Understand the system +3. [API Endpoints](./API.md) - Explore available APIs + +### Development +- [Development Workflow](./ARCHITECTURE.md#clean-architecture-layers) - 4-phase development process +- [Domain Models](./ARCHITECTURE.md#domain-layer) - Business entities and aggregates +- [Testing Guide](./ARCHITECTURE.md#monitoring--observability) - Testing strategies + +### Integration +- [Webhooks](./API.md#webhooks) - Receiving WhatsApp events +- [Automation Flows](./AUTOMATION_GUIDE.md#creating-a-flow) - Creating automation +- [AI Configuration](./AI_CHATBOT_GUIDE.md#creating-an-ai-agent) - Setup AI chatbot + +## 🌍 Language + +This is the **English** documentation. For Vietnamese, see [docs/vi/](../vi/README.md). + +## 📖 Main README + +Return to [main README](../../README.md) for service overview. 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 deleted file mode 100644 index cdda2162..00000000 --- a/services/mkt-whatsapp-service-net/docs/vi/AI_CHATBOT_GUIDE.md +++ /dev/null @@ -1,416 +0,0 @@ -# Hướng Dẫn AI Chatbot - -**Cập nhật lần cuối**: 2026-01-18 - -Học cách cấu hình và tối ưu chatbot AI cho hội thoại WhatsApp. - -## Tổng Quan - -AI Chatbot sử dụng Large Language Models (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âu hỏi không mong đợi -- Học từ các mẫu hội thoại - -## Nhà Cung Cấp LLM Được Hỗ Trợ - -| Nhà Cung Cấp | Model | Chi Phí (per 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 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 vấn đề phức tạp" - ], - "promptTemplate": "Bạn là nhân viên hỗ trợ khách hàng thân thiện cho {shop_name}." - }, - "knowledgeBaseId": "kb-guid", - "isActive": false -} -``` - -## Cấu Hình Personality - -### Tùy Chọn Tone - -**Friendly** (Khuyến nghị cho bán lẻ) -``` -"Bạn là trợ lý nhiệt tình và thân thiện. Sử dụng emoji thỉnh thoảng. -Xưng hô với khách hàng một cách thân mật 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ẻ) -``` -"Bạn là trợ lý chill và gần gũi. Sử dụng ngôn ngữ không chính thức. -Giữ phản hồi ngắn gọn. Dùng slang thịnh hành khi phù 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 dùng tiếng Anh -3. Xử lý ngôn ngữ hỗn hợp (Vienglish) - -### Constraints (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ó phê duyệt", - "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 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ò: Giúp khách hàng với câu hỏi về sản phẩm, tra đơ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} -- Đơn hàng trước đây: {purchase_count} - -Knowledge Base: -{knowledge_base_content} - -Hướng dẫn: -- Hữu ích và ngắn gọn -- Nếu không chắc chắn, nói thẳng và đề nghị kết nối nhân viên -- Không bao giờ bịa thông tin -- Luôn xác nhận trước khi hành động - -Ngày hiện tại: {current_date} -Thời gian hiện tại: {current_time} -``` - -## Tích Hợp Knowledge Base - -### Tạo Knowledge Base - -Upload 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 miễn phí vận chuyển cho đơn hàng trên 500,000 VNĐ..." - }, - { - "title": "Chính Sách Đổi Trả", - "content": "Bạn có thể đổi trả sản phẩm 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 khảo 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. - -### Biến Ngữ Cảnh Tùy Chỉnh - -Đưa vào ngữ cảnh động: - -```json -{ - "contextVariables": { - "customer_tier": "vip", - "cart_value": "2500000", - "last_purchase_date": "2026-01-10", - "preferred_category": "electronics" - } -} -``` - -## Tạo Phản Hồi - -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" - -[Internal AI Pipeline] -1. Load lịch sử hội thoại -2. Lấy hồ sơ khách hàng (tags, custom fields) -3. Query knowledge base cho thông tin liên quan -4. Xây dựng prompt với ngữ cảnh -5. Gọi OpenAI API -6. Parse phản hồi -7. Áp dụng safety filters -8. Gửi đến khách hàng -``` - -## Xử Lý Fallback - -### Khi AI Nên Chuyển Giao - -Cấu hình điều kiện để chuyển cho nhân viên: - -```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"} - ] -} -``` - -## Tối Ưu Chi Phí - -### 1. Phân Loại Intent - -Trước khi gọi GPT-4 đắt tiền, dùng classifier rẻ: - -```json -{ - "intentClassifier": { - "enabled": true, - "model": "gpt-3.5-turbo", - "categories": ["faq", "product_inquiry", "order_tracking", "complaint", "other"] - } -} -``` - -Route sang GPT-3.5 cho FAQs, GPT-4 cho truy vấn phức tạp. - -### 2. Response Caching - -Cache các câu hỏi phổ biến: - -```json -{ - "caching": { - "enabled": true, - "ttl": 3600, - "similarityThreshold": 0.95 - } -} -``` - -Nếu khách hàng hỏi "Có giao hàng đến Hà Nội không?" và cache có câu trả lời cho câu hỏi tương tự → trả về cached response (không API call = $0). - -### 3. Giới Hạn Token - -Đặt max tokens để tránh chi phí vượt quá: - -```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 đạt 80% ngân sách. - -## An Toàn & Kiểm Duyệt - -### Lọc Nội Dung - -Bật OpenAI moderation: - -```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 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. - -## Kiểm Tra - -### Test Mode - -Mô phỏng phản hồi AI mà không gửi đến 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"] - } -} -``` - -## Cách Tiếp Cận Hybrid - -Kết hợp tự động hóa + AI để có kết quả tốt nhất: - -### Chiến Lược 1: Tự Động Hóa Trước - -1. Tin nhắn đến → Kiểm tra automation flows -2. Nếu không khớp → Route đến AI -3. Phản hồi AI → Gửi đến khách hàng - -### Chiến Lược 2: AI Phân Loại - -1. AI phân loại intent -2. Route đến automation flow phù hợp -3. Fallback sang AI nếu không có flow 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 -- Ngoài giờ: Chỉ tự động hóa (FAQ đơn giản) - -## Thực Hành Tốt - -1. **Bắt đầu với phạm vi hẹp** - Train AI trên các danh mục cụ thể trước -2. **Review thường xuyên** - Mẫu hội thoại hàng tuần -3. **Cập nhật knowledge base** - Giữ thông tin sản phẩm/chính sách hiện tại -4. **Đặt constraints rõ ràng** - Định nghĩa AI có thể/không thể làm gì -5. **Giám sát chi phí** - Đặt ngân sách và cảnh báo -6. **Human in the loop** - Luôn cung cấp đường chuyển giao -7. **Tối ưu 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 - -## Xử Lý Sự Cố - -### Phản Hồi AI Quá Chung Chung - -**Giải pháp**: Thêm nhiều ngữ cảnh và ví dụ vào prompt template. - -### AI Cung Cấp Thông Tin Sai - -**Gải pháp**: -1. Cập nhật knowledge base -2. Thêm constraint trong prompt -3. Review và retrain - -### Chi Phí Cao - -**Giải pháp**: -1. Bật phân loại intent -2. Giảm max tokens -3. 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 context window (ít tin nhắn lịch sử hơn) -2. Bật streaming -3. Dùng model nhanh hơn (GPT-3.5) - -## Bước Tiếp Theo - -- [Tài Liệu API](API.md) - Tài liệu API cho AI agent -- [Hướng Dẫn Tự Động Hóa](AUTOMATION_GUIDE.md) - Kết hợp với automation -- [Kiến Trúc](ARCHITECTURE.md) - Hiểu về AI pipeline - -## Tài Nguyên - -- [OpenAI Best Practices](https://platform.openai.com/docs/guides/prompt-engineering) -- [Prompt Engineering Guide](https://www.promptingguide.ai/) -- [LLM Cost Calculator](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 deleted file mode 100644 index ae2061c5..00000000 --- a/services/mkt-whatsapp-service-net/docs/vi/API.md +++ /dev/null @@ -1,390 +0,0 @@ -# Tài Liệu API - -**Dịch vụ**: mkt-whatsapp-service-net -**Phiên bản**: v1.0 -**Base URL**: `/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 Response - -Tất cả responses tuân theo cấu trúc này: - -```json -{ - "success": true | false, - "data": { ... }, - "error": "Error message" | null, - "pagination": { ... } | null -} -``` - ---- - -## Webhooks - -### Xác Minh Webhook - -**GET** `/webhooks` - -WhatsApp verification challenge. - -**Response**: (Plain text) hub.challenge value - -### Nhận Events - -**POST** `/webhooks` - -Nhận sự kiện tin nhắn từ WhatsApp. - -**Headers**: -- `X-Hub-Signature-256` - HMAC-SHA256 signature - ---- - -## Tài Khoản WhatsApp - -### Kết Nối Tài Khoản - -**POST** `/accounts` - -Kết nối WhatsApp Business Account. - -**Request**: -```json -{ - "shopId": "550e8400-e29b-41d4-a716-446655440000", - "phoneNumberId": "123456789", - "accessToken": "EAAxxxxx", - "webhookUrl": "https://yourdomain.com/api/v1/whatsapp/webhooks" -} -``` - -### Lấy Tài Khoản - -**GET** `/accounts/{shopId}` - -Lấy chi tiết tài khoản cho shop. - -### Ngắt Kết Nối Tài Khoản - -**DELETE** `/accounts/{shopId}` - -Ngắt kết nối WhatsApp Business Account. - ---- - -## Hội Thoại - -### Liệt Kê Hội Thoại - -**GET** `/conversations` - -Lấy danh sách hội thoại có phân trang. - -**Query Parameters**: -- `shopId` (bắt buộc) - Shop ID -- `status` (tùy chọn) - Lọc: `active`, `closed`, `expired` -- `assignedAgentId` (tùy chọn) - Lọc theo agent -- `skip` (mặc định: 0) - Offset phân trang -- `take` (mặc định: 20, max: 100) - Kích thước trang - -### Lấy Hội Thoại - -**GET** `/conversations/{conversationId}` - -Lấy chi tiết hội thoại với tin nhắn. - -### Gửi Tin Nhắn - -**POST** `/conversations/{conversationId}/messages` - -Gửi tin nhắn trong hội thoại. - -**Request (Text)**: -```json -{ - "content": { - "type": "text", - "text": "Cảm ơn bạn đã liên hệ!" - } -} -``` - -**Request (Media)**: -```json -{ - "content": { - "type": "image", - "url": "https://example.com/product.jpg", - "caption": "Xem sản phẩm này!" - } -} -``` - -**Request (Interactive)**: -```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"} - ] - } - } - } -} -``` - -### Chỉ Định Hội Thoại - -**POST** `/conversations/{conversationId}/assign` - -Chỉ định hội thoại cho một agent. - -### Đóng Hội Thoại - -**POST** `/conversations/{conversationId}/close` - -Đóng hội thoại. - ---- - -## Khách Hàng - -### Liệt Kê Khách Hàng - -**GET** `/customers` - -Lấy danh sách khách hàng có phân trang. - -**Query Parameters**: -- `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 tách bằng dấu phẩy) -- `skip` / `take` (phân trang) - -### Lấy Khách Hàng - -**GET** `/customers/{waId}` - -Lấy hồ sơ khách hàng. - -### Cập Nhật Tags Khách Hàng - -**PUT** `/customers/{waId}/tags` - -Thêm hoặc xóa tags khách hàng. - -**Request**: -```json -{ - "addTags": ["vip", "mua-dien-tu"], - "removeTags": ["khach-hang-moi"] -} -``` - -### Cập Nhật Trạng Thái Opt-In - -**PUT** `/customers/{waId}/opt-in` - -Cập nhật đồng ý của khách hàng. - -**Request**: -```json -{ - "status": "opted_in", - "source": "web" -} -``` - ---- - -## Automation Flows - -### Liệt Kê Flows - -**GET** `/flows` - -Lấy automation flows. - -### Tạo Flow - -**POST** `/flows` - -Tạo automation flow. - -### Cập Nhật Flow - -**PUT** `/flows/{flowId}` - -Cập nhật cấu hình flow. - -### Kích Hoạt Flow - -**POST** `/flows/{flowId}/activate` - -Bật automation flow. - -### Vô Hiệu Hóa Flow - -**POST** `/flows/{flowId}/deactivate` - -Tắt automation flow. - ---- - -## AI Agents - -### Tạo AI Agent - -**POST** `/ai-agents` - -Cấu hình chatbot AI. - -### Cập Nhật AI Agent - -**PUT** `/ai-agents/{agentId}` - -Cập nhật personality/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"] - } -} -``` - -**Response**: -```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 metrics khối lượng tin nhắn. - -### Metrics Hội Thoại - -**GET** `/analytics/conversations` - -Lấy metrics hiệu suất hội thoại. - -### Hiệu Suất Tự Động Hóa - -**GET** `/analytics/automations` - -Lấy thống kê thực thi automation flow. - ---- - -## Mã Lỗi - -| Code | Thông Báo | Mô Tả | -|------|---------|-------------| -| 400 | Bad Request | Định dạng request không hợp lệ | -| 401 | Unauthorized | Thiếu hoặc auth token không hợp lệ | -| 404 | Not Found | Resource không tồn tại | -| 409 | Conflict | Resource trùng lặp | -| 422 | Validation Error | Vi phạm business rule | -| 429 | Rate Limit Exceeded | Quá nhiều requests | -| 500 | Internal Server Error | Lỗi server | - -**Định Dạng Error Response**: -```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 requests/phút per shop -- **Webhooks**: Không giới hạn (nhưng phải phản hồi < 5s) -- **Analytics**: 10 requests/phút per shop - -## Xác Thực Webhook Signature - -Xác minh header `X-Hub-Signature-256`. - -## Phân Trang - -Tất cả list endpoints hỗ trợ phân trang: - -**Request**: -``` -GET /conversations?skip=20&take=20 -``` - -**Response**: -```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 -- Automation flows -- 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 deleted file mode 100644 index ab9f0732..00000000 --- a/services/mkt-whatsapp-service-net/docs/vi/ARCHITECTURE.md +++ /dev/null @@ -1,238 +0,0 @@ -# Tài Liệu Kiến Trúc - -**Dịch vụ**: mkt-whatsapp-service-net -**Phiên bản**: 1.0 -**Cập nhật lần cuối**: 2026-01-18 - -## Tổng Quan Hệ Thống - -MKT WhatsApp Service là một microservice toàn diện được xây dựng trên nguyên tắc Clean Architecture, triển khai các pattern Domain-Driven Design (DDD) và CQRS. Dịch vụ cung cấp ba khả năng cốt lõi: - -1. **Chatbot Tự Động**: Luồng hội thoại dựa trên quy tắc -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 - -### Kiến Trúc Tổng Thể - -_(Diagram giống như phiên bản English)_ - -## Các Tầng Clean Architecture - -### 1. Tầng API (`MktWhatsAppService.API`) - -**Trách nhiệm**: Giao diện HTTP, xử lý request/response - -#### Controllers -- `WebhooksController` - Xác thực webhook và sự kiện tin nhắn từ WhatsApp -- `WhatsAppAccountsController` - Quản lý kết nối tài khoản -- `ConversationsController` - Các API liên quan hội thoại và tin nhắn -- `CustomersController` - Quản lý hồ sơ khách hàng -- `AutomationFlowsController` - CRUD automation flows -- `AIAgentsController` - Cấu hình AI agent -- `AnalyticsController` - Metrics và báo cáo - -#### Background Jobs -- `ConversationExpiryJob` - Đóng hội thoại hết hạn sau 24h -- `MessageStatusSyncJob` - Đồng bộ trạng thái delivered/read từ WhatsApp -- `FlowSchedulerJob` - Trigger automation flows theo thời gian - -### 2. Tầng Application (`MktWhatsAppService.API/Application`) - -**Trách nhiệm**: Use cases, orchestration, 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` - Hủy kích hoạt tài khoản - -**Tin Nhắn** -- `ProcessIncomingMessageCommand` - Xử lý tin nhắn đến từ WhatsApp -- `SendMessageCommand` - Gửi tin nhắn đi -- `SendTemplateMessageCommand` - Gửi template đã được phê duyệt - -**Tự Động Hóa** -- `CreateAutomationFlowCommand` - Định nghĩa flow mới -- `UpdateFlowStepCommand` - Sửa đổi logic flow -- `ActivateFlowCommand` - Bật tự động hóa -- `DeactivateFlowCommand` - Tắt tự động hóa - -**AI Agent** -- `CreateAIAgentCommand` - Cấu hình chatbot AI -- `UpdateAgentPersonalityCommand` - Sửa đổi hành vi AI -- `GenerateAIResponseCommand` - Lấy phản hồi AI - -**Khách Hàng** -- `CreateCustomerCommand` - Đăng ký khách hàng mới -- `UpdateCustomerOptInCommand` - Quản lý đồng ý nhận tin -- `TagCustomerCommand` - Thêm/xóa tags - -#### Queries (Đọc) - -**Hội Thoại** -- `GetConversationQuery` - Lấy 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 full-text - -**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` - Metrics khối 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 flow - -#### MediatR Pipeline Behaviors -1. **Logging Behavior** - 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**: Business logic, entities, business rules - -#### Aggregates - -_(Nội dung chi tiết aggregates tương tự phiên bản English, chỉ dịch các comment và description sang tiếng Việt)_ - -### 4. Tầng Infrastructure (`MktWhatsAppService.Infrastructure`) - -**Trách nhiệm**: External concerns, persistence, API clients - -#### Truy Cập Dữ Liệu -- `MktWhatsAppServiceContext` - EF Core DbContext -- Entity Configurations sử dụng Fluent API -- Repositories triển khai domain interfaces - -#### External Services - -##### WhatsAppCloudApiClient -HTTP client cho WhatsApp Cloud API với Polly resilience policies. - -##### LlmService -Abstraction cho LLM provider (triển khai OpenAI). - -## Luồng Xử Lý Tin Nhắn - -_(Sequence diagrams tương tự phiên bản English)_ - -## Mô Hình Dữ Liệu - -Xem [Tài Liệu Database Schema](DATABASE_SCHEMA.md) để biết chi tiết cấu trúc bảng 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ẻ (owned by conversation) -- `customers` - Hồ sơ khách hàng -- `automation_flows` - Định nghĩa automation flow -- `flow_steps` - Cấu hình bước flow -- `ai_agents` - Cấu hình AI agent - -## Integration Events - -Dịch vụ publish events đến RabbitMQ để các service khác consume. - -### Events Được Publish - -**WhatsAppMessageReceivedEvent** -- Phát ra khi: Khách hàng gửi tin nhắn đến shop -- Consumers: analytics-service (metrics), merchant-service (thông báo) - -**ConversationClosedEvent** -- Phát ra khi: Hội thoại được đóng hoặc hết hạn -- Consumers: 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 -- Consumers: wallet-service (billing), analytics-service (theo dõi chi phí) - -**CustomerOptInChangedEvent** -- Phát ra khi: Trạng thái opt-in của khách hàng thay đổi -- Consumers: marketing services (cập nhật quyền) - -## Bảo Mật - -### Xác Thực Webhook Signature - -Tất cả webhooks đến từ WhatsApp được xác thực bằng HMAC-SHA256. - -### Mã Hóa Access Token - -WhatsApp access tokens được mã hóa khi lưu trữ bằng AES-256-GCM. - -### Rate Limiting - -Rate limiter phân tán dựa trên Redis: -- 60 requests/phút per shop -- 1000 requests/phút per service instance - -### Tuân Thủ GDPR - -- Dữ liệu khách hàng có thể được export qua API -- Right to be forgotten: soft delete với anonymization -- Tracking đồng ý opt-in với timestamps -- Chính sách lưu trữ dữ liệu được thực thi - -## Tối Ưu Hiệu Năng - -### Chiến Lược Caching - -**Sử Dụng Redis Cache:** -1. **Conversation Context** - 10 tin nhắn cuối (TTL: 1 giờ) -2. **Customer Profiles** - Khách hàng được truy cập thường xuyên (TTL: 30 phút) -3. **Active Flows** - Automation flows (TTL: 5 phút) -4. **Rate Limit Counters** - Số requests per shop (TTL: 1 phút) - -### Tối Ưu Query - -- Dùng Dapper cho read-heavy queries (bypass EF Core) -- Triển khai pagination cho tất cả list endpoints -- Index trên foreign keys và các cột thường được filter -- Không có N+1 queries (dùng `Include()` hoặc projections) - -### Background Processing - -- Webhook processing trả về 200 ngay lập tức -- Gửi tin nhắn được queue vào background job -- Flow execution chạy bất đồng bộ - -## Giám Sát & Quan Sát - -### Health Checks - -Kiểm tra kết nối đến PostgreSQL, Redis, RabbitMQ, WhatsApp API, và 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 với correlation IDs và redaction cho sensitive data. - -## Kiến Trúc Triển Khai - -Xem [Deployment Guide](DEPLOYMENT.md) cho Kubernetes manifests và scaling strategies. - -**Trigger Mở Rộng:** -- CPU > 70% → Scale up pods -- Webhook queue > 1000 messages → Scale up -- Memory > 80% → Investigate + scale - -**Resource Limits:** -- 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) -- [OpenAPI Specification](../openapi.yaml) -- [Domain Model Details](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 deleted file mode 100644 index ea144703..00000000 --- a/services/mkt-whatsapp-service-net/docs/vi/AUTOMATION_GUIDE.md +++ /dev/null @@ -1,262 +0,0 @@ -# Hướng Dẫn Tự Động Hóa - -**Cập nhật lần cuối**: 2026-01-18 - -Học cách tạo và quản lý automation flows cho hội thoại WhatsApp. - -## Tổng Quan - -Automation flows cho phép bạn định nghĩa logic chatbot dựa trên quy tắc không cần AI. Các use case 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 -- Phân loại leads -- Đặt lịch hẹn -- Định tuyến hỗ trợ khách hàng - -## Khái Niệm Cốt Lõi - -### Loại Trigger - -|Trigger | Mô Tả | Ví Dụ | -|---------|-------------|---------| -| **Keyword** | Tin nhắn chứa văn bản cụ thể | "hi", "help", "giá" | -| **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 trong Flow - -Mỗi flow bao gồm các bước được sắp xếp. Loại bước: - -**1. Send Message** - Gửi tin nhắn text hoặc media - -**2. Quick Reply** - Hiển thị nút để khách hàng nhấn - -**3. Tag Customer** - Thêm/xóa tag khách hàng - -**4. Call Webhook** - POST dữ liệu đến URL bên ngoài - -**5. Assign to Agent** - Chuyển hội thoại cho nhân viên - -**6. Delay** - Chờ trước bước tiếp theo - -**7. Conditional Branch** - Logic if/else - -## Tạo Flow - -### 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", "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ợ"} - ] - } - } - ] -} -``` - -## Ví Dụ Flow - -### Ví Dụ 1: FAQ Bot - -**Trigger**: Keywords "giá", "chi phí", "bao nhiêu" - -**Flow**: -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 gì?" -2. Quick Reply: ["Quần Áo", "Điện Tử", "Thực Phẩm"] -3. Conditional: - - Nếu "Quần Áo" → Gửi bảng giá quần áo - - 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**: Keyword "đặt lịch", "hẹn" - -**Flow**: -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. Quick Reply: ["Tư Vấn", "Khám", "Tái Khám"] -4. Tag Customer: "lich-hen-cho-xu-ly" -5. Call Webhook: POST đến hệ thống đặt lịch -6. Delay: 2 giây (chờ webhook response) -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 Đơn Hàng - -**Trigger**: Keyword "tra đơn", "đơn hàng" - -**Flow**: -1. Gửi: "Vui lòng gửi mã đơn hàng (VD: #12345)" -2. (Khách hàng trả lời với mã đơn hàng) -3. Call Webhook: GET trạng thái đơn hàng từ backend -4. Conditional: - - Nếu tìm thấy đơn → Gửi trạng thái + link tracking - - 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ố điện thoại WhatsApp -- `{customer_tags}` - Tags phân tách bằng dấu phẩy - -### Biến Shop - -- `{shop_name}` - Tên shop -- `{shop_url}` - URL website shop - -### Biến Hội Thoại - -- `{conversation_id}` - UUID hội thoại -- `{message_count}` - Số tin nhắn trong hội thoại - -## Điều Kiện - -### Các Điều Kiện Được Hỗ Trợ - -**Tag Tồn Tại** -```json -{ - "type": "tag_exists", - "tag": "khach-hang-vip" -} -``` - -**Custom Field Bằng** -```json -{ - "type": "custom_field_equals", - "field": "city", - "value": "Hanoi" -} -``` - -**Thời Gian Trong Ngày** -```json -{ - "type": "time_of_day", - "start": "09:00", - "end": "17:00", - "timezone": "Asia/Ho_Chi_Minh" -} -``` - -## Kích Hoạt Flow - -```bash -POST /api/v1/whatsapp/flows/{flowId}/activate -``` - -## Kiểm Tra Flow - -### Test Mode - -Bật test mode để xem 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": "chào" -} -``` - -## Thực Hành Tốt - -### 1. Giữ Flow Đơn Giản - -- Tối đa 10 bước mỗi flow -- Tránh nesting sâu của điều kiện -- Chia flow phức tạp thành nhiều flow 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 ("hỗ trợ", "help") -- Bắt đầu lại ("restart", "menu") -- Opt out ("stop", "unsubscribe") - -### 3. Xử Lý Input Không Biết - -Thêm bước fallback: -```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 Delays Khôn Ngoan - -- Sau webhook calls: 2-5 giây -- Giữa các tin nhắn: 1-2 giây (tự nhiên hơn) -- Tránh delays > 10 giây (khách hàng có thể rời đi) - -## Giới Hạn - -- Tối đa 50 flows active mỗi shop -- Tối đa 20 bước mỗi flow -- Tối đa 10 nút quick reply mỗi tin nhắn -- Webhook timeout: 10 giây -- Không có vòng lặp (xác thực chống cycle) - -## Xử Lý Sự Cố - -### Flow Không Trigger - -**Kiểm tra**: -1. Flow đã được kích hoạt (`isActive: true`) -2. Trigger keyword khớp chính xác (không phân biệt chữ hoa/thường) -3. Không có flow ưu tiên cao hơn matching trước -4. Khách hàng chưa opt out - -### Webhook Thất Bại - -**Kiểm tra**: -1. Webhook URL có thể truy cập (yêu cầu HTTPS) -2. Webhook phản hồi trong vòng 10 giây -3. Response status code là 200 -4. Response JSON hợp lệ - -## 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 hybrid -- [Tài Liệu API](API.md) - Tài liệu API đầy đủ -- [Kiến Trúc](ARCHITECTURE.md) - Hiểu về automation engine diff --git a/services/mkt-whatsapp-service-net/docs/vi/README.md b/services/mkt-whatsapp-service-net/docs/vi/README.md new file mode 100644 index 00000000..16009d0c --- /dev/null +++ b/services/mkt-whatsapp-service-net/docs/vi/README.md @@ -0,0 +1,36 @@ +# Tài Liệu Dịch Vụ MKT WhatsApp + +Chào mừng đến với tài liệu Dịch vụ MKT WhatsApp. + +## 📚 Tài Liệu + +- **[Kiến Trúc](./ARCHITECTURE.md)** - Thiết kế hệ thống, các tầng Clean Architecture, domain models, và integration patterns +- **[Tài Liệu API](./API.md)** - Tài liệu API đầy đủ với ví dụ request/response +- **[Hướng Dẫn Thiết Lập WhatsApp](./WHATSAPP_SETUP.md)** - Hướng dẫn từng bước thiết lập Meta Business Account và WhatsApp API +- **[Hướng Dẫn Tự Động Hóa](./AUTOMATION_GUIDE.md)** - Tạo automation flows với triggers, steps, và conditions +- **[Hướng Dẫn AI Chatbot](./AI_CHATBOT_GUIDE.md)** - Cấu hình AI agents với LLM, prompt engineering, và tối ưu chi phí + +## 🚀 Liên Kết Nhanh + +### Bắt Đầu +1. [Hướng Dẫn Thiết Lập WhatsApp](./WHATSAPP_SETUP.md) - Thiết lập WhatsApp Business API +2. [Tổng Quan Kiến Trúc](./ARCHITECTURE.md#tổng-quan-hệ-thống) - Hiểu về hệ thống +3. [API Endpoints](./API.md) - Khám phá các APIs có sẵn + +### Phát Triển +- [Quy Trình Phát Triển](./ARCHITECTURE.md#các-tầng-clean-architecture) - Quy trình 4 giai đoạn +- [Domain Models](./ARCHITECTURE.md#tầng-domain-mktwhatsappservicedomain) - Business entities và aggregates +- [Hướng Dẫn Kiểm Thử](./ARCHITECTURE.md#giám-sát--quan-sát) - Chiến lược testing + +### Tích Hợp +- [Webhooks](./API.md#webhooks) - Nhận sự kiện WhatsApp +- [Automation Flows](./AUTOMATION_GUIDE.md#tạo-flow) - Tạo tự động hóa +- [Cấu Hình AI](./AI_CHATBOT_GUIDE.md#tạo-ai-agent) - Thiết lập AI chatbot + +## 🌍 Ngôn Ngữ + +Đây là tài liệu **Tiếng Việt**. Để xem tiếng Anh, truy cập [docs/en/](../en/README.md). + +## 📖 README Chính + +Quay lại [README chính](../../README.md) để xem tổng quan dịch vụ. diff --git a/services/mkt-whatsapp-service-net/docs/vi/WHATSAPP_SETUP.md b/services/mkt-whatsapp-service-net/docs/vi/WHATSAPP_SETUP.md deleted file mode 100644 index 756be211..00000000 --- a/services/mkt-whatsapp-service-net/docs/vi/WHATSAPP_SETUP.md +++ /dev/null @@ -1,261 +0,0 @@ -# Hướng Dẫn Thiết Lập WhatsApp - -**Cập nhật lần cuối**: 2026-01-18 - -Hướng dẫn từng bước để thiết lập truy cập WhatsApp Business API cho MKT WhatsApp Service. - -## Yêu Cầu Trước Khi Bắt Đầu - -- Tài khoản Meta Business -- Quyền truy cập Facebook Business Manager -- Doanh nghiệp đã được xác minh (để có giới hạn tier cao hơn) -- Domain có 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 "Tạo Tài Khoản" -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 khuyến nghị cho hầu hết các trường hợp sử dụng. - -## Bước 3: Lấy Số Điện Thoại - -### Số Test (Development) - -Meta cung cấp một số test cho phát triển: - -1. Trong cài đặt WhatsApp product, bạn sẽ thấy số điện thoại test -2. Copy `Phone Number ID` -3. Thêm người nhận test (tối đa 5 người) trong tab Configuration - -### Số Production - -1. Nhấp "Add Phone Number" -2. Chọn một trong hai: - - **Use existing**: 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/gọi điện -4. Hoàn thành 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 WhatsApp Business App trên số này. - -## Bước 4: Tạo Access Token - -### Token Tạm Thời (24 giờ) - -1. Vào WhatsApp → API Setup -2. Copy temporary access token -3. Chỉ dùng để test - -### Token Vĩnh Viễn - -1. Vào Meta Business Suite → Settings → System Users -2. Nhấp "Add" → Tạo system user (tên: "WhatsApp API") -3. Gán role "Admin" -4. Nhấp "Generate Token" -5. Chọn app của bạn -6. Chọn permissions: - - `whatsapp_business_management` - - `whatsapp_business_messaging` -7. Copy token (lưu an toàn, chỉ hiển thị một lần) - -## Bước 5: Cấu Hình Webhook - -### Lấy Webhook URL - -Từ service đã deploy 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 thực webhook: - -```bash -# Tạo token ngẫu nhiên -openssl rand -hex 32 -``` - -Lưu vào `WHATSAPP_WEBHOOK_VERIFY_TOKEN` trong `.env` - -### Thiết Lập Trong Meta - -1. Vào WhatsApp → Configuration → Webhook -2. Nhấp "Edit" -3. Nhập: - - **Callback URL**: `https://yourdomain.com/api/v1/whatsapp/webhooks` - - **Verify Token**: Token bạn vừa tạo -4. Nhấp "Verify and Save" - -### Đăng Ký Events - -Sau khi xác minh, đăng ký: -- ✅ `messages` - Tin nhắn đến từ khách hàng -- ✅ `message_status` (tùy chọn) - Trạng thái delivered/read -- ✅ `messaging_postbacks` (tùy chọn) - Tương tác với nút - -## Bước 6: Lấy App Secret - -Để xác thực webhook signature: - -1. Vào App Dashboard → Settings → Basic -2. Nhấp "Show" bên cạnh "App Secret" -3. Copy và lưu vào `WHATSAPP_APP_SECRET` - -## Bước 7: Cấu Hình Service - -Cập nhật file `.env`: - -```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 - -Service sẽ tự động xử lý xác thực 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 Test - -Sử dụng API để gửi tin nhắn test đến khách hàng. - -### Nhận Tin Nhắn Test - -1. Gửi tin nhắn từ WhatsApp của khách hàng test đến số doanh nghiệp -2. Kiểm tra service logs cho incoming webhook -3. Xác minh tin nhắn được lưu trong database - -## Bước 9: Message Templates - -Để gửi tin nhắn ngoài cửa sổ 24 giờ, bạn cần templates đã được phê duyệt. - -### Tạo Template - -1. Vào WhatsApp → Message Templates -2. Nhấp "Create Template" -3. Điền: - - **Name**: `order_confirmation` (chữ thường, gạch dưới) - - **Category**: Utility/Marketing/Authentication - - **Language**: Vietnamese, English, etc. - - **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. Submit để review (phê duyệt mất 1-3 ngày) - -## 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 hội thoại/ngày). - -### Quy Trình Nâng Cấp - -Tiers tự động nâng cấp dựa trên: -1. **Chất lượng số điện thoại** (tỷ lệ block 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 Cấp 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 | - -## Xử Lý Sự Cố - -### Webhook Verification 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 service đ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. Format: `84901234567` (Việt Nam), không phải `+84901234567` - -### 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 - -## Thực Hành Tốt Về Bảo Mật - -1. **Không bao giờ commit tokens** - Dùng biến môi trường -2. **Xoay vòng tokens thường xuyên** - Tạo token mới mỗi 6 tháng -3. **Xác minh webhook signatures** - Luôn validate `X-Hub-Signature-256` -4. **Chỉ dùng HTTPS** - WhatsApp sẽ từ chối HTTP webhooks -5. **Hạn chế truy cập IP** - Whitelist Meta IP ranges nếu có thể - -## Tối Ưu Chi Phí - -1. **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ệ block cao có thể giới hạn tài khoản -4. **Giám sát conversations** - 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 Tự Động Hóa](AUTOMATION_GUIDE.md) - Thiết lập automation flows -- [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) -- [Message Templates Guide](https://developers.facebook.com/docs/whatsapp/business-management-api/message-templates) -- [Webhook Reference](https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks) diff --git a/services/mkt-x-service-net/docs/API.md b/services/mkt-x-service-net/docs/en/API.md similarity index 100% rename from services/mkt-x-service-net/docs/API.md rename to services/mkt-x-service-net/docs/en/API.md diff --git a/services/mkt-x-service-net/docs/ARCHITECTURE.md b/services/mkt-x-service-net/docs/en/ARCHITECTURE.md similarity index 100% rename from services/mkt-x-service-net/docs/ARCHITECTURE.md rename to services/mkt-x-service-net/docs/en/ARCHITECTURE.md diff --git a/services/mkt-x-service-net/docs/TWITTER_SETUP.md b/services/mkt-x-service-net/docs/en/TWITTER_SETUP.md similarity index 100% rename from services/mkt-x-service-net/docs/TWITTER_SETUP.md rename to services/mkt-x-service-net/docs/en/TWITTER_SETUP.md diff --git a/services/mkt-x-service-net/docs/vi/CAI-DAT-TWITTER.md b/services/mkt-x-service-net/docs/vi/CAI-DAT-TWITTER.md new file mode 100644 index 00000000..45bf952b --- /dev/null +++ b/services/mkt-x-service-net/docs/vi/CAI-DAT-TWITTER.md @@ -0,0 +1,346 @@ +# Hướng Dẫn Thiết Lập Twitter API + +## Mục Lục + +1. [Yêu Cầu Trước Khi Bắt Đầu](#yêu-cầu-trước-khi-bắt-đầu) +2. [Tạo Tài Khoản Twitter Developer](#tạo-tài-khoản-twitter-developer) +3. [Tạo Twitter App](#tạo-twitter-app) +4. [Cấu Hình OAuth](#cấu-hình-oauth) +5. [Thiết Lập Account Activity API](#thiết-lập-account-activity-api) +6. [Cấu Hình Webhooks](#cấu-hình-webhooks) +7. [Kiểm Tra Tích Hợp](#kiểm-tra-tích-hợp) +8. [Xử Lý Sự Cố](#xử-lý-sự-cố) + +--- + +## Yêu Cầu Trước Khi Bắt Đầu + +Trước khi thiết lập tích hợp Twitter API, đảm bảo bạn có: + +- ✅ Tài khoản Twitter (tốt nhất là tài khoản doanh nghiệp) +- ✅ MKT X Service đã triển khai và có thể truy cập qua HTTPS +- ✅ Chứng chỉ SSL hợp lệ cho webhook URL +- ✅ Quyền truy cập vào cấu hình server + +--- + +## Tạo Tài Khoản Twitter Developer + +### Bước 1: Đăng Ký Developer Access + +1. Truy cập [Twitter Developer Portal](https://developer.twitter.com/) +2. Nhấp "Sign up" và đăng nhập bằng tài khoản Twitter +3. Điền form đăng ký: + - **Loại tài khoản**: Chọn "Business" hoặc "Professional" + - **Use case chính**: Marketing automation và customer service + - **Bạn có chia sẻ nội dung Twitter cho chính phủ không?**: Không +4. Xem xét và chấp nhận Developer Agreement +5. Xác minh địa chỉ email + +**Thời gian xử lý**: Thường ngay lập tức, nhưng có thể mất đến 24-48 giờ + +### Bước 2: Tạo Project + +1. Điều hướng đến [Developer Portal Dashboard](https://developer.twitter.com/en/portal/dashboard) +2. Nhấp "Create Project" +3. Điền thông tin project: + - **Tên project**: "GoodGo Marketing" + - **Use case**: Customer engagement + - **Mô tả project**: "Twitter marketing automation for e-commerce" +4. Nhấp "Next" và "Create" + +--- + +## Tạo Twitter App + +### Bước 1: Tạo App Mới + +1. Trong project của bạn, nhấp "+ Add App" +2. Chọn môi trường "Production" +3. Nhập tên app (vd: "GoodGo-MKT-X-Prod") +4. Lưu thông tin xác thực API: + +``` +API Key: xxxxxxxxxxxxxxxxxxxxx +API Key Secret: xxxxxxxxxxxxxxxxxxxxx +Bearer Token: xxxxxxxxxxxxxxxxxxxxx +``` + +**⚠️ Quan trọng**: Lưu trữ thông tin xác thực này an toàn. Chúng sẽ không hiển thị lại. + +### Bước 2: Cấu Hình Quyền App + +1. Vào cài đặt app +2. Điều hướng đến "User authentication settings" +3. Nhấp "Set up" +4. Cấu hình quyền: + +``` +Quyền app: +☑ Read +☑ Write +☑ Direct Messages + +Loại App: +☑ Web App, Automated App or Bot + +Thông tin App: +Callback URI: https://your-domain.com/api/v1/mkt-x/oauth/callback +Website URL: https://your-domain.com +``` + +5. Lưu thay đổi + +--- + +## Cấu Hình OAuth + +### Thiết Lập OAuth 1.0a + +Twitter Direct Messages API yêu cầu xác thực OAuth 1.0a. + +### Bước 1: Tạo Access Tokens + +1. Trong cài đặt app, vào "Keys and tokens" +2. Dưới "Authentication Tokens", nhấp "Generate" +3. Lưu tokens: + +``` +Access Token: xxxxxxxxxxxxxxxxxxxxx +Access Token Secret: xxxxxxxxxxxxxxxxxxxxx +``` + +### Bước 2: Thêm Thông Tin Xác Thực Vào Service + +Cập nhật `appsettings.json`: + +```json +{ + "Twitter": { + "ApiKey": "your_api_key", + "ApiKeySecret": "your_api_key_secret", + "BearerToken": "your_bearer_token", + "AccessToken": "your_access_token", + "AccessTokenSecret": "your_access_token_secret", + "WebhookUrl": "https://your-domain.com/api/v1/mkt-x/webhooks/twitter" + } +} +``` + +**🔒 Bảo mật**: Sử dụng biến môi trường hoặc secrets manager cho production: + +```bash +export TWITTER__API_KEY="your_api_key" +export TWITTER__API_KEY_SECRET="your_api_key_secret" +export TWITTER__ACCESS_TOKEN="your_access_token" +export TWITTER__ACCESS_TOKEN_SECRET="your_access_token_secret" +``` + +--- + +## Thiết Lập Account Activity API + +Account Activity API cho phép bạn nhận sự kiện Twitter thời gian thực qua webhooks. + +### Bước 1: Đăng Ký Account Activity API Access + +1. Truy cập trang [Account Activity API](https://developer.twitter.com/en/products/twitter-api/account-activity-api) +2. Yêu cầu quyền truy cập cho app của bạn +3. Chọn môi trường "Sandbox" cho phát triển (miễn phí) +4. Cho production, bạn cần tier "Enterprise" hoặc "Premium" + +**Pricing**: +- **Sandbox**: Miễn phí (1 webhook, 15 subscriptions) +- **Premium**: Từ $149/tháng (5 webhooks, 500 subscriptions) +- **Enterprise**: Giá tùy chỉnh + +### Bước 2: Đăng Ký Webhook URL + +Đăng ký webhook URL của bạn với Twitter: + +```bash +curl -X POST \ + 'https://api.twitter.com/1.1/account_activity/all/:env_name/webhooks.json' \ + -H 'Authorization: OAuth oauth_consumer_key="YOUR_API_KEY", ...' \ + -d 'url=https://your-domain.com/api/v1/mkt-x/webhooks/twitter' +``` + +**Hoặc sử dụng MKT X Service API**: + +```bash +POST /api/v1/mkt-x/accounts/{accountId}/register-webhook +``` + +### Bước 3: Xác Minh CRC (Challenge-Response Check) + +Twitter sẽ gửi GET request đến webhook URL với tham số `crc_token`. Service của bạn phải phản hồi: + +```json +{ + "response_token": "sha256=base64_encoded_hmac" +} +``` + +Service tự động xử lý điều này qua endpoint `/webhooks/verify`. + +--- + +## Cấu Hình Webhooks + +### Sự Kiện Bạn Sẽ Nhận + +**Direct Message Events** +```json +{ + "direct_message_events": [ + { + "type": "message_create", + "id": "123456789", + "created_timestamp": "1642000000000", + "message_create": { + "sender_id": "987654321", + "message_data": { + "text": "Xin chào!" + } + } + } + ] +} +``` + +### Webhook Security + +Tất cả webhook requests từ Twitter bao gồm: + +1. **X-Twitter-Webhooks-Signature** header +2. HMAC-SHA256 signature của request body + +Service tự động xác thực signature này. + +--- + +## Kiểm Tra Tích Hợp + +### Bước 1: Kiểm Tra Kết Nối OAuth + +```bash +curl -X POST http://localhost:5000/api/v1/mkt-x/accounts \ + -H "Authorization: Bearer YOUR_JWT_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "oauthToken": "YOUR_ACCESS_TOKEN", + "oauthTokenSecret": "YOUR_ACCESS_TOKEN_SECRET" + }' +``` + +**Phản hồi mong đợi**: +```json +{ + "success": true, + "data": { + "id": "uuid", + "twitterUserId": "123456789", + "username": "your_username", + "status": "active" + } +} +``` + +### Bước 2: Kiểm Tra Webhook URL + +```bash +curl -X GET 'https://your-domain.com/api/v1/mkt-x/webhooks/verify?crc_token=test' +``` + +### Bước 3: Gửi Test Direct Message + +1. Gửi direct message đến tài khoản Twitter đã kết nối từ tài khoản khác +2. Kiểm tra service logs để xác nhận webhook event đã nhận +3. Xác minh conversation và message đã được tạo trong database + +--- + +## Xử Lý Sự Cố + +### Vấn Đề 1: Đăng Ký Webhook Thất Bại + +**Lỗi**: `401 Unauthorized` khi đăng ký webhook + +**Giải pháp**: +1. Xác minh thông tin xác thực OAuth đúng +2. Đảm bảo app có quyền "Read + Write + Direct Messages" +3. Kiểm tra webhook URL là HTTPS (không phải HTTP) +4. Xác nhận chứng chỉ SSL hợp lệ + +### Vấn Đề 2: Không Nhận Webhook Events + +**Triệu chứng**: Không có events trong logs sau khi gửi DM + +**Giải pháp**: +1. Xác minh webhook đã đăng ký +2. Kiểm tra webhook subscription +3. Đảm bảo firewall cho phép traffic HTTPS đến +4. Kiểm tra service logs cho lỗi xác thực webhook + +### Vấn Đề 3: Vượt Giới Hạn Tốc Độ + +**Lỗi**: `429 Too Many Requests` + +**Giải pháp**: +- Giới hạn Twitter DM: 500 tin nhắn / 24 giờ mỗi tài khoản +- Kiểm tra mức sử dụng hiện tại +- Triển khai hàng đợi tin nhắn để tuân thủ giới hạn + +--- + +## Best Practices + +### 1. Bảo Mật + +- ✅ Lưu trữ thông tin xác thực API trong biến môi trường +- ✅ Sử dụng HTTPS cho tất cả webhook endpoints +- ✅ Xác thực webhook signatures +- ✅ Xoay vòng OAuth tokens định kỳ + +### 2. Độ Tin Cậy + +- ✅ Triển khai retry logic cho failed API calls +- ✅ Sử dụng message queues cho xử lý webhook +- ✅ Monitor webhook endpoint uptime +- ✅ Thiết lập alerting cho API errors + +### 3. Hiệu Năng + +- ✅ Xử lý webhooks bất đồng bộ +- ✅ Sử dụng caching cho user data +- ✅ Batch API requests khi có thể +- ✅ Monitor API quotas + +--- + +## Giới Hạn Tốc Độ + +### Twitter API v2 Limits + +| Endpoint | Giới Hạn | Cửa Sổ | +|----------|-----------|---------| +| Direct Messages (Send) | 500 requests | 24 giờ | +| Direct Messages (Read) | 300 requests | 15 phút | +| User Lookup | 900 requests | 15 phút | + +--- + +## Tài Nguyên Bổ Sung + +- [Twitter API Documentation](https://developer.twitter.com/en/docs/twitter-api) +- [Account Activity API Guide](https://developer.twitter.com/en/docs/twitter-api/enterprise/account-activity-api/overview) +- [OAuth 1.0a Specification](https://oauth.net/core/1.0a/) + +--- + +## Hỗ Trợ + +Để được hỗ trợ về tích hợp Twitter API: + +- **Twitter Developer Forums**: https://twittercommunity.com/ +- **Hỗ Trợ MKT X Service**: api-support@goodgo.com diff --git a/services/mkt-x-service-net/docs/vi/KIEN-TRUC.md b/services/mkt-x-service-net/docs/vi/KIEN-TRUC.md new file mode 100644 index 00000000..fe3f9f80 --- /dev/null +++ b/services/mkt-x-service-net/docs/vi/KIEN-TRUC.md @@ -0,0 +1,467 @@ +# Dịch Vụ MKT X/Twitter - Kiến Trúc Hệ Thống + +## Mục Lục + +1. [Tổng Quan](#tổng-quan) +2. [Kiến Trúc Hệ Thống](#kiến-trúc-hệ-thống) +3. [Mô Hình Domain](#mô-hình-domain) +4. [Thiết Kế Component](#thiết-kế-component) +5. [Kiến Trúc Dữ Liệu](#kiến-trúc-dữ-liệu) +6. [Kiến Trúc Tích Hợp](#kiến-trúc-tích-hợp) +7. [Kiến Trúc Bảo Mật](#kiến-trúc-bảo-mật) +8. [Kiến Trúc Triển Khai](#kiến-trúc-triển-khai) + +--- + +## Tổng Quan + +### Mục Đích Dịch Vụ + +Dịch Vụ Marketing X/Twitter (`mkt-x-service-net`) là nền tảng marketing truyền thông xã hội toàn diện được xây dựng trên .NET 8, cung cấp ba khả năng cốt lõi: + +1. **CHATBOT Automation Messenger** - Gửi tin nhắn tự động dựa trên template với điều phối workflow +2. **CHATBOT AI Messenger** - Giao diện trò chuyện được hỗ trợ AI sử dụng tích hợp OpenAI +3. **Customer Management** - 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 Chính + +- ✅ Tích hợp đa tài khoản Twitter với OAuth 1.0a +- ✅ Trình thiết kế workflow trực quan cho tự động hóa tin nhắn +- ✅ Trò chuyện ngôn ngữ tự nhiên được hỗ trợ AI +- ✅ Phân khúc khách hàng nâng cao +- ✅ Quản lý chiến dịch với kiểm thử A/B +- ✅ Phân tích và báo cáo thời gian thực +- ✅ Xử lý sự kiện dựa trên webhook +- ✅ Quản lý giới hạn tốc độ và quota + +--- + +## Kiến Trúc Hệ Thống + +### Kiến Trúc Tổng Quan + +``` +┌─────────────────────────────────────────────────────────┐ +│ Load Balancer (Traefik) │ +└─────────────┬───────────────────────────┬───────────────┘ + │ │ + ┌─────────▼─────────┐ ┌────────▼────────┐ + │ API Instance 1 │ │ API Instance 2 │ + │ (Web API + Jobs) │ │ (Web API + Jobs) │ + └─────────┬─────────┘ └────────┬────────┘ + │ │ + └──────────┬────────────────┘ + │ + ┌────────────────┼────────────────┐ + │ │ │ + ┌─────▼─────┐ ┌────▼────┐ ┌─────▼─────┐ + │PostgreSQL │ │ Redis │ │ RabbitMQ │ + │(Primary) │ │ (Cache) │ │(Event Bus)│ + └───────────┘ └──────────┘ └───────────┘ + │ + ┌─────▼─────────────┐ + │ Dịch Vụ Bên Ngoài │ + │ - Twitter API │ + │ - OpenAI API │ + └───────────────────┘ +``` + +### Các Tầng Clean Architecture + +``` +┌──────────────────────────────────────────────┐ +│ Tầng API (Presentation) │ +│ - Controllers │ +│ - Middleware (Auth, Exception, Logging) │ +│ - Swagger/OpenAPI │ +└──────────────────┬───────────────────────────┘ + │ +┌──────────────────▼───────────────────────────┐ +│ Tầng Application (Use Cases) │ +│ - Commands (MediatR) │ +│ - Queries (MediatR) │ +│ - DTOs │ +│ - Validators (FluentValidation) │ +│ - Pipeline Behaviors │ +└──────────────────┬───────────────────────────┘ + │ +┌──────────────────▼───────────────────────────┐ +│ Tầng Domain (Business Logic) │ +│ - Aggregates (TwitterAccount, Contact...) │ +│ - Entities │ +│ - Value Objects │ +│ - Domain Events │ +│ - Domain Services │ +└──────────────────┬───────────────────────────┘ + │ +┌──────────────────▼───────────────────────────┐ +│ Tầng Infrastructure (External Concerns) │ +│ - EF Core DbContext │ +│ - Repositories │ +│ - External API Clients (Twitter, OpenAI) │ +│ - Background Jobs │ +│ - Event Bus Integration │ +└──────────────────────────────────────────────┘ +``` + +--- + +## Mô Hình Domain + +### Aggregate Roots + +#### 1. TwitterAccount Aggregate + +**Mục đích**: Quản lý tài khoản Twitter đã kết nối với thông tin xác thực OAuth + +```csharp +public class TwitterAccount : Entity, IAggregateRoot +{ + public Guid MerchantId { get; private set; } + public string TwitterUserId { get; private set; } + public string Username { get; private set; } + public TwitterAccountStatus Status { get; private set; } + + public void ConnectAccount(string oauthToken, string oauthSecret); + public void Disconnect(); + public void UpdateCredentials(string token, string secret); +} +``` + +**Quy Tắc Nghiệp Vụ**: +- Một merchant có thể có nhiều tài khoản Twitter +- OAuth tokens phải được mã hóa khi lưu trữ +- Tài khoản phải vượt qua xác minh Twitter trước khi kích hoạt + +#### 2. Contact Aggregate + +**Mục đích**: Đại diện cho người dùng Twitter tương tác với tài khoản merchant + +```csharp +public class Contact : Entity, IAggregateRoot +{ + public Guid AccountId { get; private set; } + public string TwitterUserId { get; private set; } + public List Tags { get; private set; } + public Dictionary Attributes { get; private set; } + + public void AddTag(string tagName); + public void RemoveTag(string tagName); + public void UpdateAttribute(string key, object value); +} +``` + +**Quy Tắc Nghiệp Vụ**: +- Mỗi người dùng Twitter là duy nhất cho mỗi merchant account +- Tags phải là duy nhất cho mỗi contact +- Thuộc tính tùy chỉnh hỗ trợ các kiểu dữ liệu linh hoạt (string, number, boolean, date) + +#### 3. Conversation Aggregate + +**Mục đích**: Quản lý chuỗi tin nhắn giữa contacts và merchants + +```csharp +public class Conversation : Entity, IAggregateRoot +{ + public Guid ContactId { get; private set; } + public Guid AccountId { get; private set; } + public ConversationStatus Status { get; private set; } + public List Messages { get; private set; } + + public void AddMessage(Message message); + public void Close(); + public void AssignToAgent(Guid userId); +} +``` + +**Quy Tắc Nghiệp Vụ**: +- Conversations tự động đóng sau 24 giờ không hoạt động +- Tin nhắn không thể xóa, chỉ lưu trữ +- Tin nhắn từ bot được đánh dấu rõ ràng + +#### 4. Template Aggregate + +**Mục đích**: Mẫu tin nhắn có thể tái sử dụng với thay thế biến + +```csharp +public class Template : Entity, IAggregateRoot +{ + public Guid MerchantId { get; private set; } + public string Name { get; private set; } + public string Content { get; private set; } + public List Variables { get; private set; } + + public string Render(Dictionary values); + public void Validate(); +} +``` + +**Quy Tắc Nghiệp Vụ**: +- Nội dung template không được vượt quá giới hạn Twitter DM (10,000 ký tự) +- Biến sử dụng cú pháp {{variable_name}} +- Tất cả biến đã khai báo phải được cung cấp khi render + +#### 5. Campaign Aggregate + +**Mục đích**: Điều phối chiến dịch gửi tin nhắn hàng loạt với lịch trình + +```csharp +public class Campaign : Entity, IAggregateRoot +{ + public Guid MerchantId { get; private set; } + public Guid TemplateId { get; private set; } + public List SegmentIds { get; private set; } + public Schedule Schedule { get; private set; } + public CampaignMetrics Metrics { get; private set; } + + public void Start(); + public void Pause(); + public void Resume(); + public void Complete(); +} +``` + +**Quy Tắc Nghiệp Vụ**: +- Campaign không thể bắt đầu nếu không có ít nhất một segment +- Tuân thủ giới hạn tốc độ Twitter (500 DMs/24 giờ) +- Không thể sửa đổi campaign sau khi đã bắt đầu +- Campaigns đã lên lịch tự động thực thi vào thời gian chỉ định + +--- + +## Thiết Kế Component + +### Commands (Thao Tác Ghi) + +**Quản Lý Tài Khoản** +- `ConnectTwitterAccountCommand` - Kết nối tài khoản Twitter mới +- `DisconnectAccountCommand` - Ngắt kết nối tài khoản +- `UpdateAccountSettingsCommand` - Cập nhật cấu hình tài khoản + +**Quản Lý Liên Hệ** +- `CreateContactCommand` - Tạo liên hệ mới +- `UpdateContactCommand` - Cập nhật chi tiết liên hệ +- `AddContactTagCommand` - Thêm tag vào liên hệ +- `RemoveContactTagCommand` - Xóa tag +- `UpdateContactAttributesCommand` - Cập nhật hàng loạt thuộc tính + +**Quản Lý Chiến Dịch** +- `CreateCampaignCommand` - Tạo chiến dịch +- `StartCampaignCommand` - Bắt đầu thực thi chiến dịch +- `PauseCampaignCommand` - Tạm dừng chiến dịch đang chạy +- `ResumeCampaignCommand` - Tiếp tục chiến dịch đã tạm dừng + +### Queries (Thao Tác Đọc) + +**Analytics Queries** +- `GetOverviewAnalyticsQuery` - Số liệu dashboard +- `GetContactAnalyticsQuery` - Thống kê liên hệ +- `GetConversationAnalyticsQuery` - Số liệu hội thoại +- `GetCampaignAnalyticsQuery` - Hiệu suất chiến dịch + +--- + +## Kiến Trúc Dữ Liệu + +### Database Schema + +#### Bảng Chính + +**twitter_accounts** +```sql +CREATE TABLE twitter_accounts ( + id UUID PRIMARY KEY, + merchant_id UUID NOT NULL, + twitter_user_id VARCHAR(100) NOT NULL UNIQUE, + username VARCHAR(100) NOT NULL, + display_name VARCHAR(200), + status VARCHAR(20) NOT NULL, + oauth_token TEXT NOT NULL, -- được mã hóa + oauth_token_secret TEXT NOT NULL, -- được mã hóa + webhook_id VARCHAR(100), + connected_at TIMESTAMP NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT NOW() +); +``` + +**contacts** +```sql +CREATE TABLE contacts ( + id UUID PRIMARY KEY, + account_id UUID NOT NULL REFERENCES twitter_accounts(id), + twitter_user_id VARCHAR(100) NOT NULL, + username VARCHAR(100) NOT NULL, + display_name VARCHAR(200), attributes JSONB DEFAULT '{}', + first_interaction_at TIMESTAMP NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT NOW(), + UNIQUE(account_id, twitter_user_id) +); + +CREATE INDEX idx_contacts_account ON contacts(account_id); +CREATE INDEX idx_contacts_attributes ON contacts USING GIN(attributes); +``` + +### Chiến Lược Caching + +**Cấu Trúc Redis Cache** + +``` +Hồ Sơ Liên Hệ: "contact:{contactId}" - TTL: 1 giờ +Templates: "template:{templateId}" - TTL: 10 phút +Segments: "segment:{segmentId}:contacts" - TTL: 5 phút +Số Liệu Campaign: "campaign:{campaignId}:metrics" - TTL: 1 phút +Giới Hạn Tốc Độ: "ratelimit:twitter:{accountId}" - TTL: 24 giờ +``` + +--- + +## Kiến Trúc Tích Hợp + +### Tích Hợp Twitter API + +#### OAuth 1.0a Flow + +``` +1. Merchant khởi tạo kết nối +2. Service yêu cầu request token từ Twitter +3. Chuyển hướng merchant đến URL ủy quyền Twitter +4. Twitter chuyển hướng lại với verifier +5. Service trao đổi verifier để lấy access token +6. Lưu trữ tokens đã mã hóa trong database +7. Đăng ký webhooks cho tài khoản +``` + +#### Webhook Events + +**Sự Kiện Được Hỗ Trợ**: +- `direct_message_events` - Nhận DM mới +- `direct_message_indicate_typing_events` - Người dùng đang gõ +- `direct_message_mark_read_events` - Tin nhắn đã đọc +- `follow_events` - Người theo dõi mới +- `favorite_events` - Tweet được thích + +### Tích Hợp OpenAI + +#### Luồng AI Conversation + +``` +1. Người dùng gửi tin nhắn +2. Trích xuất ngữ cảnh hội thoại (10 tin nhắn cuối) +3. Gọi OpenAI API với ngữ cảnh và tin nhắn +4. Phân tích intent và entities +5. Nếu intent cần dữ liệu, gọi dịch vụ nội bộ +6. Tạo phản hồi sử dụng OpenAI +7. Gửi phản hồi cho người dùng +8. Lưu trữ ngữ cảnh hội thoại +``` + +--- + +## Kiến Trúc Bảo Mật + +### Xác Thực & Ủy Quyền + +**Xác Thực API** +- JWT Bearer tokens cho truy cập API +- OAuth 1.0a cho kết nối tài khoản Twitter +- Xoay vòng refresh token + +**Ủy Quyền** +- Kiểm soát truy cập dựa trên vai trò (RBAC) +- Cô lập dữ liệu cấp merchant +- Kiểm tra quyền ở tầng API và domain + +### Bảo Vệ Dữ Liệu + +**Mã Hóa Dữ Liệu Lưu Trữ** +- OAuth tokens được mã hóa bằng AES-256 +- Khóa mã hóa lưu trong Azure Key Vault / AWS KMS +- Mã hóa database cho các trường nhạy cảm + +**Mã Hóa Truyền Tải** +- TLS 1.3 cho tất cả giao tiếp HTTP +- Certificate pinning cho gọi Twitter API + +--- + +## Kiến Trúc Triển Khai + +### Cấu Hình Container + +**Dockerfile** +```dockerfile +FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build +WORKDIR /src +COPY . . +RUN dotnet restore +RUN dotnet publish -c Release -o /app + +FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine +WORKDIR /app +COPY --from=build /app . +RUN adduser -D appuser && chown -R appuser /app +USER appuser +EXPOSE 8080 +ENTRYPOINT ["dotnet", "MktXService.API.dll"] +``` + +### Triển Khai Kubernetes + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mkt-x-service +spec: + replicas: 3 + template: + spec: + containers: + - name: api + image: mkt-x-service:latest + resources: + requests: + memory: "256Mi" + cpu: "250m" + limits: + memory: "512Mi" + cpu: "500m" +``` + +--- + +## Mục Tiêu Hiệu Năng + +| Chỉ Số | Mục Tiêu | Ghi Chú | +|--------|----------|---------| +| Thời Gian Phản Hồi API (P95) | < 500ms | Không bao gồm gọi API bên ngoài | +| Xử Lý Tin Nhắn | 100 msg/giây | Mỗi tài khoản Twitter | +| Thông Lượng Campaign | 10,000 liên hệ/phút | Với giới hạn tốc độ | +| Truy Vấn Database (P95) | < 100ms | Truy vấn bảng đơn | +| Cache Hit Ratio | > 80% | Cho tra cứu liên hệ | + +--- + +## Monitoring & Observability + +### Metrics (Prometheus) + +``` +# API Metrics +http_requests_total{method, endpoint, status} +http_request_duration_seconds{method, endpoint} + +# Business Metrics +twitter_messages_sent_total{account_id} +twitter_campaigns_active{merchant_id} +twitter_conversations_active{account_id} +``` + +--- + +## Tài Liệu 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/microservices/) +- [Domain-Driven Design by Eric Evans](https://domainlanguage.com/ddd/) diff --git a/services/mkt-zalo-service-net/README.md b/services/mkt-zalo-service-net/README.md index cfababe8..69bd1888 100644 --- a/services/mkt-zalo-service-net/README.md +++ b/services/mkt-zalo-service-net/README.md @@ -1,332 +1,54 @@ -# MKT Zalo Service / Dịch Vụ MKT Zalo +# MKT Zalo Service -**EN**: Marketing service for Zalo Official Account integration, providing chatbot automation, AI-powered messaging, and customer relationship management. +Marketing service for Zalo Official Account integration, providing chatbot automation, AI-powered messaging, and customer relationship management. -**VI**: Dịch vụ marketing tích hợp Zalo Official Account, cung cấp chatbot tự động, nhắn tin AI, và quản lý quan hệ khách hàng. +## 📖 Documentation -## Overview / Tổng Quan +- **English**: [docs/en/](./docs/en/) +- **Tiếng Việt**: [docs/vi/](./docs/vi/) -The MKT Zalo Service enables businesses to leverage Zalo's messaging platform for customer engagement, automated responses, and personalized marketing campaigns. +## 🚀 Quick Links -Dịch vụ MKT Zalo cho phép doanh nghiệp tận dụng nền tảng nhắn tin Zalo để tương tác khách hàng, phản hồi tự động và chiến dịch marketing cá nhân hóa. +### English Documentation +- [Architecture](./docs/en/ARCHITECTURE.md) - System design and solution architecture +- [API Reference](./docs/en/API.md) - Complete API endpoints specification +- [Domain Models](./docs/en/DOMAIN_MODELS.md) - Domain entities and aggregates +- [Zalo Setup Guide](./docs/en/ZALO_SETUP.md) - Integration with Zalo Official Account +- [Database Schema](./docs/en/DATABASE.md) - Database design and migrations -### Key Features / Tính Năng Chính +### Tài Liệu Tiếng Việt +- [Kiến Trúc](./docs/vi/ARCHITECTURE.md) - Thiết kế hệ thống và solution +- [Tài Liệu API](./docs/vi/API.md) - Đặc tả API endpoints đầy đủ +- [Mô Hình Domain](./docs/vi/DOMAIN_MODELS.md) - Domain entities và aggregates +- [Hướng Dẫn Zalo](./docs/vi/ZALO_SETUP.md) - Tích hợp Zalo Official Account +- [Schema Database](./docs/vi/DATABASE.md) - Thiết kế database và migrations -- ✅ **CHATBOT Automation**: Rule-based automated responses for customer inquiries -- ✅ **AI Chatbot**: LLM-powered intelligent conversations and context-aware responses -- ✅ **Customer Management**: Unified CRM for tracking customer interactions and preferences -- ✅ **Webhook Integration**: Real-time event handling from Zalo Official Account -- ✅ **Message Templates**: Pre-approved ZNS (Zalo Notification Service) templates -- ✅ **Analytics Dashboard**: Conversation metrics, engagement rates, and performance tracking +## 🎯 Key Features -## Architecture / Kiến Trúc +- ✅ **CHATBOT Automation** - Rule-based automated responses +- ✅ **AI Chatbot** - LLM-powered intelligent conversations +- ✅ **Customer Management** - CRM with segmentation and tracking + +## 🏗️ Architecture ``` -┌─────────────────────────────────────────────────────────────────┐ -│ Zalo Official Account │ -│ (Customer sends messages via Zalo) │ -└────────────────────┬────────────────────────────────────────────┘ - │ Webhook Events - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ mkt-zalo-service-net │ -│ │ -│ ┌──────────────────────────────────────────────────────────┐ │ -│ │ Webhook Handler (API Layer) │ │ -│ │ • Verify signature │ │ -│ │ • Parse events (message, follow, buttons) │ │ -│ │ • Return 200 quickly │ │ -│ └───────────────┬──────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌──────────────────────────────────────────────────────────┐ │ -│ │ Message Processing Engine │ │ -│ │ ┌────────────────┐ ┌────────────────┐ │ │ -│ │ │ Rule Engine │ │ AI Engine │ │ │ -│ │ │ (Automation) │ │ (LLM Based) │ │ │ -│ │ └────────────────┘ └────────────────┘ │ │ -│ └───────────────┬──────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌──────────────────────────────────────────────────────────┐ │ -│ │ Domain Layer │ │ -│ │ • Conversation Aggregate │ │ -│ │ • ZaloCustomer Aggregate │ │ -│ │ • ChatbotRule Entity │ │ -│ │ • MessageTemplate Entity │ │ -│ └──────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌──────────────────────────────────────────────────────────┐ │ -│ │ Integration Layer │ │ -│ │ • Zalo OA API Client (Send messages) │ │ -│ │ • LLM Provider (OpenAI, Vertex AI) │ │ -│ └──────────────────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────────┘ - │ - ▼ - ┌──────────────┐ - │ PostgreSQL │ - │ (Customer, │ - │ Conversation,│ - │ Templates) │ - └──────────────┘ +Zalo OA → Webhooks → Message Queue → Processing Engine → Database + (Rule-based / AI) ``` -## Technology Stack / Công Nghệ +## 🛠️ Tech Stack -| Layer | Technology | -|-------|------------| -| **Framework** | .NET 10, ASP.NET Core | -| **Patterns** | CQRS + MediatR, DDD, Event-Driven | -| **Database** | PostgreSQL (Neon), EF Core | -| **Caching** | Redis (conversation context) | -| **External APIs** | Zalo OA API, OpenAI/Vertex AI | -| **Message Queue** | RabbitMQ (MassTransit) | -| **Observability** | Prometheus, Grafana, Loki | +- .NET 10, ASP.NET Core +- PostgreSQL, Redis, RabbitMQ +- OpenAI / Vertex AI (for AI chatbot) +- Docker, Traefik -## Project Structure / Cấu Trúc Dự Án +## 📦 Getting Started -``` -mkt-zalo-service-net/ -├── src/ -│ ├── MktZaloService.API/ # API Layer -│ │ ├── Controllers/ -│ │ │ ├── WebhooksController.cs # Zalo webhook endpoint -│ │ │ ├── ConversationsController.cs # Conversation management -│ │ │ ├── CustomersController.cs # Customer CRM -│ │ │ ├── ChatbotRulesController.cs # Automation rules -│ │ │ └── Admin/ # Admin APIs -│ │ ├── Application/ -│ │ │ ├── Commands/ # Write operations -│ │ │ ├── Queries/ # Read operations -│ │ │ └── IntegrationEvents/ # Events from/to other services -│ │ └── Program.cs -│ │ -│ ├── MktZaloService.Domain/ # Domain Layer -│ │ ├── AggregatesModel/ -│ │ │ ├── ConversationAggregate/ -│ │ │ │ ├── Conversation.cs # Aggregate root -│ │ │ │ ├── Message.cs # Entity -│ │ │ │ ├── MessageType.cs # Enum -│ │ │ │ └── ConversationStatus.cs # Enum -│ │ │ ├── ZaloCustomerAggregate/ -│ │ │ │ ├── ZaloCustomer.cs # Aggregate root -│ │ │ │ ├── CustomerProfile.cs # Value object -│ │ │ │ ├── Tag.cs # Entity -│ │ │ │ └── CustomerSegment.cs # Enum -│ │ │ ├── ChatbotRuleAggregate/ -│ │ │ │ ├── ChatbotRule.cs # Aggregate root -│ │ │ │ ├── RuleCondition.cs # Value object -│ │ │ │ ├── RuleAction.cs # Value object -│ │ │ │ └── RuleType.cs # Enum -│ │ │ └── MessageTemplateAggregate/ -│ │ │ ├── MessageTemplate.cs # Aggregate root -│ │ │ └── TemplateParameter.cs # Value object -│ │ ├── Exceptions/ -│ │ │ └── ZaloDomainException.cs -│ │ ├── Events/ -│ │ │ ├── ConversationStartedDomainEvent.cs -│ │ │ ├── MessageReceivedDomainEvent.cs -│ │ │ └── CustomerProfileUpdatedDomainEvent.cs -│ │ └── SeedWork/ -│ │ ├── Entity.cs -│ │ ├── IAggregateRoot.cs -│ │ └── ValueObject.cs -│ │ -│ └── MktZaloService.Infrastructure/ # Infrastructure Layer -│ ├── Data/ -│ │ ├── MktZaloServiceContext.cs -│ │ ├── EntityConfigurations/ -│ │ └── Migrations/ -│ ├── Repositories/ -│ │ ├── ConversationRepository.cs -│ │ ├── ZaloCustomerRepository.cs -│ │ ├── ChatbotRuleRepository.cs -│ │ └── MessageTemplateRepository.cs -│ └── ExternalServices/ -│ ├── ZaloOfficialAccountClient.cs # Zalo OA API integration -│ ├── LlmService.cs # OpenAI/Vertex AI -│ └── ChatbotEngine/ -│ ├── RuleBasedChatbotEngine.cs -│ └── AiChatbotEngine.cs -│ -├── tests/ -│ ├── MktZaloService.UnitTests/ -│ └── MktZaloService.IntegrationTests/ -│ -├── docs/ -│ ├── README.md # This file -│ ├── SOLUTION.md # Solution architecture (detailed) -│ ├── API_DESIGN.md # API endpoints specification -│ ├── DOMAIN_MODELS.md # Domain entities and aggregates -│ ├── INTEGRATION.md # Zalo OA API integration guide -│ └── DATABASE_SCHEMA.md # Database design -│ -├── Dockerfile -├── docker-compose.yml -└── MktZaloService.slnx -``` +See detailed setup guides: +- English: [docs/en/ZALO_SETUP.md](./docs/en/ZALO_SETUP.md) +- Tiếng Việt: [docs/vi/ZALO_SETUP.md](./docs/vi/ZALO_SETUP.md) -## Getting Started / Bắt Đầu - -### Prerequisites / Yêu Cầu - -- .NET 10 SDK -- PostgreSQL 15+ -- Redis 7+ -- Zalo Official Account (verified) -- Zalo App ID & Secret Key -- Access Token from Zalo OA - -### Setup Steps / Các Bước Thiết Lập - -1. **Clone repository** - ```bash - cd services/mkt-zalo-service-net - ``` - -2. **Configure environment variables** - ```bash - # .env file - DATABASE_URL=postgresql://user:password@localhost:5432/mkt_zalo_db - REDIS_URL=redis://localhost:6379 - ZALO_APP_ID=your_app_id - ZALO_APP_SECRET=your_app_secret - ZALO_OA_ID=your_oa_id - ZALO_ACCESS_TOKEN=your_access_token - OPENAI_API_KEY=your_openai_key # For AI chatbot - ``` - -3. **Run database migrations** - ```bash - dotnet ef database update --project src/MktZaloService.Infrastructure - ``` - -4. **Run the service** - ```bash - dotnet run --project src/MktZaloService.API - ``` - -5. **Configure Zalo Webhook** - - Go to Zalo Developers portal - - Set webhook URL: `https://yourdomain.com/api/v1/zalo/webhooks` - - Enable events: `user_send_text`, `user_send_image`, `user_send_link`, `follow`, `unfollow` - -## API Endpoints / Các API Endpoints - -### Public APIs (Zalo Webhooks) -- `POST /api/v1/zalo/webhooks` - Receive Zalo OA events - -### Customer Management -- `GET /api/v1/zalo/customers` - List customers -- `GET /api/v1/zalo/customers/{id}` - Get customer details -- `PUT /api/v1/zalo/customers/{id}` - Update customer profile -- `POST /api/v1/zalo/customers/{id}/tags` - Add customer tags - -### Conversation Management -- `GET /api/v1/zalo/conversations` - List conversations -- `GET /api/v1/zalo/conversations/{id}` - Get conversation history -- `POST /api/v1/zalo/conversations/{id}/messages` - Send message - -### Chatbot Automation Rules -- `GET /api/v1/zalo/chatbot-rules` - List automation rules -- `POST /api/v1/zalo/chatbot-rules` - Create automation rule -- `PUT /api/v1/zalo/chatbot-rules/{id}` - Update rule -- `DELETE /api/v1/zalo/chatbot-rules/{id}` - Delete rule - -### Message Templates (ZNS) -- `GET /api/v1/zalo/templates` - List templates -- `POST /api/v1/zalo/templates/{id}/send` - Send template message - -### Admin APIs -- `GET /api/v1/zalo/admin/analytics` - Conversation analytics -- `GET /api/v1/zalo/admin/messages` - Search all messages -- `POST /api/v1/zalo/admin/broadcast` - Broadcast message to segments - -See [API_DESIGN.md](./docs/API_DESIGN.md) for full API documentation. - -## Key Workflows / Quy Trình Chính - -### 1. Receiving Webhook from Zalo -``` -Zalo → POST /webhooks → Verify signature → Parse event → Queue for processing → Return 200 -``` - -### 2. Processing Incoming Message -``` -Parse message → Load customer context → Route to engine (Rule vs AI) → Generate response → Call Zalo API → Save to DB -``` - -### 3. AI Chatbot Flow -``` -Receive text → Load conversation history → Build LLM prompt with context → Call OpenAI/Vertex AI → Parse response → Send to customer -``` - -## Environment Variables / Biến Môi Trường - -| Variable | Description | Required | -|----------|-------------|----------| -| `DATABASE_URL` | PostgreSQL connection string | Yes | -| `REDIS_URL` | Redis connection string | Yes | -| `ZALO_APP_ID` | Zalo Application ID | Yes | -| `ZALO_APP_SECRET` | Zalo Application Secret Key | Yes | -| `ZALO_OA_ID` | Zalo Official Account ID | Yes | -| `ZALO_ACCESS_TOKEN` | OA Access Token (1 year validity) | Yes | -| `ZALO_WEBHOOK_SECRET` | Webhook signature verification key | Yes | -| `OPENAI_API_KEY` | OpenAI API key for AI chatbot | Optional | -| `VERTEX_AI_PROJECT` | Google Vertex AI project | Optional | -| `ENABLE_AI_CHATBOT` | Enable/disable AI chatbot (true/false) | No | - -## Testing / Kiểm Thử - -### Unit Tests -```bash -dotnet test tests/MktZaloService.UnitTests -``` - -### Integration Tests -```bash -dotnet test tests/MktZaloService.IntegrationTests -``` - -### Manual Testing with Zalo -1. Send a message to your Zalo OA from a test account -2. Check logs for webhook reception -3. Verify response is sent back to Zalo -4. Check database for stored conversation - -## Deployment / Triển Khai - -### Docker -```bash -# Build image -docker build -t mkt-zalo-service-net . - -# Run container -docker run -p 8080:8080 \ - -e DATABASE_URL=... \ - -e ZALO_APP_ID=... \ - mkt-zalo-service-net -``` - -### Docker Compose (Local) -```bash -cd deployments/local -docker-compose up -d mkt-zalo-service-net -``` - -## Related Documentation / Tài Liệu Liên Quan - -- [SOLUTION.md](./docs/SOLUTION.md) - Detailed solution architecture -- [API_DESIGN.md](./docs/API_DESIGN.md) - Complete API specification -- [DOMAIN_MODELS.md](./docs/DOMAIN_MODELS.md) - Domain model details -- [INTEGRATION.md](./docs/INTEGRATION.md) - Zalo OA API integration -- [DATABASE_SCHEMA.md](./docs/DATABASE_SCHEMA.md) - Database schema - -## Contributing / Đóng Góp - -Please read [CONTRIBUTING.md](../../CONTRIBUTING.md) for development guidelines. - -## License / Giấy Phép +## 📄 License Copyright © 2026 GoodGo Platform. All rights reserved. diff --git a/services/mkt-zalo-service-net/docs/API_DESIGN.md b/services/mkt-zalo-service-net/docs/API_DESIGN.md deleted file mode 100644 index b49f6f8b..00000000 --- a/services/mkt-zalo-service-net/docs/API_DESIGN.md +++ /dev/null @@ -1,971 +0,0 @@ -# API Design Specification - -**EN**: Complete API design specification for MKT Zalo Service including endpoints, DTOs, request/response formats, and Swagger documentation. - -**VI**: Đặc tả thiết kế API đầy đủ cho Dịch vụ MKT Zalo bao gồm endpoints, DTOs, định dạng request/response, và tài liệu Swagger. - ---- - -## Table of Contents / Mục Lục - -1. [API Overview](#api-overview) -2. [Authentication & Authorization](#authentication--authorization) -3. [Webhook APIs](#webhook-apis) -4. [Conversation APIs](#conversation-apis) -5. [Customer Management APIs](#customer-management-apis) -6. [Chatbot Rule APIs](#chatbot-rule-apis) -7. [Template APIs](#template-apis) -8. [Admin APIs](#admin-apis) -9. [Common DTOs](#common-dtos) -10. [Error Responses](#error-responses) - ---- - -## API Overview - -### Base URL Pattern -``` -http://localhost/api/v{version}/zalo -``` - -### API Versioning -- Version: `1.0` -- Format: URL path versioning (`/api/v1/zalo/...`) - -### Response Wrapper -All APIs use the standard `ApiResponse` wrapper: -```json -{ - "success": true, - "data": { ... }, - "error": null, - "pagination": { ... } // For list endpoints -} -``` - ---- - -## Authentication & Authorization - -### Authentication Schemes - -| Endpoint Category | Auth Method | Details | -|-------------------|-------------|---------| -| **Webhooks** | Signature verification | Zalo webhook signature in header | -| **Public APIs** | JWT Bearer | From IAM service | -| **Admin APIs** | JWT Bearer + Role | Requires `admin` or `marketing_manager` role | - -### Authorization Header -``` -Authorization: Bearer eyJhbGciOiJIUzI1NiIs... -``` - ---- - -## Webhook APIs - -### 1. Receive Zalo Webhook - -**EN**: Endpoint to receive events from Zalo Official Account (user messages, follows, etc.). - -**VI**: Endpoint nhận sự kiện từ Zalo Official Account (tin nhắn, follow, etc.). - -```http -POST /api/v1/zalo/webhooks -Content-Type: application/json -X-Zalo-Signature: -``` - -#### Request Body -```json -{ - "app_id": "1234567890", - "event_name": "user_send_text", - "timestamp": 1705586400000, - "sender": { - "id": "1234567890123456789" - }, - "recipient": { - "id": "9876543210" - }, - "message": { - "text": "Xin chào, tôi cần hỗ trợ", - "msg_id": "msg_123456" - } -} -``` - -#### Response -```http -HTTP/1.1 200 OK -Content-Type: application/json - -{ - "success": true -} -``` - -#### Error Responses -- `401 Unauthorized` - Invalid signature -- `400 Bad Request` - Malformed webhook payload - -#### Implementation Notes -- **MUST** return `200 OK` within 2 seconds -- Webhook processing is async (queued to RabbitMQ) -- Signature verification using `X-Zalo-Signature` header - ---- - -## Conversation APIs - -### 2. Get Conversations List - -**EN**: Get list of conversations with pagination and filtering. - -**VI**: Lấy danh sách hội thoại với phân trang và bộ lọc. - -```http -GET /api/v1/zalo/conversations?skip=0&take=20&status=active&fromDate=2026-01-01 -Authorization: Bearer -``` - -#### Query Parameters -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `skip` | int | No | Number of records to skip (default: 0) | -| `take` | int | No | Number of records to return (default: 20, max: 100) | -| `status` | enum | No | `active`, `closed`, `all` | -| `zaloUserId` | string | No | Filter by Zalo user ID | -| `fromDate` | datetime | No | Filter conversations after this date | -| `toDate` | datetime | No | Filter conversations before this date | - -#### Response -```http -HTTP/1.1 200 OK - -{ - "success": true, - "data": { - "conversations": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "zaloUserId": "1234567890123456789", - "customerName": "Nguyễn Văn A", - "customerAvatar": "https://s.zalo.me/avatar.jpg", - "status": "active", - "lastMessage": "Cảm ơn bạn", - "lastMessageAt": "2026-01-18T10:30:00Z", - "startedAt": "2026-01-18T10:00:00Z", - "messageCount": 15, - "unreadCount": 2 - } - ], - "totalCount": 120 - }, - "pagination": { - "page": 1, - "limit": 20, - "total": 120, - "totalPages": 6 - } -} -``` - ---- - -### 3. Get Conversation Details - -**EN**: Get detailed conversation with full message history. - -**VI**: Lấy chi tiết hội thoại với lịch sử tin nhắn đầy đủ. - -```http -GET /api/v1/zalo/conversations/{conversationId} -Authorization: Bearer -``` - -#### Path Parameters -- `conversationId` (guid) - Conversation ID - -#### Query Parameters -| Parameter | Type | Description | -|-----------|------|-------------| -| `messageSkip` | int | Skip messages (for pagination) | -| `messageTake` | int | Take messages (default: 50) | - -#### Response -```http -HTTP/1.1 200 OK - -{ - "success": true, - "data": { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "zaloUserId": "1234567890123456789", - "customerId": "abc85f64-5717-4562-b3fc-2c963f66afa6", - "status": "active", - "startedAt": "2026-01-18T10:00:00Z", - "endedAt": null, - "customer": { - "id": "abc85f64-5717-4562-b3fc-2c963f66afa6", - "zaloUserId": "1234567890123456789", - "displayName": "Nguyễn Văn A", - "avatarUrl": "https://s.zalo.me/avatar.jpg", - "phoneNumber": "+84901234567", - "tags": ["vip", "interested-in-retail"] - }, - "messages": [ - { - "id": "msg-001", - "type": "text", - "content": "Xin chào", - "direction": "incoming", - "isFromBot": false, - "sentAt": "2026-01-18T10:00:00Z" - }, - { - "id": "msg-002", - "type": "text", - "content": "Xin chào! Tôi có thể giúp gì cho bạn?", - "direction": "outgoing", - "isFromBot": true, - "sentAt": "2026-01-18T10:00:05Z" - } - ], - "messageCount": 15, - "totalMessages": 15 - } -} -``` - ---- - -### 4. Send Message - -**EN**: Send a message to a customer in an active conversation. - -**VI**: Gửi tin nhắn đến khách hàng trong hội thoại đang hoạt động. - -```http -POST /api/v1/zalo/conversations/{conversationId}/messages -Authorization: Bearer -Content-Type: application/json -``` - -#### Request Body -```json -{ - "type": "text", - "content": "Cảm ơn bạn đã liên hệ. Chúng tôi sẽ xử lý yêu cầu của bạn ngay." -} -``` - -#### Response -```http -HTTP/1.1 201 Created - -{ - "success": true, - "data": { - "messageId": "msg-003", - "sentAt": "2026-01-18T10:05:00Z", - "zaloMessageId": "zalo_msg_xyz" - } -} -``` - -#### Error Responses -- `404 Not Found` - Conversation not found -- `400 Bad Request` - Conversation is closed -- `422 Unprocessable Entity` - Failed to send via Zalo API - ---- - -### 5. Close Conversation - -**EN**: Close an active conversation. - -**VI**: Đóng hội thoại đang hoạt động. - -```http -POST /api/v1/zalo/conversations/{conversationId}/close -Authorization: Bearer -``` - -#### Response -```http -HTTP/1.1 200 OK - -{ - "success": true, - "data": { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "status": "closed", - "closedAt": "2026-01-18T11:00:00Z" - } -} -``` - ---- - -## Customer Management APIs - -### 6. Get Customers List - -**EN**: Get list of Zalo customers with filtering and search. - -**VI**: Lấy danh sách khách hàng Zalo với bộ lọc và tìm kiếm. - -```http -GET /api/v1/zalo/customers?skip=0&take=20&search=Nguyen&segment=vip -Authorization: Bearer -``` - -#### Query Parameters -| Parameter | Type | Description | -|-----------|------|-------------| -| `skip` | int | Pagination skip | -| `take` | int | Pagination limit | -| `search` | string | Search by name, phone, email | -| `segment` | enum | `new`, `regular`, `active`, `vip` | -| `tags` | string[] | Filter by tags (comma-separated) | - -#### Response -```http -HTTP/1.1 200 OK - -{ - "success": true, - "data": { - "customers": [ - { - "id": "abc85f64-5717-4562-b3fc-2c963f66afa6", - "zaloUserId": "1234567890123456789", - "displayName": "Nguyễn Văn A", - "avatarUrl": "https://s.zalo.me/avatar.jpg", - "phoneNumber": "+84901234567", - "email": "nguyenvana@example.com", - "segment": "vip", - "tags": ["vip", "interested-in-retail", "high-value"], - "firstInteractionAt": "2026-01-01T08:00:00Z", - "lastInteractionAt": "2026-01-18T10:30:00Z", - "conversationCount": 12, - "totalSpent": 5000000 - } - ], - "totalCount": 1523 - }, - "pagination": { ... } -} -``` - ---- - -### 7. Get Customer Details - -**EN**: Get detailed customer profile with interaction summary. - -**VI**: Lấy hồ sơ khách hàng chi tiết với tóm tắt tương tác. - -```http -GET /api/v1/zalo/customers/{customerId} -Authorization: Bearer -``` - -#### Response -```http -HTTP/1.1 200 OK - -{ - "success": true, - "data": { - "id": "abc85f64-5717-4562-b3fc-2c963f66afa6", - "zaloUserId": "1234567890123456789", - "profile": { - "displayName": "Nguyễn Văn A", - "avatarUrl": "https://s.zalo.me/avatar.jpg", - "phoneNumber": "+84901234567", - "email": "nguyenvana@example.com" - }, - "segment": "vip", - "tags": ["vip", "interested-in-retail"], - "interactionSummary": { - "totalConversations": 12, - "totalMessages": 156, - "averageResponseTime": "PT2M30S", - "lastInteractionAt": "2026-01-18T10:30:00Z", - "firstInteractionAt": "2026-01-01T08:00:00Z" - }, - "recentConversations": [ - { - "id": "conv-001", - "startedAt": "2026-01-18T10:00:00Z", - "messageCount": 15 - } - ] - } -} -``` - ---- - -### 8. Update Customer Profile - -**EN**: Update customer profile information and tags. - -**VI**: Cập nhật thông tin hồ sơ khách hàng và tags. - -```http -PUT /api/v1/zalo/customers/{customerId} -Authorization: Bearer -Content-Type: application/json -``` - -#### Request Body -```json -{ - "phoneNumber": "+84901234567", - "email": "nguyenvana@example.com", - "tags": ["vip", "interested-in-retail", "high-value"] -} -``` - -#### Response -```http -HTTP/1.1 200 OK - -{ - "success": true, - "data": { - "id": "abc85f64-5717-4562-b3fc-2c963f66afa6", - "updatedAt": "2026-01-18T11:00:00Z" - } -} -``` - ---- - -## Chatbot Rule APIs - -### 9. Get Chatbot Rules - -**EN**: Get list of chatbot automation rules. - -**VI**: Lấy danh sách quy tắc tự động chatbot. - -```http -GET /api/v1/zalo/chatbot-rules?isActive=true -Authorization: Bearer -``` - -#### Query Parameters -| Parameter | Type | Description | -|-----------|------|-------------| -| `isActive` | bool | Filter by active status | -| `type` | enum | `keyword`, `regex`, `intent` | - -#### Response -```http -HTTP/1.1 200 OK - -{ - "success": true, - "data": { - "rules": [ - { - "id": "rule-001", - "name": "Greeting Rule", - "type": "keyword", - "priority": 100, - "isActive": true, - "conditions": [ - { - "field": "message_text", - "operator": "contains", - "value": "xin chào" - } - ], - "action": { - "type": "send_text", - "responseText": "Xin chào! Tôi có thể giúp gì cho bạn?" - }, - "matchCount": 523, - "lastMatchedAt": "2026-01-18T10:30:00Z" - } - ], - "totalCount": 15 - } -} -``` - ---- - -### 10. Create Chatbot Rule - -**EN**: Create a new chatbot automation rule. - -**VI**: Tạo quy tắc tự động chatbot mới. - -```http -POST /api/v1/zalo/chatbot-rules -Authorization: Bearer -Content-Type: application/json -``` - -#### Request Body -```json -{ - "name": "Pricing Inquiry", - "type": "keyword", - "priority": 90, - "conditions": [ - { - "field": "message_text", - "operator": "contains_any", - "values": ["giá", "bao nhiêu", "price"] - } - ], - "action": { - "type": "send_text", - "responseText": "Bảng giá của chúng tôi: [link]" - } -} -``` - -#### Response -```http -HTTP/1.1 201 Created - -{ - "success": true, - "data": { - "id": "rule-002", - "createdAt": "2026-01-18T11:00:00Z" - } -} -``` - ---- - -### 11. Update Chatbot Rule - -**EN**: Update an existing chatbot rule. - -**VI**: Cập nhật quy tắc chatbot hiện có. - -```http -PUT /api/v1/zalo/chatbot-rules/{ruleId} -Authorization: Bearer -Content-Type: application/json -``` - -#### Request Body -```json -{ - "name": "Updated Pricing Inquiry", - "priority": 95, - "isActive": true, - "action": { - "type": "send_text", - "responseText": "Bảng giá mới: [link]" - } -} -``` - -#### Response -```http -HTTP/1.1 200 OK - -{ - "success": true, - "data": { - "id": "rule-002", - "updatedAt": "2026-01-18T11:05:00Z" - } -} -``` - ---- - -### 12. Delete Chatbot Rule - -**EN**: Delete a chatbot automation rule. - -**VI**: Xóa quy tắc tự động chatbot. - -```http -DELETE /api/v1/zalo/chatbot-rules/{ruleId} -Authorization: Bearer -``` - -#### Response -```http -HTTP/1.1 204 No Content -``` - ---- - -## Template APIs - -### 13. Get Message Templates - -**EN**: Get list of approved Zalo Notification Service (ZNS) templates. - -**VI**: Lấy danh sách templates Zalo Notification Service (ZNS) đã duyệt. - -```http -GET /api/v1/zalo/templates -Authorization: Bearer -``` - -#### Response -```http -HTTP/1.1 200 OK - -{ - "success": true, - "data": { - "templates": [ - { - "id": "template-001", - "templateId": "283746", // Zalo template ID - "name": "Order Confirmation", - "content": "Đơn hàng {{order_id}} của bạn đã được xác nhận. Tổng: {{total_amount}}đ", - "parameters": [ - { - "name": "order_id", - "type": "string", - "required": true - }, - { - "name": "total_amount", - "type": "number", - "required": true - } - ], - "status": "approved" - } - ] - } -} -``` - ---- - -### 14. Send Template Message - -**EN**: Send a template message (ZNS) to a customer. - -**VI**: Gửi tin nhắn template (ZNS) đến khách hàng. - -```http -POST /api/v1/zalo/templates/{templateId}/send -Authorization: Bearer -Content-Type: application/json -``` - -#### Request Body -```json -{ - "zaloUserId": "1234567890123456789", - "parameters": { - "order_id": "ORD-12345", - "total_amount": "500000" - } -} -``` - -#### Response -```http -HTTP/1.1 200 OK - -{ - "success": true, - "data": { - "messageId": "msg-zns-001", - "sentAt": "2026-01-18T11:00:00Z", - "zaloMessageId": "zalo_msg_xyz" - } -} -``` - ---- - -## Admin APIs - -### 15. Get Analytics Dashboard - -**EN**: Get conversation and engagement analytics. - -**VI**: Lấy phân tích hội thoại và tương tác. - -```http -GET /api/v1/zalo/admin/analytics?fromDate=2026-01-01&toDate=2026-01-18 -Authorization: Bearer -``` - -#### Query Parameters -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `fromDate` | date | Yes | Start date (ISO 8601) | -| `toDate` | date | Yes | End date (ISO 8601) | -| `groupBy` | enum | No | `day`, `week`, `month` | - -#### Response -```json -{ - "success": true, - "data": { - "period": { - "from": "2026-01-01", - "to": "2026-01-18" - }, - "metrics": { - "totalConversations": 1523, - "activeConversations": 234, - "totalMessages": 15678, - "averageResponseTime": "PT1M45S", - "automationRate": 0.72, - "customerSatisfactionScore": 4.5 - }, - "timeline": [ - { - "date": "2026-01-01", - "conversations": 45, - "messages": 567, - "newCustomers": 12 - } - ], - "topKeywords": [ - { "keyword": "giá cả", "count": 234 }, - { "keyword": "giao hàng", "count": 189 } - ], - "rulePerformance": [ - { - "ruleId": "rule-001", - "ruleName": "Greeting Rule", - "matchCount": 523, - "successRate": 0.95 - } - ] - } -} -``` - ---- - -### 16. Search All Messages - -**EN**: Search across all conversations (admin only). - -**VI**: Tìm kiếm trong tất cả hội thoại (chỉ admin). - -```http -GET /api/v1/zalo/admin/messages?search=đơn hàng&skip=0&take=50 -Authorization: Bearer -``` - -#### Query Parameters -| Parameter | Type | Description | -|-----------|------|-------------| -| `search` | string | Full-text search | -| `fromDate` | date | Filter by date | -| `toDate` | date | Filter by date | -| `isFromBot` | bool | Filter bot/customer messages | - -#### Response -```json -{ - "success": true, - "data": { - "messages": [ - { - "id": "msg-001", - "conversationId": "conv-001", - "content": "Đơn hàng của tôi đâu rồi?", - "sentAt": "2026-01-18T10:00:00Z", - "customer": { - "name": "Nguyễn Văn A", - "zaloUserId": "123456" - } - } - ], - "totalCount": 45 - }, - "pagination": { ... } -} -``` - ---- - -### 17. Broadcast Message - -**EN**: Send broadcast message to customer segments. - -**VI**: Gửi tin nhắn quảng bá đến phân khúc khách hàng. - -```http -POST /api/v1/zalo/admin/broadcast -Authorization: Bearer -Content-Type: application/json -``` - -#### Request Body -```json -{ - "targetSegments": ["vip", "active"], - "message": { - "type": "text", - "content": "🎉 Khuyến mãi đặc biệt cho khách hàng VIP!" - }, - "scheduleAt": "2026-01-20T10:00:00Z" // Optional -} -``` - -#### Response -```json -{ - "success": true, - "data": { - "broadcastId": "broadcast-001", - "targetCustomerCount": 1234, - "scheduledAt": "2026-01-20T10:00:00Z", - "status": "scheduled" - } -} -``` - ---- - -## Common DTOs - -### ApiResponse -```csharp -public class ApiResponse -{ - public bool Success { get; set; } - public T? Data { get; set; } - public string? Error { get; set; } - public PaginationInfo? Pagination { get; set; } -} -``` - -### PaginationInfo -```csharp -public record PaginationInfo( - int Page, - int Limit, - int Total, - int TotalPages); -``` - -### Enums - -```csharp -public enum ConversationStatus -{ - Active, - Closed -} - -public enum MessageType -{ - Text, - Image, - Link, - Sticker, - Audio, - Template -} - -public enum MessageDirection -{ - Incoming, // From customer - Outgoing // To customer -} - -public enum CustomerSegment -{ - New, - Regular, - Active, - VIP -} - -public enum RuleType -{ - Keyword, - Regex, - Intent -} -``` - ---- - -## Error Responses - -### Standard Error Format -```json -{ - "success": false, - "error": "Conversation not found", - "details": { - "code": "CONVERSATION_NOT_FOUND", - "conversationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6" - } -} -``` - -### Common HTTP Status Codes - -| Code | Meaning | When to Use | -|------|---------|-------------| -| `200` | OK | Successful GET, PUT, POST (non-creation) | -| `201` | Created | Successful POST (resource created) | -| `204` | No Content | Successful DELETE | -| `400` | Bad Request | Invalid request body/parameters | -| `401` | Unauthorized | Missing or invalid auth token | -| `403` | Forbidden | Insufficient permissions | -| `404` | Not Found | Resource doesn't exist | -| `409` | Conflict | Duplicate resource | -| `422` | Unprocessable Entity | Business logic error (e.g., closed conversation) | -| `500` | Internal Server Error | Unexpected server error | -| `503` | Service Unavailable | Zalo API down, database unavailable | - ---- - -## Swagger Documentation - -### Controller Annotations - -```csharp -[ApiController] -[ApiVersion("1.0")] -[Route("api/v{version:apiVersion}/zalo/conversations")] -[SwaggerTag("Conversation Management - View and manage customer conversations")] -public class ConversationsController : ControllerBase -{ - /// - /// EN: Get list of conversations. - /// VI: Lấy danh sách hội thoại. - /// - [HttpGet] - [Authorize] - [SwaggerOperation(Summary = "Get conversations list")] - [SwaggerResponse(200, "Conversations retrieved successfully")] - [SwaggerResponse(401, "Unauthorized")] - public async Task>> GetConversations( - [FromQuery] int skip = 0, - [FromQuery] int take = 20, - CancellationToken ct = default) - { - // Implementation - } -} -``` - ---- - -**Document Version**: 1.0 -**Last Updated**: 2026-01-18 -**Author**: GoodGo Platform Team diff --git a/services/mkt-zalo-service-net/docs/DATABASE_SCHEMA.md b/services/mkt-zalo-service-net/docs/DATABASE_SCHEMA.md deleted file mode 100644 index a941d4f6..00000000 --- a/services/mkt-zalo-service-net/docs/DATABASE_SCHEMA.md +++ /dev/null @@ -1,562 +0,0 @@ -# Database Schema Design - -**EN**: Database schema design for MKT Zalo Service including tables, relationships, indexes, and migration strategy. - -**VI**: Thiết kế schema cơ sở dữ liệu cho Dịch vụ MKT Zalo bao gồm bảng, mối quan hệ, indexes và chiến lược migration. - ---- - -## Table of Contents / Mục Lục - -1. [Schema Overview](#schema-overview) -2. [Tables](#tables) -3. [Relationships](#relationships) -4. [Indexes](#indexes) -5. [Migrations Strategy](#migrations-strategy) - ---- - -## Schema Overview / Tổng Quan Schema - -```mermaid -erDiagram - ZaloCustomers ||--o{ Conversations : has - Conversations ||--o{ Messages : contains - Conversations }o--|| ZaloCustomers : belongs_to - ZaloCustomers ||--o{ CustomerTags : has - ChatbotRules ||--o{ RuleConditions : contains - ChatbotRules ||--|| RuleActions : has - MessageTemplates ||--o{ TemplateParameters : has - - ZaloCustomers { - uuid Id PK - string ZaloUserId UK - string DisplayName - string AvatarUrl - string PhoneNumber - string Email - int Segment - datetime FirstInteractionAt - datetime LastInteractionAt - datetime CreatedAt - datetime UpdatedAt - } - - CustomerTags { - uuid Id PK - uuid CustomerId FK - string TagName - datetime CreatedAt - } - - Conversations { - uuid Id PK - uuid CustomerId FK - string ZaloUserId - int Status - datetime StartedAt - datetime EndedAt - datetime CreatedAt - datetime UpdatedAt - } - - Messages { - uuid Id PK - uuid ConversationId FK - int Type - string Content - int Direction - bool IsFromBot - datetime SentAt - string ZaloMessageId - } - - ChatbotRules { - uuid Id PK - string Name - int Type - int Priority - bool IsActive - int MatchCount - datetime LastMatchedAt - datetime CreatedAt - datetime UpdatedAt - } - - RuleConditions { - uuid Id PK - uuid RuleId FK - string Field - string Operator - string Value - } - - RuleActions { - uuid Id PK - uuid RuleId FK - int ActionType - string ResponseText - string TemplateId - } - - MessageTemplates { - uuid Id PK - string ZaloTemplateId UK - string Name - string Content - int Status - datetime CreatedAt - datetime UpdatedAt - } - - TemplateParameters { - uuid Id PK - uuid TemplateId FK - string ParameterName - int ParameterType - bool IsRequired - } -``` - ---- - -## Tables / Các Bảng - -### 1. ZaloCustomers - -**EN**: Stores Zalo customer profile and CRM data. - -**VI**: Lưu trữ hồ sơ khách hàng Zalo và dữ liệu CRM. - -```sql -CREATE TABLE "ZaloCustomers" ( - "Id" UUID PRIMARY KEY DEFAULT gen_random_uuid(), - "ZaloUserId" VARCHAR(50) NOT NULL UNIQUE, -- From Zalo OA - "DisplayName" VARCHAR(255) NOT NULL, - "AvatarUrl" VARCHAR(500), - "PhoneNumber" VARCHAR(20), - "Email" VARCHAR(255), - "Segment" INT NOT NULL DEFAULT 0, -- 0=New, 1=Regular, 2=Active, 3=VIP - "FirstInteractionAt" TIMESTAMPTZ NOT NULL, - "LastInteractionAt" TIMESTAMPTZ NOT NULL, - "CreatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW(), - "UpdatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW() -); - --- Indexesfor fast lookup -CREATE INDEX "IX_ZaloCustomers_ZaloUserId" ON "ZaloCustomers" ("ZaloUserId"); -CREATE INDEX "IX_ZaloCustomers_Segment" ON "ZaloCustomers" ("Segment"); -CREATE INDEX "IX_ZaloCustomers_LastInteractionAt" ON "ZaloCustomers" ("LastInteractionAt" DESC); -``` - -**Columns:** -- `Id`: Primary key (GUID) -- `ZaloUserId`: Unique ID from Zalo Official Account -- `DisplayName`: Customer's display name -- `AvatarUrl`: Avatar image URL -- `PhoneNumber`: Contact phone (nullable) -- `Email`: Contact email (nullable) -- `Segment`: Customer segment (0=New, 1=Regular, 2=Active, 3=VIP) -- `FirstInteractionAt`: First conversation timestamp -- `LastInteractionAt`: Most recent conversation timestamp - ---- - -### 2. CustomerTags - -**EN**: Many-to-many tags for customer segmentation and filtering. - -**VI**: Tags nhiều-nhiều cho phân khúc và lọc khách hàng. - -```sql -CREATE TABLE "CustomerTags" ( - "Id" UUID PRIMARY KEY DEFAULT gen_random_uuid(), - "CustomerId" UUID NOT NULL REFERENCES "ZaloCustomers"("Id") ON DELETE CASCADE, - "TagName" VARCHAR(50) NOT NULL, - "CreatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW() -); - -CREATE INDEX "IX_CustomerTags_CustomerId" ON "CustomerTags" ("CustomerId"); -CREATE INDEX "IX_CustomerTags_TagName" ON "CustomerTags" ("TagName"); -CREATE UNIQUE INDEX "UX_CustomerTags_CustomerId_TagName" ON "CustomerTags" ("CustomerId", "TagName"); -``` - ---- - -### 3. Conversations - -**EN**: Tracks conversation sessions between customers and the chatbot. - -**VI**: Theo dõi phiên hội thoại giữa khách hàng và chatbot. - -```sql -CREATE TABLE "Conversations" ( - "Id" UUID PRIMARY KEY DEFAULT gen_random_uuid(), - "CustomerId" UUID NOT NULL REFERENCES "ZaloCustomers"("Id") ON DELETE CASCADE, - "ZaloUserId" VARCHAR(50) NOT NULL, -- Denormalized for quick access - "Status" INT NOT NULL DEFAULT 0, -- 0=Active, 1=Closed - "StartedAt" TIMESTAMPTZ NOT NULL, - "EndedAt" TIMESTAMPTZ, - "CreatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW(), - "UpdatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW() -); - -CREATE INDEX "IX_Conversations_CustomerId" ON "Conversations" ("CustomerId"); -CREATE INDEX "IX_Conversations_Status_StartedAt" ON "Conversations" ("Status", "StartedAt" DESC); -CREATE INDEX "IX_Conversations_ZaloUserId" ON "Conversations" ("ZaloUserId"); -``` - ---- - -### 4. Messages - -**EN**: Stores all messages within conversations (customer and bot messages). - -**VI**: Lưu trữ tất cả tin nhắn trong hội thoại (tin khách hàng và bot). - -```sql -CREATE TABLE "Messages" ( - "Id" UUID PRIMARY KEY DEFAULT gen_random_uuid(), - "ConversationId" UUID NOT NULL REFERENCES "Conversations"("Id") ON DELETE CASCADE, - "Type" INT NOT NULL, -- 0=Text, 1=Image, 2=Link, 3=Sticker, 4=Audio, 5=Template - "Content" TEXT NOT NULL, - "Direction" INT NOT NULL, -- 0=Incoming, 1=Outgoing - "IsFromBot" BOOLEAN NOT NULL DEFAULT FALSE, - "SentAt" TIMESTAMPTZ NOT NULL, - "ZaloMessageId" VARCHAR(100), -- Zalo's message ID for tracking - "CreatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW() -); - -CREATE INDEX "IX_Messages_ConversationId_SentAt" ON "Messages" ("ConversationId", "SentAt" DESC); -CREATE INDEX "IX_Messages_SentAt" ON "Messages" ("SentAt" DESC); -CREATE INDEX "IX_Messages_ZaloMessageId" ON "Messages" ("ZaloMessageId") WHERE "ZaloMessageId" IS NOT NULL; - --- Full-text search index for message content -CREATE INDEX "IX_Messages_Content_FullText" ON "Messages" USING GIN (to_tsvector('english', "Content")); -``` - -**Columns:** -- `Type`: 0=Text, 1=Image, 2=Link, 3=Sticker, 4=Audio, 5=Template -- `Direction`: 0=Incoming (from customer), 1=Outgoing (to customer) -- `IsFromBot`: TRUE if automated, FALSE if manual response -- `ZaloMessageId`: Tracking ID from Zalo API response - ---- - -### 5. ChatbotRules - -**EN**: Automation rules for rule-based chatbot engine. - -**VI**: Quy tắc tự động hóa cho engine chatbot dựa trên quy tắc. - -```sql -CREATE TABLE "ChatbotRules" ( - "Id" UUID PRIMARY KEY DEFAULT gen_random_uuid(), - "Name" VARCHAR(255) NOT NULL, - "Type" INT NOT NULL, -- 0=Keyword, 1=Regex, 2=Intent - "Priority" INT NOT NULL DEFAULT 50, -- Higher = evaluated first - "IsActive" BOOLEAN NOT NULL DEFAULT TRUE, - "MatchCount" INT NOT NULL DEFAULT 0, - "LastMatchedAt" TIMESTAMPTZ, - "CreatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW(), - "UpdatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW() -); - -CREATE INDEX "IX_ChatbotRules_IsActive_Priority" ON "ChatbotRules" ("IsActive", "Priority" DESC); -CREATE INDEX "IX_ChatbotRules_Type" ON "ChatbotRules" ("Type"); -``` - ---- - -### 6. RuleConditions - -**EN**: Conditions for chatbot rule matching (1-to-many with ChatbotRules). - -**VI**: Điều kiện khớp quy tắc chatbot (1-nhiều với ChatbotRules). - -```sql -CREATE TABLE "RuleConditions" ( - "Id" UUID PRIMARY KEY DEFAULT gen_random_uuid(), - "RuleId" UUID NOT NULL REFERENCES "ChatbotRules"("Id") ON DELETE CASCADE, - "Field" VARCHAR(50) NOT NULL, -- e.g., "message_text", "customer_segment" - "Operator" VARCHAR(50) NOT NULL, -- e.g., "contains", "equals", "regex" - "Value" TEXT NOT NULL, - "CreatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW() -); - -CREATE INDEX "IX_RuleConditions_RuleId" ON "RuleConditions" ("RuleId"); -``` - ---- - -### 7. RuleActions - -**EN**: Actions to execute when a chatbot rule matches (1-to-1 with ChatbotRules). - -**VI**: Hành động thực thi khi quy tắc chatbot khớp (1-1 với ChatbotRules). - -```sql -CREATE TABLE "RuleActions" ( - "Id" UUID PRIMARY KEY DEFAULT gen_random_uuid(), - "RuleId" UUID NOT NULL UNIQUE REFERENCES "ChatbotRules"("Id") ON DELETE CASCADE, - "ActionType" INT NOT NULL, -- 0=SendText, 1=SendTemplate, 2=ForwardToHuman - "ResponseText" TEXT, - "TemplateId" UUID, -- Reference to MessageTemplates (nullable) - "CreatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW() -); - -CREATE INDEX "IX_RuleActions_RuleId" ON "RuleActions" ("RuleId"); -``` - ---- - -### 8. MessageTemplates - -**EN**: Approved ZNS (Zalo Notification Service) templates. - -**VI**: Templates ZNS (Zalo Notification Service) đã duyệt. - -```sql -CREATE TABLE "MessageTemplates" ( - "Id" UUID PRIMARY KEY DEFAULT gen_random_uuid(), - "ZaloTemplateId" VARCHAR(50) NOT NULL UNIQUE, -- Zalo's template ID - "Name" VARCHAR(255) NOT NULL, - "Content" TEXT NOT NULL, - "Status" INT NOT NULL DEFAULT 0, -- 0=Pending, 1=Approved, 2=Rejected - "CreatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW(), - "UpdatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW() -); - -CREATE INDEX "IX_MessageTemplates_ZaloTemplateId" ON "MessageTemplates" ("ZaloTemplateId"); -CREATE INDEX "IX_MessageTemplates_Status" ON "MessageTemplates" ("Status"); -``` - ---- - -### 9. TemplateParameters - -**EN**: Parameters for message templates (1-to-many with MessageTemplates). - -**VI**: Tham số cho message templates (1-nhiều với MessageTemplates). - -```sql -CREATE TABLE "TemplateParameters" ( - "Id" UUID PRIMARY KEY DEFAULT gen_random_uuid(), - "TemplateId" UUID NOT NULL REFERENCES "MessageTemplates"("Id") ON DELETE CASCADE, - "ParameterName" VARCHAR(100) NOT NULL, - "ParameterType" INT NOT NULL, -- 0=String, 1=Number, 2=Date - "IsRequired" BOOLEAN NOT NULL DEFAULT TRUE, - "CreatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW() -); - -CREATE INDEX "IX_TemplateParameters_TemplateId" ON "TemplateParameters" ("TemplateId"); -``` - ---- - -## Relationships / Mối Quan Hệ - -``` -ZaloCustomers (1) ──── (M) CustomerTags -ZaloCustomers (1) ──── (M) Conversations -Conversations (1) ──── (M) Messages -ChatbotRules (1) ──── (M) RuleConditions -ChatbotRules (1) ──── (1) RuleActions -MessageTemplates (1) ──── (M) TemplateParameters -``` - ---- - -## Indexes / Chỉ Mục - -### Performance-Critical Indexes - -| Table | Index | Purpose | -|-------|-------|---------| -| `ZaloCustomers` | `IX_ZaloCustomers_ZaloUserId` | Fast lookup by Zalo user ID (webhook processing) | -| `Conversations` | `IX_Conversations_Status_StartedAt` | List active/recent conversations | -| `Messages` | `IX_Messages_ConversationId_SentAt` | Get conversation history (descending) | -| `Messages` | `IX_Messages_Content_FullText` | Full-text search for admin search API | -| `ChatbotRules` | `IX_ChatbotRules_IsActive_Priority` | Fast rule evaluation (ordered by priority) | - -### Unique Constraints - -- `ZaloCustomers.ZaloUserId` - Prevent duplicate customers -- `MessageTemplates.ZaloTemplateId` - One template per Zalo ID -- `CustomerTags (CustomerId, TagName)` - No duplicate tags per customer - ---- - -## Migrations Strategy / Chiến Lược Migration - -### Initial Migration (`20260118_InitialSchema`) - -```bash -dotnet ef migrations add InitialSchema \ - --project src/MktZaloService.Infrastructure \ - --startup-project src/MktZaloService.API -``` - -**Includes:** -1. All 9 tables -2. All indexes -3. Foreign key constraints -4. Default values - -### Seed Data Migration (`20260118_SeedDefaultRules`) - -**EN**: Seed common chatbot rules for Vietnamese greetings and FAQs. - -**VI**: Seed quy tắc chatbot phổ biến cho lời chào và FAQ tiếng Việt. - -```sql -INSERT INTO "ChatbotRules" ("Id", "Name", "Type", "Priority", "IsActive") -VALUES - (gen_random_uuid(), 'Greeting Rule', 0, 100, TRUE), - (gen_random_uuid(), 'Pricing Inquiry', 0, 90, TRUE), - (gen_random_uuid(), 'Store Hours', 0, 90, TRUE); - --- Conditions and actions... -``` - -### Migration Workflow - -```bash -# 1. Create migration -dotnet ef migrations add MigrationName \ - --project src/MktZaloService.Infrastructure - -# 2. Review migration (check Up/Down methods) - -# 3. Apply to local database -dotnet ef database update \ - --project src/MktZaloService.Infrastructure - -# 4. Test rollback -dotnet ef database update PreviousMigration \ - --project src/MktZaloService.Infrastructure - -# 5. Deploy to production -# (Migrations are applied automatically on service startup) -``` - ---- - -## EF Core Configuration Examples - -### Conversation Entity Configuration - -```csharp -public class ConversationEntityConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.ToTable("Conversations"); - - builder.HasKey(c => c.Id); - - builder.Property(c => c.ZaloUserId) - .IsRequired() - .HasMaxLength(50); - - builder.Property(c => c.Status) - .HasConversion(); // Enum to int - - builder.HasMany(c => c.Messages) - .WithOne() - .HasForeignKey("ConversationId") - .OnDelete(DeleteBehavior.Cascade); - - builder.HasIndex(c => new { c.Status, c.StartedAt }) - .HasDatabaseName("IX_Conversations_Status_StartedAt"); - } -} -``` - -### Message Entity Configuration - -```csharp -public class MessageEntityConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.ToTable("Messages"); - - builder.HasKey(m => m.Id); - - builder.Property(m => m.Type) - .HasConversion(); - - builder.Property(m => m.Direction) - .HasConversion(); - - builder.Property(m => m.Content) - .IsRequired(); - - builder.HasIndex(m => new { m.ConversationId, m.SentAt }) - .HasDatabaseName("IX_Messages_ConversationId_SentAt"); - } -} -``` - ---- - -## Database Statistics / Thống Kê Cơ Sở Dữ Liệu - -### Expected Data Volume (6 months) - -| Table | Est. Rows | Growth Rate | -|-------|-----------|-------------| -| `ZaloCustomers` | 10,000 | +500/day | -| `Conversations` | 50,000 | +2,000/day | -| `Messages` | 750,000 | +30,000/day | -| `ChatbotRules` | 50 | +1/week | -| `MessageTemplates` | 20 | +2/month | - -### Storage Estimates - -- **Messages table**: ~100MB per 100K messages -- **Total DB size (6 months)**: ~2GB -- **Recommended instance**: PostgreSQL 15+ with 4GB RAM - ---- - -## Backup & Maintenance / Sao Lưu & Bảo Trì - -### Backup Strategy - -```bash -# Daily automated backups (Neon PostgreSQL) -- Full backup: Daily at 02:00 UTC -- Retention: 30 days -- Point-in-time recovery: Last 7 days -``` - -### Maintenance Tasks - -```sql --- Monthly vacuum analyze (performance) -VACUUM ANALYZE "Messages"; -VACUUM ANALYZE "Conversations"; - --- Reindex if needed -REINDEX TABLE "Messages"; -``` - -### Archival Strategy - -```sql --- Archive conversations older than 1 year -INSERT INTO "ConversationsArchive" -SELECT * FROM "Conversations" -WHERE "StartedAt" < NOW() - INTERVAL '1 year'; - -DELETE FROM "Conversations" -WHERE "StartedAt" < NOW() - INTERVAL '1 year'; -``` - ---- - -**Document Version**: 1.0 -**Last Updated**: 2026-01-18 -**Author**: GoodGo Platform Team diff --git a/services/mkt-zalo-service-net/docs/DOMAIN_MODELS.md b/services/mkt-zalo-service-net/docs/DOMAIN_MODELS.md deleted file mode 100644 index 219e139e..00000000 --- a/services/mkt-zalo-service-net/docs/DOMAIN_MODELS.md +++ /dev/null @@ -1,733 +0,0 @@ -# Domain Models Documentation - -**EN**: Detailed documentation of domain entities, aggregates, value objects, and domain events for MKT Zalo Service. - -**VI**: Tài liệu chi tiết về domain entities, aggregates, value objects và domain events cho Dịch vụ MKT Zalo. - ---- - -## Table of Contents / Mục Lục - -1. [Domain-Driven Design Principles](#ddd-principles) -2. [Aggregates](#aggregates) -3. [Entities](#entities) -4. [Value Objects](#value-objects) -5. [Domain Events](#domain-events) -6. [Enumerations](#enumerations) - ---- - -## DDD Principles / Nguyên Tắc DDD - -### Aggregate Design Rules / Quy Tắc Thiết Kế Aggregate - -1. **One Repository Per Aggregate Root** / Một Repository cho mỗi Aggregate Root -2. **Reference Other Aggregates by ID** / Tham chiếu Aggregates khác qua ID -3. **Enforce Business Rules Within Aggregate** / Thực thi Business Rules trong Aggregate -4. **Keep Aggregates Small** / Giữ Aggregates nhỏ gọn - ---- - -## Aggregates - -### 1. Conversation Aggregate - -**EN**: Manages conversation lifecycle and messages between customer and chatbot. - -**VI**: Quản lý vòng đời hội thoại và tin nhắn giữa khách hàng và chatbot. - -```csharp -/// -/// EN: Conversation aggregate root. -/// VI: Aggregate root Conversation. -/// -public class Conversation : Entity, IAggregateRoot -{ - private readonly List _messages = new(); - - // EN: Properties / VI: Thuộc tính - public string ZaloUserId { get; private set; } - public Guid CustomerId { get; private set; } - public ConversationStatus Status { get; private set; } - public DateTime StartedAt { get; private set; } - public DateTime? EndedAt { get; private set; } - public IReadOnlyCollection Messages => _messages.AsReadOnly(); - - // EN: Private constructor for EF Core - // VI: Constructor private cho EF Core - private Conversation() { } - - // EN: Public factory method - // VI: Factory method public - public Conversation(string zaloUserId, Guid customerId) - { - Id = Guid.NewGuid(); - ZaloUserId = zaloUserId ?? throw new ArgumentNullException(nameof(zaloUserId)); - CustomerId = customerId; - Status = ConversationStatus.Active; - StartedAt = DateTime.UtcNow; - - AddDomainEvent(new ConversationStartedDomainEvent(Id, zaloUserId, customerId)); - } - - // EN: Business logic methods / VI: Phương thức business logic - public void AddMessage(MessageType type, string content, MessageDirection direction, bool isFromBot) - { - // EN: Business rule: Cannot add messages to closed conversations - // VI: Quy tắc: Không thể thêm tin nhắn vào hội thoại đã đóng - if (Status == ConversationStatus.Closed) - throw new ZaloDomainException("Cannot add message to closed conversation"); - - if (string.IsNullOrWhiteSpace(content)) - throw new ArgumentException("Message content cannot be empty", nameof(content)); - - if (content.Length > 2000) - throw new ArgumentException("Message content exceeds 2000 characters", nameof(content)); - - var message = new Message(type, content, direction, isFromBot); - _messages.Add(message); - - AddDomainEvent(new MessageReceivedDomainEvent(Id, message.Id, content, direction)); - } - - public void Close() - { - // EN: Business rule: Already closed conversations remain closed - // VI: Quy tắc: Hội thoại đã đóng vẫn giữ trạng thái đóng - if (Status == ConversationStatus.Closed) - return; - - Status = ConversationStatus.Closed; - EndedAt = DateTime.UtcNow; - - AddDomainEvent(new ConversationClosedDomainEvent(Id)); - } - - public void Reopen() - { - // EN: Business rule: Can only reopen closed conversations - // VI: Quy tắc: Chỉ có thể mở lại hội thoại đã đóng - if (Status != ConversationStatus.Closed) - throw new ZaloDomainException("Can only reopen closed conversations"); - - Status = ConversationStatus.Active; - EndedAt = null; - } -} -``` - -**Invariants / Bất Biến:** -- A conversation must have a ZaloUserId and CustomerId -- Messages cannot be added to closed conversations -- Conversation status must be either Active or Closed - ---- - -### 2. ZaloCustomer Aggregate - -**EN**: Manages customer profile, tags, segmentation, and interaction history. - -**VI**: Quản lý hồ sơ khách hàng, tags, phân khúc và lịch sử tương tác. - -```csharp -/// -/// EN: Zalo customer aggregate root. -/// VI: Aggregate root ZaloCustomer. -/// -public class ZaloCustomer : Entity, IAggregateRoot -{ - private readonly List _tags = new(); - - public string ZaloUserId { get; private set; } - public CustomerProfile Profile { get; private set; } - public CustomerSegment Segment { get; private set; } - public DateTime FirstInteractionAt { get; private set; } - public DateTime LastInteractionAt { get; private set; } - public IReadOnlyCollection Tags => _tags.AsReadOnly(); - - private ZaloCustomer() { } - - public ZaloCustomer(string zaloUserId, string displayName, string avatarUrl) - { - Id = Guid.NewGuid(); - ZaloUserId = zaloUserId ?? throw new ArgumentNullException(nameof(zaloUserId)); - Profile = new CustomerProfile(displayName, avatarUrl, null, null); - Segment = CustomerSegment.New; - FirstInteractionAt = DateTime.UtcNow; - LastInteractionAt = DateTime.UtcNow; - - AddDomainEvent(new CustomerCreatedDomainEvent(Id, zaloUserId)); - } - - public void UpdateProfile(string displayName, string avatarUrl, string? phoneNumber = null, string? email = null) - { - // EN: Business rule: Display name is required - // VI: Quy tắc: Display name bắt buộc - if (string.IsNullOrWhiteSpace(displayName)) - throw new ArgumentException("Display name cannot be empty", nameof(displayName)); - - Profile = new CustomerProfile(displayName, avatarUrl, phoneNumber, email); - - AddDomainEvent(new CustomerProfileUpdatedDomainEvent(Id, ZaloUserId)); - } - - public void AddTag(string tagName) - { - // EN: Business rule: No duplicate tags - // VI: Quy tắc: Không trùng tags - if (string.IsNullOrWhiteSpace(tagName)) - throw new ArgumentException("Tag name cannot be empty", nameof(tagName)); - - if (_tags.Any(t => t.Name.Equals(tagName, StringComparison.OrdinalIgnoreCase))) - return; // Already exists - - _tags.Add(new Tag(tagName)); - } - - public void RemoveTag(string tagName) - { - var tag = _tags.FirstOrDefault(t => t.Name.Equals(tagName, StringComparison.OrdinalIgnoreCase)); - if (tag != null) - _tags.Remove(tag); - } - - public void UpdateLastInteraction() - { - LastInteractionAt = DateTime.UtcNow; - } - - public void UpdateSegment(int conversationCount, int messageCount) - { - // EN: Auto-segment based on engagement - // VI: Tự động phân khúc dựa trên tương tác - Segment = (conversationCount, messageCount) switch - { - (> 50, > 500) => CustomerSegment.VIP, - (> 20, > 200) => CustomerSegment.Active, - (> 5, > 50) => CustomerSegment.Regular, - _ => CustomerSegment.New - }; - } -} -``` - -**Invariants:** -- ZaloUserId must be unique -- DisplayName cannot be empty -- Last interaction must be >= first interaction - ---- - -### 3. ChatbotRule Aggregate - -**EN**: Defines automation rules for rule-based chatbot responses. - -**VI**: Định nghĩa quy tắc tự động cho phản hồi chatbot dựa trên quy tắc. - -```csharp -/// -/// EN: Chatbot rule aggregate root. -/// VI: Aggregate root ChatbotRule. -/// -public class ChatbotRule : Entity, IAggregateRoot -{ - private readonly List _conditions = new(); - - public string Name { get; private set; } - public RuleType Type { get; private set; } - public IReadOnlyCollection Conditions => _conditions.AsReadOnly(); - public RuleAction Action { get; private set; } - public int Priority { get; private set; } - public bool IsActive { get; private set; } - public int MatchCount { get; private set; } - public DateTime? LastMatchedAt { get; private set; } - - private ChatbotRule() { } - - public ChatbotRule(string name, RuleType type, int priority, RuleAction action) - { - Id = Guid.NewGuid(); - Name = name ?? throw new ArgumentNullException(nameof(name)); - Type = type; - Action = action ?? throw new ArgumentNullException(nameof(action)); - Priority = priority; - IsActive = true; - MatchCount = 0; - } - - public void AddCondition(string field, string operatorType, string value) - { - // EN: Business rule: At least one condition required - // VI: Quy tắc: Ít nhất một điều kiện được yêu cầu - var condition = new RuleCondition(field, operatorType, value); - _conditions.Add(condition); - } - - public bool Evaluate(string userMessage, CustomerSegment? customerSegment = null) - { - if (!IsActive) - return false; - - // EN: Evaluate based on rule type - // VI: Đánh giá dựa trên loại quy tắc - return Type switch - { - RuleType.Keyword => EvaluateKeywordRule(userMessage), - RuleType.Regex => EvaluateRegexRule(userMessage), - RuleType.Intent => EvaluateIntentRule(userMessage), - _ => false - }; - } - - private bool EvaluateKeywordRule(string userMessage) - { - return _conditions.Any(c => - userMessage.Contains(c.Value, StringComparison.OrdinalIgnoreCase)); - } - - private bool EvaluateRegexRule(string userMessage) - { - return _conditions.Any(c => Regex.IsMatch(userMessage, c.Value)); - } - - private bool EvaluateIntentRule(string userMessage) - { - // EN: Intent classification would use NLP/ML model - // VI: Phân loại intent sử dụng mô hình NLP/ML - return false; // Placeholder - } - - public void RecordMatch() - { - MatchCount++; - LastMatchedAt = DateTime.UtcNow; - } - - public void Activate() => IsActive = true; - public void Deactivate() => IsActive = false; - - public void UpdatePriority(int newPriority) - { - // EN: Business rule: Priority must be 0-100 - // VI: Quy tắc: Priority phải từ 0-100 - if (newPriority < 0 || newPriority > 100) - throw new ArgumentException("Priority must be between 0 and 100", nameof(newPriority)); - - Priority = newPriority; - } -} -``` - -**Invariants:** -- Rule must have at least one condition -- Priority must be 0-100 -- Action must be defined - ---- - -### 4. MessageTemplate Aggregate - -**EN**: Manages approved Zalo Notification Service (ZNS) templates. - -**VI**: Quản lý templates Zalo Notification Service (ZNS) đã duyệt. - -```csharp -/// -/// EN: Message template aggregate root. -/// VI: Aggregate root MessageTemplate. -/// -public class MessageTemplate : Entity, IAggregateRoot -{ - private readonly List _parameters = new(); - - public string ZaloTemplateId { get; private set; } - public string Name { get; private set; } - public string Content { get; private set; } - public TemplateStatus Status { get; private set; } - public IReadOnlyCollection Parameters => _parameters.AsReadOnly(); - - private MessageTemplate() { } - - public MessageTemplate(string zaloTemplateId, string name, string content) - { - Id = Guid.NewGuid(); - ZaloTemplateId = zaloTemplateId ?? throw new ArgumentNullException(nameof(zaloTemplateId)); - Name = name ?? throw new ArgumentNullException(nameof(name)); - Content = content ?? throw new ArgumentNullException(nameof(content)); - Status = TemplateStatus.Pending; - } - - public void AddParameter(string parameterName, ParameterType type, bool isRequired) - { - var param = new TemplateParameter(parameterName, type, isRequired); - _parameters.Add(param); - } - - public void Approve() => Status = TemplateStatus.Approved; - public void Reject() => Status = TemplateStatus.Rejected; - - public Dictionary ValidateParameters(Dictionary providedParams) - { - // EN: Business rule: All required parameters must be provided - // VI: Quy tắc: Tất cả parameters bắt buộc phải được cung cấp - var missingParams = _parameters - .Where(p => p.IsRequired && !providedParams.ContainsKey(p.Name)) - .Select(p => p.Name) - .ToList(); - - if (missingParams.Any()) - throw new ZaloDomainException($"Missing required parameters: {string.Join(", ", missingParams)}"); - - return providedParams; - } -} -``` - ---- - -## Entities / Thực Thể - -### Message Entity - -```csharp -/// -/// EN: Message entity within Conversation aggregate. -/// VI: Entity Message trong aggregate Conversation. -/// -public class Message : Entity -{ - public MessageType Type { get; private set; } - public string Content { get; private set; } - public MessageDirection Direction { get; private set; } - public bool IsFromBot { get; private set; } - public DateTime SentAt { get; private set; } - public string? ZaloMessageId { get; private set; } - - private Message() { } - - public Message(MessageType type, string content, MessageDirection direction, bool isFromBot) - { - Id = Guid.NewGuid(); - Type = type; - Content = content ?? throw new ArgumentNullException(nameof(content)); - Direction = direction; - IsFromBot = isFromBot; - SentAt = DateTime.UtcNow; - } - - public void SetZaloMessageId(string zaloMessageId) - { - ZaloMessageId = zaloMessageId; - } -} -``` - -### Tag Entity - -```csharp -/// -/// EN: Tag entity within ZaloCustomer aggregate. -/// VI: Entity Tag trong aggregate ZaloCustomer. -/// -public class Tag : Entity -{ - public string Name { get; private set; } - public DateTime CreatedAt { get; private set; } - - private Tag() { } - - public Tag(string name) - { - Id = Guid.NewGuid(); - Name = name?.Trim() ?? throw new ArgumentNullException(nameof(name)); - CreatedAt = DateTime.UtcNow; - } -} -``` - ---- - -## Value Objects - -### CustomerProfile Value Object - -```csharp -/// -/// EN: Customer profile value object. -/// VI: Value object hồ sơ khách hàng. -/// -public class CustomerProfile : ValueObject -{ - public string DisplayName { get; } - public string AvatarUrl { get; } - public string? PhoneNumber { get; } - public string? Email { get; } - - public CustomerProfile(string displayName, string avatarUrl, string? phoneNumber, string? email) - { - DisplayName = displayName ?? throw new ArgumentNullException(nameof(displayName)); - AvatarUrl = avatarUrl ?? throw new ArgumentNullException(nameof(avatarUrl)); - PhoneNumber = phoneNumber; - Email = email; - } - - protected override IEnumerable GetEqualityComponents() - { - yield return DisplayName; - yield return AvatarUrl; - yield return PhoneNumber; - yield return Email; - } -} -``` - -### RuleCondition Value Object - -```csharp -/// -/// EN: Rule condition value object. -/// VI: Value object điều kiện quy tắc. -/// -public class RuleCondition : ValueObject -{ - public string Field { get; } - public string Operator { get; } - public string Value { get; } - - public RuleCondition(string field, string operatorType, string value) - { - Field = field ?? throw new ArgumentNullException(nameof(field)); - Operator = operatorType ?? throw new ArgumentNullException(nameof(operatorType)); - Value = value ?? throw new ArgumentNullException(nameof(value)); - } - - protected override IEnumerable GetEqualityComponents() - { - yield return Field; - yield return Operator; - yield return Value; - } -} -``` - -### RuleAction Value Object - -```csharp -/// -/// EN: Rule action value object. -/// VI: Value object hành động quy tắc. -/// -public class RuleAction : ValueObject -{ - public ActionType ActionType { get; } - public string? ResponseText { get; } - public Guid? TemplateId { get; } - - public RuleAction(ActionType actionType, string? responseText = null, Guid? templateId = null) - { - ActionType = actionType; - ResponseText = responseText; - TemplateId = templateId; - - // EN: Business rule: SendText must have ResponseText - // VI: Quy tắc: SendText phải có ResponseText - if (actionType == ActionType.SendText && string.IsNullOrWhiteSpace(responseText)) - throw new ArgumentException("SendText action requires ResponseText", nameof(responseText)); - - // EN: Business rule: SendTemplate must have TemplateId - // VI: Quy tắc: SendTemplate phải có TemplateId - if (actionType == ActionType.SendTemplate && !templateId.HasValue) - throw new ArgumentException("SendTemplate action requires TemplateId", nameof(templateId)); - } - - protected override IEnumerable GetEqualityComponents() - { - yield return ActionType; - yield return ResponseText; - yield return TemplateId; - } -} -``` - -### TemplateParameter Value Object - -```csharp -/// -/// EN: Template parameter value object. -/// VI: Value object tham số template. -/// -public class TemplateParameter : ValueObject -{ - public string Name { get; } - public ParameterType Type { get; } - public bool IsRequired { get; } - - public TemplateParameter(string name, ParameterType type, bool isRequired) - { - Name = name ?? throw new ArgumentNullException(nameof(name)); - Type = type; - IsRequired = isRequired; - } - - protected override IEnumerable GetEqualityComponents() - { - yield return Name; - yield return Type; - yield return IsRequired; - } -} -``` - ---- - -## Domain Events - -### ConversationStartedDomainEvent - -```csharp -/// -/// EN: Domain event when conversation starts. -/// VI: Domain event khi hội thoại bắt đầu. -/// -public record ConversationStartedDomainEvent : IDomainEvent -{ - public Guid Id { get; } = Guid.NewGuid(); - public DateTime OccurredOn { get; } = DateTime.UtcNow; - public Guid ConversationId { get; init; } - public string ZaloUserId { get; init; } - public Guid CustomerId { get; init; } - - public ConversationStartedDomainEvent(Guid conversationId, string zaloUserId, Guid customerId) - { - ConversationId = conversationId; - ZaloUserId = zaloUserId; - CustomerId = customerId; - } -} -``` - -### MessageReceivedDomainEvent - -```csharp -/// -/// EN: Domain event when message is received. -/// VI: Domain event khi tin nhắn được nhận. -/// -public record MessageReceivedDomainEvent : IDomainEvent -{ - public Guid Id { get; } = Guid.NewGuid(); - public DateTime OccurredOn { get; } = DateTime.UtcNow; - public Guid ConversationId { get; init; } - public Guid MessageId { get; init; } - public string Content { get; init; } - public MessageDirection Direction { get; init; } - - public MessageReceivedDomainEvent(Guid conversationId, Guid messageId, string content, MessageDirection direction) - { - ConversationId = conversationId; - MessageId = messageId; - Content = content; - Direction = direction; - } -} -``` - -### CustomerProfileUpdatedDomainEvent - -```csharp -/// -/// EN: Domain event when customer profile is updated. -/// VI: Domain event khi hồ sơ khách hàng được cập nhật. -/// -public record CustomerProfileUpdatedDomainEvent : IDomainEvent -{ - public Guid Id { get; } = Guid.NewGuid(); - public DateTime OccurredOn { get; } = DateTime.UtcNow; - public Guid CustomerId { get; init; } - public string ZaloUserId { get; init; } - - public CustomerProfileUpdatedDomainEvent(Guid customerId, string zaloUserId) - { - CustomerId = customerId; - ZaloUserId = zaloUserId; - } -} -``` - ---- - -## Enumerations / Liệt Kê - -```csharp -/// EN: Conversation status / VI: Trạng thái hội thoại -public enum ConversationStatus -{ - Active = 0, - Closed = 1 -} - -/// EN: Message type / VI: Loại tin nhắn -public enum MessageType -{ - Text = 0, - Image = 1, - Link = 2, - Sticker = 3, - Audio = 4, - Template = 5 -} - -/// EN: Message direction / VI: Hướng tin nhắn -public enum MessageDirection -{ - Incoming = 0, // From customer - Outgoing = 1 // To customer -} - -/// EN: Customer segment / VI: Phân khúc khách hàng -public enum CustomerSegment -{ - New = 0, - Regular = 1, - Active = 2, - VIP = 3 -} - -/// EN: Rule type / VI: Loại quy tắc -public enum RuleType -{ - Keyword = 0, - Regex = 1, - Intent = 2 -} - -/// EN: Action type / VI: Loại hành động -public enum ActionType -{ - SendText = 0, - SendTemplate = 1, - ForwardToHuman = 2 -} - -/// EN: Template status / VI: Trạng thái template -public enum TemplateStatus -{ - Pending = 0, - Approved = 1, - Rejected = 2 -} - -/// EN: Parameter type / VI: Loại tham số -public enum ParameterType -{ - String = 0, - Number = 1, - Date = 2 -} -``` - ---- - -**Document Version**: 1.0 -**Last Updated**: 2026-01-18 -**Author**: GoodGo Platform Team diff --git a/services/mkt-zalo-service-net/docs/INTEGRATION.md b/services/mkt-zalo-service-net/docs/INTEGRATION.md deleted file mode 100644 index b88a9241..00000000 --- a/services/mkt-zalo-service-net/docs/INTEGRATION.md +++ /dev/null @@ -1,579 +0,0 @@ -# Zalo Official Account Integration Guide - -**EN**: Comprehensive integration guide for Zalo Official Account API, webhooks, authentication, and best practices. - -**VI**: Hướng dẫn tích hợp toàn diện cho Zalo Official Account API, webhooks, xác thực và best practices. - ---- - -## Table of Contents / Mục Lục - -1. [Prerequisites](#prerequisites) -2. [Zalo OA Setup](#zalo-oa-setup) -3. [Authentication & Access Token](#authentication--access-token) -4. [Webhook Configuration](#webhook-configuration) -5. [API Endpoints](#api-endpoints) -6. [Event Types](#event-types) -7. [Rate Limits](#rate-limits) -8. [Error Handling](#error-handling) -9. [Best Practices](#best-practices) - ---- - -## Prerequisites / Yêu Cầu - -### 1. Zalo Official Account (OA) - -**EN**: You must have a verified Zalo Official Account for businesses. - -**VI**: Bạn phải có Zalo Official Account đã xác minh cho doanh nghiệp. - -**Steps:** -1. Register at: https://oa.zalo.me/ -2. Complete business verification (requires business license) -3. Wait for approval (1-3 business days) - -### 2. Zalo Application - -**EN**: Create a Zalo application to get App ID and Secret Key. - -**VI**: Tạo ứng dụng Zalo để lấy App ID và Secret Key. - -**Steps:** -1. Go to: https://developers.zalo.me/ -2. Create new application -3. Link application to your Official Account -4. Note your `App ID` and `Secret Key` - ---- - -## Zalo OA Setup / Thiết Lập Zalo OA - -### Link Application to OA - -1. **Login to Zalo Developers**: https://developers.zalo.me/ -2. **Select your application** -3. **Go to "Official Account" tab** -4. **Click "Link OA"** and select your Official Account -5. **Grant permissions**: Message, User Info, Notification - -### Required Permissions - -| Permission | Purpose | -|------------|---------| -| `User Info` | Get customer profile (name, avatar) | -| `Send Message` | Send messages to customers | -| `Receive Message` | Receive webhook events | -| `ZNS` | Send Zalo Notification Service templates | - ---- - -## Authentication & Access Token - -### Get OA Access Token - -**Method 1: Via Zalo Developers Portal** (Recommended for development) - -1. Go to: https://developers.zalo.me/tools/explorer -2. Select your application and OA -3. Click "Get Access Token" -4. Copy the token (valid for 1 year) - -**Method 2: Via OAuth API** (For production) - -```http -POST https://oauth.zaloapp.com/v4/oa/access_token -Content-Type: application/x-www-form-urlencoded - -app_id={app_id} -&secret_key={secret_key} -&code={authorization_code} -``` - -Response: -```json -{ - "access_token": "your_access_token", - "refresh_token": "your_refresh_token", - "expires_in": 31536000 // 1 year -} -``` - -### Refresh Access Token - -```http -POST https://oauth.zaloapp.com/v4/oa/access_token -Content-Type: application/x-www-form-urlencoded - -app_id={app_id} -&refresh_token={refresh_token} -&grant_type=refresh_token -``` - -### Store Securely - -```bash -# Environment variable -ZALO_ACCESS_TOKEN=your_access_token_here - -# Or Azure Key Vault / AWS Secrets Manager -``` - ---- - -## Webhook Configuration / Cấu Hình Webhook - -### 1. Set Webhook URL - -**In Zalo Developers Portal:** -1. Go to your application settings -2. Navigate to "Webhooks" tab -3. Set webhook URL: `https://yourdomain.com/api/v1/zalo/webhooks` -4. Set secret key for signature verification - -### 2. Enable Events - -**Required events to enable:** -- ✅ `user_send_text` - Customer sends text message -- ✅ `user_send_image` - Customer sends image -- ✅ `user_send_link` - Customer sends link -- ✅ `user_send_sticker` - Customer sends sticker -- ✅ `user_send_audio` - Customer sends audio -- ✅ `follow` - Customer follows OA -- ✅ `unfollow` - Customer unfollows OA -- ✅ `user_click_chatnow` - Customer clicks "Chat Now" button - -### 3. Webhook Signature Verification - -**EN**: Verify webhook signature to prevent spoofing attacks. - -**VI**: Xác thực chữ ký webhook để chống tấn công giả mạo. - -```csharp -public class ZaloWebhookVerifier -{ - private readonly string _secretKey; - - public bool VerifySignature(string body, string signature) - { - using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(_secretKey)); - var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(body)); - var computed = BitConverter.ToString(hash).Replace("-", "").ToLower(); - - return signature.Equals(computed, StringComparison.OrdinalIgnoreCase); - } -} -``` - -**Webhook Request Headers:** -``` -X-Zalo-Signature: -Content-Type: application/json -``` - -### 4. Webhook Response Requirements - -**CRITICAL**: Must return `200 OK` within **2 seconds**. - -```csharp -[HttpPost("webhooks")] -public async Task ReceiveWebhook([FromBody] ZaloWebhookEvent webhook) -{ - // 1. Verify signature (FAST) - if (!_verifier.VerifySignature(RequestBody, Request.Headers["X-Zalo-Signature"])) - return Unauthorized(); - - // 2. Queue for async processing (FAST) - await _messageQueue.PublishAsync(webhook); - - // 3. Return immediately (< 2s) - return Ok(new { success = true }); -} -``` - -**DO NOT** process webhook synchronously: -- ❌ Database queries -- ❌ External API calls -- ❌ LLM processing -- ✅ Signature verification only -- ✅ Queue message -- ✅ Return 200 - ---- - -## API Endpoints / Các API Endpoints - -### Base URL -``` -https://openapi.zalo.me -``` - -### 1. Send Text Message - -```http -POST /v3.0/oa/message/cs -Authorization: access_token {your_access_token} -Content-Type: application/json - -{ - "recipient": { - "user_id": "1234567890123456789" - }, - "message": { - "text": "Xin chào! Tôi có thể giúp gì cho bạn?" - } -} -``` - -**Response:** -```json -{ - "error": 0, - "message": "Success", - "data": { - "message_id": "zalo_msg_xyz123" - } -} -``` - -### 2. Send Image Message - -```http -POST /v3.0/oa/message/cs -Authorization: access_token {your_access_token} -Content-Type: application/json - -{ - "recipient": { - "user_id": "1234567890123456789" - }, - "message": { - "attachment": { - "type": "template", - "payload": { - "template_type": "media", - "elements": [ - { - "media_type": "image", - "url": "https://example.com/image.jpg" - } - ] - } - } - } -} -``` - -### 3. Get User Profile - -```http -GET /v3.0/oa/user/detail?data={"user_id":"1234567890123456789"} -Authorization: access_token {your_access_token} -``` - -**Response:** -```json -{ - "error": 0, - "message": "Success", - "data": { - "user_id": "1234567890123456789", - "display_name": "Nguyễn Văn A", - "avatar": "https://s.zalo.me/avatar.jpg", - "user_gender": 1, // 0=Female, 1=Male, 2=Unknown - "user_id_by_app": "app_scoped_user_id" - } -} -``` - -### 4. Send ZNS Template - -```http -POST /v3.0/oa/message/template -Authorization: access_token {your_access_token} -Content-Type: application/json - -{ - "phone": "+84901234567", - "template_id": "283746", - "template_data": { - "order_id": "ORD-12345", - "total_amount": "500000" - } -} -``` - ---- - -## Event Types / Các Loại Sự Kiện - -### 1. user_send_text - -```json -{ - "app_id": "1234567890", - "event_name": "user_send_text", - "timestamp": 1705586400000, - "sender": { - "id": "1234567890123456789" - }, - "recipient": { - "id": "9876543210" - }, - "message": { - "text": "Xin chào", - "msg_id": "msg_123456" - } -} -``` - -### 2. user_send_image - -```json -{ - "app_id": "1234567890", - "event_name": "user_send_image", - "timestamp": 1705586400000, - "sender": { - "id": "1234567890123456789" - }, - "message": { - "attachments": [ - { - "type": "image", - "payload": { - "url": "https://zalo-api.zadn.vn/api/emoticon/sticker/...", - "thumbnail": "https://zalo-api.zadn.vn/api/emoticon/thumb/..." - } - } - ], - "msg_id": "msg_123457" - } -} -``` - -### 3. follow - -```json -{ - "app_id": "1234567890", - "event_name": "follow", - "timestamp": 1705586400000, - "follower": { - "id": "1234567890123456789" - }, - "oa_id": "9876543210" -} -``` - -### 4. unfollow - -```json -{ - "app_id": "1234567890", - "event_name": "unfollow", - "timestamp": 1705586400000, - "follower": { - "id": "1234567890123456789" - } -} -``` - ---- - -## Rate Limits / Giới Hạn Tốc Độ - -### API Rate Limits - -| API | Limit | Window | -|-----|-------|--------| -| Send Message (CS) | 1000 requests | Per day per user | -| Send ZNS | 10000 requests | Per day | -| Get User Profile | 5000 requests | Per day | -| Webhook Receipt | Unlimited | - | - -### Handling Rate Limits - -```csharp -public class ZaloApiClient -{ - private readonly HttpClient _httpClient; - private readonly SemaphoreSlim _rateLimiter = new(100, 100); // 100 concurrent - - public async Task SendMessageAsync(...) - { - await _rateLimiter.WaitAsync(); - try - { - // API call - var response = await _httpClient.PostAsync(...); - - if (response.StatusCode == HttpStatusCode.TooManyRequests) - { - // Wait and retry - await Task.Delay(TimeSpan.FromMinutes(1)); - return await SendMessageAsync(...); - } - - return await response.Content.ReadFromJsonAsync(); - } - finally - { - _rateLimiter.Release(); - } - } -} -``` - ---- - -## Error Handling / Xử Lý Lỗi - -### Common Error Codes - -| Error Code | Message | Resolution | -|------------|---------|------------| -| `-201` | Invalid access token | Refresh token | -| `-213` | User has blocked OA | Mark customer as inactive | -| `-214` | User hasn't interacted in 7 days | Use ZNS instead of CS message | -| `-216` | Message too long (max 2000 chars) | Split message | -| `-300` | Rate limit exceeded | Wait and retry | - -### Error Response Format - -```json -{ - "error": -201, - "message": "Invalid access token", - "data": {} -} -``` - -### Retry Strategy - -```csharp -var retryPolicy = Policy - .Handle() - .Or() - .OrResult(r => (int)r.StatusCode >= 500) - .WaitAndRetryAsync(3, retryAttempt => - TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); - -var response = await retryPolicy.ExecuteAsync(async () => -{ - return await _httpClient.PostAsync(...); -}); -``` - ---- - -## Best Practices / Thực Hành Tốt - -### 1. Webhook Processing - -✅ **DO:** -- Verify signature on every webhook -- Return 200 within 2 seconds -- Process asynchronously via message queue -- Store raw webhook events for 7 days (debugging) - -❌ **DON'T:** -- Make database queries in webhook handler -- Call external APIs synchronously -- Process LLM in webhook handler - -### 2. Message Quality - -✅ **DO:** -- Keep messages under 2000 characters -- Use ZNS for important notifications (OTP, orders) -- Provide fallback for images (text description) -- Respect customer's OA block status - -❌ **DON'T:** -- Send too many messages (spam) -- Send promotional messages without consent -- Use CS messages for users inactive >7 days - -### 3. Access Token Management - -✅ **DO:** -- Store token securely (environment variable, secrets manager) -- Set up token refresh automation (before 1 year expiry) -- Log token refresh events - -❌ **DON'T:** -- Hardcode token in source code -- Share token publicly (Git, Slack) - -### 4. Conversation Context - -✅ **DO:** -- Cache last 10 messages in Redis (for AI context) -- Load customer profile once per conversation -- Track conversation state (active/closed) - -❌ **DON'T:** -- Query full conversation history for each message -- Lose context between messages - ---- - -## Testing / Kiểm Thử - -### 1. Sandbox Environment - -Zalo provides a test OA for development: -- Register test OA at https://oa.zalo.me/ -- Use separate access token for staging - -### 2. Manual Testing - -```bash -# Send test webhook to your local service -curl -X POST http://localhost:8080/api/v1/zalo/webhooks \ - -H "Content-Type: application/json" \ - -H "X-Zalo-Signature: " \ - -d '{ - "app_id": "test123", - "event_name": "user_send_text", - "timestamp": 1705586400000, - "sender": { "id": "test_user_123" }, - "message": { "text": "Xin chào", "msg_id": "msg_001" } - }' -``` - -### 3. Integration Tests - -```csharp -[Fact] -public async Task SendMessage_ValidUser_ReturnsSuccess() -{ - // Arrange - var client = new ZaloOfficialAccountClient(_httpClient, _config, _logger); - - // Act - var result = await client.SendTextMessageAsync( - "test_user_123", - "Hello from test", - CancellationToken.None); - - // Assert - Assert.NotNull(result.MessageId); -} -``` - ---- - -## Resources / Tài Nguyên - -- **Zalo Developers**: https://developers.zalo.me/ -- **Zalo OA Docs**: https://developers.zalo.me/docs/official-account -- **API Explorer**: https://developers.zalo.me/tools/explorer -- **Zalo OA Manager**: https://oa.zalo.me/ - ---- - -**Document Version**: 1.0 -**Last Updated**: 2026-01-18 -**Author**: GoodGo Platform Team diff --git a/services/mkt-zalo-service-net/docs/SOLUTION.md b/services/mkt-zalo-service-net/docs/SOLUTION.md deleted file mode 100644 index 31921462..00000000 --- a/services/mkt-zalo-service-net/docs/SOLUTION.md +++ /dev/null @@ -1,779 +0,0 @@ -# MKT Zalo Service Solution Architecture - -**EN**: Comprehensive solution architecture for the Marketing Zalo Service, detailing system design, domain model, integration patterns, and technical implementation. - -**VI**: Kiến trúc giải pháp toàn diện cho Dịch vụ Marketing Zalo, chi tiết thiết kế hệ thống, mô hình domain, patterns tích hợp và triển khai kỹ thuật. - ---- - -## Table of Contents / Mục Lục - -1. [Business Context / Ngữ Cảnh Nghiệp Vụ](#business-context) -2. [System Architecture / Kiến Trúc Hệ Thống](#system-architecture) -3. [Domain Model / Mô Hình Domain](#domain-model) -4. [CQRS Commands & Queries](#cqrs-commands--queries) -5. [Integration Patterns / Mẫu Tích Hợp](#integration-patterns) -6. [Data Flow / Luồng Dữ Liệu](#data-flow) -7. [Security & Authentication / Bảo Mật](#security--authentication) -8. [Performance & Scalability / Hiệu Năng](#performance--scalability) -9. [Monitoring & Observability / Giám Sát](#monitoring--observability) - ---- - -## Business Context / Ngữ Cảnh Nghiệp Vụ - -### Problem Statement / Vấn Đề - -**EN**: Businesses need to engage with customers on Zalo, Vietnam's leading messaging platform with 80M+ users. This requires: -- Automated responses for common inquiries (24/7 availability) -- AI-powered conversations for complex customer needs -- Centralized customer data and interaction history -- Scalable messaging infrastructure for campaigns - -**VI**: Doanh nghiệp cần tương tác khách hàng trên Zalo, nền tản g nhắn tin hàng đầu Việt Nam với 80M+ người dùng. Yêu cầu: -- Phản hồi tự động cho câu hỏi thường gặp (24/7) -- Hội thoại AI cho nhu cầu phức tạp -- Dữ liệu khách hàng và lịch sử tập trung -- Hạ tầng nhắn tin mở rộng cho chiến dịch - -### Business Goals / Mục Tiêu Nghiệp Vụ - -1. **Customer Engagement / Tương Tác KH**: 90% response rate within 1 minute -2. **Automation / Tự Động Hóa**: 70% of inquiries handled without human intervention -3. **Personalization / Cá Nhân Hóa**: Context-aware responses based on customer history -4. **Scalability / Mở Rộng**: Support 10,000+ concurrent conversations - ---- - -## System Architecture / Kiến Trúc Hệ Thống - -### High-Level Architecture / Kiến Trúc Tổng Quan - -```mermaid -graph TB - ZaloOA[Zalo Official Account] - - subgraph "mkt-zalo-service-net" - WH[Webhook Handler
WebhooksController] - MQ[Message Queue
RabbitMQ] - - subgraph "Processing Engines" - RE[Rule Engine
Automation] - AI[AI Engine
LLM Based] - end - - subgraph "Domain Layer" - Conv[Conversation
Aggregate] - Cust[ZaloCustomer
Aggregate] - Rule[ChatbotRule
Aggregate] - Tmpl[MessageTemplate
Aggregate] - end - - DB[(PostgreSQL
Main DB)] - Cache[(Redis
Cache)] - - ZaloAPI[Zalo OA API Client] - LLM[LLM Provider
OpenAI/Vertex AI] - end - - ZaloOA -->|Webhook Events| WH - WH -->|Queue Message| MQ - MQ -->|Process| RE - MQ -->|Process| AI - - RE -->|Load Rules| Rule - AI -->|Call LLM| LLM - - RE -->|Update| Conv - AI -->|Update| Conv - - Conv -->|Store| DB - Cust -->|Store| DB - Rule -->|Store| DB - Tmpl -->|Store| DB - - Conv -.->|Cache Context| Cache - - RE -->|Send Response| ZaloAPI - AI -->|Send Response| ZaloAPI - ZaloAPI -->|API Call| ZaloOA -``` - -### Clean Architecture Layers / Các Tầng Clean Architecture - -``` -┌────────────────────────────────────────────────────────────────┐ -│ API Layer │ -│ Controllers → MediatR → Commands/Queries │ -│ • WebhooksController (public, no auth) │ -│ • ConversationsController (authenticated) │ -│ • CustomersController (CRM management) │ -│ • ChatbotRulesController (automation config) │ -│ • Admin/* (analytics, broadcast) │ -└────────────────────────┬───────────────────────────────────────┘ - │ -┌────────────────────────▼───────────────────────────────────────┐ -│ Application Layer │ -│ Commands: ProcessWebhookCommand, SendMessageCommand │ -│ Queries: GetConversationHistoryQuery, GetCustomerQuery │ -│ Handlers: ProcessWebhookCommandHandler (routes to engines) │ -│ Behaviors: ValidationBehavior, LoggingBehavior │ -└────────────────────────┬───────────────────────────────────────┘ - │ -┌────────────────────────▼───────────────────────────────────────┐ -│ Domain Layer │ -│ Aggregates: │ -│ • Conversation (messages, status, context) │ -│ • ZaloCustomer (profile, tags, segment) │ -│ • ChatbotRule (conditions, actions) │ -│ • MessageTemplate (ZNS templates) │ -│ │ -│ Business Rules: │ -│ • Conversation.AddMessage() - validate message type │ -│ • ZaloCustomer.UpdateProfile() - enforce data quality │ -│ • ChatbotRule.Evaluate() - match conditions │ -└────────────────────────┬───────────────────────────────────────┘ - │ -┌────────────────────────▼───────────────────────────────────────┐ -│ Infrastructure Layer │ -│ • EF Core DbContext (persistence) │ -│ • Repositories (ConversationRepository, CustomerRepository) │ -│ • ZaloOfficialAccountClient (HTTP client with Polly) │ -│ • RuleBasedChatbotEngine (keyword matching, regex) │ -│ • AiChatbotEngine (LLM integration) │ -│ • Redis Caching (conversation context) │ -└────────────────────────────────────────────────────────────────┘ -``` - ---- - -## Domain Model / Mô Hình Domain - -### Aggregates Overview / Tổng Quan Aggregates - -```mermaid -classDiagram - class Conversation { - +Guid Id - +string ZaloUserId - +Guid CustomerId - +ConversationStatus Status - +DateTime StartedAt - +DateTime? EndedAt - +List~Message~ Messages - +AddMessage(Message) - +Close() - +Reopen() - } - - class Message { - +Guid Id - +MessageType Type - +string Content - +MessageDirection Direction - +DateTime SentAt - +bool IsFromBot - } - - class ZaloCustomer { - +Guid Id - +string ZaloUserId - +CustomerProfile Profile - +List~Tag~ Tags - +CustomerSegment Segment - +DateTime FirstInteractionAt - +DateTime LastInteractionAt - +UpdateProfile(CustomerProfile) - +AddTag(Tag) - +UpdateSegment() - } - - class CustomerProfile { - +string DisplayName - +string AvatarUrl - +string PhoneNumber - +string Email - } - - class ChatbotRule { - +Guid Id - +string Name - +RuleType Type - +List~RuleCondition~ Conditions - +RuleAction Action - +int Priority - +bool IsActive - +Evaluate(string) - } - - class MessageTemplate { - +Guid Id - +string TemplateId - +string Name - +string Content - +List~TemplateParameter~ Parameters - } - - Conversation "1" *-- "many" Message - ZaloCustomer "1" *-- "1" CustomerProfile - ZaloCustomer "1" *-- "many" Tag - ChatbotRule "1" *-- "many" RuleCondition - Conversation "many" --> "1" ZaloCustomer -``` - -### Aggregate Details / Chi Tiết Aggregates - -#### 1. Conversation Aggregate - -```csharp -/// -/// EN: Conversation aggregate root - tracks customer interactions. -/// VI: Aggregate root Conversation - theo dõi tương tác khách hàng. -/// -public class Conversation : Entity, IAggregateRoot -{ - private readonly List _messages = new(); - - public string ZaloUserId { get; private set; } - public Guid CustomerId { get; private set; } - public ConversationStatus Status { get; private set; } - public DateTime StartedAt { get; private set; } - public DateTime? EndedAt { get; private set; } - public IReadOnlyCollection Messages => _messages.AsReadOnly(); - - public void AddMessage(MessageType type, string content, MessageDirection direction, bool isFromBot) - { - if (Status == ConversationStatus.Closed) - throw new ZaloDomainException("Cannot add message to closed conversation"); - - var message = new Message(type, content, direction, isFromBot); - _messages.Add(message); - - AddDomainEvent(new MessageReceivedDomainEvent(Id, message.Id, content)); - } - - public void Close() - { - if (Status == ConversationStatus.Closed) - return; - - Status = ConversationStatus.Closed; - EndedAt = DateTime.UtcNow; - } -} -``` - -#### 2. ZaloCustomer Aggregate - -```csharp -/// -/// EN: Zalo customer aggregate - customer relationship management. -/// VI: Aggregate ZaloCustomer - quản lý quan hệ khách hàng. -/// -public class ZaloCustomer : Entity, IAggregateRoot -{ - private readonly List _tags = new(); - - public string ZaloUserId { get; private set; } // From Zalo OA - public CustomerProfile Profile { get; private set; } - public CustomerSegment Segment { get; private set; } - public DateTime FirstInteractionAt { get; private set; } - public DateTime LastInteractionAt { get; private set; } - public IReadOnlyCollection Tags => _tags.AsReadOnly(); - - public void UpdateProfile(string displayName, string avatarUrl, string? phoneNumber = null, string? email = null) - { - Profile = new CustomerProfile(displayName, avatarUrl, phoneNumber, email); - AddDomainEvent(new CustomerProfileUpdatedDomainEvent(Id, ZaloUserId)); - } - - public void AddTag(string tagName) - { - if (_tags.Any(t => t.Name == tagName)) - return; - - _tags.Add(new Tag(tagName)); - } - - public void UpdateSegment() - { - // EN: Auto-segment based on behavior - // VI: Tự động phân khúc dựa trên hành vi - var interactionCount = _tags.Count(t => t.Name.StartsWith("interaction")); - - Segment = interactionCount switch - { - > 50 => CustomerSegment.VIP, - > 20 => CustomerSegment.Active, - > 5 => CustomerSegment.Regular, - _ => CustomerSegment.New - }; - } -} -``` - -#### 3. ChatbotRule Aggregate - -```csharp -/// -/// EN: Chatbot rule aggregate - automation logic. -/// VI: Aggregate ChatbotRule - logic tự động hóa. -/// -public class ChatbotRule : Entity, IAggregateRoot -{ - private readonly List _conditions = new(); - - public string Name { get; private set; } - public RuleType Type { get; private set; } // Keyword, Regex, Intent - public IReadOnlyCollection Conditions => _conditions.AsReadOnly(); - public RuleAction Action { get; private set; } - public int Priority { get; private set; } // Higher = evaluated first - public bool IsActive { get; private set; } - - public bool Evaluate(string userMessage) - { - if (!IsActive) - return false; - - return Type switch - { - RuleType.Keyword => _conditions.Any(c => userMessage.Contains(c.Value, StringComparison.OrdinalIgnoreCase)), - RuleType.Regex => _conditions.Any(c => Regex.IsMatch(userMessage, c.Value)), - _ => false - }; - } -} -``` - ---- - -## CQRS Commands & Queries - -### Commands (Write Operations) - -```csharp -// EN: Process incoming webhook from Zalo -// VI: Xử lý webhook từ Zalo -public record ProcessWebhookCommand( - string EventName, - string ZaloUserId, - string MessageText, - string MessageType, - DateTime Timestamp) : IRequest; - -// EN: Send message to Zalo customer -// VI: Gửi tin nhắn đến khách hàng Zalo -public record SendMessageCommand( - Guid ConversationId, - string ZaloUserId, - string MessageText, - MessageType Type = MessageType.Text) : IRequest; - -// EN: Create chatbot automation rule -// VI: Tạo quy tắc tự động chatbot -public record CreateChatbotRuleCommand( - string Name, - RuleType Type, - List Conditions, - RuleActionDto Action, - int Priority) : IRequest; - -// EN: Update customer profile -// VI: Cập nhật hồ sơ khách hàng -public record UpdateCustomerProfileCommand( - Guid CustomerId, - string DisplayName, - string? PhoneNumber, - string? Email, - List? Tags) : IRequest; -``` - -### Queries (Read Operations) - -```csharp -// EN: Get conversation history -// VI: Lấy lịch sử hội thoại -public record GetConversationHistoryQuery( - Guid ConversationId, - int Skip = 0, - int Take = 50) : IRequest; - -// EN: Get customer details with interaction summary -// VI: Lấy chi tiết khách hàng với tóm tắt tương tác -public record GetCustomerQuery( - Guid CustomerId) : IRequest; - -// EN: Search conversations -// VI: Tìm kiếm hội thoại -public record SearchConversationsQuery( - string? ZaloUserId = null, - ConversationStatus? Status = null, - DateTime? FromDate = null, - DateTime? ToDate = null, - int Skip = 0, - int Take = 20) : IRequest>; - -// EN: Get chatbot automation rules -// VI: Lấy quy tắc tự động chatbot -public record GetActiveChatbotRulesQuery() : IRequest>; -``` - ---- - -## Integration Patterns / Mẫu Tích Hợp - -### 1. Zalo Official Account Integration - -```mermaid -sequenceDiagram - participant Zalo as Zalo OA - participant WH as WebhooksController - participant MQ as RabbitMQ - participant Engine as Processing Engine - participant DB as PostgreSQL - participant ZaloAPI as Zalo API Client - - Zalo->>WH: POST /webhooks
(user_send_text) - WH->>WH: Verify signature - WH->>MQ: Publish(WebhookEvent) - WH->>Zalo: 200 OK (< 2s) - - MQ->>Engine: Consume(WebhookEvent) - Engine->>DB: Load customer context - Engine->>Engine: Generate response - Engine->>DB: Save conversation - Engine->>ZaloAPI: SendMessage() - ZaloAPI->>Zalo: POST /message/text - Zalo->>ZaloAPI: 200 OK -``` - -#### Zalo OA API Client - -```csharp -/// -/// EN: HTTP client for Zalo Official Account API with resilience. -/// VI: HTTP client cho Zalo OA API với khả năng phục hồi. -/// -public class ZaloOfficialAccountClient : IZaloOfficialAccountClient -{ - private readonly HttpClient _httpClient; - private readonly ILogger _logger; - private readonly string _accessToken; - - public async Task SendTextMessageAsync( - string recipientZaloUserId, - string text, - CancellationToken ct = default) - { - var request = new - { - recipient = new { user_id = recipientZaloUserId }, - message = new { text } - }; - - var response = await _httpClient.PostAsJsonAsync( - "/v3.0/oa/message/cs", - request, - ct); - - response.EnsureSuccessStatusCode(); - return await response.Content.ReadFromJsonAsync(ct); - } - - public async Task GetUserProfileAsync( - string zaloUserId, - CancellationToken ct = default) - { - var response = await _httpClient.GetAsync( - $"/v3.0/oa/user/detail?data={{\"user_id\":\"{zaloUserId}\"}}", - ct); - - response.EnsureSuccessStatusCode(); - return await response.Content.ReadFromJsonAsync(ct); - } -} -``` - -### 2. Rule-Based Chatbot Engine - -```csharp -/// -/// EN: Rule-based automation engine for keyword/pattern matching. -/// VI: Engine tự động dựa trên quy tắc cho khớp từ khóa/mẫu. -/// -public class RuleBasedChatbotEngine : IChatbotEngine -{ - private readonly IChatbotRuleRepository _ruleRepository; - private readonly ILogger _logger; - - public async Task ProcessAsync( - string userMessage, - ConversationContext context, - CancellationToken ct = default) - { - // EN: Load active rules ordered by priority - // VI: Load rules active theo priority - var rules = await _ruleRepository.GetActiveRulesOrderedByPriorityAsync(ct); - - foreach (var rule in rules) - { - if (rule.Evaluate(userMessage)) - { - _logger.LogInformation( - "EN: Matched rule {RuleName} / VI: Khớp quy tắc {RuleName}", - rule.Name); - - return new ChatbotResponse( - ResponseText: rule.Action.ResponseText, - MatchedRuleId: rule.Id, - Confidence: 1.0); - } - } - - // EN: No rule matched, fallback to AI - // VI: Không khớp quy tắc, fallback sang AI - return ChatbotResponse.NoMatch; - } -} -``` - -### 3. AI Chatbot Engine (LLM Integration) - -```csharp -/// -/// EN: AI-powered chatbot using LLM (OpenAI/Vertex AI). -/// VI: Chatbot AI dùng LLM (OpenAI/Vertex AI). -/// -public class AiChatbotEngine : IChatbotEngine -{ - private readonly ILlmService _llmService; - private readonly IConversationRepository _conversationRepository; - private readonly IRedisCache _cache; - - public async Task ProcessAsync( - string userMessage, - ConversationContext context, - CancellationToken ct = default) - { - // EN: Load conversation history for context - // VI: Load lịch sử hội thoại để có context - var conversationHistory = await _cache.GetOrSetAsync( - $"conversation:{context.ConversationId}", - async () => await _conversationRepository.GetMessagesAsync(context.ConversationId, take: 10, ct), - TimeSpan.FromMinutes(30), - ct); - - // EN: Build LLM prompt with context - // VI: Xây dựng prompt LLM với context - var prompt = BuildPrompt(userMessage, conversationHistory, context.CustomerProfile); - - // EN: Call LLM provider - // VI: Gọi LLM provider - var llmResponse = await _llmService.GenerateResponseAsync(prompt, ct); - - return new ChatbotResponse( - ResponseText: llmResponse.Text, - Confidence: llmResponse.Confidence); - } - - private string BuildPrompt(string userMessage, IEnumerable history, CustomerProfile profile) - { - var historyText = string.Join("\n", history.Select(m => - $"{(m.IsFromBot ? "Assistant" : "User")}: {m.Content}")); - - return $@" -You are a helpful customer service assistant for GoodGo. -Customer name: {profile.DisplayName} -Conversation history: -{historyText} - -User: {userMessage} -Assistant:"; - } -} -``` - ---- - -## Data Flow / Luồng Dữ Liệu - -### Webhook Processing Flow / Luồng Xử Lý Webhook - -```mermaid -flowchart TD - A[Zalo sends webhook] --> B{Verify signature} - B -->|Invalid| C[Return 401] - B -->|Valid| D[Parse event] - D --> E{Event type?} - - E -->|user_send_text| F[ProcessWebhookCommand] - E -->|user_send_image| G[HandleImageMessage] - E -->|follow| H[CreateCustomer] - E -->|unfollow| I[MarkCustomerInactive] - - F --> J[Queue to RabbitMQ] - J --> K[Return 200 to Zalo] - - J --> L[Consumer processes] - L --> M{Load or create customer} - M --> N{Load or create conversation} - N --> O{Route to engine} - - O -->|Has matching rule| P[RuleBasedEngine] - O -->|No rule or AI enabled| Q[AiChatbotEngine] - - P --> R[Generate response] - Q --> S[Call LLM] - S --> R - - R --> T[Save to DB] - T --> U[Send via Zalo API] - U --> V[Update cache] -``` - ---- - -## Security & Authentication / Bảo Mật - -### 1. Webhook Signature Verification - -```csharp -/// -/// EN: Verify Zalo webhook signature to prevent spoofing. -/// VI: Xác thực chữ ký webhook Zalo để chống giả mạo. -/// -public class ZaloWebhookSignatureValidator -{ - private readonly string _webhookSecret; - - public bool ValidateSignature(string body, string signature) - { - var computedSignature = ComputeHmac256(body, _webhookSecret); - return signature.Equals(computedSignature, StringComparison.OrdinalIgnoreCase); - } - - private string ComputeHmac256(string message, string secret) - { - var encoding = new UTF8Encoding(); - var keyBytes = encoding.GetBytes(secret); - using var hmac = new HMACSHA256(keyBytes); - var hashBytes = hmac.ComputeHash(encoding.GetBytes(message)); - return BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); - } -} -``` - -### 2. API Authentication - -- **Public APIs** (Webhooks): Signature verification only -- **Customer APIs**: JWT Bearer tokens from IAM service -- **Admin APIs**: JWT + Admin role claim - ---- - -## Performance & Scalability / Hiệu Năng - -### Performance Targets / Mục Tiêu Hiệu Năng - -| Metric | Target | Strategy | -|--------|--------|----------| -| Webhook response time | < 2s | Queue immediately, return 200 | -| Message processing time | < 5s | Async processing via RabbitMQ | -| AI response generation | < 3s | LLM caching, prompt optimization | -| Database query time | < 100ms | Indexed queries, read replicas | -| Concurrent conversations | 10,000+ | Stateless processing, Redis cache | - -### Caching Strategy / Chiến Lược Caching - -```csharp -// EN: Cache conversation context in Redis -// VI: Cache context hội thoại trong Redis -Key: "conversation:{conversationId}" -TTL: 30 minutes -Data: Last 10 messages, customer profile, active rules - -// EN: Cache chatbot rules -// VI: Cache quy tắc chatbot -Key: "chatbot:rules:active" -TTL: 5 minutes -Data: All active rules ordered by priority -``` - ---- - -## Monitoring & Observability / Giám Sát - -### Key Metrics / Chỉ Số Quan Trọng - -``` -# Webhook metrics -zalo_webhook_events_total{event_type="user_send_text"} -zalo_webhook_processing_duration_seconds - -# Chatbot metrics -zalo_messages_processed_total{engine="rule_based|ai"} -zalo_chatbot_rule_matches_total{rule_id="..."} -zalo_ai_llm_latency_seconds - -# Business metrics -zalo_active_conversations_total -zalo_customer_satisfaction_score -zalo_automation_rate -``` - -### Logging Strategy / Chiến Lược Logging - -``` -INFO: User message received, rule matched -WARN: No rule matched, fallback to AI -ERROR: Failed to send Zalo message, retrying -``` - ---- - -## Deployment Considerations / Cân Nhắc Triển Khai - -### Environment Configuration - -```yaml -# Production -- Webhook URL: https://api.goodgo.vn/api/v1/zalo/webhooks -- Database: Neon PostgreSQL (multi-region) -- Redis: ElastiCache cluster -- LLM: Vertex AI (gcp-asia-southeast1) - -# Staging -- Webhook URL: https://staging-api.goodgo.vn/api/v1/zalo/webhooks -- Zalo OA: Test account -``` - -### Disaster Recovery / Khôi Phục Thảm Họa - -- **Database backups**: Daily snapshots, 30-day retention -- **Message queue**: Durable queues with replication -- **Webhook replay**: Store raw webhook events for 7 days - ---- - -## Future Enhancements / Cải Tiến Tương Lai - -1. **Multi-language support** - Vietnamese + English chatbot -2. **Voice message processing** - Speech-to-text integration -3. **Sentiment analysis** - Detect customer emotions -4. **A/B testing** - Test different chatbot responses -5. **Zalo Mini App integration** - Deep linking to mini apps - ---- - -## Related Documentation / Tài Liệu Liên Quan - -- [API Design](./API_DESIGN.md) - Complete API specification -- [Domain Models](./DOMAIN_MODELS.md) - Detailed domain entities -- [Integration Guide](./INTEGRATION.md) - Zalo OA API integration -- [Database Schema](./DATABASE_SCHEMA.md) - DB design and migrations - ---- - -**Document Version**: 1.0 -**Last Updated**: 2026-01-18 -**Author**: GoodGo Platform Team diff --git a/services/mkt-zalo-service-net/docs/en/ARCHITECTURE.md b/services/mkt-zalo-service-net/docs/en/ARCHITECTURE.md new file mode 100644 index 00000000..3f861b2d --- /dev/null +++ b/services/mkt-zalo-service-net/docs/en/ARCHITECTURE.md @@ -0,0 +1,437 @@ +# MKT Zalo Service - Solution Architecture + +## Table of Contents + +1. [Business Context](#business-context) +2. [System Architecture](#system-architecture) +3. [Domain Model](#domain-model) +4. [CQRS Commands & Queries](#cqrs-commands--queries) +5. [Integration Patterns](#integration-patterns) +6. [Data Flow](#data-flow) +7. [Security & Authentication](#security--authentication) +8. [Performance & Scalability](#performance--scalability) +9. [Monitoring & Observability](#monitoring--observability) + +--- + +## Business Context + +### Problem Statement + +Businesses need to engage with customers on Zalo, Vietnam's leading messaging platform with 80M+ users. This requires: +- Automated responses for common inquiries (24/7 availability) +- AI-powered conversations for complex customer needs +- Centralized customer data and interaction history +- Scalable messaging infrastructure for campaigns + +### Business Goals + +1. **Customer Engagement**: 90% response rate within 1 minute +2. **Automation**: 70% of inquiries handled without human intervention +3. **Personalization**: Context-aware responses based on customer history +4. **Scalability**: Support 10,000+ concurrent conversations + +--- + +## System Architecture + +### High-Level Architecture + +``` +┌─────────────────────────────────────────────────────────┐ +│ Zalo Official Account │ +│ (Customer sends messages via Zalo) │ +└────────────────────┬────────────────────────────────────┘ + │ Webhook Events + ▼ +┌─────────────────────────────────────────────────────────┐ +│ mkt-zalo-service-net │ +│ │ +│ ┌──────────────────────────────────────────────────┐ │ +│ │ Webhook Handler (API Layer) │ │ +│ │ • Verify signature │ │ +│ │ • Parse events (message, follow, buttons) │ │ +│ │ • Return 200 quickly │ │ +│ └───────────────┬──────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────────────────────────────────────────────┐ │ +│ │ Message Processing Engine │ │ +│ │ ┌────────────────┐ ┌────────────────┐ │ │ +│ │ │ Rule Engine │ │ AI Engine │ │ │ +│ │ │ (Automation) │ │ (LLM Based) │ │ │ +│ │ └────────────────┘ └────────────────┘ │ │ +│ └───────────────┬──────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────────────────────────────────────────────┐ │ +│ │ Domain Layer │ │ +│ │ • Conversation Aggregate │ │ +│ │ • ZaloCustomer Aggregate │ │ +│ │ • ChatbotRule Entity │ │ +│ │ • MessageTemplate Entity │ │ +│ └──────────────────────────────────────────────────┘ │ +│ │ +│ ┌──────────────────────────────────────────────────┐ │ +│ │ Integration Layer │ │ +│ │ • Zalo OA API Client (Send messages) │ │ +│ │ • LLM Provider (OpenAI, Vertex AI) │ │ +│ └──────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────┘ + │ + ▼ + ┌──────────────┐ + │ PostgreSQL │ + │ (Customer, │ + │ Conversation,│ + │ Templates) │ + └──────────────┘ +``` + +### Clean Architecture Layers + +``` +┌────────────────────────────────────────────────────────────┐ +│ API Layer │ +│ Controllers → MediatR → Commands/Queries │ +│ • WebhooksController (public, no auth) │ +│ • ConversationsController (authenticated) │ +│ • CustomersController (CRM management) │ +│ • ChatbotRulesController (automation config) │ +│ • Admin/* (analytics, broadcast) │ +└────────────────────────┬───────────────────────────────────┘ + │ +┌────────────────────────▼───────────────────────────────────┐ +│ Application Layer │ +│ Commands: ProcessWebhookCommand, SendMessageCommand │ +│ Queries: GetConversationHistoryQuery, GetCustomerQuery │ +│ Handlers: ProcessWebhookCommandHandler (routes to engines)│ +│ Behaviors: ValidationBehavior, LoggingBehavior │ +└────────────────────────┬───────────────────────────────────┘ + │ +┌────────────────────────▼───────────────────────────────────┐ +│ Domain Layer │ +│ Aggregates: │ +│ • Conversation (messages, status, context) │ +│ • ZaloCustomer (profile, tags, segment) │ +│ • ChatbotRule (conditions, actions) │ +│ • MessageTemplate (ZNS templates) │ +│ │ +│ Business Rules: │ +│ • Conversation.AddMessage() - validate message type │ +│ • ZaloCustomer.UpdateProfile() - enforce data quality │ +│ • ChatbotRule.Evaluate() - match conditions │ +└────────────────────────┬───────────────────────────────────┘ + │ +┌────────────────────────▼───────────────────────────────────┐ +│ Infrastructure Layer │ +│ • EF Core DbContext (persistence) │ +│ • Repositories (ConversationRepository, CustomerRepository)│ +│ • ZaloOfficialAccountClient (HTTP client with Polly) │ +│ • RuleBasedChatbotEngine (keyword matching, regex) │ +│ • AiChatbotEngine (LLM integration) │ +│ • Redis Caching (conversation context) │ +└────────────────────────────────────────────────────────────┘ +``` + +--- + +## Domain Model + +### Aggregates Overview + +**4 Aggregate Roots:** + +1. **Conversation** - Manages conversation lifecycle and messages +2. **ZaloCustomer** - Customer profiles, tags, and segmentation +3. **ChatbotRule** - Automation rules (keyword/regex/intent) +4. **MessageTemplate** - ZNS template management + +See [DOMAIN_MODELS.md](./DOMAIN_MODELS.md) for detailed implementation. + +--- + +## CQRS Commands & Queries + +### Commands (Write Operations) + +```csharp +// Process incoming webhook from Zalo +public record ProcessWebhookCommand( + string EventName, + string ZaloUserId, + string MessageText, + string MessageType, + DateTime Timestamp) : IRequest; + +// Send message to Zalo customer +public record SendMessageCommand( + Guid ConversationId, + string ZaloUserId, + string MessageText, + MessageType Type = MessageType.Text) : IRequest; + +// Create chatbot automation rule +public record CreateChatbotRuleCommand( + string Name, + RuleType Type, + List Conditions, + RuleActionDto Action, + int Priority) : IRequest; +``` + +### Queries (Read Operations) + +```csharp +// Get conversation history +public record GetConversationHistoryQuery( + Guid ConversationId, + int Skip = 0, + int Take = 50) : IRequest; + +// Get customer details with interaction summary +public record GetCustomerQuery( + Guid CustomerId) : IRequest; + +// Search conversations +public record SearchConversationsQuery( + string? ZaloUserId = null, + ConversationStatus? Status = null, + DateTime? FromDate = null, + DateTime? ToDate = null, + int Skip = 0, + int Take = 20) : IRequest>; +``` + +--- + +## Integration Patterns + +### 1. Zalo Official Account Integration + +**Webhook Processing Flow:** + +``` +Zalo → POST /webhooks → Verify signature → Parse event → Queue to RabbitMQ → Return 200 + ↓ + RabbitMQ Consumer → Load customer → Route to Engine → Generate response → Send via Zalo API +``` + +**Critical Requirements:** +- Must return 200 within 2 seconds +- Signature verification (HMAC SHA256) +- Async processing via message queue + +### 2. Rule-Based Chatbot Engine + +```csharp +public class RuleBasedChatbotEngine : IChatbotEngine +{ + public async Task ProcessAsync( + string userMessage, + ConversationContext context, + CancellationToken ct) + { + var rules = await _ruleRepository.GetActiveRulesOrderedByPriorityAsync(ct); + + foreach (var rule in rules) + { + if (rule.Evaluate(userMessage)) + { + return new ChatbotResponse( + ResponseText: rule.Action.ResponseText, + MatchedRuleId: rule.Id, + Confidence: 1.0); + } + } + + return ChatbotResponse.NoMatch; + } +} +``` + +### 3. AI Chatbot Engine (LLM) + +```csharp +public class AiChatbotEngine : IChatbotEngine +{ + public async Task ProcessAsync( + string userMessage, + ConversationContext context, + CancellationToken ct) + { + // Load conversation history for context + var conversationHistory = await _cache.GetOrSetAsync( + $"conversation:{context.ConversationId}", + async () => await _conversationRepository.GetMessagesAsync( + context.ConversationId, take: 10, ct), + TimeSpan.FromMinutes(30), + ct); + + // Build LLM prompt with context + var prompt = BuildPrompt(userMessage, conversationHistory, context.CustomerProfile); + + // Call LLM provider + var llmResponse = await _llmService.GenerateResponseAsync(prompt, ct); + + return new ChatbotResponse( + ResponseText: llmResponse.Text, + Confidence: llmResponse.Confidence); + } +} +``` + +--- + +## Data Flow + +### Webhook Processing Flow + +``` +1. Zalo sends webhook → WebhooksController +2. Verify signature (HMAC SHA256) +3. Parse event (user_send_text, follow, etc.) +4. Publish to RabbitMQ +5. Return 200 to Zalo (< 2s) + +6. Consumer processes event +7. Load or create ZaloCustomer +8. Load or create Conversation +9. Route to Rule Engine or AI Engine +10. Generate response +11. Save to database +12. Send via Zalo API +13. Update Redis cache +``` + +--- + +## Security & Authentication + +### 1. Webhook Signature Verification + +```csharp +public class ZaloWebhookSignatureValidator +{ + private readonly string _webhookSecret; + + public bool ValidateSignature(string body, string signature) + { + var computedSignature = ComputeHmac256(body, _webhookSecret); + return signature.Equals(computedSignature, StringComparison.OrdinalIgnoreCase); + } + + private string ComputeHmac256(string message, string secret) + { + var encoding = new UTF8Encoding(); + var keyBytes = encoding.GetBytes(secret); + using var hmac = new HMACSHA256(keyBytes); + var hashBytes = hmac.ComputeHash(encoding.GetBytes(message)); + return BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); + } +} +``` + +### 2. API Authentication + +- **Public APIs** (Webhooks): Signature verification only +- **Customer APIs**: JWT Bearer tokens from IAM service +- **Admin APIs**: JWT + Admin role claim + +--- + +## Performance & Scalability + +### Performance Targets + +| Metric | Target | Strategy | +|--------|--------|----------| +| Webhook response time | < 2s | Queue immediately, return 200 | +| Message processing time | < 5s | Async processing via RabbitMQ | +| AI response generation | < 3s | LLM caching, prompt optimization | +| Database query time | < 100ms | Indexed queries, read replicas | +| Concurrent conversations | 10,000+ | Stateless processing, Redis cache | + +### Caching Strategy + +```csharp +// Cache conversation context in Redis +Key: "conversation:{conversationId}" +TTL: 30 minutes +Data: Last 10 messages, customer profile, active rules + +// Cache chatbot rules +Key: "chatbot:rules:active" +TTL: 5 minutes +Data: All active rules ordered by priority +``` + +--- + +## Monitoring & Observability + +### Key Metrics + +``` +# Webhook metrics +zalo_webhook_events_total{event_type="user_send_text"} +zalo_webhook_processing_duration_seconds + +# Chatbot metrics +zalo_messages_processed_total{engine="rule_based|ai"} +zalo_chatbot_rule_matches_total{rule_id="..."} +zalo_ai_llm_latency_seconds + +# Business metrics +zalo_active_conversations_total +zalo_customer_satisfaction_score +zalo_automation_rate +``` + +### Logging Strategy + +``` +INFO: User message received, rule matched +WARN: No rule matched, fallback to AI +ERROR: Failed to send Zalo message, retrying +``` + +--- + +## Deployment Considerations + +### Environment Configuration + +```yaml +# Production +- Webhook URL: https://api.goodgo.vn/api/v1/zalo/webhooks +- Database: Neon PostgreSQL (multi-region) +- Redis: ElastiCache cluster +- LLM: Vertex AI (gcp-asia-southeast1) + +# Staging +- Webhook URL: https://staging-api.goodgo.vn/api/v1/zalo/webhooks +- Zalo OA: Test account +``` + +### Disaster Recovery + +- **Database backups**: Daily snapshots, 30-day retention +- **Message queue**: Durable queues with replication +- **Webhook replay**: Store raw webhook events for 7 days + +--- + +## Future Enhancements + +1. **Multi-language support** - Vietnamese + English chatbot +2. **Voice message processing** - Speech-to-text integration +3. **Sentiment analysis** - Detect customer emotions +4. **A/B testing** - Test different chatbot responses +5. **Zalo Mini App integration** - Deep linking to mini apps + +--- + +**Document Version**: 1.0 +**Last Updated**: 2026-01-18 +**Author**: GoodGo Platform Team