Endpoint WebSocket
Producciónwss://agente.hablaip.com/ws/webrtc?access_token=TOKEN_WEBSOCKET
Este endpoint recibe señalización WebRTC por WebSocket. El audio viaja por WebRTC/RTP.
Información para conectar clientes externos al WebSocket/WebRTC de RA AGENTE, validar conectividad desde Linux y probar endpoints auxiliares ASR/TTS/IA.
wss://agente.hablaip.com/ws/webrtc?access_token=TOKEN_WEBSOCKET
Este endpoint recibe señalización WebRTC por WebSocket. El audio viaja por WebRTC/RTP.
https://agente.hablaip.com/api/version
Úsalo para validar que IIS, HTTPS y la aplicación estén activos.
curl -i https://agente.hablaip.com/api/version npm install -g wscat wscat -c wss://agente.hablaip.com/ws/webrtc
Si wscat conecta, el upgrade WebSocket está operativo en IIS/proxy/firewall.
El cliente debe enviar una oferta WebRTC con esta estructura:
{
"type": "offer",
"sdp": "v=0..."
}
El servidor responde:
{
"type": "answer",
"sdp": "v=0..."
}
{
"type": "candidate",
"candidate": {
"candidate": "candidate:...",
"sdpMid": "0",
"sdpMLineIndex": 0
}
}
{
"type": "asr_result",
"result": "{...respuesta ASR...}"
}
El cliente debe extraer el texto reconocido desde la respuesta ASR.
Después de completar la negociación WebRTC, el cliente envía audio por el track de micrófono. El servidor procesa el audio, llama al servicio ASR y devuelve el resultado por el mismo WebSocket.
ws.onmessage = async event => {
const msg = JSON.parse(event.data);
if (msg.type === "ready") {
console.log("WebSocket listo", msg.sessionId);
}
if (msg.type === "answer") {
await pc.setRemoteDescription({ type: "answer", sdp: msg.sdp });
}
if (msg.type === "candidate") {
await pc.addIceCandidate(msg.candidate);
}
if (msg.type === "asr_result") {
const text = getAsrText(msg.result);
if (text) {
console.log("Texto reconocido:", text);
// Aquí puedes enviarlo a tu bot, PBX, CRM o flujo propio.
}
}
};
Función sugerida para extraer texto desde distintas respuestas ASR:
function getAsrText(result) {
try {
const data = typeof result === "string" ? JSON.parse(result) : result;
return findText(data);
} catch {
return String(result || "").trim();
}
}
function findText(value) {
if (!value) return "";
if (typeof value === "string") return value.trim();
if (Array.isArray(value)) return value.map(findText).find(Boolean) || "";
if (typeof value !== "object") return "";
for (const key of ["text", "transcript", "transcription", "result", "respuesta"]) {
const text = findText(value[key]);
if (text) return text;
}
for (const item of Object.values(value)) {
const text = findText(item);
if (text) return text;
}
return "";
}
El WebSocket actual entrega resultados ASR y señalización WebRTC. Para convertir texto a voz, usa el endpoint HTTP TTS. La respuesta es un archivo de audio reproducible por el cliente.
async function playTts(text) {
const form = new FormData();
form.append("language", "es");
form.append("type", "N");
form.append("text", text);
const response = await fetch("https://agente.hablaip.com/api/testing/tts", {
method: "POST",
body: form
});
if (!response.ok) {
throw new Error(`TTS HTTP ${response.status}: ${await response.text()}`);
}
const audioBlob = await response.blob();
const audioUrl = URL.createObjectURL(audioBlob);
const audio = new Audio(audioUrl);
audio.onended = () => URL.revokeObjectURL(audioUrl);
await audio.play();
}
Ejemplo integrando ASR recibido por WebSocket con TTS:
if (msg.type === "asr_result") {
const text = getAsrText(msg.result);
if (text) {
await playTts(`Recibí: ${text}`);
}
}
const token = "TOKEN_WEBSOCKET";
const ws = new WebSocket(`wss://agente.hablaip.com/ws/webrtc?access_token=${encodeURIComponent(token)}`);
const pc = new RTCPeerConnection({
iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
});
ws.onmessage = async event => {
const msg = JSON.parse(event.data);
if (msg.type === "answer") {
await pc.setRemoteDescription({ type: "answer", sdp: msg.sdp });
}
if (msg.type === "candidate") {
await pc.addIceCandidate(msg.candidate);
}
if (msg.type === "asr_result") {
const text = getAsrText(msg.result);
console.log("ASR", text || msg.result);
}
};
pc.onicecandidate = event => {
if (event.candidate) {
ws.send(JSON.stringify({ type: "candidate", candidate: event.candidate }));
}
};
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
stream.getTracks().forEach(track => pc.addTrack(track, stream));
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
ws.onopen = () => ws.send(JSON.stringify({ type: "offer", sdp: offer.sdp }));
curl -i -X POST https://agente.hablaip.com/api/testing/asr \ -F "language=es" \ -F "audio=@audio.wav;type=audio/wav"
curl -i -X POST https://agente.hablaip.com/api/testing/tts \ -F "language=es" \ -F "type=N" \ -F "text=Hola, esto es una prueba"
agente.hablaip.com.Upgrade: websocket.P:\Publicacion\AGENTE.HABLAIP.COM.LOG.