WebSocket disconnects immediately when bridging AppFoundry SDK to Cognigy bot

I’m building a custom desktop app using the Genesys Cloud AppFoundry SDK (JavaScript). The goal is to handle a voice interaction and bridge it to a NICE Cognigy bot via the bot orchestration API. The initial connection to the bot works fine, and I can send the first text payload. However, the moment the bot responds with a prompt and I try to capture audio from the user’s mic to send back as a WebSocket frame, the connection drops with error code 1006.

I’ve verified the audio stream is valid using a local test server, so the issue seems specific to the Genesys websocket endpoint. Here’s the relevant snippet where I attach the audio stream:

botClient.on('prompt', (data) => {
 console.log('Bot prompted:', data);
 const audioStream = getAudioStream(); // Returns MediaStream
 ws.send(JSON.stringify({ type: 'audio', data: audioStream }));
});

The logs show the prompt event firing correctly, but the ws.send call seems to hang before the disconnect happens. I’ve tried setting ws.binaryType = 'arraybuffer' but that didn’t change anything. Is there a specific header or payload format required for audio chunks in this integration? I’ve checked the docs but they’re vague on the exact WebSocket message structure for audio handoffs.

The 1006 error usually means the server closed the connection without a proper close frame. In your case, it’s likely the WebSocket payload structure for the audio chunks is wrong or the framing isn’t matching what Cognigy expects over the AppFoundry bridge.

Check your audio encoding. Genesys Cloud expects PCM 16-bit signed little-endian at 16kHz mono for most bot integrations. If you’re sending Opus or raw WebM, the bot will drop it immediately.

Here is how you should structure the audio send loop in the AppFoundry SDK:

const audioContext = new AudioContext({ sampleRate: 16000 });
const stream = await .mediaDevices.getUserMedia({ audio: true });
const source = audioContext.createMediaStreamSource(stream);
const processor = audioContext.createScriptProcessor(4096, 1, 1);

source.connect(processor);
processor.connect(audioContext.destination);

processor.onaudioprocess = (e) => {
 const inputData = e.inputBuffer.getChannelData(0);
 // Convert Float32 to Int16
 const int16Data = new Int16Array(inputData.length);
 for (let i = 0; i < inputData.length; i++) {
 int16Data[i] = inputData[i] * 0x7FFF;
 }
 
 // Send via WebSocket
 ws.send(int16Data.buffer);
};

Also, verify you are handling the onmessage events from Cognigy correctly. If the bot sends a turn_complete signal, you need to stop sending audio or pause the stream. Sending audio after the bot has finished its turn causes a state mismatch, leading to the disconnect.

Make sure your WebSocket keep-alive interval is under 30 seconds. AppFoundry environments can be strict about idle connections. If the bot takes too long to process, the gateway might kill the session.

Check the network tab in your browser dev tools. Look for the exact bytes being sent. If the buffer size is too large, chunk it. Most bots prefer 20-100ms chunks.