Hi David.
For the second data action, to query multiple queues, you'd need to convert the array of queue IDs into an array of predicates that could be included in the request body. Unfortunately I don't know of a way to do that in the data action itself, so your best option is probably to build up the predicate expression in architect before you call the second data action.
E.g. Your architect flow would take the IDs returned from the first data action, then loop through them and convert them into one of the following: ideally (a) an array of predicates; or if you can't get that to work, (b) a single string containing the predicate expression which you can embed into the request body; or worst case, (c) a single string containing the entire request body [to use in the second data action]. (Sorry I'd like to tell you which option would work best but without actually creating all this stuff myself I don't know the answer.)
Taking the optimistic approach and going with option (a), then the architect flow would create an array of predicate objects that would look something like this:
[
{
"type": "dimension",
"dimension": "queueId",
"operator": "matches",
"value": "<queue-id-1>"
},
{
"type": "dimension",
"dimension": "queueId",
"operator": "matches",
"value": "<queue-id-2>"
}
]
The above array would be passed into the second data action, and you'd embed it in the response body using something like this:
{
"filter": {
"type": "and",
"predicates": [
{
"type": "dimension",
"dimension": "mediaType",
"operator": "matches",
"value": "voice"
}
],
"clauses": [
{
"type": "or",
"predicates": ${input.predicateArray}
}
]
},
"metrics": [
"oWaiting",
"oAlerting",
"oInteracting"
]
}
Also since the data action response will contain multiple queue statistics, you'll want to get rid of $successTemplateUtils.firstFromArray() from your successTemplate, and aggregate them in the translationMap using the sum function. So your response definition might look something like this:
{
"translationMap": {
"waiting": "$.sum($.results[*].data[?(@.metric=='oWaiting')].stats.count)",
"interacting": "$.sum($.results[*].data[?(@.metric=='oInteracting')].stats.count)",
"alerting": "$.sum($.results[*].data[?(@.metric=='oAlerting')].stats.count)"
},
"translationMapDefaults": {
"waiting": "0",
"interacting": "0",
"alerting": "0"
},
"successTemplate": "{ \"WaitingCount\": ${waiting}, \"AlertingCount\": ${alerting}, \"InteractingCount\": ${interacting} }"
}
NB: I've used $.sum(...) rather than tacking .sum() on at the end of each line because it better handles the case where the stat isn't present. Having said that though, the translationMapDefaults above also deal with this situation, so it is really just a matter of taste.
Hopefully this all makes some sense? I'd suggest you implement these recommendations incrementally to make it easier to detect syntactical errors that I might have made above?
Nick.
------------------------------
Nick Tait
Genesys Consultant
------------------------------
Original Message:
Sent: 04-03-2025 09:41
From: David Mann
Subject: Get Metrics for all current queues
Hello all,
Hope your having a good week.
We are in need of your help. We currently have 195 Sip Trunks, with a 100% redundancy. meaning we have 390 available Sip trunks for taking calls.
If a major event drives high call volumes across the trunk, the current solution would stop calls over a limit however this is agnostic of the Business Unit. This means that an issue in one Business Unit could stop all calls into another Business Unit.
PROPOSAL OVERVIEW
The proposal is to implement a queue limit solution. As a standard call flow feature, Genesys Cloud allows you to natively determine the position of a call within a queue which allows you to gauge the depth of a queue when a call is first placed into a queue. However, this functionality wouldn't be suitable for building a solution to manage surge scenarios for a couple of reasons, firstly a typical surge event impacts more than one queue at a time and secondly it isn't only calls currently queuing that consume a trunk.
The proposal is to group a series of queues together that represent either a business unit or a function within a business unit and then consider these as a collective to understand how many calls are queueing, interacting and alerting as a total "in queue" figure. Each business unit or function can then have an "in queue" limit applied on it, where if they go over then new calls will be played a prompt (such as "sorry we're experiencing exceptionally high volume at the moment and cannot currently take your call, please visit our self-service portal or try again later") and then the call is disconnected to free up trunk capacity.
There are a couple of points to note. Firstly, the efficacy of the solution will depend on new queues being configured correctly so that they are part of this process. Secondly, the limit will only take place once a call is delivered to a queue, i.e. where there is an IVR configured, once an
option has been chosen. This means that where a business unit is above their threshold, customers will still be able to dial in and navigate IVRs and therefore they will still be able to consume a small number of trunks above the threshold that is set.
DESIGN OVERVIEW
DATA TABLE
A new data table is required to hold the queue group surge limits, this will be used to control how many concurrent calls will be allowed per group of queues before gracefully disconnecting new ones. The lookup column for this table should be the Group Name (to match the naming convention in the queue names), a column for the surge limits (which will hold an integer value for the number of calls allowed per group) and a column for the name of the prompt to play should the limits be reached, this allows a bespoke message per group of queues.
DATA ACTION
A couple of data actions will be required to get the number of calls active on a queue: A data action that calls the Genesys API: GET /api/v2/routing/queues, allowing an input of the Group Name and passing the output as an array of queue id's associated with the Group Name.
A data action that calls the Genesys API: POST /api/v2/analytics/queues/observations/query, allowing an input of the list of queue id's and passing the output as an array of the number waiting, interacting and alerting.
FLOW
This feature should be added into your Inbound call flow, after the queue to route to has been
defined but before routing to that queue. Using the queue that will be routed to, determine the
Group Name. The group will be everything before the first "_" in the queue name.
With the Group Name determined, call the first data action built to get the queue ID's related to
it. Pass in the Group Name and get the queue id's back that are associated with the group.
Transform the list of ID's into JSON a string so that it can be passed into the second data action.
Pass in this JSON string and get the number waiting, interacting and alerting back.
Sum the waiting, interacting and alerting to get the current queue group depth, and determine if
the limit for the queue group is exceeded by comparing the the values in the data table.
If the limit is exceeded then play the prompt named in the data table and terminate the call.
PROGRESS SO FAR
We have made the Datable, very simple. But we struggled on the Data actions as we had no experience making these. This is where we need your help.
We have created a Data action which grabs all Queue Id's and outputs it as an array.
But the second Data action is a bit tricky for us, We can't seem to figure out the correct way to grab all those queue Id's and get the metrics for it. We have managed to create a Data Action which works but ONLY for one queue at a time, by having a single string input for one queue which then outputs the Metrics we need (WaitingCount, AlertingCount, InteractingCount).
How do we create this data action to grab all the queues the previous one got for us and then Sum up the queues and give us a total Number at the end which we can play with?
DATA ACTION
Request body
{ "filter": { "type": "and", "predicates": [ { "type": "dimension", "dimension": "mediaType", "operator": "matches", "value": "voice" }, { "type": "dimension", "dimension": "queueId", "operator": "matches", "value": "${input.QueueID}" } ] }, "metrics": [ "oWaiting", "oAlerting", "oInteracting" ]}
Response
{ "translationMap": { "waiting": "$.results[*].data[?(@.metric=='oWaiting')].stats.count", "interacting": "$.results[*].data[?(@.metric=='oInteracting')].stats.count", "alerting": "$.results[*].data[?(@.metric=='oAlerting')].stats.count" }, "translationMapDefaults": {}, "successTemplate": "{\"WaitingCount\":$successTemplateUtils.firstFromArray(${waiting}),\"AlertingCount\":$successTemplateUtils.firstFromArray(${alerting}),\"InteractingCount\":$successTemplateUtils.firstFromArray(${interacting})}"}

#API/Integrations
#ArchitectureandDesign
------------------------------
David Mann
na
------------------------------