|
|
import logging |
|
|
import os |
|
|
import sqlite3 |
|
|
import threading |
|
|
import urllib.parse |
|
|
from http.server import BaseHTTPRequestHandler, HTTPServer |
|
|
|
|
|
import plivo |
|
|
import streamlit as st |
|
|
from streamlit_autorefresh import st_autorefresh |
|
|
from dotenv import load_dotenv |
|
|
|
|
|
|
|
|
logging.basicConfig(level=logging.INFO) |
|
|
|
|
|
|
|
|
load_dotenv() |
|
|
|
|
|
|
|
|
try: |
|
|
PLIVO_AUTH_ID = os.getenv("PLIVO_AUTH_ID") |
|
|
PLIVO_AUTH_TOKEN = os.getenv("PLIVO_AUTH_TOKEN") |
|
|
KORA_PHONE_NUMBER = os.getenv("KORA_PHONE_NUMBER") |
|
|
client = plivo.RestClient(auth_id=PLIVO_AUTH_ID, auth_token=PLIVO_AUTH_TOKEN) |
|
|
except Exception as e: |
|
|
st.error(f"Error setting up Plivo: {e}") |
|
|
|
|
|
|
|
|
db_lock = threading.Lock() |
|
|
|
|
|
|
|
|
try: |
|
|
conn = sqlite3.connect("chat.db", check_same_thread=False) |
|
|
c = conn.cursor() |
|
|
with db_lock: |
|
|
c.execute( |
|
|
""" |
|
|
CREATE TABLE IF NOT EXISTS messages ( |
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT, |
|
|
sender TEXT, |
|
|
text TEXT, |
|
|
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP |
|
|
) |
|
|
""" |
|
|
) |
|
|
conn.commit() |
|
|
except sqlite3.Error as e: |
|
|
st.error(f"Error setting up SQLite: {e}") |
|
|
|
|
|
|
|
|
class SMSWebhookHandler(BaseHTTPRequestHandler): |
|
|
def do_POST(self): |
|
|
try: |
|
|
length = int(self.headers["Content-Length"]) |
|
|
post_data = self.rfile.read(length) |
|
|
data = urllib.parse.parse_qs(post_data.decode("utf-8")) |
|
|
|
|
|
logging.info(f"Webhook received: {data}") |
|
|
message_text = data.get("Text", [""])[0] |
|
|
|
|
|
if message_text: |
|
|
with db_lock: |
|
|
c.execute( |
|
|
"INSERT INTO messages (sender, text) VALUES (?, ?)", |
|
|
(KORA_PHONE_NUMBER, message_text), |
|
|
) |
|
|
conn.commit() |
|
|
|
|
|
self.send_response(200) |
|
|
self.end_headers() |
|
|
self.wfile.write( |
|
|
b"<?xml version='1.0'?><Response><Message>Got it!</Message></Response>" |
|
|
) |
|
|
|
|
|
except Exception as e: |
|
|
logging.error(f"Webhook error: {e}") |
|
|
self.send_response(500) |
|
|
self.end_headers() |
|
|
self.wfile.write(b"Error processing request") |
|
|
|
|
|
|
|
|
def run_webhook_server(): |
|
|
try: |
|
|
server = HTTPServer(("", 8502), SMSWebhookHandler) |
|
|
logging.info("Webhook server started on port 8502") |
|
|
server.serve_forever() |
|
|
except Exception as e: |
|
|
logging.error(f"Error starting webhook server: {e}") |
|
|
|
|
|
|
|
|
if not hasattr(st.session_state, "webhook_server_started"): |
|
|
threading.Thread(target=run_webhook_server, daemon=True).start() |
|
|
st.session_state.webhook_server_started = True |
|
|
|
|
|
|
|
|
st.title("📲 Chat with KORA") |
|
|
|
|
|
|
|
|
if "show_confirmation" not in st.session_state: |
|
|
st.session_state.show_confirmation = False |
|
|
if "last_message_count" not in st.session_state: |
|
|
st.session_state.last_message_count = 0 |
|
|
|
|
|
|
|
|
PLIVO_PHONE_NUMBER = st.text_input( |
|
|
"Enter your phone number to chat with KORA", value="+13602304837", max_chars=15 |
|
|
) |
|
|
|
|
|
|
|
|
if not st.session_state.show_confirmation: |
|
|
if st.button("Clear Chat"): |
|
|
st.session_state.show_confirmation = True |
|
|
st.rerun() |
|
|
else: |
|
|
col1, col2 = st.columns(2) |
|
|
if col1.button("Yes, clear chat"): |
|
|
try: |
|
|
with db_lock: |
|
|
c.execute("DELETE FROM messages") |
|
|
conn.commit() |
|
|
st.success("Chat history cleared.") |
|
|
st.session_state.show_confirmation = False |
|
|
st.session_state.last_message_count = 0 |
|
|
st.rerun() |
|
|
except sqlite3.Error as e: |
|
|
st.error(f"Error clearing chat history: {e}") |
|
|
elif col2.button("Cancel"): |
|
|
st.session_state.show_confirmation = False |
|
|
st.rerun() |
|
|
|
|
|
|
|
|
try: |
|
|
with db_lock: |
|
|
messages = c.execute( |
|
|
"SELECT sender, text FROM messages WHERE sender IN (?, ?) ORDER BY timestamp ASC", |
|
|
(PLIVO_PHONE_NUMBER, KORA_PHONE_NUMBER), |
|
|
).fetchall() |
|
|
except sqlite3.Error as e: |
|
|
messages = [] |
|
|
st.error(f"Error fetching messages: {e}") |
|
|
|
|
|
|
|
|
for sender, text in messages: |
|
|
role = "user" if sender == PLIVO_PHONE_NUMBER else "assistant" |
|
|
st.chat_message(role).write(text) |
|
|
|
|
|
st.session_state.last_message_count = len(messages) |
|
|
|
|
|
|
|
|
if prompt := st.chat_input("Type your message..."): |
|
|
try: |
|
|
|
|
|
with db_lock: |
|
|
c.execute( |
|
|
"INSERT INTO messages (sender, text) VALUES (?, ?)", |
|
|
(PLIVO_PHONE_NUMBER, prompt), |
|
|
) |
|
|
conn.commit() |
|
|
|
|
|
|
|
|
client.messages.create( |
|
|
text=prompt, src=PLIVO_PHONE_NUMBER, dst=KORA_PHONE_NUMBER |
|
|
) |
|
|
|
|
|
st.rerun() |
|
|
except sqlite3.Error as e: |
|
|
st.error(f"Error saving message: {e}") |
|
|
except Exception as e: |
|
|
st.error(f"Error sending message via Plivo: {e}") |
|
|
|
|
|
st_autorefresh(interval=1000, key="auto_refresh") |