Josedcape commited on
Commit
3aed6db
verified
1 Parent(s): 9b72b9e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +514 -57
app.py CHANGED
@@ -1,401 +1,858 @@
1
  import streamlit as st
 
2
  import openai
 
3
  import os
 
4
  import tempfile
 
5
  from google.cloud import texttospeech
 
6
  from dotenv import load_dotenv
 
7
  from docx import Document
 
8
  import base64
 
9
  from streamlit_player import st_player
 
10
  import smtplib
 
11
  from email.mime.multipart import MIMEMultipart
 
12
  from email.mime.text import MIMEText
 
13
  from email.mime.application import MIMEApplication
14
 
 
 
15
  # Configuraci贸n de la interfaz
 
16
  st.set_page_config(page_title="SURVEY ASSISTANT", layout="wide")
17
 
 
 
18
  # Cargar variables de entorno
 
19
  load_dotenv()
 
20
  openai.api_key = os.getenv("OPENAI_API_KEY")
 
21
  os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "botidinamix-g.json"
22
 
 
 
23
  # Funci贸n para obtener respuesta de OpenAI con historial de conversaci贸n
 
24
  def obtener_respuesta(pregunta, historial, modelo="gpt-4", temperatura=0.5):
 
25
  mensajes = historial + [
 
26
  {"role": "user", "content": pregunta}
 
27
  ]
 
28
  response = openai.ChatCompletion.create(
 
29
  model=modelo,
 
30
  messages=mensajes,
 
31
  temperature=temperatura,
 
32
  max_tokens=300,
 
33
  )
 
34
  respuesta = response['choices'][0]['message']['content']
 
35
  return respuesta
36
 
 
 
37
  # Funci贸n para convertir texto a voz usando Google Cloud Text-to-Speech
 
38
  def text_to_speech(text):
 
39
  client = texttospeech.TextToSpeechClient()
 
40
  synthesis_input = texttospeech.SynthesisInput(text=text)
 
41
  voice = texttospeech.VoiceSelectionParams(language_code="es-ES", ssml_gender=texttospeech.SsmlVoiceGender.NEUTRAL)
 
42
  audio_config = texttospeech.AudioConfig(audio_encoding=texttospeech.AudioEncoding.MP3)
 
43
  response = client.synthesize_speech(input=synthesis_input, voice=voice, audio_config=audio_config)
 
44
  audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name
 
45
  with open(audio_path, "wb") as out:
 
46
  out.write(response.audio_content)
 
47
  return audio_path
48
 
 
 
49
  # Funci贸n para reproducir un archivo de audio
 
50
  def reproducir_audio(file_path):
 
51
  audio_file = open(file_path, "rb")
 
52
  audio_data = audio_file.read()
 
53
  audio_base64 = base64.b64encode(audio_data).decode()
 
54
  audio_file.close()
55
 
 
 
 
 
 
 
 
 
56
  st.markdown(
 
57
  f"""
58
- <audio autoplay>
 
 
59
  <source src="data:audio/mp3;base64,{audio_base64}" type="audio/mp3">
 
60
  </audio>
 
61
  """,
 
62
  unsafe_allow_html=True
 
63
  )
64
 
 
 
 
 
 
 
 
 
 
 
65
  # Funci贸n para manejar la encuesta din谩mica
 
66
  def encuesta_asistente():
 
67
  st.title("Asistente Boti Encuesta")
 
68
  st.write("Este asistente te guiar谩 a trav茅s de una serie de preguntas para ayudarte a configurar tu asistente virtual")
69
 
 
 
70
  # Logo de ayuda del asistente
 
71
  ayuda_logo = "https://img.freepik.com/premium-vector/minimal-ai-tech-robot-vector-illustration_589744-869.jpg"
 
72
  st.image(ayuda_logo, width=50)
73
 
 
 
74
  # Bot贸n de ayuda del asistente
 
75
  if st.button("Ayuda del asistente"):
 
76
  reproducir_audio("audios/instructivo.mp3")
77
 
 
 
78
  preguntas = [
 
79
  {
 
80
  "pregunta": "驴Cu谩l es tu nombre?",
 
81
  "tipo": "texto"
 
82
  },
 
83
  {
 
84
  "pregunta": "驴Qu茅 tipo de asistente virtual deseas?",
 
85
  "tipo": "multiple",
 
86
  "opciones": ["Asistente Personal", "Asistente de Negocios", "Asistente de Salud", "Asistente de Educaci贸n", "Otro"]
 
87
  },
 
88
  {
 
89
  "pregunta": "驴Qu茅 objetivo debe cumplir este asistente?",
 
90
  "tipo": "multiple",
 
91
  "opciones": ["Organizaci贸n Personal", "Mejora de Productividad", "Asistencia M茅dica", "Educaci贸n y Aprendizaje", "Otro"]
 
92
  },
 
93
  {
 
94
  "pregunta": "驴Cu谩les son las funciones que debe tener?",
 
95
  "tipo": "multiple",
 
96
  "opciones": ["Gesti贸n de Calendarios", "Recordatorios", "Consultas M茅dicas", "Ayuda con Tareas Escolares", "Otro"]
 
97
  },
 
98
  {
 
99
  "pregunta": "驴C贸mo te gustar铆a que este asistente te ayude en tus tareas diarias?",
 
100
  "tipo": "multiple",
 
101
  "opciones": ["Planificaci贸n de D铆a", "Recordatorios", "Consultas y Respuestas", "Apoyo Emocional", "Otro"]
 
102
  },
 
103
  {
 
104
  "pregunta": "驴Qu茅 interfaz deber铆a tener este asistente?",
 
105
  "tipo": "multiple",
 
106
  "opciones": ["Aplicaci贸n M贸vil", "Aplicaci贸n Web", "Asistente de Voz", "Chatbot en Redes Sociales", "Otro"]
 
107
  },
 
108
  {
 
109
  "pregunta": "驴Utilizar铆as el asistente para aumentar tu tiempo libre o para generar ingresos adicionales?",
 
110
  "tipo": "multiple",
 
111
  "opciones": ["Aumentar tiempo libre", "Generar ingresos adicionales"]
 
112
  },
 
113
  {
 
114
  "pregunta": "Por 煤ltimo, 驴qu茅 estilos y elementos visuales deber铆a tener?",
 
115
  "tipo": "multiple",
 
116
  "opciones": ["Estilo moderno con colores vivos", "Colores sobrios y cl谩sico", "Moderno, colores pastel o simples", "Moderno, elegante, simple, no importa el estilo", "Otro"]
 
117
  }
 
118
  ]
