State Selection Text Chatbot Service - Complete Developer Documentation¶
Service: Text Chatbot Setup State Machine
Port: 8007
Purpose: Manage 3-step setup flow for text chatbots (simplified variant)
Technology: FastAPI (Python 3.9+)
Code Location:/state-selection-textchatbot-service/src/main.py(138 lines, 3 endpoints)
Owner: Backend Team
Last Updated: 2025-12-26
Table of Contents¶
- Service Overview
- State Machine Flow
- Complete Endpoints
- Comparison with 3D Chatbot Service
- Deployment
Service Overview¶
The State Selection Text Chatbot Service is a simplified version of the 3D chatbot setup flow. Text chatbots require fewer configuration steps (no avatar, no voice selection), resulting in a 3-step state machine instead of 6.
Key Responsibilities¶
✅ State Machine - Track progress through 3 setup steps
✅ Validation - Verify chatbot type and purpose
✅ Database Selection - Track CosmosDB vs Milvus choice
✅ Simple Configuration - No avatar, voice, or greeting setup
Statistics¶
- Total Lines: 138 (SMALLEST state service!)
- Endpoints: 3
- State Steps: 3 (start → chatbot_type_selected → sitemap_urls_fetched → END)
- No Email Integration (no quota management needed here)
- No Azure Dependencies
State Machine Flow¶
3-Step Setup Process¶
graph TD
START["start<br/>(No chatbot found)"]
STEP1["chatbot_type_selected<br/>(text-chatbot chosen)"]
STEP2["sitemap_urls_fetched<br/>(Data collection done)"]
END["END<br/>(Setup complete)"]
START -->|"POST /v2/select-chatbot<br/>chatbot_type=text-chatbot"| STEP1
STEP1 -->|"POST /v2/save-datacollection-status<br/>(Crawl URLs)"| STEP2
STEP2 -->|"POST /v2/save-text-chatbot-selection<br/>(Purpose + Save)"| END
style START fill:#ffebee
style STEP1 fill:#fff3e0
style STEP2 fill:#e3f2fd
style END fill:#c8e6c9
Comparison to 3D Chatbot (6 steps):
| Step | 3D Chatbot | Text Chatbot |
|---|---|---|
| 1 | Select type | Select type |
| 2 | Crawl data | Crawl data |
| 3 | Select purpose | Select purpose + DONE ✓ |
| 4 | Select avatar | ❌ Not needed |
| 5 | Select voice | ❌ Not needed |
| 6 | Final save | ❌ Combined with step 3 |
3 steps vs 6 steps = 50% faster setup!
State Check Logic¶
Endpoint: GET /v2/check-text-selection-state
Code Location: Lines 96-120
Complete Logic:
@app.get("/v2/check-text-selection-state")
def check_selection_state_text(user_id: str, project_id: str):
logger.info(f"Checking selection state for user_id={user_id}, project_id={project_id}")
selection = selection_collection.find_one({"user_id": user_id, "project_id": project_id})
# State 1: No selection or not text chatbot
if not selection or selection.get("chatbot_type") != "text-chatbot":
return {"state": "start", "message": "No chatbot collection found."}
# State 2: Type selected, waiting for data collection
elif "chatbot_type" in selection and "sitemap_urls" not in selection:
return {"state": "chatbot_type_selected"}
# State 3: Data collected, waiting for purpose (FINAL STEP)
elif "chatbot_type" in selection and "sitemap_urls" in selection and "chatbot_purpose" not in selection:
return {"state": "sitemap_urls_fetched"}
# State 4: All complete!
elif "chatbot_type" in selection and "sitemap_urls" in selection and "chatbot_purpose" in selection:
return {"state": "END"} # Setup complete!
else:
return {"state": "start"}
State Responses:
| State | Meaning | Next Step |
|---|---|---|
start |
No chatbot or not text | Select chatbot type |
chatbot_type_selected |
Type=text chosen | Crawl data |
sitemap_urls_fetched |
Data collected | Select purpose & save |
END |
Complete! | Launch chatbot |
Complete Endpoints¶
1. POST /v2/save-text-chatbot-selection¶
Purpose: FINAL STEP - Save text chatbot configuration
Code Location: Lines 53-93
Request:
POST /v2/save-text-chatbot-selection
Content-Type: multipart/form-data
user_id=User-123456
project_id=User-123456_Project_1
chatbot_type=text-chatbot
chatbot_purpose=Service-Agent
Supported Purposes:
Sales-AgentService-AgentCustom-AgentInformational-AgentRemote-Physio
Validation:
if chatbot_type not in ["text-chatbot", "voice-chatbot", "3D-chatbot"]:
return {"error": "Invalid chatbot type selected"}
if chatbot_purpose not in ["Sales-Agent", "Service-Agent", "Custom-Agent",
"Informational-Agent", "Remote-Physio"]:
return {"error": "Invalid purpose type selected"}
Database Selection Check:
# Get database_type from selection_history
db_selection = selection_collection.find_one(
{"user_id": user_id, "project_id": project_id},
{"database_type": 1}
)
database_type = db_selection.get("database_type",
os.getenv("DEFAULT_DATABASE", "cosmosdb")) \
if db_selection else os.getenv("DEFAULT_DATABASE", "cosmosdb")
Insert Document:
selection_data = {
"user_id": user_id,
"project_id": project_id,
"chatbot_type": chatbot_type, # "text-chatbot"
"chatbot_purpose": chatbot_purpose, # "Service-Agent"
"chatbot_registered_at": datetime.utcnow(),
"database_type": database_type # "cosmosdb" or "milvus"
}
result = chatbot_collection.insert_one(selection_data)
Response:
chatbot_selections Document:
{
"_id": ObjectId("507f1f77bcf86cd799439011"),
"user_id": "User-123456",
"project_id": "User-123456_Project_1",
"chatbot_type": "text-chatbot",
"chatbot_purpose": "Service-Agent",
"chatbot_registered_at": ISODate("2025-01-15T14:00:00Z"),
"database_type": "milvus"
}
Notice: Much simpler than 3D chatbot! No:
- ❌ avatar
- ❌ avatar_type
- ❌ hidden_name
- ❌ voice
- ❌ model
- ❌ system_prompt
- ❌ title_name
2. GET /v2/check-text-selection-state¶
Purpose: Check current step in setup flow
Code Location: Lines 96-120
Request:
Response (Step 2):
Response (Complete):
3. GET /v2/get-chatbot-selection¶
Purpose: Retrieve saved chatbot configuration
Code Location: Lines 123-133
Request:
Response:
{
"_id": "507f1f77bcf86cd799439011",
"user_id": "User-123456",
"project_id": "User-123456_Project_1",
"chatbot_type": "text-chatbot",
"chatbot_purpose": "Service-Agent",
"chatbot_registered_at": "2025-01-15T14:00:00.000Z",
"database_type": "milvus"
}
Error (Not Found):
HTTP Status: 400
Comparison with 3D Chatbot Service¶
Code Complexity¶
| Metric | Text Chatbot (8007) | 3D Chatbot (8006) | Difference |
|---|---|---|---|
| Lines of Code | 138 | 1009 | 7.3× smaller |
| Endpoints | 3 | 20+ | 6.7× fewer |
| State Steps | 3 | 6 | 50% fewer |
| Collections Used | 2 | 10+ | 5× fewer |
| Dependencies | Basic | Azure Email, httpx | No external APIs |
Feature Comparison¶
| Feature | Text Chatbot | 3D Chatbot |
|---|---|---|
| Avatar Selection | ❌ No | ✅ Yes (7 options) |
| Voice Selection | ❌ No | ✅ Yes (10 voices) |
| Hidden Name | ❌ No | ✅ Yes |
| System Prompt | ❌ Not stored here | ✅ Yes (fetched & stored) |
| Quota Management | ❌ No | ✅ Yes (with emails) |
| Greeting Generation | ❌ No | ✅ Yes (TTS + lip-sync) |
| LLM Configuration | ❌ Basic | ✅ Advanced (multiple LLMs) |
| Database Selection | ✅ Yes | ✅ Yes |
Endpoint Mapping¶
| Text Chatbot (8007) | 3D Chatbot (8006) | Notes |
|---|---|---|
POST /v2/save-text-chatbot-selection |
POST /v2/save-chatbot-selection |
Text: simpler (4 fields), 3D: complex (12+ fields) |
GET /v2/check-text-selection-state |
GET /v2/check-selection-state |
Text: 3 states, 3D: 6 states |
GET /v2/get-chatbot-selection |
GET /v2/get-chatbot-selection |
Same endpoint name, different collections |
When to Use Each Service¶
Use Text Chatbot Service (8007) when:
- ✅ Simple FAQ bot needed
- ✅ Want fastest setup time
- ✅ No visual/audio requirements
- ✅ Budget-conscious (no TTS costs)
Use 3D Chatbot Service (8006) when:
- ✅ Brand identity important (custom avatar)
- ✅ Engaging user experience needed
- ✅ Voice interaction desired
- ✅ Premium product positioning
Deployment¶
Docker Configuration¶
Dockerfile:
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY src/ .
EXPOSE 8007
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8007"]
Requirements.txt¶
fastapi>=0.95.0
uvicorn[standard]>=0.22.0
pymongo>=4.3.3
python-multipart>=0.0.6
python-dotenv>=1.0.0
httpx>=0.25.0 # For inter-service calls
Notice: Much simpler than 3D! No:
- ❌ azure-communication-email
- ❌ pytz
- ❌ pydantic
Docker Compose¶
state-selection-textchatbot-service:
build: ./state-selection-textchatbot-service
container_name: state-selection-textchatbot-service
ports:
- "8007:8007"
networks:
- app-network
labels:
- "logging=loki"
- "app=machine-agent-app"
environment:
- MONGO_URI=${MONGO_URI}
- MONGO_DB_NAME=Machine_agent_demo
- DEFAULT_DATABASE=${DEFAULT_DATABASE:-cosmosdb}
- DD_SERVICE=state-selection-textchatbot-service
- DD_ENV=production
restart: always
Environment Variables¶
# Database
MONGO_URI=mongodb://...
MONGO_DB_NAME=Machine_agent_demo
# Database default (CosmosDB or Milvus)
DEFAULT_DATABASE=cosmosdb
# DataDog
DD_SERVICE=state-selection-textchatbot-service
DD_ENV=production
Performance Metrics¶
| Operation | Latency | Notes |
|---|---|---|
| Check state | 10-20ms | Simple query |
| Save text chatbot | 30-50ms | Single insert |
| Get chatbot selection | 10-20ms | Simple query |
Much faster than 3D chatbot (no email sending, no TTS, no greeting generation)
Security Analysis¶
Good Practices¶
✅ No Hardcoded Credentials - Unlike 3D service
✅ Simple Validation - Type and purpose checked
✅ No External API Calls - Reduced attack surface
Missing Features¶
⚠️ No Quota Enforcement - Users can create unlimited text chatbots (quota should be checked here!)
⚠️ No Rate Limiting - Should limit chatbot creation rate
⚠️ CORS Allow All - Same issue as other services
Usage Example¶
Complete Text Chatbot Setup Flow¶
Step 1: Select Type
response = requests.post(
"http://localhost:8004/v2/select-chatbot",
data={
"user_id": "User-123456",
"project_id": "User-123456_Project_1",
"chatbot_type": "text-chatbot"
}
)
# State: "chatbot_type_selected"
Step 2: Crawl Data
response = requests.post(
"http://localhost:8005/extract-contents",
data={
"user_id": "User-123456",
"project_id": "User-123456_Project_1",
"domain": "https://example.com",
"urls": "https://example.com/page1,https://example.com/page2"
}
)
# Mark as complete
requests.post(
"http://localhost:8006/v2/save-datacollection-status",
data={
"user_id": "User-123456",
"project_id": "User-123456_Project_1"
}
)
# State: "sitemap_urls_fetched"
Step 3: Save Final Configuration
response = requests.post(
"http://localhost:8007/v2/save-text-chatbot-selection",
data={
"user_id": "User-123456",
"project_id": "User-123456_Project_1",
"chatbot_type": "text-chatbot",
"chatbot_purpose": "Service-Agent"
}
)
# State: "END"
# Response: {"message": "Chatbot selection saved successfully", "selection_id": "..."}
Total Time: ~30 seconds (vs 3-5 minutes for 3D chatbot)
Related Documentation¶
- State Selection 3D Chatbot Service - Full-featured variant
- Selection Chatbot Service - Individual selection endpoints
- Create Chatbot Service - Project creation
- Data Crawling Service - Content extraction
Recommendations¶
Improvements¶
- Add Quota Enforcement - Check chatbot limits before creation
- Add Rate Limiting - Prevent spam
- Add System Prompt Storage - Even text chatbots need prompts
- Add Email Notifications - Quota warnings for text chatbots too
Code Quality¶
- Add Type Hints - Improve readability
- Add Unit Tests - Test state machine logic
- Standardized Logging - Use the logger module like other services
Last Updated: 2025-12-26
Code Version: state-selection-textchatbot-service/src/main.py (138 lines)
Total Endpoints: 3
Review Cycle: Quarterly
"Simple, fast, effective."