Hello everyone,
I'm working on a Node.js application that integrates with Genesys Cloud to monitor a queue for web messaging interactions via WebSocket. The main functionality is:
- When an interaction is received by a dummy agent and connected, it automatically transfers the interaction to another queue.
- This transfer is successful and allows the in-queue flow to process it accordingly.
The Issue:
After the transfer is completed, the application continues to log information about the specific conversation. I want to stop the logging for that conversation after the transfer is successful, but my attempts to implement this have either not worked or have broken the application.
What I've Tried:
- Using a Processed Conversations Set:
- I introduced a
Set
calledprocessedConversations
to keep track of conversations that have been transferred. - I tried adding the conversation ID to this set immediately upon detecting the conversation, and also after the transfer is completed.
- Despite this, the logs continue to show entries for the conversation after the transfer.
- Adjusting the WebSocket Message Handler:
- Modified the
ws.on('message')
handler to check if the conversation ID is inprocessedConversations
before processing. - Attempted to suppress logs by returning early if the conversation was already processed.
- Suppressing Logs After Transfer:
- I tried adding the conversation ID to a
suppressedConversations
set after a successful transfer and checking this set before logging. - This approach either didn't stop the logs or caused the application to stop processing events altogether.
Code Snippet:
Here is the relevant portion of my code:
// Set to track processed conversations
const processedConversations = new Set();
// WebSocket message handler
ws.on('message', async (message) => {
try {
const msgData = JSON.parse(message);
// Ignore heartbeats
if (msgData.eventBody && msgData.eventBody.message === 'WebSocket Heartbeat') {
return;
}
// Check if the event is for the monitored queue
if (msgData.topicName.includes(`v2.routing.queues.${queueIdToMonitor}.conversations`)) {
const conversationId = msgData.eventBody.id;
// If conversation has already been processed, skip it
if (processedConversations.has(conversationId)) {
return;
}
// Mark conversation as processed (I've tried placing this line here and after transfer)
// processedConversations.add(conversationId);
// Extract participants
const participants = msgData.eventBody.participants;
// Check for transfer events
const transferEvent = participants.some(
participant =>
participant.state === 'disconnected' &&
participant.disconnectType === 'transfer'
);
if (transferEvent) {
// Suppress further logging for this conversation
// processedConversations.add(conversationId);
return;
}
// Proceed with processing and logging
logger.info(`Conversation ID: ${conversationId}`);
// Check if customer participant is connected
const customerParticipant = participants.find(
(participant) =>
participant.purpose === 'customer' && participant.state === 'connected'
);
if (customerParticipant) {
await checkParticipantsConnected(conversationsApi, conversationId);
} else {
await fetchCustomerParticipant(conversationsApi, conversationId);
}
}
} catch (error) {
logger.error(`Error parsing WebSocket message: ${error.message}`, {
stack: error.stack,
});
}
});
// Function to check participants and perform transfer
async function checkParticipantsConnected(conversationsApi, conversationId, retryCount = 0, maxRetries = 12) {
try {
const conversationData = await apiCallWithRetry(
conversationsApi.getConversationsMessage.bind(conversationsApi),
[conversationId]
);
const customerParticipant = conversationData.participants.find(
(participant) => participant.purpose === 'customer' && participant.state === 'connected'
);
const agentParticipant = conversationData.participants.find(
(participant) => participant.purpose === 'agent' && participant.state === 'connected'
);
const flowParticipant = conversationData.participants.find(
(participant) => participant.purpose === 'acd' && participant.state === 'connected'
);
if (customerParticipant && agentParticipant && !flowParticipant) {
logger.info('Customer and connected agent found. Proceeding with transfer.');
const transferPayload = {
transferType: 'Unattended',
keepInternalMessageAlive: true,
queueId: targetQueueId,
voicemail: false,
};
try {
await apiCallWithRetry(
conversationsApi.postConversationsMessageParticipantReplace.bind(conversationsApi),
[conversationId, agentParticipant.id, transferPayload]
);
logger.info('Transfer successful.');
// Apply wrap-up code
const wrapupPayload = { code: defaultWrapupCodeId };
await apiCallWithRetry(
conversationsApi.postConversationsMessageParticipantWrapup.bind(conversationsApi),
[conversationId, agentParticipant.id, wrapupPayload]
);
// Mark conversation as processed to suppress further logging
processedConversations.add(conversationId);
} catch (error) {
logger.error(`Failed to transfer interaction: ${error.message}`);
}
} else if (retryCount < maxRetries) {
setTimeout(() => {
checkParticipantsConnected(conversationsApi, conversationId, retryCount + 1);
}, 5000);
} else {
logger.warn('Max retries reached. Unable to transfer the interaction.');
}
} catch (error) {
logger.error(`Error fetching conversation details: ${error.message}`);
}
}
Logs After Transfer:
Even after the transfer is completed, I continue to see logs like these:
[info]: Customer and connected agent found. Proceeding with transfer.
[info]: Transfer Payload: { ... }
[info]: Customer Participant Payload: { ... }
[info]: Agent Participant Payload: { ... }
[info]: Customer and connected agent found. Proceeding with transfer.
[info]: Transfer Payload: { ... }
Questions:
- How can I effectively suppress logging for a specific conversation after a successful transfer without breaking the application?
- Is there a better approach to detect that a conversation has been transferred and prevent further processing or logging for that conversation?
- Are there any known issues with handling WebSocket events in this context that might cause the suppression logic to fail?
Additional Information:
- The application is designed to automatically transfer interactions from a dummy agent to another queue once connected.
- I need to ensure that new interactions are still processed and logged appropriately.
- The suppression logic seems to either not work or stops the application from processing events altogether.
Any help or suggestions would be greatly appreciated!
Thank you in advance!