Skip to content

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

  1. Service Overview
  2. State Machine Flow
  3. Complete Endpoints
  4. Comparison with 3D Chatbot Service
  5. 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-Agent
  • Service-Agent
  • Custom-Agent
  • Informational-Agent
  • Remote-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:

{
  "message": "Chatbot selection saved successfully",
  "selection_id": "507f1f77bcf86cd799439011"
}

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:

GET /v2/check-text-selection-state?user_id=User-123456&project_id=User-123456_Project_1

Response (Step 2):

{
  "state": "sitemap_urls_fetched"
}

Response (Complete):

{
  "state": "END"
}

3. GET /v2/get-chatbot-selection

Purpose: Retrieve saved chatbot configuration

Code Location: Lines 123-133

Request:

GET /v2/get-chatbot-selection?user_id=User-123456&project_id=User-123456_Project_1

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):

{
  "detail": "No chatbot selection found for this user_id and project_id"
}

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)



Recommendations

Improvements

  1. Add Quota Enforcement - Check chatbot limits before creation
  2. Add Rate Limiting - Prevent spam
  3. Add System Prompt Storage - Even text chatbots need prompts
  4. Add Email Notifications - Quota warnings for text chatbots too

Code Quality

  1. Add Type Hints - Improve readability
  2. Add Unit Tests - Test state machine logic
  3. 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."