119
 
 
 
120
  if 'respuestas' not in st.session_state:
 
121
  st.session_state.respuestas = {}
 
122
  st.session_state.historial = [{"role": "system", "content": "Eres Boty, un asistente de la empresa Botidinamix AI para el desarrollo e implementaci贸n de asistentes virtuales automatizados. Te guiar谩s a trav茅s de dos o tres preguntas para ayudarte a orientar y configurar tu asistente virtual. Act煤as de manera muy amable, entusiasta y te diriges por el nombre a cada encuestado. Limita las preguntas adicionales a un m谩ximo de 3 preguntas espec铆ficas."}]
 
123
  st.session_state.pregunta_actual = 0
 
124
  st.session_state.preguntas_adicionales = []
 
125
  st.session_state.pregunta_adicional_actual = 0
 
126
  st.session_state.respuestas_adicionales = {}
 
127
  st.session_state.respuestas_adicionales_completadas = False
128
 
 
 
129
  # Validaci贸n de preguntas adicionales
 
130
  if st.session_state.preguntas_adicionales and not st.session_state.respuestas_adicionales_completadas:
 
131
  st.write("Por favor, para poder continuar con el cuestionario es necesario que responda todas las preguntas adicionales.")
 
132
  pregunta_adicional_actual = st.session_state.pregunta_adicional_actual
133
- if pregunta_adicional_actual < len(st.session_state.preguntas_adicionales):
134
- pregunta_adicional = st.session_state.preguntas_adicionales[pregunta_adicional_actual]
135
- st.write(f"**Pregunta adicional {pregunta_adicional_actual + 1}:** {pregunta_adicional}")
136
-
137
- st.session_state.respuestas_adicionales[f'respuesta_adicional_1_{pregunta_adicional_actual}'] = st.text_input("Respuesta adicional 1:", key=f"respuesta_adicional_1_{pregunta_adicional_actual}")
138
- st.session_state.respuestas_adicionales[f'respuesta_adicional_2_{pregunta_adicional_actual}'] = st.text_input("Respuesta adicional 2:", key=f"respuesta_adicional_2_{pregunta_adicional_actual}")
139
- st.session_state.respuestas_adicionales[f'otras_observaciones_{pregunta_adicional_actual}'] = st.text_input("Otras observaciones:", key=f'otras_observaciones_{pregunta_adicional_actual}')
140
-
141
- if st.button("Enviar respuestas adicionales", key=f"btn_adicional_{pregunta_adicional_actual}"):
142
- with st.spinner('Procesando sus respuestas, por favor espere...'):
143
- st.session_state.respuestas[pregunta_adicional + " (Respuesta adicional 1)"] = st.session_state.respuestas_adicionales[f'respuesta_adicional_1_{pregunta_adicional_actual}']
144
- st.session_state.respuestas[pregunta_adicional + " (Respuesta adicional 2)"] = st.session_state.respuestas_adicionales[f'respuesta_adicional_2_{pregunta_adicional_actual}']
145
- st.session_state.respuestas[pregunta_adicional + " (Otras observaciones)"] = st.session_state.respuestas_adicionales[f'otras_observaciones_{pregunta_adicional_actual}']
146
-
147
- st.session_state.historial.append({"role": "user", "content": st.session_state.respuestas_adicionales[f'respuesta_adicional_1_{pregunta_adicional_actual}']})
148
- st.session_state.historial.append({"role": "user", "content": st.session_state.respuestas_adicionales[f'respuesta_adicional_2_{pregunta_adicional_actual}']})
149
- st.session_state.historial.append({"role": "user", "content": st.session_state.respuestas_adicionales[f'otras_observaciones_{pregunta_adicional_actual}']})
150
- st.session_state.historial.append({"role": "assistant", "content": st.session_state.respuesta_actual})
151
-
152
- st.session_state.pregunta_adicional_actual += 1
153
-
154
- if st.session_state.pregunta_adicional_actual == len(st.session_state.preguntas_adicionales):
155
- st.session_state.respuestas_adicionales_completadas = True
156
- st.session_state.preguntas_adicionales = []
157
 
158
- st.experimental_rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  else:
 
160
  if st.session_state.pregunta_actual < len(preguntas):
 
161
  pregunta_actual = preguntas[st.session_state.pregunta_actual]
 
162
  st.write(f"**Pregunta:** {pregunta_actual['pregunta']}")
163
 
 
 
164
  if pregunta_actual["tipo"] == "texto":
 
165
  respuesta = st.text_input("Tu respuesta:", key=f"respuesta_{st.session_state.pregunta_actual}")
 
166
  elif pregunta_actual["tipo"] == "multiple":
 
167
  respuesta = st.selectbox("Selecciona una opci贸n:", pregunta_actual["opciones"], key=f"respuesta_{st.session_state.pregunta_actual}")
 
168
  if respuesta == "Otro":
 
169
  respuesta_otro = st.text_input("Por favor especifica:", key=f"respuesta_otro_{st.session_state.pregunta_actual}")
 
170
  if respuesta_otro:
 
171
  respuesta = respuesta_otro
172
 
 
 
173
  if st.button("Enviar respuesta", key=f"btn_{st.session_state.pregunta_actual}"):
 
174
  with st.spinner('Procesando su respuesta, por favor espere...'):
 
