Node.js WebSocket ping/pong timeout causing premature disconnect on Genesys Cloud Notification API

I’m running a local Docker Compose setup to mock the Genesys Cloud Notification API for my Terraform integration tests. The goal is to keep a persistent WebSocket connection alive while waiting for specific user events.

The connection works fine initially, but after about 5-10 minutes of inactivity, the server drops the connection. My Node.js client using the ws library isn’t handling the reconnection gracefully. It seems like the ping/pong interval is misconfigured or the library is treating a delayed pong as a failure.

Here’s the relevant snippet from my websocket-client.js:

const WebSocket = require('ws');

const connect = () => {
 const ws = new WebSocket('wss://api.mypurecloud.com/api/v2/analytics/events');
 
 ws.on('open', () => {
 console.log('Connected to GC Notification API');
 // Start ping interval
 ws.pingInterval = setInterval(() => {
 if (ws.readyState === WebSocket.OPEN) {
 ws.ping('keepalive');
 }
 }, 15000);
 });

 ws.on('pong', (data) => {
 console.log('Pong received', data);
 });

 ws.on('close', (code, reason) => {
 console.log(`Connection closed: ${code} ${reason}`);
 clearInterval(ws.pingInterval);
 // Retry logic
 setTimeout(connect, 5000);
 });

 ws.on('error', (err) => {
 console.error('WebSocket error:', err.message);
 });
};

connect();

The console logs show the pong is received, but shortly after, the close event fires with code 1006 (abnormal closure). I’m not sure if the Genesys Cloud API has a specific timeout requirement that I’m missing, or if my ping implementation is flawed. The docs mention a keep-alive mechanism but don’t specify the exact interval or payload format.

Is there a standard way to handle this in Node.js for GC? I’ve tried increasing the ping interval to 30 seconds, but it doesn’t help. The connection still drops.

Also, when I look at the network traffic in my mock server logs, I see the ping frames going out, but the server doesn’t seem to be responding with a pong frame in the expected format. Maybe the mock server needs to be updated to handle the ping opcode correctly?

I’m stuck on whether this is a client-side issue or a server-side mock configuration issue. Any pointers?