Node Kafka consumer drops analytics notification payloads after 3 minutes

The Kafka consumer just drops every analytics notification after the first 180 seconds.

const client = new PureCloudPlatformClientV2.NotificationClient();
client.subscribe(‘/api/v2/analytics/notifications’, (payload) => {
producer.send({ topic: ‘genesys-analytics’, messages: [{ value: JSON.stringify(payload) }] });
});

It’s not throwing anything when the stream cuts. Token scope looks fine. WebSocket ping just dies right when the messages stop landing.

The issue isn’t the Kafka producer timing out, it’s that the WebSocket connection to the Genesys Cloud notification service is dropping because the client isn’t handling the reconnection logic properly after a period of inactivity or network jitter. The NotificationClient in the Node SDK is stateful, and if the underlying socket closes without the SDK catching it, your subscription just hangs.

You need to listen to the close or error events on the client instance and manually restart the subscription. Also, make sure you’re using the correct scope analytics:read which you probably have, but it’s worth double checking if the token was refreshed correctly during that 3 minute window.

Here is a more resilient pattern for handling the subscription. You’ll want to wrap the subscribe call in a function that you can call again if the connection drops.

const PureCloudPlatformClientV2 = require('@genesyscloud/genesyscloud');
const client = new PureCloudPlatformClientV2.NotificationClient();

// Ensure you have initialized the client with valid credentials first
// PureCloudPlatformClientV2.PureCloudPlatformClientV2.init(...);

let isSubscribed = false;

function subscribeToNotifications() {
 if (isSubscribed) return;
 
 console.log('Attempting to subscribe to analytics notifications...');
 
 const subscription = client.subscribe('/api/v2/analytics/notifications', (payload) => {
 // Your existing Kafka producer logic
 producer.send({ 
 topic: 'genesys-analytics', 
 messages: [{ value: JSON.stringify(payload) }] 
 });
 });

 // Handle connection drops
 client.on('close', () => {
 console.warn('Notification client disconnected. Reconnecting...');
 isSubscribed = false;
 // Small delay before reconnecting to avoid hammering the API
 setTimeout(subscribeToNotifications, 5000);
 });

 client.on('error', (err) => {
 console.error('Notification client error:', err);
 isSubscribed = false;
 setTimeout(subscribeToNotifications, 5000);
 });

 isSubscribed = true;
}

// Initial call
subscribeToNotifications();

The key here is that client.on('close') fires when the WebSocket disconnects. If you don’t listen to it, your app thinks it’s still connected but it’s not. The 3 minute mark is likely when the Genesys Cloud server sends a ping/pong or closes idle connections, and your client isn’t responding or reconnecting.

Also, check your Kafka producer configuration. If you’re not setting ack: 'all' or similar, you might be losing messages silently if the broker is under load, but since you said the WebSocket ping dies, it’s definitely a connectivity issue on the Genesys side of the integration.

Make sure your environment variables for the Genesys client initialization are loaded before you start the subscription loop. If the token expires, the subscription will fail silently unless you handle the auth refresh separately. The SDK usually handles this, but it’s good to log it just in case.

One more thing, if you’re running this in a container or serverless environment, make sure the process doesn’t exit. Node.js won’t keep running just because of an open WebSocket unless you have something else keeping the event loop alive. If this is a long running service, add a simple keep alive interval or ensure your main process doesn’t terminate.

The reconnection logic above should fix the dropping payloads. If it still drops, check the Genesys Cloud API logs for any rate limiting errors on the notification endpoint, though that’s less likely to happen exactly at 180 seconds. It’s almost always the client side not handling the socket closure.

is on the right track. The socket drop is real, but the Node SDK’s NotificationClient doesn’t auto-reconnect by default in this version. You’re seeing a silent failure because the close event fires, but your code isn’t catching it to trigger a new subscription.

Here’s how I handle it in my WFM adherence scripts. Wrap the subscription in a retry loop with exponential backoff. This keeps the analytics stream alive even if the network hiccups.

const PureCloud = require('genesyscloud-purecloud-platform-client-v2');
const client = new PureCloud.NotificationClient();

async function subscribeWithRetry(topic, callback, maxRetries = 10) {
 let retries = 0;
 
 const connect = () => {
 client.subscribe(topic, (payload) => {
 callback(payload);
 });

 // Critical: Handle disconnects explicitly
 client.on('close', (code, reason) => {
 console.warn(`WebSocket closed: ${code} - ${reason}`);
 if (retries < maxRetries) {
 const delay = Math.min(1000 * Math.pow(2, retries), 30000);
 setTimeout(() => {
 retries++;
 console.log(`Reconnecting... attempt ${retries}`);
 connect();
 }, delay);
 } else {
 console.error('Max retries reached');
 }
 });
 };

 connect();
}

// Usage
subscribeWithRetry('/api/v2/analytics/notifications', (data) => {
 // Push to Kafka here
 producer.send({ topic: 'genesys-analytics', messages: [{ value: JSON.stringify(data) }] });
});

Make sure your OAuth token has the analytics:notification:subscribe scope. If the token expires during the long-lived connection, the socket closes with a 401. You’ll need to refresh the token and re-init the client in the close handler if that happens. Don’t just restart the whole process.