175
  st.session_state.respuestas[pregunta_actual['pregunta']] = respuesta
176
 
 
 
177
  # Obtener respuesta del asistente
 
178
  respuesta_asistente = obtener_respuesta(respuesta, st.session_state.historial)
 
179
  st.session_state.respuesta_actual = respuesta_asistente
180
 
 
 
181
  # Agregar la pregunta y respuesta actual al historial
 
182
  st.session_state.historial.append({"role": "user", "content": respuesta})
 
183
  st.session_state.historial.append({"role": "assistant", "content": respuesta_asistente})
184
 
 
 
185
  # Verificar si el asistente hace una pregunta adicional
 
186
  if "pregunta" in respuesta_asistente.lower() and len(st.session_state.preguntas_adicionales) < 3:
 
187
  st.session_state.preguntas_adicionales.append(respuesta_asistente)
 
188
  st.session_state.respuestas_adicionales_completadas = False
189
 
 
 
190
  # Convertir respuesta a audio
 
191
  audio_path = text_to_speech(respuesta_asistente)
 
192
  st.session_state.audio_path = audio_path
193
 
 
 
194
  st.session_state.pregunta_actual += 1
 
195
  st.experimental_rerun()
 
196
  else:
197
- # Mostrar el resumen de la encuesta antes de registrar
198
- st.write("NO OLVIDE DESCARGAR EL ARCHIVO AL FINALIZAR LA ENCUESTA")
199
- st.write("A continuaci贸n, se muestra un resumen del asistente de acuerdo a sus respuestas:")
200
  resumen = generar_resumen(st.session_state.respuestas)
 
 
 
201
  st.write(resumen)
202
-
 
 
203
  st.write("Gracias por responder todas las preguntas. Haz clic en 'Registrar Encuesta' para finalizar y generar el archivo descargable.")
 
204
  if st.button("Registrar Encuesta"):
 
205
  st.session_state.encuesta_completada = True
206
- enviar_correo(resumen)
207
- st.success("Encuesta completada exitosamente. Haz clic en 'Obtener Resultado de la Encuesta' para descargar el archivo.")
 
 
208
 
209
  if 'respuesta_actual' in st.session_state:
 
210
  st.write("Respuesta del asistente:")
 
211
  st.write(st.session_state.respuesta_actual)
212
 
 
 
213
  audio_path = st.session_state.audio_path
 
214
  audio_file = open(audio_path, "rb")
 
215
  audio_data = audio_file.read()
 
216
  audio_base64 = base64.b64encode(audio_data).decode()
217
 
 
 
218
  st.markdown(
 
219
  f"""
 
220
  <audio autoplay>
 
221
  <source src="data:audio/mp3;base64,{audio_base64}" type="audio/mp3">
 
222
  </audio>
 
223
  """,
 
224
  unsafe_allow_html=True
 
225
  )
226
 
 
 
227
  if 'encuesta_completada' in st.session_state and st.session_state.encuesta_completada:
 
228
  st.markdown(
 
229
  """
 
230
  <style>
 
231
  .download-button {
 
232
  font-size: 20px !important;
 
233
  padding: 10px !important;
 
234
  background-color: #007bff !important;
 
235
  color: white !important;
 
236
  border: none !important;
 
237
  text-align: center !important;
 
238
  cursor: pointer !important;
 
239
  }
 
240
  </style>
 
241
  """,
 
242
  unsafe_allow_html=True
 
243
  )
 
244
  generar_documento()
245
 
 
 
246
  def generar_resumen(respuestas):
247
- # Generar un resumen en formato de texto
248
- resumen = "Este es el asistente configurado de acuerdo a sus respuestas:\n\n"
 
249
  for pregunta, respuesta in respuestas.items():
250
- resumen += f"{pregunta}: {respuesta}\n"
 
 
251
  return resumen
252
 
 
 
253
  def generar_documento():
 
254
  if 'respuestas' in st.session_state:
 
255
  respuestas = st.session_state.respuestas
256
 
 
 
257
  doc = Document()
 
258
  doc.add_heading('Respuestas de la Encuesta', 0)
259
 
 
 
260
  for pregunta, respuesta in respuestas.items():
 
261
  doc.add_heading(pregunta, level=1)
 
262
  doc.add_paragraph(respuesta)
263
 
 
 
264
  temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".docx")
 
265
  doc.save(temp_file.name)
266
 
 
 
267
  with open(temp_file.name, "rb") as file:
 
268
  st.download_button(
 
269
  label="Descargar Archivo",
 
270
  data=file,
 
271
  file_name="resultado_encuesta.docx",
 
272
  mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
 
273
  key="btn_descargar_archivo"
 
274
  )
275
 
276
- def enviar_correo(resumen):
277
- remitente = "tucorreo@gmail.com"
 
 
 
 
 
 
 
 
278
  destinatario = "josedcape@gmail.com"
279
- asunto = "Resumen de la Encuesta"
280
- cuerpo = resumen
281
 
282
- mensaje = MIMEMultipart()
283
- mensaje['From'] = remitente
284
- mensaje['To'] = destinatario
285
- mensaje['Subject'] = asunto
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
286
 
287
- mensaje.attach(MIMEText(cuerpo, 'plain'))
288
 
289
- # Iniciar la sesi贸n SMTP
290
- servidor = smtplib.SMTP('smtp.gmail.com', 587)
291
- servidor.starttls()
292
- servidor.login(remitente, os.getenv("EMAIL_PASSWORD"))
293
- texto = mensaje.as_string()
294
- servidor.sendmail(remitente, destinatario, texto)
295
- servidor.quit()
296
 
297
  # Funci贸n para incrustar video en la p谩gina principal
 
298
  def incrustar_video_principal():
299
- video_url = "https://www.youtube.com/watch?v=uGzZe1LxVPk" # Reemplaza con el enlace correcto
300
- st_player(video_url, playing=True, volume=100)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
 
