Pop Up
Implementación del Pop-Up: Código y Manejo de Datos
💡 Importante: Autorización de ventanas emergentes.
Es indispensable habilitar las ventanas emergentes para que el pop-up funcione correctamente. Si esta función está bloqueada, la ventana no se abrirá y no será posible continuar con el proceso. Le recomendamos permitir ventanas emergentes en su navegador o incluir este sitio en la lista de excepciones para evitar inconvenientes.
Una vez que tengas el token de acceso, debes levantar el Pop-Up (o ventana emergente) dentro de tu aplicación utilizando la siguiente lógica:
const response = await login(); // La función login() simula la función que obtiene el token.
const data = {
view: "analysis",
token: response.access_token, // Se obtiene el token de la sentencia de login.
doctorId: "", // Ingrese el ID del doctor que está generando el informe.
appointmentId: "", // Ingrese el ID de la consulta médica a la cual se le está generando el informe.
reportExampleId: "", // (Opcional) Id de plantilla que quieran preseleccionar.
};
// Crea un objeto URLSearchParams para enviar los datos dentro de la URL.
const urlParams = new URLSearchParams(data);
// Define las dimensiones y posicion del Pop-Up
const height = 650;
const width = 900;
const left = (window.screen.width - width) / 2;
const top = (window.screen.height - height) / 2.5;
// Construye la URL para el Pop-Up de Speaknosis.
const popUpUrl = `http://qa-portal.speaknosis.com/#/pop-up/?${urlParams}`; // Ambiente de QA
// OR
const popUpUrl = `http://portal.speaknosis.com/#/pop-up/?${urlParams}`; // Ambiente de PROD
// Abre el modal con la función window.open
const popup = window.open(
popUpUrl, // URL con parámetros de la consulta.
"SpeaknosisPopUp",
`width=${width},height=${height},top=${top},left=${left}` // Entregar configuración del Pop-Up.
);
// Validación para verificar si se abrió correctamente el Pop-Up.
if (!popup) {
console.error("No se pudo abrir el pop-up");
}
Método Alternativo: Autenticación vía postMessage
Además de enviar el token directamente en la URL, Speaknosis soporta un método alternativo de autenticación mediante postMessage. Este enfoque es útil cuando:
- Prefieres no exponer el token en la URL.
- Necesitas enviar datos adicionales junto con el token (como un JSON de configuración).
- Tu arquitectura requiere generar el token después de abrir el Pop-Up.
1. Abrir el Pop-Up sin token en la URL
En este flujo, abres el Pop-Up sin incluir el token en los parámetros de la URL:
const data = {
view: "analysis",
// token: NO se incluye en la URL
doctorId: "", // Ingrese el ID del doctor que está generando el informe.
appointmentId: "", // Ingrese el ID de la consulta médica.
reportExampleId: "", // (Opcional) Id de plantilla que quieran preseleccionar.
};
// Crea un objeto URLSearchParams para enviar los datos dentro de la URL.
const urlParams = new URLSearchParams(data);
// Define las dimensiones y posicion del Pop-Up
const height = 650;
const width = 900;
const left = (window.screen.width - width) / 2;
const top = (window.screen.height - height) / 2.5;
// Construye la URL para el Pop-Up de Speaknosis.
const popUpUrl = `https://qa-portal.speaknosis.com/#/pop-up/?${urlParams}`; // Ambiente de QA
// OR
const popUpUrl = `https://portal.speaknosis.com/#/pop-up/?${urlParams}`; // Ambiente de PROD
// Guarda una referencia al popup y los datos de autenticación
const popupRef = window.open(
popUpUrl,
"SpeaknosisPopUp",
`width=${width},height=${height},top=${top},left=${left}`
);
// Guarda los datos pendientes de autenticación para enviar posteriormente
const pendingAuthData = {
token: response.access_token, // Token obtenido de tu sistema de login
jsonReport: {}, // Opcional: estructura JSON para plantillas dinámicas
};
2. Escuchar y responder a la solicitud de autenticación
Speaknosis enviará un mensaje de tipo AUTH_REQUEST cuando esté listo para recibir las credenciales. Tu aplicación debe escuchar este evento y responder con un mensaje AUTH_RESPONSE:
useEffect(() => {
const messageHandler = (event) => {
// Escuchar la solicitud de autenticación desde Speaknosis
if (event.data?.type === "AUTH_REQUEST") {
console.log("[App] Solicitud de autenticación recibida desde Speaknosis");
// Verificar que tenemos los datos y la referencia al popup
if (pendingAuthData && popupRef) {
const authResponse = {
type: "AUTH_RESPONSE",
token: pendingAuthData.token,
jsonReport: pendingAuthData.jsonReport, // (Opcional) Datos adicionales en formato JSON
};
// Enviar la respuesta al popup
popupRef.postMessage(authResponse, "*");
console.log("[App] Respuesta de autenticación enviada");
} else {
console.warn("[App] No hay datos de autenticación disponibles");
}
return;
}
// Continuar manejando otros mensajes del popup (ej: datos clínicos)
// ...
};
window.addEventListener("message", messageHandler);
return () => window.removeEventListener("message", messageHandler);
}, [pendingAuthData, popupRef]);
⚠️ Importante: Si la ventana padre no responde dentro de un tiempo límite (aprox. 5 segundos con 1 reintento automático), Speaknosis redirigirá a una vista de error. Asegúrate de que tu listener esté activo antes de que el popup complete su carga.
Estructura del mensaje AUTH_RESPONSE
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
type | string | ✅ | Debe ser "AUTH_RESPONSE" |
token | string | ✅ | Token de autenticación JWT válido |
jsonReport | object | null | Opcional | Datos adicionales en formato JSON para configuración avanzada. Para definir correctamente la estructura del JSON, contáctate con el equipo de Speaknosis para que te entreguen la documentación. |
Uso y Funcionamiento del Pop-Up
Si el Pop-Up recibió los datos de la consulta (token, doctorId y appointmentId) de manera correcta, se debería visualizar el componente del Pop-Up.
Puedes usar tu teléfono como micrófono externo escaneando el código QR que se muestra en el Pop-up:
Imagen de referencia:

