Conexiones
Tipos de Conexión
El SDK admite diferentes modos de conexión basados en el proveedor:
Conexión con Clave de API
{
apiKey: string;
config?: BaseConfig;
}
Conexión con Proveedor Sofya Compliance
{
provider: "sofya_compliance";
endpoint: string;
config: SofyaComplianceConfig;
}
Conexión con Proveedor Sofya As Service
{
provider: "sofya_as_service";
endpoint: string;
config: SofyaSpeechConfig;
}
Tipos de Configuración
BaseConfig
interface BaseConfig {
language: string;
external_id?: string;
record?: boolean;
}
| Campo | Tipo | Descripción |
|---|---|---|
external_id | string (opcional) | Identificador de la consulta en tu aplicación. Se envía al servidor como query param x-external-id en cada conexión — incluidas las reconexiones — y se usa para agrupar las grabaciones de la misma consulta. Debe ser opaco: UUID, hash o id interno; nunca CPF/DNI, nombre, historia clínica legible o correo electrónico. Para usarse literalmente en la ruta de la grabación: ^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$ (letra o dígito al inicio, hasta 64 caracteres, sin :, /, espacios ni acentos); fuera de ese patrón el servidor usa un hash en la ruta y guarda el valor original solo en los metadatos. Máximo 512 caracteres. Usa el mismo valor en cada reconexión. |
record | boolean (opcional) | Solicita (true) o rechaza (false) la grabación de esta sesión en el servidor. Si se omite, el SDK no envía nada y decide el valor por defecto del entorno. true solo graba si el entorno lo permite; de lo contrario la sesión continúa con normalidad. Grabar nunca modifica la transcripción. |
const transcriber = new SofyaTranscriber({
provider: "sofya_as_service",
endpoint: "<wss-url>",
config: {
language: "es-ES",
external_id: "<id-de-la-consulta>",
record: true,
},
});
external_id y record son aditivos y opcionales. Las aplicaciones que no los usen seguirán funcionando exactamente igual que antes, incluso contra servidores anteriores.
SofyaComplianceConfig
interface SofyaComplianceConfig extends BaseConfig {
token: string;
compartmentId: string;
region: string;
}
SofyaSpeechConfig
interface SofyaSpeechConfig extends BaseConfig {
auth?: DirectModeAuth;
}
Autenticación en Modo Directo (auth)
Las conexiones directas ({ provider, endpoint, config }) pueden enviar la clave de API del STT mediante el campo opcional config.auth. Está disponible en las configs de los proveedores Whisper directos (sofya_as_service, sofya_whisper_flow, stt_wvad); la conexión con clave de API no cambia, porque ya se autentica a través de la API de Sofya.
type DirectModeAuth =
| { type: "none" }
| {
type: "api_key";
key: string;
transport?: "subprotocol" | "query";
}
| { type: "jwt"; token: string };
| Campo | Tipo | Descripción |
|---|---|---|
type | "none" | "api_key" | "jwt" | "none" es el valor por defecto cuando se omite auth y no envía credenciales. "api_key" envía la clave de API del STT. "jwt" envía un JWT en su lugar (ver JWT). |
key | string | La clave de API del STT. Obligatoria cuando type es "api_key". El SDK nunca transforma el valor. |
transport | "subprotocol" | "query" (opcional) | Cómo llega la clave al servidor. Por defecto "subprotocol". El navegador no puede definir cabeceras en el handshake del WebSocket, así que estas son las dos únicas opciones. |
token | string | El JWT sin procesar. Obligatorio cuando type es "jwt". Sin Bearer : el SDK añade el prefijo. |
transport: "subprotocol" (por defecto)
La clave viaja como un token extra de Sec-WebSocket-Protocol, x-api-key.<clave>. El servidor elimina ese token antes de que la aplicación lo vea y devuelve el primer subprotocolo solicitado, por lo que el SDK mantiene tus protocolos al frente y añade el token de la clave al final.
const transcriber = new SofyaTranscriber({
provider: "sofya_as_service",
endpoint: "<wss-url>",
config: {
language: "es-ES",
auth: { type: "api_key", key: "<clave-api-stt>" },
},
});
config.protocols | Subprotocolos enviados en el handshake |
|---|---|
| omitido | ["sofya-stt.v1", "x-api-key.<clave>"] |
"bearer.jwt" | ["bearer.jwt", "x-api-key.<clave>"] |
["bearer.jwt", "sofya-stt.v1"] | ["bearer.jwt", "sofya-stt.v1", "x-api-key.<clave>"] |
- El servidor rechaza el handshake en el que el token de la clave es el único subprotocolo (
subprotocol_companion_required); por eso el SDK añade el token acompañantesofya-stt.v1cuando no configuras ningún protocolo. - Los tokens de subprotocolo del RFC 6455 aceptan solo letras, dígitos y
!#$%&'*+-.^_`|~—=,/,,, espacios y comillas no están permitidos. Con una clave fuera de ese conjunto el SDK lanzaSofyaAuthErrorantes de conectar; emite una clave compatible o usa el transportequery.
transport: "query"
La clave se añade a la URL de tiempo real como el parámetro x-api-key y los config.protocols se envían sin cambios.
const transcriber = new SofyaTranscriber({
provider: "sofya_as_service",
endpoint: "<wss-url>",
config: {
language: "es-ES",
auth: {
type: "api_key",
key: "<clave-api-stt>",
transport: "query",
},
},
});
Las URLs quedan registradas por proxies, gateways, logs de acceso e historial del navegador. Prefiere subprotocol y usa query solo cuando la clave no pueda ser un token RFC 6455.
- Las reconexiones reutilizan la misma autenticación: la URL y la lista de subprotocolos se reconstruyen igual en cada intento.
- La clave también se envía como cabecera
x-api-keyen las llamadas HTTP que hace el SDK (reprocesamiento por lote e ingesta de auditoría), salvo que esa cabecera ya esté configurada. - El SDK nunca registra la clave: aparece como
[redacted]en la salida de depuración. - Cuando el servidor rechaza la clave, deniega el handshake con HTTP 401 o cierra con el código
4401. Ante un4401el SDK emiteerrorcon unSofyaAuthError(códigoAUTH_REJECTED) y deja de reconectar en lugar de reintentar la misma clave.
auth es aditivo y opcional. Omitirlo (o usar { type: "none" }) mantiene el comportamiento anterior, incluidos los protocols configurados y la URL.
type: "jwt"
Envía un JWT en lugar de la clave de API. Las dos estrategias son exclusivas: la sesión se autentica con una de ellas, y toda solicitud del SDK sigue la elegida.
const transcriber = new SofyaTranscriber({
provider: "sofya_as_service",
endpoint: "<wss-url>",
config: {
language: "pt-BR",
auth: { type: "jwt", token: "<jwt>" }, // "eyJ...", no "Bearer eyJ..."
},
});
No añadas Bearer al token: el SDK añade el prefijo en las solicitudes HTTP. Un token que empieza con Bearer hace que el SDK lance SofyaAuthError con el código INVALID_JWT antes de conectar; el prefijo nunca se elimina en silencio.
| Solicitud | api_key | jwt |
|---|---|---|
| WebSocket | subprotocolo x-api-key.<clave> (último) o query x-api-key | el JWT como primer subprotocolo, antes de config.protocols, y el servidor lo devuelve |
| Batch, batch reprocess, audit ingestion | cabecera x-api-key | Authorization: Bearer <token> |
| Final upload | nada | nada |
- Las sesiones realtime envían el JWT como subprotocolo, así que debe ser un token RFC 6455. Un JWT estándar (base64url, sin padding) siempre lo es; cualquier cosa con
=,/,,, espacios o comillas lanzaSofyaAuthError(INVALID_JWT_CHARACTERS) antes de conectar. Las sesiones batch lo envían solo en la cabecera y aceptan cualquier carácter. - No pongas el JWT también en
config.protocols, o se enviará dos veces. - Una cabecera
Authorizationdefinida enconfig.headerstiene prioridad sobre el JWT. - El STT de Sofya no valida JWT. Usa
jwtcon STTs que tienen la autenticación desactivada o están detrás de un gateway que valida el token; un STT que exige clave de API rechaza la conexión. El audit ingestion exigex-api-key, así que solo conjwtse omite con el avisomissing_api_key. - El JWT nunca aparece en la salida de debug (
[redacted]).
config.token obsoletoEn modo directo, config.token está obsoleto y se eliminará en la 1.0.0; usa auth: { type: "jwt", token }. Hasta entonces sigue convirtiéndose en Authorization: Bearer <token>, el SDK registra un aviso de obsolescencia, y auth.token tiene prioridad cuando se informan ambos.
Flujo de Conexión
Flujo de Conexión con Clave de API
- El SDK se autentica con la API Sofya usando la clave de API proporcionada.
- La API devuelve una lista de proveedores disponibles y sus configuraciones.
- El SDK intenta conectarse a cada proveedor en orden hasta que se establece una conexión exitosa.
- Una vez conectado, el SDK emite un evento 'ready'.
Flujo de Conexión Específico del Proveedor
- El SDK intenta conectarse directamente al proveedor especificado usando el endpoint y la configuración proporcionados.
- Una vez conectado, el SDK emite un evento 'ready'.