302
  # Estilos personalizados
 
303
  st.markdown(
 
304
  """
 
305
  <style>
 
306
  .sidebar .sidebar-content {
 
307
  background-color: #2C3E50;
 
308
  }
 
309
  .sidebar .sidebar-content .element-container {
 
310
  color: #ECF0F1;
 
311
  }
 
312
  .main {
 
313
  background-color: #000000;
 
314
  color: #ECF0F1;
 
315
  background-image: url('https://images6.alphacoders.com/774/thumb-1920-774373.jpg');
 
316
  background-size: cover;
 
317
  }
 
318
  h1, h2, h3, h4, h5, h6 {
 
319
  color: #FFFFFF;
 
320
  font-weight: bold;
 
321
  }
 
322
  .big-button, .stButton button {
 
323
  font-size: 20px !important;
 
324
  padding: 10px !important;
 
325
  background-color: #007bff !important;
 
326
  color: white !important;
 
327
  border: none !important;
 
328
  text-align: center !important;
 
329
  cursor: pointer !important;
 
330
  }
 
331
  .stTextInput input {
 
332
  color: black !important;
 
333
  background-color: white !important;
 
334
  }
 
335
  .nav-bar {
 
336
  background-color: #000000; /* Cambiado a negro */
 
337
  color: white;
 
338
  padding: 10px;
 
339
  text-align: center;
 
340
  font-size: 24px;
 
341
  font-weight: bold;
 
342
  }
 
343
  .nav-link {
 
344
  color: white;
 
345
  margin: 0 15px;
 
346
  text-decoration: none;
 
347
  cursor: pointer;
 
348
  }
 
349
  </style>
 
350
  """,
 
351
  unsafe_allow_html=True
 
352
  )
353
 
 
 
354
  # Funci贸n para la barra de navegaci贸n
 
355
  def barra_navegacion():
 
356
  st.markdown(
 
357
  """
 
358
  <div class="nav-bar">
 
359
  <a class="nav-link" href="?page=principal">""" + ("P谩gina Principal" if st.session_state.idioma == "Espa帽ol" else "Main Page") + """</a>
 
360
  <a class="nav-link" href="?page=asistente">""" + ("Asistente Boti" if st.session_state.idioma == "Espa帽ol" else "Boti Assistant") + """</a>
361
- </div>
 
 
 
 
362
  """,
 
363
  unsafe_allow_html=True
 
364
  )
365
 
 
 
366
  # Funci贸n para seleccionar idioma
 
367
  def seleccionar_idioma():
 
368
  idioma = st.sidebar.radio("Idioma", ("Espa帽ol", "English"))
 
369
  st.session_state.idioma = idioma
370
 
 
 
371
  # Funciones para las p谩ginas
 
372
  def pagina_principal():
 
373
  st.title("Bienvenido a Boti Asistente")
 
374
  st.write("Esta es la p谩gina principal de Boti Asistente, especializado en el desarrollo de bots para Botidinamix.")
 
375
  incrustar_video_principal()
 
376
  st.markdown("<h2 style='text-align: center; color: white;'>Para realizar su encuesta, haga clic en la barra superior</h2>", unsafe_allow_html=True)
377
 
 
 
378
  def pagina_asistente():
 
379
  encuesta_asistente()
380
 
381
- def pagina_ver_video():
382
- incrustar_video_principal()
 
 
 
 
 
 
 
383
 
384
  # Funci贸n principal
 
385
  def main():
 
386
  if 'idioma' not in st.session_state:
 
387
  st.session_state.idioma = 'Espa帽ol'
 
388
 
 
389
  seleccionar_idioma()
 
390
  barra_navegacion()
 
391
 
 
392
  query_params = st.experimental_get_query_params()
 
393
  page = query_params.get("page", ["principal"])[0]
 
394
  if page == "principal":
 
395
  pagina_principal()
 
396
  elif page == "asistente":
 
397
  pagina_asistente()
398
-
 
 
 
 
 
399
 
400
  if __name__ == "__main__":
 
401
  main()
 
 
1
  import streamlit as st
2
+
3
  import openai
4
+
5
  import os
6
+
7
  import tempfile
8
+
9
  from google.cloud import texttospeech
10
+
11
  from dotenv import load_dotenv
12
+
13
  from docx import Document
14
+
15
  import base64
16
+
17
  from streamlit_player import st_player
18
+
19
  import smtplib
20
+
21
  from email.mime.multipart import MIMEMultipart
22
+
23
  from email.mime.text import MIMEText
24
+
25
  from email.mime.application import MIMEApplication
26
 
27
+
28
+
29
  # Configuraci贸n de la interfaz
30
+
31
  st.set_page_config(page_title="SURVEY ASSISTANT", layout="wide")
32
 
33
+
34
+
35
  # Cargar variables de entorno
36
+
37
  load_dotenv()
38
+
39
  openai.api_key = os.getenv("OPENAI_API_KEY")
40
+
41
  os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "botidinamix-g.json"
42
 
43
+
44
+
45
  # Funci贸n para obtener respuesta de OpenAI con historial de conversaci贸n
46
+
47
  def obtener_respuesta(pregunta, historial, modelo="gpt-4", temperatura=0.5):
48
+
49
  mensajes = historial + [
50
+
51
  {"role": "user", "content": pregunta}
52
+
53
  ]
54
+
55
  response = openai.ChatCompletion.create(
56
+
57
  model=modelo,
58
+
59
  messages=mensajes,
60
+
61
  temperature=temperatura,
62
+
63
  max_tokens=300,
64
+
65
  )
66
+
67
  respuesta = response['choices'][0]['message']['content']
68
+
69
  return respuesta
70
 
71
+
72
+
73
  # Funci贸n para convertir texto a voz usando Google Cloud Text-to-Speech
74
+
75
  def text_to_speech(text):
76
+
77
  client = texttospeech.TextToSpeechClient()
