Struggling to figure out why my WebSocket subscription to conversation events is failing with a 1006 close code right after the authentication handshake completes, despite using valid OAuth tokens generated via grant_type=client_credentials.
- I am building a service in Node.js to monitor inbound message flows for real-time status updates, specifically targeting the
conversation:conversation:updated event type to trigger downstream API calls.
- The connection to
wss://<org-id>.mypurecloud.com/websocket establishes successfully, and I send the initial auth message with the access_token in the token field within the data object.
- The server responds with an
auth-success message, confirming the token is valid and the scopes (view:conversation, view:notification) are present.
- Immediately after, I send the
subscribe message with the event_type set to conversation:conversation:updated and the id set to the specific conversation ID I want to track.
- The server acknowledges the subscription with an
subscribe-success response, but within milliseconds, the connection closes with code 1006 (Abnormal Closure) and no error message body is returned.
- I have verified the
origin header matches the registered domain in the Developer Portal, and the user-agent is set correctly.
- My JSON payload for the subscribe message looks like this:
{
"id": "sub-1",
"event_type": "conversation:conversation:updated",
"id": "conv-12345"
}
- I suspect there might be an issue with how I am handling the message framing or the sequence of messages, but the docs suggest
auth then subscribe is sufficient.
- Is there a specific rate limit or a missing header in the
subscribe payload that causes an immediate drop?
- I am running this from an AWS Lambda environment in
ap-northeast-1, which might affect latency, but the immediate drop suggests a protocol violation rather than a timeout.
- Any insights on debugging the
1006 closure in this context would be appreciated, especially if there are known issues with the conversation:updated event schema.
The quickest way to solve this is ensuring your token includes the notification:websocket:read scope. Client credentials tokens often lack this by default. Switch to resource owner password or add the scope if using custom grants.
- Verify token scopes via
/api/v2/oauth2/introspect
- Check WebSocket URL format
- Review server-side logging
This looks like a scope configuration issue rather than a network timeout. The client credentials flow often misses the required websocket permissions by default.
Check your token introspection results. You likely need notification:websocket:read explicitly added to your app’s scopes in the developer portal before generating the token.
Here is how to verify the active scopes on your current token:
curl -X POST https://api.mypurecloud.com/api/v2/oauth2/introspect \
-H "Authorization: Basic {client_id}:{client_secret}" \
-d "token={access_token}"
Have you tried validating the WebSocket handshake payload against the strict schema requirements? The suggestion above correctly identifies notification:websocket:read as a required scope, but 1006 errors often stem from malformed subscription requests immediately following authentication. Genesys Cloud drops the connection silently if the initial subscribe message lacks the mandatory filter object or uses an invalid event type path.
Ensure your Node.js client sends a valid JSON subscription request immediately after the WebSocket open event. Do not send raw strings. The server expects a specific structure. If you send an empty payload or omit the id field, the server closes the socket without a descriptive close frame, resulting in the generic 1006 error.
Here is the correct payload structure for subscribing to conversation updates:
const subscriptionMessage = {
"id": "ws-sub-001",
"type": "subscribe",
"filter": {
"eventTypes": ["conversation:conversation:updated"],
"entities": [] // Optional: specific entity IDs if not subscribing to all
}
};
ws.on('open', () => {
ws.send(JSON.stringify(subscriptionMessage));
});
ws.on('message', (data) => {
const msg = JSON.parse(data);
if (msg.type === 'confirmation') {
console.log('Subscription confirmed for event:', msg.filter.eventTypes[0]);
}
});
Also, verify your OAuth token expiration. If the token expires during the initial handshake, the server may terminate the connection abruptly. Use /api/v2/oauth2/introspect to confirm the exp claim is valid for at least 10 minutes. If you are using client credentials, ensure the token generation endpoint is not returning a short-lived token by mistake. Check the exp timestamp in the introspection response. If the token is invalid, the WebSocket server will reject the handshake or drop it instantly.
You might want to check at your local Docker Compose environment’s clock synchronization before implementing complex deduplication logic. In my intermediate experience with Terraform CX-as-Code deployments, t…
When mocking the Genesys Cloud Notification API, the websocket server often rejects tokens if the nbf (not before) claim is slightly ahead of the container’s system clock. This causes the 1006 close code immediately after handshake.
Ensure your mock service validates the JWT timestamp against the host system clock. Here is the docker-compose.yml snippet to sync time:
services:
mock-gc:
image: gc-mock-server:latest
environment:
- TZ=America/Los_Angeles
- JWT_VALIDATION_MODE=strict
volumes:
- /etc/localtime:/etc/localtime:ro
Verify the token introspection endpoint returns the notification:websocket:read scope. If the scope is present but the connection still drops, check the initial subscription payload. The mock server expects a valid JSON object with a filter key. Missing this key triggers an immediate disconnect in strict mode.