Workforce Engagement Management

 View Only

Discussion Thread View
  • 1.  Chat Utilization and Adherence

    Posted 03-05-2025 13:26

    When an agent goes to lunch or break and is taking two chats concurrently, the only way to stop additional chats from coming in is to go "off queue" or put themselves in "available." On busy days, the agents are struggling with maintaining their adherence because of going off queue or going into available while waiting for the other interaction to wrap up.

    My question: Is there a best practice or solution for the agents needing to go on break and not get another chat? Would it be best to have the agents stay in ACW for their first interaction while their second interaction is concluding? Any assistance would be greatly appreciated!


    #Monitoring/Adherence

    ------------------------------
    Amanda "Mandy" Frankeberger
    ------------------------------


  • 2.  RE: Chat Utilization and Adherence

    Posted 03-09-2025 20:12

    Hey Mandy, 

    This is a super interesting one - we (and I'm sure many others) have the same issue. 

    What we have done is;

    • We have a 10min "pre break" activity code (base code is busy) that an agent has on their roster before each break 
    • We have a system that automatically puts the agent into the "pre break" code - therefore stopping them from getting any interactions from that time and still ensuring all AHT metrics are correct 
    • Agent then puts themselves into break/meal when their last chat finishes. 

    It's not perfect, but it's better than the other way. You still get some exceptions if they finish quickly and then go on break early (and then finish early based on their actual break times) 

    Just an idea, I don't think there is another way that's built into Gen 



    ------------------------------
    Lawrence Drayton
    ------------------------------



  • 3.  RE: Chat Utilization and Adherence

    Posted 03-10-2025 04:56

    Something for the future may be to vote on this idea. It's not on the roadmap at present but some more interest may help it move. https://genesyscloud.ideas.aha.io/ideas/WEM-I-199 Workforce Routing: Target agents based on WFM schedules. The idea being when someone is near break and the next interaction would cause them to go out of adherence they would not be targeted.



    ------------------------------
    Richard Chandler
    Connect
    ------------------------------



  • 4.  RE: Chat Utilization and Adherence

    Posted 03-11-2025 13:19

    Hello Community,

    In addition to the idea Richard posted there is also this idea: https://genesyscloud.ideas.aha.io/ideas/DIG-I-347

    This idea is gaining traction and is currently under PM review.  



    ------------------------------
    Belinda Herrera
    Genesys, Staff Product Manager
    ------------------------------



  • 5.  RE: Chat Utilization and Adherence

    Posted 03-11-2025 12:29
    Edited by Gina Palmer 03-11-2025 12:33

    Hi @Lawrence Drayton,

    How did you set it up so that the agent is automatically put into the pre-break code?  Is this a Genesys radio-button thing that I just missed?



    ------------------------------
    Gina Palmer
    Manager, Workforce Management
    Papa, Inc.
    ------------------------------



  • 6.  RE: Chat Utilization and Adherence

    Posted 03-11-2025 18:06

    Hey @Gina Palmer

    Unfortunately not a Genesys out-of-the-box option, I have built a system that checks users, then gets all their IDs, calculates the correct date, pulls the agent schedules and then runs a bit of code to see at that time if there are any agents on queue that are <= 10 min away from a break, and then updates the agents presence. 

    Happy to share what I have done around this - you would just need a dev to slap together the components and host it somewhere it can run :)



    ------------------------------
    Lawrence Drayton
    ------------------------------



  • 7.  RE: Chat Utilization and Adherence

    Posted 03-14-2025 16:29

    Hi, @Lawrence Drayton! Thank you for your replies. Very helpful information you're sharing.

    Are you able to expand more on how you've set up this system that checks users? This is something we would like to explore with our setup.



    ------------------------------
    Amanda Frankeberger
    ------------------------------



  • 8.  RE: Chat Utilization and Adherence

    Posted 03-14-2025 18:35

    Hey @Amanda Frankeberger

    Sure thing! 

    This workflow automates updating agent presence statuses in Genesys Cloud to a 'Pre-Break' state based on their upcoming scheduled breaks. It's implemented using an internal platform called 'Integrate' (Based on N8N), leveraging HTTP calls and custom JavaScript logic.
     
    Workflow Steps
     
    1. Scheduled Trigger
    - Purpose:
    - Triggers the workflow at predefined intervals using a cron schedule.
      
    2. Fetch Active Users
    - Genesys Cloud API call:
      GET https://api.mypurecloud.com/api/v2/users?pageSize=100&expand=presence,routingStatus,integrationPresence,conversationSummary,profileSkills,groups&state=active
    - Authentication: OAuth2 credentials.
    - Retrieves active user details: presence, routing status, and conversations.
     
    3. Extract User Data
    - Code logic:
      - Processes user information, extracting relevant details:
        - User ID
        - User Name
        - System Presence
        - Routing Status
        - Active Conversations Count
        - Presence Definition (mapped to specific presence ID)
     
    - Logic to calculate active conversations/user information:
    javascript
    // Get the users from the previous node's response
    const users = items[0].json.entities;
     
    // Function to compute active conversations
    function getActiveConversations(conversationSummary) {
      let totalActiveConversations = 0;
     
      if (!conversationSummary) {
        return 0;
      }
     
      for (const mediaType in conversationSummary) {
        const mediaSummary = conversationSummary[mediaType];
     
        if (mediaSummary.contactCenter) {
          totalActiveConversations += mediaSummary.contactCenter.active || 0;
          totalActiveConversations += mediaSummary.contactCenter.acw || 0;
        }
     
        if (mediaSummary.enterprise) {
          totalActiveConversations += mediaSummary.enterprise.active || 0;
          totalActiveConversations += mediaSummary.enterprise.acw || 0;
        }
      }
     
      return totalActiveConversations;
    }
     
    // Extract user data
    const userData = users.map(user => {
      // Get the presenceDefinition id
      const presenceId = user.presence?.presenceDefinition?.id || null;
     
      // Map the presenceDefinition id to desired value
      let presenceDefinition = presenceId;
     
      if (presenceId === 'e3bedde6-f747-4dbb-bb76-45684b9180b6') {
        presenceDefinition = 'preBreak';
      }
     
      return {
        id: user.id,
        name: user.name,
        systemPresence: user.presence?.presenceDefinition?.systemPresence || null,
        routingStatus: user.routingStatus?.status || null,
        activeConversations: getActiveConversations(user.conversationSummary),
        presenceDefinition: presenceDefinition
      };
    });
     
    // Extract user IDs
    const userIds = userData.map(user => user.id);
     
    // Return the userData array and userIds
    return [
      {
        json: {
          userIds,
          userData
        }
      }
    ];
     
    3. Calculate Dates
    - Purpose:
      - Generates the current day's start and end times based on Sydney's local timezone.
      - Converts these times to UTC ISO format for Genesys API compatibility.
     
    - Key Functions:
    javascript
    const { DateTime } = require('luxon');
     
    // Get current date and time in Sydney timezone
    const nowSydney = DateTime.now().setZone('Australia/Sydney');
     
    // Start of the day in Sydney time
    const startSydney = nowSydney.startOf('day');
     
    // End of the day in Sydney time
    const endSydney = nowSydney.endOf('day');
     
    // Convert to UTC ISO strings
    const startDateUTC = startSydney.toUTC().toISO();
    const endDateUTC = endSydney.toUTC().toISO();
     
    // Return startDate and endDate
    return [
      {
        json: {
          startDate: startDateUTC,
          endDate: endDateUTC
        }
      }
    ];
     
    4. Retrieve Agent Schedules
    - Genesys Cloud API call:
      POST https://api.mypurecloud.com.au/api/v2/workforcemanagement/managementunits/{managementUnitId}/agentschedules/search
    - Payload:
    json
      {
        "startDate": "<UTC start date>",
        "endDate": "<UTC end date>",
        "userIds": [List of User IDs]
      }
    - Retrieves agent schedules within the defined Sydney time range.
     
    5. Determine Agents to Update
    - Logic:
      - Checks agent shifts occurring within the next 10 minutes.
      - Identifies agents who are currently "On Queue" (systemPresence = 'On Queue', routingStatus either 'IDLE' or 'INTERACTING').
      - Identifies agents scheduled for specific activities (activityCodeId '1' or '2') that warrant a pre-break status update.
     
    - Code snippet for filtering agents:
    javascript
     
    // Get the agent schedules from the 'Get Agent Schedules' node
    const agentSchedules = $node['Get Agent Schedules'].json.result.agentSchedules;
     
    // Get the user data from the 'Get User IDs' node
    const userData = $node['Get User IDs'].json.userData;
     
    // Ensure that userData is defined and is an array
    if (!Array.isArray(userData)) {
      throw new Error('userData is not an array. Check the output of the "Get User IDs" node.');
    }
     
    // Initialize an array to hold agents who need presence updates
    let agentsToUpdate = [];
     
    // Get current time in UTC
    const nowUTC = new Date();
     
    // Get time 15 minutes from now
    const nowPlus15 = new Date(nowUTC.getTime() + 10 * 60 * 1000);
     
    // Loop over each agent's schedule
    for (let agentSchedule of agentSchedules) {
      const userId = agentSchedule.user.id;
     
      // Find the user's data
      const user = userData.find(u => u.id === userId);
     
      if (!user) {
        continue; // User data not found
      }
     
      const systemPresence = user.systemPresence;
      const routingStatus = user.routingStatus;
     
      // Only proceed if the agent is 'On Queue'
      // Assuming 'On Queue' means systemPresence is 'On Queue' and routingStatus is 'IDLE' or 'INTERACTING'
      if (systemPresence !== 'On Queue' || (routingStatus !== 'IDLE' && routingStatus !== 'INTERACTING')) {
        continue; // Agent is not 'On Queue'
      }
     
      // Get the agent's shifts
      const shifts = agentSchedule.shifts;
     
      if (!shifts) {
        continue; // No shifts found for this agent
      }
     
      // Loop over each shift
      for (let shift of shifts) {
        // Get the activities within the shift
        const activities = shift.activities;
     
        if (!activities) {
          continue; // No activities found in this shift
        }
     
        // Loop over each activity
        for (let activity of activities) {
          const activityCodeId = activity.activityCodeId;
     
          // Check if activityCodeId is '1' or '2'
          if (activityCodeId === '1' || activityCodeId === '2') {
            // Get the activity start time
            const activityStart = new Date(activity.startDate);
     
            // Check if activity start time is within the next 15 minutes
            if (activityStart >= nowUTC && activityStart <= nowPlus15) {
              // Agent needs presence update
              agentsToUpdate.push({
                id: userId,
                presenceDefinition: {
                  id: 'e3bedde6-f747-4dbb-bb76-45684b9180b6' // Replace with your 'pre break' presence ID
                },
                source: 'PURECLOUD'
              });
     
              // Break the loop since we found a matching activity
              break;
            }
          }
        }
      }
    }
     
    // Return the agentsToUpdate array as a property of 'json'
    return [
      {
        json: {
          agentsToUpdate: agentsToUpdate
        }
      }
    ];
     
    6. Bulk Update Agent Presence
    - Genesys Cloud API call:
    - Request payload:
    json
    {{ JSON.stringify($json.agentsToUpdate) }}
    - Updates all selected agents' presence to "Pre Break".
     
    7. Conditional Execution (Switch Node)
    - Checks if the `agentsToUpdate` array is not empty before executing the update to avoid unnecessary API calls.
     
    Credentials
    - OAuth2 credentials are required and configured in n8n for authentication with the Genesys Cloud APIs.
     
    You'll need to create your activity code "pre break" Or whatever you want to call it, and use that in the presence definition when doing the bulk update.


    ------------------------------
    Lawrence Drayton
    ------------------------------



  • 9.  RE: Chat Utilization and Adherence

    Posted 03-20-2025 10:08

    You sure live up to your Community Rockstar title, Lawrence. Thank you!



    ------------------------------
    Linsey Edn
    Call Center Team Lead
    ------------------------------



Need Help finding something?

Check out the Genesys Knowledge Network - your all-in-one access point for Genesys resources