File size: 4,777 Bytes
ff477b8
82c04df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ff477b8
82c04df
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import streamlit as st
import json
import os
import subprocess
import time
import pandas as pd
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

st.set_page_config(layout="wide")

# Paths
SALES_SCRIPT_FILE = 'sales_script.txt'
NUMBERS_FILE = 'numbers.txt'
LOG_DIR = 'call_logs'
APP_DATA_DIR = 'application_data'
WEBHOOK_SERVER_FILE = 'webhook_server.py'

# --- Helper Functions ---
def load_sales_script():
    if os.path.exists(SALES_SCRIPT_FILE):
        with open(SALES_SCRIPT_FILE, 'r') as f:
            return f.read()
    return ""

def save_sales_script(script):
    with open(SALES_SCRIPT_FILE, 'w') as f:
        f.write(script)

def load_numbers():
    if os.path.exists(NUMBERS_FILE):
        with open(NUMBERS_FILE, 'r') as f:
            return [line.strip() for line in f.readlines()]
    return []

def save_numbers(numbers):
    with open(NUMBERS_FILE, 'w') as f:
        f.write('\n'.join(numbers))

@st.cache_data
def get_application_data():
    data = []
    if os.path.exists(APP_DATA_DIR):
        for filename in os.listdir(APP_DATA_DIR):
            if filename.endswith(".json"):
                with open(os.path.join(APP_DATA_DIR, filename), 'r') as f:
                    call_data = json.load(f)
                    call_data['call_sid'] = filename.replace('.json', '')
                    data.append(call_data)
    return pd.DataFrame(data)

# --- UI ---
st.title("AI Sales Calling Agent")

# --- Sales Script ---
with st.expander("Sales Script"):
    sales_script = st.text_area("Edit Sales Script", value=load_sales_script(), height=200)
    if st.button("Save Script"):
        save_sales_script(sales_script)
        st.success("Sales script saved!")

# --- Numbers ---
with st.expander("Manage Numbers"):
    numbers = st.text_area("Enter numbers to call (one per line)", value='\n'.join(load_numbers()), height=150)
    if st.button("Save Numbers"):
        save_numbers(numbers.split('\n'))
        st.success("Numbers saved!")

def get_huggingface_url():
    hf_space_id = os.environ.get("HF_SPACE_ID")
    if hf_space_id:
        return f"https://{hf_space_id.replace('/', '-')}.hf.space"
    return None

# --- Call Control ---
with st.expander("Call Control"):
    st.info("When running on Hugging Face Spaces, the webhook server will start automatically.")

    if os.environ.get("HF_SPACE_ID") and not hasattr(st, 'webhook_process'):
        try:
            st.webhook_process = subprocess.Popen(["python", WEBHOOK_SERVER_FILE])
            st.success("Webhook server started automatically on Hugging Face Space.")
        except Exception as e:
            st.error(f"Error starting webhook server: {e}")

    webhook_url = get_huggingface_url()
    if webhook_url:
        st.success(f"Webhook URL detected: {webhook_url}")
    else:
        st.warning("Could not determine Hugging Face URL. Please run this in a Hugging Face Space.")

    number_to_call = st.selectbox("Select number to call", load_numbers())
    if st.button("Initiate Call"):
        if webhook_url:
            try:
                from twilio.rest import Client
                client = Client(os.environ.get('TWILIO_ACCOUNT_SID'), os.environ.get('TWILIO_AUTH_TOKEN'))
                call = client.calls.create(
                    to=number_to_call,
                    from_=os.environ.get('TWILIO_PHONE_NUMBER'),
                    url=f"{webhook_url}",
                    status_callback=f"{webhook_url}/status",
                    status_callback_method="POST",
                    status_callback_event=['completed']
                )
                st.success(f"Call initiated to {number_to_call} (SID: {call.sid})")
            except Exception as e:
                st.error(f"Error initiating call: {e}")
        else:
            st.error("Webhook URL is not set. Cannot initiate call.")

# --- Real-time Logs & Data ---
st.header("Live Call Status")
log_placeholder = st.empty()

class LogHandler(FileSystemEventHandler):
    def on_modified(self, event):
        if not event.is_directory and event.src_path.endswith(".log"):
            with open(event.src_path, "r") as f:
                log_placeholder.text_area("Logs", f.read(), height=300)

if not os.path.exists(LOG_DIR):
    os.makedirs(LOG_DIR)

observer = Observer()
observer.schedule(LogHandler(), LOG_DIR, recursive=True)
observer.start()

# --- Application Data ---
st.header("Extracted Application Data")
df = get_application_data()
if not df.empty:
    st.dataframe(df)
    csv = df.to_csv(index=False).encode('utf-8')
    st.download_button(
        label="Download Application Data as CSV",
        data=csv,
        file_name='application_data.csv',
        mime='text/csv',
    )
else:
    st.info("No application data found.")