Hello,
I am not expert on Data Actions, but I've tried to investigate the topic following your question.
I have managed to get the last agent userId the following way.
- To explain why your JSONPath expression is failing.
Even if you may retrieve only one userId, filtering your "participants" array, as the filter is applied to an array, the result is an array of strings, and not a string.
So you would have to store the result of that JSONPath expression in a variable (output contract) defined as array.
In order to define an array variable, you have to both set the type to array AND provide a definition for the array items.
Like this:
"UserIdArray": {
"type": "array",
"items": {
"title": "UserId",
"type": "string"
}
}
- The Analytics Query
This what I have used for my Analytics Query (POST /api/v2/analytics/conversations/details/query)
{
"interval": "${input.INTERVAL}",
"order": "desc",
"orderBy": "conversationStart",
"paging": {
"pageSize": 1,
"pageNumber": 1
},
"segmentFilters": [
{
"type": "and",
"predicates": [
{
"type": "dimension",
"dimension": "mediaType",
"operator": "matches",
"value": "voice"
},
{
"type": "dimension",
"dimension": "purpose",
"operator": "matches",
"value": "agent"
},
{
"type": "dimension",
"dimension": "ani",
"operator": "matches",
"value": "tel:${input.ANI}"
}
]
}
]
}
Few comments on this one:
- Note that the maximum duration of the Interval is one month.
- I have set the "order" attribute to "desc" so that most recent conversations are at the beginning of the conversations array (most recent to oldest conversations)
- I have set "pageSize" to 1 so I have only two possible outcomes of my query: no conversation found, or just one (most recent call/conversation for this ANI)
- In my predicates (using "and" condition), I have checked:
-- mediaType=voice (to avoid getting a web callback conversation)
-- purpose=agent (to make sure this was a call which was connected to an agent - and not a call in self-service IVR/Bot or a call abandoned in a Queue before reaching an agent)
-- ani=tel:${input.ANI} (you may adapt this to your environment - in mine, the ANI will appear as "tel:+33123456789" in the conversation details) - I have set the "tel:" in the request to provide just the ANI as input in the Architect flow)
- The Data Action contracts and configurations
In the following Data Action, I am using 2 things:
- NBFOUND in the Output Contract is there so that I can easily check if the query returned 0 or 1 conversation in my Architect Flow.
In both case the Data Action request is considered as successful (Success path on the Data Action), so I needed something simple to check if it was necessary to analyze the UserIdArray (NBFOUND == 1) or not (NBFOUND == 0)
- ARRAYUSERID is defined as an array.
As explained above, it is there so that my JSONPath expression can leverage a filter on the participants array.
But there is an additonnal reason. You could have a call that gets connected to Agent1. Agent1 then transfers the call to another Agent, or to a Queue that could deliver the call to an agent (Agent2, or even Agent1 again).
So what I'm just trying to say is that there could be multiple participants of type agent in the conversation.
I have preferred to leverage purpose == agent in my filter, in case the call was transferred to a PureCloud user (just regular telephony enabled user - internal user - non agent).
Input Contract:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Search for Previous Conversations By ANI",
"description": "Get previous conversations for the given ANI.",
"type": "object",
"properties": {
"INTERVAL": {
"description": "The time interval to search",
"type": "string",
"minLength": 1
},
"ANI": {
"description": "The ANI of the caller",
"type": "string",
"minLength": 1
}
},
"additionalProperties": true
}
I have defined the input variables with minLength = 1.
This is just to avoid an error in the Architect Flow, where by mistake, an empty string would be passed to the Data Action (via a variable).
Output Contract:
{
"type": "object",
"properties": {
"ARRAYUSERID": {
"type": "array",
"items": {
"title": "USERID",
"type": "string"
}
},
"ARRAYPARTICIPANTID": {
"type": "array",
"items": {
"title": "PARTICIPANTID",
"type": "string"
}
},
"NBFOUND": {
"type": "integer"
}
},
"additionalProperties": true
}
The ARRAYPARTICIPANTID is not necessary. I just used it to make sure my data action was working properly, in case the same agent was connected twice to the call (same userId, but different participantId).
Input Configuration:
{
"requestUrlTemplate": "/api/v2/analytics/conversations/details/query",
"requestType": "POST",
"headers": {
"Content-Type": "application/json"
},
"requestTemplate": "{\n \"interval\": \"${input.INTERVAL}\",\n \"order\": \"desc\",\n \"orderBy\": \"conversationStart\",\n \"paging\": {\n \"pageSize\": 1,\n \"pageNumber\": 1\n },\n \"segmentFilters\": [\n {\n \"type\": \"and\",\n \"predicates\": [\n {\n \"type\": \"dimension\",\n \"dimension\": \"mediaType\",\n \"operator\": \"matches\",\n \"value\": \"voice\"\n },\n {\n \"type\": \"dimension\",\n \"dimension\": \"purpose\",\n \"operator\": \"matches\",\n \"value\": \"agent\"\n },\n {\n \"type\": \"dimension\",\n \"dimension\": \"ani\",\n \"operator\": \"matches\",\n \"value\": \"tel:${input.ANI}\"\n }\n ]\n }\n ]\n}"
}
Output Configuration:
{
"translationMap": {
"ARRAYUSERID": "$.conversations[0].participants[?(@.purpose ==\"agent\")].userId",
"ARRAYPARTICIPANTID": "$.conversations[0].participants[?(@.purpose ==\"agent\")].participantId",
"NBFOUND": "$.conversations.length()"
},
"translationMapDefaults": {
"ARRAYUSERID": "[]",
"ARRAYPARTICIPANTID": "[]",
"NBFOUND": "0"
},
"successTemplate": "{\n \"ARRAYUSERID\": ${ARRAYUSERID}\n, \"ARRAYPARTICIPANTID\": ${ARRAYPARTICIPANTID}\n, \"NBFOUND\": ${NBFOUND}\n}"
}
I can use .conversations[0] as I have limited the analytics query to return 1 result max (pageSize = 1).
I have also leveraged the translationMapDefaults - specifically for the NBFOUND - so it returns 0 if it can't "find" .conversations.
Indeed, if there are 0 matching conversations, the result of the analytics query is just {}.
- The Architect Flow
We are almost there..
As I couldn't find a way to just get the last element of the ARRAYUSERID directly in the Data Action (there is maybe a way via Data Action configuration - but I personally couldn't find one quickly), I found it was faster to perform this in the Architect flow.
Note that the items in the ARRAYUSERID will be from oldest agent participant in the conversation (index 0) to the most recent (last element/item of the array).
In order to store the ARRAYUSERID output from the data action, I have used a variable which is defined as a Collection of Strings (it is important to set it this way - as it needs to store an array of strings).
My variable was named: Flow.MyUserIds (used in the expression below)
In case NBFOUND == 1, I am retrieving the last element of the array with the following expression:
GetAt(Flow.MyUserIds, Count(Flow.MyUserIds) - 1)
Hope this helps.
Regards,
Jerome