Una vez que el Pop-up se levante, puedes comenzar a realizar una grabación de audio utilizando el micrófono de tu computadora o tu teléfono como micrófono externo. Al momento de comenzar la grabación de audio, se habilitarán dos nuevos botones: el de pausa/reanudación de grabación ( / ) y el botón que detiene la grabación ().
Imagen de referencia:

Una vez que se finalice la grabación de audio (al presionar el botón de detener), se visualizará una nueva sección donde deberás seleccionar la plantilla a utilizar para generar el informe médico.
📝 Pre-selección de Plantilla (Opcional) Si incluiste el parámetro reportExampleId en la URL inicial, el sistema utilizará ese ID de reporte de ejemplo para pre-seleccionar la plantilla en esta vista automáticamente. El doctor solo tendrá que revisar y confirmar la plantilla antes de hacer clic en 'Generar informe'. Si no se envía este parámetro, el doctor deberá seleccionar manualmente la plantilla del menú desplegable.
Imagen de referencia:

Escoge la plantilla que vas a utilizar en el menú desplegable. Una vez seleccionada, podrás hacer clic en el botón 'Generar informe'.
Imagen de referencia:

Imagen de referencia:

Una vez que se comience a generar el informe, se verá una animación que indicará que se está generando el informe. Luego, se podrá visualizar el informe médico, editarlo y aprobarlo.
Método para recibir el informe
Para recibir los informes en tu sistema, debes configurar un endpoint personalizado y seguro. La comunicación se autenticará utilizando el método que tu sistema prefiera (por ejemplo, una API Key, tokens de autorización, etc).
Una vez configurado, nuestro sistema enviará la información del informe a la URL que nos proporciones. Este proceso se activa cuando un informe es aprobado en nuestra plataforma, generando los datos en el formato acordado y enviándolos a tu endpoint.
Estructura Base de la Respuesta
La carga útil (payload) que recibirás en tu endpoint tendrá la siguiente estructura fundamental:
{
"response": {
"message": {
"appointmentId": "123123",
"report": { /* ... Contenido del informe ... */ },
"metaData": { /* ... Datos adicionales ... */ }
}
}
}
Detalle de los Campos
appointmentId(string): Identificador único de la consulta o cita médica.report(object | string): Contiene el informe médico. Su formato es flexible y depende de la configuración acordada.metaData(object): Contiene datos adicionales y estructurados, como catálogos o códigos.
El campo
reportes dinámico. Puede contener un objeto JSON estructurado o una cadena de texto (string) con el informe en formato MARKDOWN o HTML.
Contenido del Campo "report"
Opción 1: JSON Estructurado (report como objeto)
Si necesitas los datos del informe de manera segmentada, el campo report contendrá un objeto JSON.
Ejemplo:
"report": {
"reasonForVisit": "Motivo de consulta: Dolor de garganta persistente.",
"anamnesis": "Paciente refiere dolor y dificultad para tragar desde hace 3 días.",
"physicalExam": "Se observan amígdalas enrojecidas e inflamadas."
}