Flask chatbot that keeps per-user conversation state in SQLite, keyed by phone number instead of cookies.
The bot walks a caller through a short scripted conversation: greet, ask for a name, ask for a favorite song, confirm. What makes it work is the session model. Every request carries a user_phone, and the current conversation state lives as a JSON blob in a SQLite row keyed by that number. No cookies, no server-side session middleware, no in-memory state that a restart would lose. The same user can continue mid-conversation from any client, and the server can be restarted between messages without breaking the flow.
stateDiagram-v2
[*] --> start
start --> ask_name: user says "hello"
start --> start: anything else (rejected)
ask_name --> ask_song: any message, stored as name
ask_song --> done: any message, stored as favorite song
done --> done: "Thank you for using the chatbot!"
State transitions are handled in app.py; the initial input must be exactly "hello" (validate_input in libs/utils.py), after which the next two messages are stored as name and favorite_song in the session record.
app.py Flask server, single POST /chat endpoint and state machine
libs/session_manager.py Fetches a session or creates {"state": "start"} for new users
libs/db_handler.py SQLite table sessions(user_phone PRIMARY KEY, session_data JSON),
upsert via ON CONFLICT
libs/utils.py Input validation and greeting handling
docker/Dockerfile python:3.10.10 image with a curl-based HEALTHCHECK
requirements.txt flask 3.1.0, werkzeug 3.1.3
Local run:
git clone https://github.com/hsn07pk/ChatterKeep.git
cd ChatterKeep
pip install -r requirements.txt
python app.pyThe server listens on 0.0.0.0:5000 and creates sessions.db in the working directory on first start.
Docker:
docker build -f docker/Dockerfile -t chatterkeep .
docker run -p 5000:5000 chatterkeepcurl -X POST http://localhost:5000/chat \
-H "Content-Type: application/json" \
-d '{"user_phone": "+358401234567", "user_message": "hello"}'
# {"user_phone": "+358401234567", "bot_message": "What is your name?"}
curl -X POST http://localhost:5000/chat \
-H "Content-Type: application/json" \
-d '{"user_phone": "+358401234567", "user_message": "Hassan"}'
# {"user_phone": "+358401234567", "bot_message": "Hello Hassan, what is your favorite song?"}Requests missing user_phone or user_message return HTTP 400. A first message other than "hello" is rejected with a retry prompt and the session stays in start.
- The dialogue script is fixed; adding steps means adding states in
app.py. - SQLite connections are opened per operation, which is fine at this scale but not pooled.
- The database filename (
sessions.db) is hard-coded.