78
+
79
  synthesis_input = texttospeech.SynthesisInput(text=text)
80
+
81
  voice = texttospeech.VoiceSelectionParams(language_code="es-ES", ssml_gender=texttospeech.SsmlVoiceGender.NEUTRAL)
82
+
83
  audio_config = texttospeech.AudioConfig(audio_encoding=texttospeech.AudioEncoding.MP3)
84
+
85
  response = client.synthesize_speech(input=synthesis_input, voice=voice, audio_config=audio_config)
86
+
87
  audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name
88
+
89
  with open(audio_path, "wb") as out:
90
+
91
  out.write(response.audio_content)
92
+
93
  return audio_path
94
 
95
+
96
+
97
  # Funci贸n para reproducir un archivo de audio
98
+
99
  def reproducir_audio(file_path):
100
+
101
  audio_file = open(file_path, "rb")
102
+
103
  audio_data = audio_file.read()
104
+
105
  audio_base64 = base64.b64encode(audio_data).decode()
106
+
107
  audio_file.close()
108
 
109
+
110
+
111
+ st.session_state.audio_base64 = audio_base64
112
+
113
+ st.session_state.audio_playing = True
114
+
115
+
116
+
117
  st.markdown(
118
+
119
  f"""
120
+
121
+ <audio id="audio" autoplay>
122
+
123
  <source src="data:audio/mp3;base64,{audio_base64}" type="audio/mp3">
124
+
125
  </audio>
126
+
127
  """,
128
+
129
  unsafe_allow_html=True
130
+
131
  )
132
 
133
+
134
+
135
+ # Funci贸n para detener el audio
136
+
137
+ def detener_audio():
138
+
139
+ st.session_state.audio_playing = False
140
+
141
+
142
+
143
  # Funci贸n para manejar la encuesta din谩mica
144
+
145
  def encuesta_asistente():
146
+
147
  st.title("Asistente Boti Encuesta")
148
+
149
  st.write("Este asistente te guiar谩 a trav茅s de una serie de preguntas para ayudarte a configurar tu asistente virtual")
150
 
151
+
152
+
153
  # Logo de ayuda del asistente
154
+
155
  ayuda_logo = "https://img.freepik.com/premium-vector/minimal-ai-tech-robot-vector-illustration_589744-869.jpg"
156
+
157
  st.image(ayuda_logo, width=50)
158
 
159
+
160
+
161
  # Bot贸n de ayuda del asistente
162
+
163
  if st.button("Ayuda del asistente"):
164
+
165
  reproducir_audio("audios/instructivo.mp3")
166
 
167
+
168
+
169
  preguntas = [
170
+
171
  {
172
+
173
  "pregunta": "驴Cu谩l es tu nombre?",
174
+
175
  "tipo": "texto"
176
+
177
  },
178
+
179
  {
180
+
181
  "pregunta": "驴Qu茅 tipo de asistente virtual deseas?",
182
+
183
  "tipo": "multiple",
184
+
185
  "opciones": ["Asistente Personal", "Asistente de Negocios", "Asistente de Salud", "Asistente de Educaci贸n", "Otro"]
186
+
187
  },
188
+
189
  {
190
+
191
  "pregunta": "驴Qu茅 objetivo debe cumplir este asistente?",
192
+
193
  "tipo": "multiple",
194
+
195
  "opciones": ["Organizaci贸n Personal", "Mejora de Productividad", "Asistencia M茅dica", "Educaci贸n y Aprendizaje", "Otro"]
196
+
197
  },
198
+
199
  {
200
+
201
  "pregunta": "驴Cu谩les son las funciones que debe tener?",
202
+
203
  "tipo": "multiple",
204
+
205
  "opciones": ["Gesti贸n de Calendarios", "Recordatorios", "Consultas M茅dicas", "Ayuda con Tareas Escolares", "Otro"]
206
+
207
  },
208
+
209
  {
210
+
211
  "pregunta": "驴C贸mo te gustar铆a que este asistente te ayude en tus tareas diarias?",
212
+
213
  "tipo": "multiple",
214
+
215
  "opciones": ["Planificaci贸n de D铆a", "Recordatorios", "Consultas y Respuestas", "Apoyo Emocional", "Otro"]
216
+
217
  },
218
+
219
  {
220
+
221
  "pregunta": "驴Qu茅 interfaz deber铆a tener este asistente?",
222
+
223
  "tipo": "multiple",
224
+
225
  "opciones": ["Aplicaci贸n M贸vil", "Aplicaci贸n Web", "Asistente de Voz", "Chatbot en Redes Sociales", "Otro"]
226
+
227
  },
228
+
229
  {
230
+
231
  "pregunta": "驴Utilizar铆as el asistente para aumentar tu tiempo libre o para generar ingresos adicionales?",
232
+
233
  "tipo": "multiple",
234
+
235
  "opciones": ["Aumentar tiempo libre", "Generar ingresos adicionales"]
236
+
237
  },
238
+
239
  {
240
+
241
  "pregunta": "Por 煤ltimo, 驴qu茅 estilos y elementos visuales deber铆a tener?",
242
+
243
  "tipo": "multiple",
244
+
245
  "opciones": ["Estilo moderno con colores vivos", "Colores sobrios y cl谩sico", "Moderno, colores pastel o simples", "Moderno, elegante, simple, no importa el estilo", "Otro"]
246
+
247
  }
248
+
249
  ]
250
 
251
+
252
+
253
  if 'respuestas' not in st.session_state:
254
+
255
  st.session_state.respuestas = {}
256
+
257
  st.session_state.historial = [{"role": "system", "content": "Eres Boty, un asistente de la empresa Botidinamix AI para el desarrollo e implementaci贸n de asistentes virtuales automatizados. Te guiar谩s a trav茅s de dos o tres preguntas para ayudarte a orientar y configurar tu asistente virtual. Act煤as de manera muy amable, entusiasta y te diriges por el nombre a cada encuestado. Limita las preguntas adicionales a un m谩ximo de 3 preguntas espec铆ficas."}]
