Legacy Dev Forum Posts

 View Only

Sign Up

Issues Suppressing Logs After Successful Transfer in Genesys Cloud WebSocket Integration

  • 1.  Issues Suppressing Logs After Successful Transfer in Genesys Cloud WebSocket Integration

    Posted 06-05-2025 19:26

    Abrie | 2024-09-20 12:12:58 UTC | #1

    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:

    1. Using a Processed Conversations Set:
      • I introduced a Set called processedConversations 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.
    2. Adjusting the WebSocket Message Handler:
      • Modified the ws.on('message') handler to check if the conversation ID is in processedConversations before processing.
      • Attempted to suppress logs by returning early if the conversation was already processed.
    3. 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:

    1. How can I effectively suppress logging for a specific conversation after a successful transfer without breaking the application?
    2. Is there a better approach to detect that a conversation has been transferred and prevent further processing or logging for that conversation?
    3. 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!


    system | 2024-10-21 12:12:45 UTC | #2

    This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.


    This post was migrated from the old Developer Forum.

    ref: 29448