Josedcape commited on
Commit
afa7095
verified
1 Parent(s): 671b35e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +197 -129
app.py CHANGED
@@ -1,129 +1,197 @@
1
- import os
2
- import time
3
- import schedule
4
- import streamlit as st
5
- from google.cloud import texttospeech
6
- import openai
7
- from dotenv import load_dotenv
8
- import threading
9
- from datetime import datetime, timedelta
10
- from streamlit_autorefresh import st_autorefresh
11
- import tempfile
12
- import base64
13
- import PyPDF2
14
-
15
- # Cargar las variables de entorno desde el archivo .env
16
- load_dotenv()
17
-
18
- # Configura la clave de API de Google Cloud
19
- os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "credentials/botidinamix-g.json"
20
-
21
- # Configura la clave de API de OpenAI
22
- openai.api_key = os.getenv("OPENAI_API_KEY")
23
-
24
- # Verifica que la clave API de OpenAI est茅 configurada
25
- if not openai.api_key:
26
- st.error("No API key provided for OpenAI. Please set your API key in the .env file.")
27
-
28
- # Funci贸n para leer un archivo PDF y extraer el texto
29
- def leer_pdf(file):
30
- pdf_reader = PyPDF2.PdfFileReader(file)
31
- texto = ""
32
- for page_num in range(pdf_reader.numPages):
33
- page = pdf_reader.getPage(page_num)
34
- texto += page.extract_text()
35
- return texto
36
-
37
- # Funci贸n para dividir el texto en una lista de recordatorios
38
- def procesar_recordatorios(texto):
39
- recordatorios = texto.split('\n')
40
- return [r.strip() for r in recordatorios if r.strip()]
41
-
42
- # Funci贸n para generar una respuesta de voz usando Google Cloud Text-to-Speech
43
- def generar_respuesta_de_voz(text):
44
- client = texttospeech.TextToSpeechClient()
45
-
46
- synthesis_input = texttospeech.SynthesisInput(text=text)
47
- voice = texttospeech.VoiceSelectionParams(language_code="es-ES", ssml_gender=texttospeech.SsmlVoiceGender.FEMALE)
48
- audio_config = texttospeech.AudioConfig(audio_encoding=texttospeech.AudioEncoding.MP3)
49
-
50
- try:
51
- response = client.synthesize_speech(input=synthesis_input, voice=voice, audio_config=audio_config)
52
- with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_file:
53
- tmp_file.write(response.audio_content)
54
- audio_file_path = tmp_file.name
55
-
56
- st.write(f"Audio generado en: {audio_file_path}") # Depuraci贸n
57
- return audio_file_path
58
- except Exception as e:
59
- st.error(f"Error al generar el audio: {e}")
60
- return None
61
-
62
- # Funci贸n para generar y reproducir mensajes peri贸dicos
63
- def tarea_periodica(mensaje):
64
- audio_path = generar_respuesta_de_voz(mensaje)
65
- if audio_path:
66
- st.session_state.last_audio_path = audio_path
67
- st.experimental_rerun()
68
- else:
69
- st.error("No se pudo generar el audio para el mensaje.")
70
-
71
- # Funci贸n para programar los recordatorios en horas espec铆ficas
72
- def programar_recordatorios(recordatorios, horarios):
73
- schedule.clear() # Limpiar tareas programadas anteriormente
74
- for i, (recordatorio, horario) in enumerate(zip(recordatorios, horarios)):
75
- schedule.every().day.at(horario).do(lambda r=recordatorio: tarea_periodica(r))
76
- st.write(f"Recordatorio {i+1} programado para las {horario}.")
77
-
78
- # Crear la aplicaci贸n Streamlit
79
- st.title("Asistente de Recordatorios de Voz")
80
- st.write("Este asistente reproduce recordatorios en voz autom谩ticamente seg煤n los horarios configurados.")
81
-
82
- # Inicializar el 铆ndice de recordatorios en la sesi贸n
83
- if 'indice_recordatorio' not in st.session_state:
84
- st.session_state.indice_recordatorio = 0
85
-
86
- # Controles de interfaz para subir el archivo PDF y configurar los horarios
87
- pdf_file = st.file_uploader("Sube el archivo PDF con los recordatorios", type="pdf")
88
-
89
- # Procesar el archivo PDF y obtener la lista de recordatorios
90
- if pdf_file:
91
- texto_pdf = leer_pdf(pdf_file)
92
- recordatorios = procesar_recordatorios(texto_pdf)
93
- st.write("Recordatorios extra铆dos del PDF:")
94
- st.write(recordatorios)
95
-
96
- # Campo de texto para ingresar los horarios de los recordatorios
97
- horarios_input = st.text_area("Escribe los horarios de los recordatorios en formato HH:MM, separados por comas", "09:00,13:00,18:00")
98
- horarios = [h.strip() for h in horarios_input.split(',')]
99
-
100
- if st.button("Programar Recordatorios"):
101
- programar_recordatorios(recordatorios, horarios)
102
- st.success("Recordatorios programados seg煤n los horarios indicados.")
103
-
104
- # Iniciar el scheduler en un hilo separado
105
- def run_scheduler():
106
- while True:
107
- schedule.run_pending()
108
- time.sleep(1)
109
-
110
- if 'scheduler_thread' not in st.session_state:
111
- st.session_state.scheduler_thread = threading.Thread(target=run_scheduler)
112
- st.session_state.scheduler_thread.start()
113
-
114
- # C贸digo JavaScript para reproducci贸n autom谩tica de audio
115
- if 'last_audio_path' in st.session_state:
116
- with open(st.session_state.last_audio_path, "rb") as audio_file:
117
- audio_bytes = audio_file.read()
118
- audio_base64 = base64.b64encode(audio_bytes).decode()
119
-
120
- audio_html = f"""
121
- <audio autoplay>
122
- <source src="data:audio/mp3;base64,{audio_base64}" type="audio/mp3">
123
- Your browser does not support the audio element.
124
- </audio>
125
- """
126
- st.markdown(audio_html, unsafe_allow_html=True)
127
-
128
- # Autorefresh cada 30 segundos (puedes ajustar este intervalo)
129
- st_autorefresh(interval=30000, key="datarefresh")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ import schedule
4
+ import streamlit as st
5
+ from google.cloud import texttospeech
6
+ import openai
7
+ from dotenv import load_dotenv
8
+ import threading
9
+ from datetime import datetime, timedelta
10
+ from streamlit_autorefresh import st_autorefresh
11
+ import tempfile
12
+ import base64
13
+ import random
14
+
15
+ # Cargar las variables de entorno desde el archivo .env
16
+ load_dotenv()
17
+
18
+ # Configura la clave de API de Google Cloud
19
+ os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "credentials/botidinamix-g.json"
20
+
21
+ # Configura la clave de API de OpenAI
22
+ openai.api_key = os.getenv("OPENAI_API_KEY")
23
+
24
+ # Verifica que la clave API de OpenAI est茅 configurada
25
+ if not openai.api_key:
26
+ st.error("No API key provided for OpenAI. Please set your API key in the .env file.")
27
+
28
+ # Lista de preguntas para generar mensajes aleatorios
29
+ preguntas = [
30
+ "Bienvenido a la cl铆nica odontol贸gica Omardent. 驴En qu茅 puedo ayudarte hoy?",
31
+ "Hola, soy tu asistente de recepci贸n. 驴Tienes alguna consulta?",
32
+ "Gracias por elegir Omardent. 驴C贸mo puedo asistirte?",
33
+ "Bienvenido a Omardent. 驴Necesitas ayuda con algo espec铆fico?",
34
+ "Hola, estoy aqu铆 para ayudarte. 驴Tienes alguna pregunta o necesitas asistencia?"
35
+ ]
36
+
37
+ # Funci贸n para obtener respuesta del agente utilizando GPT-4
38
+ def obtener_respuesta():
39
+ pregunta = random.choice(preguntas)
40
+ prompt = f"Como asistente de recepci贸n en la cl铆nica odontol贸gica Omardent, mi trabajo es asegurar que todos se sientan bienvenidos y c贸modos. Transmitiendo mensajes de seguridad, confianza y tranquilidad en un tono amable y profesional. {pregunta}"
41
+ try:
42
+ response = openai.ChatCompletion.create(
43
+ model="gpt-4",
44
+ messages=[
45
+ {"role": "system", "content": "Eres un asistente carism谩tico y profesional."},
46
+ {"role": "user", "content": prompt},
47
+ ],
48
+ max_tokens=150
49
+ )
50
+ mensaje_generado = response['choices'][0]['message']['content'].strip()
51
+ st.write(f"Mensaje generado: {mensaje_generado}") # Depuraci贸n
52
+ return mensaje_generado
53
+ except Exception as e:
54
+ st.error(f"Error al generar el mensaje: {e}")
55
+ return "Lo siento, hubo un problema al generar el mensaje."
56
+
57
+ # Funci贸n para generar una respuesta de voz usando Google Cloud Text-to-Speech
58
+ def generar_respuesta_de_voz(text):
59
+ client = texttospeech.TextToSpeechClient()
60
+
61
+ synthesis_input = texttospeech.SynthesisInput(text=text)
62
+ voice = texttospeech.VoiceSelectionParams(language_code="es-ES", ssml_gender=texttospeech.SsmlVoiceGender.FEMALE)
63
+ audio_config = texttospeech.AudioConfig(audio_encoding=texttospeech.AudioEncoding.MP3)
64
+
65
+ try:
66
+ response = client.synthesize_speech(input=synthesis_input, voice=voice, audio_config=audio_config)
67
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_file:
68
+ tmp_file.write(response.audio_content)
69
+ audio_file_path = tmp_file.name
70
+
71
+ st.write(f"Audio generado en: {audio_file_path}") # Depuraci贸n
72
+ return audio_file_path
73
+ except Exception as e:
74
+ st.error(f"Error al generar el audio: {e}")
75
+ return None
76
+
77
+ # Funci贸n para verificar que la respuesta sea diferente
78
+ def verificar_respuesta_diferente(nueva_respuesta, respuestas_anteriores):
79
+ return nueva_respuesta not in respuestas_anteriores
80
+
81
+ # Funci贸n para generar y reproducir mensajes peri贸dicos
82
+ def tarea_periodica():
83
+ respuestas_anteriores = st.session_state.get('respuestas_anteriores', [])
84
+ nueva_respuesta = obtener_respuesta()
85
+
86
+ # Verificar que la respuesta sea diferente
87
+ if verificar_respuesta_diferente(nueva_respuesta, respuestas_anteriores):
88
+ audio_path = generar_respuesta_de_voz(nueva_respuesta)
89
+ if audio_path:
90
+ st.session_state.last_audio_path = audio_path
91
+ st.session_state.respuestas_anteriores.append(nueva_respuesta)
92
+ if len(st.session_state.respuestas_anteriores) > 10: # Mantener solo las 煤ltimas 10 respuestas
93
+ st.session_state.respuestas_anteriores.pop(0)
94
+ st.session_state.next_run_time = datetime.now() + timedelta(minutes=st.session_state.intervalo)
95
+ st.experimental_rerun()
96
+ else:
97
+ st.error("No se pudo generar el audio para el mensaje.")
98
+ else:
99
+ st.write("La respuesta generada es similar a la anterior. Generando una nueva respuesta...")
100
+ tarea_periodica() # Intentar generar una nueva respuesta
101
+
102
+ # Funci贸n para programar la tarea seg煤n el intervalo deseado
103
+ def programar_tarea(intervalo):
104
+ schedule.clear() # Limpiar tareas programadas anteriormente
105
+ schedule.every(intervalo).minutes.do(tarea_periodica)
106
+ st.session_state.next_run_time = datetime.now() + timedelta(minutes=intervalo)
107
+
108
+ # Crear la aplicaci贸n Streamlit
109
+ st.title("Asistente de Recepci贸n para Cl铆nica Odontol贸gica Omardent")
110
+ st.write("Este asistente reproduce mensajes de voz autom谩ticamente seg煤n el intervalo configurado.")
111
+
112
+ # Inicializar respuestas anteriores en la sesi贸n
113
+ if 'respuestas_anteriores' not in st.session_state:
114
+ st.session_state.respuestas_anteriores = []
115
+
116
+ # Controles de interfaz
117
+ intervalo = st.slider("Selecciona el intervalo de tiempo (minutos)", min_value=1, max_value=120, value=30, step=1)
118
+
119
+ if st.button("Actualizar Intervalo"):
120
+ st.session_state.intervalo = intervalo
121
+ programar_tarea(intervalo)
122
+ st.success(f"Intervalo de tiempo actualizado a {intervalo} minutos.")
123
+
124
+ # Campo de texto para ingresar un mensaje personalizado
125
+ mensaje_personalizado = st.text_area("Escribe el mensaje que quieres que se reproduzca:")
126
+
127
+ # Controles para reproducir el mensaje personalizado
128
+ if st.button("Reproducir ahora"):
129
+ if mensaje_personalizado:
130
+ audio_path = generar_respuesta_de_voz(mensaje_personalizado)
131
+ if audio_path:
132
+ st.session_state.last_audio_path = audio_path
133
+ st.experimental_rerun()
134
+ else:
135
+ st.error("No se pudo generar el audio para el mensaje personalizado.")
136
+ else:
137
+ st.warning("Por favor, ingresa un mensaje.")
138
+
139
+ intervalo_personalizado = st.slider("Selecciona el intervalo de tiempo para el mensaje personalizado (minutos)", min_value=1, max_value=120, value=30, step=1)
140
+
141
+ if st.button("Programar Reproducci贸n"):
142
+ if mensaje_personalizado:
143
+ schedule.every(intervalo_personalizado).minutes.do(lambda: reproducir_mensaje_personalizado(mensaje_personalizado))
144
+ st.success(f"Mensaje personalizado programado para cada {intervalo_personalizado} minutos.")
145
+ else:
146
+ st.warning("Por favor, ingresa un mensaje.")
147
+
148
+ # Funci贸n para reproducir mensaje personalizado
149
+ def reproducir_mensaje_personalizado(mensaje):
150
+ audio_path = generar_respuesta_de_voz(mensaje)
151
+ if audio_path:
152
+ st.session_state.last_audio_path = audio_path
153
+ st.experimental_rerun()
154
+ else:
155
+ st.error("No se pudo generar el audio para el mensaje.")
156
+
157
+ # Iniciar el scheduler en un hilo separado
158
+ def run_scheduler():
159
+ while True:
160
+ schedule.run_pending()
161
+ time.sleep(1)
162
+
163
+ if 'scheduler_thread' not in st.session_state:
164
+ st.session_state.scheduler_thread = threading.Thread(target=run_scheduler)
165
+ st.session_state.scheduler_thread.start()
166
+
167
+ # Mostrar el contador
168
+ if 'next_run_time' in st.session_state:
169
+ time_remaining = st.session_state.next_run_time - datetime.now()
170
+ if time_remaining.total_seconds() > 0:
171
+ st.write(f"Tiempo restante para el pr贸ximo mensaje: {str(time_remaining).split('.')[0]}")
172
+ else:
173
+ st.write("El mensaje se reproducir谩 pronto.")
174
+
175
+ # Mensaje de bienvenida inicial
176
+ if 'last_audio_path' not in st.session_state:
177
+ mensaje_bienvenida = obtener_respuesta()
178
+ audio_path = generar_respuesta_de_voz(mensaje_bienvenida)
179
+ if audio_path:
180
+ st.session_state.last_audio_path = audio_path
181
+
182
+ # C贸digo JavaScript para reproducci贸n autom谩tica de audio
183
+ if 'last_audio_path' in st.session_state:
184
+ with open(st.session_state.last_audio_path, "rb") as audio_file:
185
+ audio_bytes = audio_file.read()
186
+ audio_base64 = base64.b64encode(audio_bytes).decode()
187
+
188
+ audio_html = f"""
189
+ <audio autoplay>
190
+ <source src="data:audio/mp3;base64,{audio_base64}" type="audio/mp3">
191
+ Your browser does not support the audio element.
192
+ </audio>
193
+ """
194
+ st.markdown(audio_html, unsafe_allow_html=True)
195
+
196
+ # Autorefresh cada 30 segundos (puedes ajustar este intervalo)
197
+ st_autorefresh(interval=30000, key="datarefresh")