258
+
259
  st.session_state.pregunta_actual = 0
260
+
261
  st.session_state.preguntas_adicionales = []
262
+
263
  st.session_state.pregunta_adicional_actual = 0
264
+
265
  st.session_state.respuestas_adicionales = {}
266
+
267
  st.session_state.respuestas_adicionales_completadas = False
268
 
269
+
270
+
271
  # Validaci贸n de preguntas adicionales
272
+
273
  if st.session_state.preguntas_adicionales and not st.session_state.respuestas_adicionales_completadas:
274
+
275
  st.write("Por favor, para poder continuar con el cuestionario es necesario que responda todas las preguntas adicionales.")
276
+
277
  pregunta_adicional_actual = st.session_state.pregunta_adicional_actual
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
 
279
+ pregunta_adicional = st.session_state.preguntas_adicionales[pregunta_adicional_actual]
280
+
281
+ st.write(f"**Pregunta adicional {pregunta_adicional_actual + 1}:** {pregunta_adicional}")
282
+
283
+
284
+
285
+ st.session_state.respuestas_adicionales[f'respuesta_adicional_1_{pregunta_adicional_actual}'] = st.text_input("Respuesta adicional 1:", key=f"respuesta_adicional_1_{pregunta_adicional_actual}")
286
+
287
+ st.session_state.respuestas_adicionales[f'respuesta_adicional_2_{pregunta_adicional_actual}'] = st.text_input("Respuesta adicional 2:", key=f"respuesta_adicional_2_{pregunta_adicional_actual}")
288
+
289
+ st.session_state.respuestas_adicionales[f'otras_observaciones_{pregunta_adicional_actual}'] = st.text_input("Otras observaciones:", key=f'otras_observaciones_{pregunta_adicional_actual}')
290
+
291
+
292
+
293
+ if st.button("Enviar respuestas adicionales", key=f"btn_adicional_{pregunta_adicional_actual}"):
294
+
295
+ with st.spinner('Procesando sus respuestas, por favor espere...'):
296
+
297
+ st.session_state.respuestas[pregunta_adicional + " (Respuesta adicional 1)"] = st.session_state.respuestas_adicionales[f'respuesta_adicional_1_{pregunta_adicional_actual}']
298
+
299
+ st.session_state.respuestas[pregunta_adicional + " (Respuesta adicional 2)"] = st.session_state.respuestas_adicionales[f'respuesta_adicional_2_{pregunta_adicional_actual}']
300
+
301
+ st.session_state.respuestas[pregunta_adicional + " (Otras observaciones)"] = st.session_state.respuestas_adicionales[f'otras_observaciones_{pregunta_adicional_actual}']
302
+
303
+
304
+
305
+ st.session_state.historial.append({"role": "user", "content": st.session_state.respuestas_adicionales[f'respuesta_adicional_1_{pregunta_adicional_actual}']})
306
+
307
+ st.session_state.historial.append({"role": "user", "content": st.session_state.respuestas_adicionales[f'respuesta_adicional_2_{pregunta_adicional_actual}']})
308
+
309
+ st.session_state.historial.append({"role": "user", "content": st.session_state.respuestas_adicionales[f'otras_observaciones_{pregunta_adicional_actual}']})
310
+
311
+ st.session_state.historial.append({"role": "assistant", "content": st.session_state.respuesta_actual})
312
+
313
+
314
+
315
+ st.session_state.pregunta_adicional_actual += 1
316
+
317
+
318
+
319
+ if st.session_state.pregunta_adicional_actual == len(st.session_state.preguntas_adicionales):
320
+
321
+ st.session_state.respuestas_adicionales_completadas = True
322
+
323
+ st.session_state.preguntas_adicionales = []
324
+
325
+
326
+
327
+ st.experimental_rerun()
328
+
329
  else:
330
+
331
  if st.session_state.pregunta_actual < len(preguntas):
332
+
333
  pregunta_actual = preguntas[st.session_state.pregunta_actual]
334
+
335
  st.write(f"**Pregunta:** {pregunta_actual['pregunta']}")
336
 
337
+
338
+
339
  if pregunta_actual["tipo"] == "texto":
340
+
341
  respuesta = st.text_input("Tu respuesta:", key=f"respuesta_{st.session_state.pregunta_actual}")
342
+
343
  elif pregunta_actual["tipo"] == "multiple":
344
+
345
  respuesta = st.selectbox("Selecciona una opci贸n:", pregunta_actual["opciones"], key=f"respuesta_{st.session_state.pregunta_actual}")
346
+
347
  if respuesta == "Otro":
348
+
349
  respuesta_otro = st.text_input("Por favor especifica:", key=f"respuesta_otro_{st.session_state.pregunta_actual}")
350
+
351
  if respuesta_otro:
352
+
353
  respuesta = respuesta_otro
354
 
355
+
356
+
357
  if st.button("Enviar respuesta", key=f"btn_{st.session_state.pregunta_actual}"):
358
+
359
  with st.spinner('Procesando su respuesta, por favor espere...'):
360
+
361
  st.session_state.respuestas[pregunta_actual['pregunta']] = respuesta
362
 
363
+
364
+
365
  # Obtener respuesta del asistente
366
+
367
  respuesta_asistente = obtener_respuesta(respuesta, st.session_state.historial)
368
+
369
  st.session_state.respuesta_actual = respuesta_asistente
370
 
371
+
372
+
373
  # Agregar la pregunta y respuesta actual al historial
374
+
375
  st.session_state.historial.append({"role": "user", "content": respuesta})
376
+
377
  st.session_state.historial.append({"role": "assistant", "content": respuesta_asistente})
378
 
379
+
380
+
381
  # Verificar si el asistente hace una pregunta adicional
382
+
383
  if "pregunta" in respuesta_asistente.lower() and len(st.session_state.preguntas_adicionales) < 3:
384
+
385
  st.session_state.preguntas_adicionales.append(respuesta_asistente)
386
+
387
  st.session_state.respuestas_adicionales_completadas = False
388
 
389
+
390
+
391
  # Convertir respuesta a audio
392
+
393
  audio_path = text_to_speech(respuesta_asistente)
394
+
395
  st.session_state.audio_path = audio_path
396
 
397
+
398
+
399
  st.session_state.pregunta_actual += 1
400
+
401
  st.experimental_rerun()
402
+
403
  else:
404
+
405
+ # Mostrar resumen
406
+
407
  resumen = generar_resumen(st.session_state.respuestas)
408
+
409
+ st.write("Resumen del asistente configurado:")
410
+
411
  st.write(resumen)
412
+
413
+
414
+
415
  st.write("Gracias por responder todas las preguntas. Haz clic en 'Registrar Encuesta' para finalizar y generar el archivo descargable.")
416
+
417
  if st.button("Registrar Encuesta"):
418
+
419
  st.session_state.encuesta_completada = True
420
+
421
+ st.success("Encuesta completada exitosamente. NO OLVIDE DESCARGAR EL ARCHIVO AL FINALIZAR LA ENCUESTA. Haz clic en 'Obtener Resultado de la Encuesta' para descargar el archivo.")
422
+
423
+
424
 
425
  if 'respuesta_actual' in st.session_state:
426
+
427
  st.write("Respuesta del asistente:")
428
+
429
  st.write(st.session_state.respuesta_actual)
430
 
431
+
432
+
433
  audio_path = st.session_state.audio_path
434
+
435
  audio_file = open(audio_path, "rb")
436
+
437
  audio_data = audio_file.read()
438
+
439
  audio_base64 = base64.b64encode(audio_data).decode()
440
 
441
+
442
+
443
  st.markdown(
444
+
445
  f"""
446
+
447
  <audio autoplay>
448
+
449
  <source src="data:audio/mp3;base64,{audio_base64}" type="audio/mp3">
450
+
451
  </audio>
452
+
453
  """,
454
+
455
  unsafe_allow_html=True
456
+
457
  )
458
 
459
+
460
+
461
  if 'encuesta_completada' in st.session_state and st.session_state.encuesta_completada:
462
+
463
  st.markdown(
464
+
465
  """
466
+
467
  <style>
468
+
469
  .download-button {
470
+
471
  font-size: 20px !important;
472
+
473
  padding: 10px !important;
474
+
475
  background-color: #007bff !important;
476
+
477
  color: white !important;
478
+
479
  border: none !important;
480
+
481
  text-align: center !important;
482
+
483
  cursor: pointer !important;
484
+
485
  }
486
+
487
  </style>
488
+
489
  """,
490
+
491
  unsafe_allow_html=True
492
+
493
  )
494
+
495
  generar_documento()
496
 
497
+
498
+
499
  def generar_resumen(respuestas):
500
+
501
+ resumen = "De acuerdo a sus respuestas, se ha configurado un asistente con las siguientes caracter铆sticas:\n\n"
502
+
503
  for pregunta, respuesta in respuestas.items():
504
+
505
+ resumen += f"- {pregunta}: {respuesta}\n"
506
+
507
  return resumen
508
 
509
+
510
+
511
  def generar_documento():
512
+
513
  if 'respuestas' in st.session_state:
514
+
515
  respuestas = st.session_state.respuestas
516
 
517
+
518
+
519
  doc = Document()
520
+
521
  doc.add_heading('Respuestas de la Encuesta', 0)
522
 
523
+
524
+
525
  for pregunta, respuesta in respuestas.items():
526
+
527
  doc.add_heading(pregunta, level=1)
528
+
529
  doc.add_paragraph(respuesta)
530
 
531
+
532
+
533
  temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".docx")
534
+
535
  doc.save(temp_file.name)
536
 
537
+
538
+
539
  with open(temp_file.name, "rb") as file:
540
+
541
  st.download_button(
542
+
543
  label="Descargar Archivo",
544
+
545
  data=file,
546
+
547
  file_name="resultado_encuesta.docx",
548
+
549
  mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
550
+
551
  key="btn_descargar_archivo"
552
+
553
  )
554
 
555
+
556
+
557
+ enviar_correo(temp_file.name)
558
+
559
+
560
+
561
+ def enviar_correo(archivo_path):
562
+
563
+ remitente = "tucorreo@example.com"
564
+
565
  destinatario = "josedcape@gmail.com"
 
 
566
 
567
+ asunto = "Resultado de la Encuesta de Asistente Virtual"
568
+
569
+ cuerpo = "Adjunto encontrar谩 el archivo con el resultado de la encuesta para la configuraci贸n del asistente virtual."
570
+
571
+
572
+
573
+ msg = MIMEMultipart()
574
+
575
+ msg['From'] = remitente
576
+
577
+ msg['To'] = destinatario
578
+
579
+ msg['Subject'] = asunto
580
+
581
+ msg.attach(MIMEText(cuerpo, 'plain'))
582
+
583
+
584
+
585
+ with open(archivo_path, "rb") as attachment:
586
+
587
+ part = MIMEApplication(attachment.read(), Name=os.path.basename(archivo_path))
588
+
589
+ part['Content-Disposition'] = f'attachment; filename="{os.path.basename(archivo_path)}"'
590
+
591
+ msg.attach(part)
592
+
593
+
594
+
595
+ try:
596
+
597
+ servidor = smtplib.SMTP('smtp.gmail.com', 587)
598
+
599
+ servidor.starttls()
600
+
601
+ servidor.login(remitente, "tu_contrase帽a")
602
+
603
+ texto = msg.as_string()
604
+
605
+ servidor.sendmail(remitente, destinatario, texto)
606
+
607
+ servidor.quit()
608
+
609
+ st.success("Correo enviado exitosamente.")
610
+
611
+ except Exception as e:
612
+
613
+ st.error(f"Error al enviar el correo: {e}")
614
 
 
615
 
 
 
 
 
 
 
 
616
 
617
  # Funci贸n para incrustar video en la p谩gina principal
618
+
619
  def incrustar_video_principal():
620
+
621
+ video_url = "https://www.youtube.com/watch?v=example_video_url" # Reemplaza con el enlace correcto
622
+
623
+ st_player(video_url, playing=True, volume=0)
624
+
625
+
626
+
627
+ if st.session_state.audio_playing:
628
+
629
+ st.markdown(
630
+
631
+ f"""
632
+
633
+ <audio id="audio" autoplay>
634
+
635
+ <source src="data:audio/mp3;base64,{st.session_state.audio_base64}" type="audio/mp3">
636
+
637
+ </audio>
638
+
639
+ """,
640
+
641
+ unsafe_allow_html=True
642
+
643
+ )
644
+
645
+
646
+
647
+ if st.button("Detener Audio", key="detener_audio", help="Haz clic para detener el audio", css_class="big-button"):
648
+
649
+ detener_audio()
650
+
651
+
652
 
653
  # Estilos personalizados
654
+
655
  st.markdown(
656
+
657
  """
658
+
659
  <style>
660
+
661
  .sidebar .sidebar-content {
662
+
663
  background-color: #2C3E50;
664
+
665
  }
666
+
667
  .sidebar .sidebar-content .element-container {
668
+
669
  color: #ECF0F1;
670
+
671
  }
672
+
673
  .main {
674
+
675
  background-color: #000000;
676
+
677
  color: #ECF0F1;
678
+
679
  background-image: url('https://images6.alphacoders.com/774/thumb-1920-774373.jpg');
680
+
681
  background-size: cover;
682
+
683
  }
684
+
685
  h1, h2, h3, h4, h5, h6 {
686
+
687
  color: #FFFFFF;
688
+
689
  font-weight: bold;
690
+
691
  }
692
+
693
  .big-button, .stButton button {
694
+
695
  font-size: 20px !important;
696
+
697
  padding: 10px !important;
698
+
699
  background-color: #007bff !important;
700
+
701
  color: white !important;
702
+
703
  border: none !important;
704
+
705
  text-align: center !important;
706
+
707
  cursor: pointer !important;
708
+
709
  }
710
+
711
  .stTextInput input {
712
+
713
  color: black !important;
714
+
715
  background-color: white !important;
716
+
717
  }
718
+
719
  .nav-bar {
720
+
721
  background-color: #000000; /* Cambiado a negro */
722
+
723
  color: white;
724
+
725
  padding: 10px;
726
+
727
  text-align: center;
728
+
729
  font-size: 24px;
730
+
731
  font-weight: bold;
732
+
733
  }
734
+
735
  .nav-link {
736
+
737
  color: white;
738
+
739
  margin: 0 15px;
740
+
741
  text-decoration: none;
742
+
743
  cursor: pointer;
744
+
745
  }
746
+
747
  </style>
748
+
749
  """,
750
+
751
  unsafe_allow_html=True
752
+
753
  )
754
 
755
+
756
+
757
  # Funci贸n para la barra de navegaci贸n
758
+
759
  def barra_navegacion():
760
+
761
  st.markdown(
762
+
763
  """
764
+
765
  <div class="nav-bar">
766
+
767
  <a class="nav-link" href="?page=principal">""" + ("P谩gina Principal" if st.session_state.idioma == "Espa帽ol" else "Main Page") + """</a>
768
+
769
  <a class="nav-link" href="?page=asistente">""" + ("Asistente Boti" if st.session_state.idioma == "Espa帽ol" else "Boti Assistant") + """</a>
770
+
771
+ <a class="nav-link" href="?page=video">""" + ("Ver Video" if st.session_state.idioma == "Espa帽ol" else "Watch Video") + """</a>
772
+
773
+ </div>
774
+
775
  """,
776
+
777
  unsafe_allow_html=True
778
+
779
  )
780
 
781
+
782
+
783
  # Funci贸n para seleccionar idioma
784
+
785
  def seleccionar_idioma():
786
+
787
  idioma = st.sidebar.radio("Idioma", ("Espa帽ol", "English"))
788
+
789
  st.session_state.idioma = idioma
790
 
791
+
792
+
793
  # Funciones para las p谩ginas
794
+
795
  def pagina_principal():
796
+
797
  st.title("Bienvenido a Boti Asistente")
798
+
799
  st.write("Esta es la p谩gina principal de Boti Asistente, especializado en el desarrollo de bots para Botidinamix.")
800
+
801
  incrustar_video_principal()
802
+
803
  st.markdown("<h2 style='text-align: center; color: white;'>Para realizar su encuesta, haga clic en la barra superior</h2>", unsafe_allow_html=True)
804
 
805
+
806
+
807
  def pagina_asistente():
808
+
809
  encuesta_asistente()
810
 
811
+
812
+
813
+ def pagina_video():
814
+
815
+ st.title("Ver Video")
816
+
817
+ st_player("https://www.youtube.com/watch?v=example_video_url") # Reemplaza con el enlace correcto
818
+
819
+
820
 
821
  # Funci贸n principal
822
+
823
  def main():
824
+
825
  if 'idioma' not in st.session_state:
826
+
827
  st.session_state.idioma = 'Espa帽ol'
828
+
829
 
830
+
831
  seleccionar_idioma()
832
+
833
  barra_navegacion()
834
+
835
 
836
+
837
  query_params = st.experimental_get_query_params()
838
+
839
  page = query_params.get("page", ["principal"])[0]
840
+
841
  if page == "principal":
842
+
843
  pagina_principal()
844
+
845
  elif page == "asistente":
846
+
847
  pagina_asistente()
848
+
849
+ elif page == "video":
850
+
851
+ pagina_video()
852
+
853
+
854
 
855
  if __name__ == "__main__":
856
+
857
  main()
858
+