Queue Conversation with the longest duration Assistance

Hello,

Hoping for some advice and guidance.

I am trying to create a data action that checks all of the current calls that are in a queue and makes a decision based on the longest call in the queue.

How do I go about getting the longest call in a queue?

I am assuming that I can use /api/v2/analytics/conversations/details/query with the query below, or is there a better way?

{
 "interval": "2022-05-30T23:00:00.000Z/2022-05-31T23:00:00.000Z",
 "order": "asc",
 "orderBy": "conversationStart",
 "paging": {
  "pageSize": 25,
  "pageNumber": 1
 },
 "segmentFilters": [
  {
   "type": "or",
   "predicates": [
    {
     "type": "dimension",
     "dimension": "queueId",
     "operator": "matches",
     "value": "2bdc494e-3db9-4f53-8327-a6439d548a1c"
    }
   ]
  }
 ],
 "conversationFilters": [
  {
   "type": "or",
   "predicates": [
    {
     "type": "dimension",
     "dimension": "conversationEnd",
     "operator": "notExists",
     "value": null
    }
   ]
  }
 ]
}

Thank you.

This probably isn't quite what you want. This query will return conversations that have not ended and have been in the specified queue at any point. If you're looking for conversations that are waiting in queue, make the segment filter type and and add predicates for purpose: acd and segmentEnd not exists. That will make the segment match all three predicates. The conversation filter can then be removed as it's redundant.

For the longest conversation, you'll need to get all the results and sort them by the time the acd segment started.

Hi Tim,

Conversation Detail only returns total hits, therefore, I am unable to sort and then use a decision to do anything.

Is there another way?

Thank you

I'm not sure what you mean. POST /api/v2/analytics/conversations/details/query does have a property totalHits, but it also has a property conversations that contains a collection of conversation objects that you'd use for further inspection.

Ah apologies, It looks like I have 0 total hits and that would be why. :face_with_head_bandage:

Hi Tim,

What would be the most efficient way to get the list sorted as I cannot sort the results by with segmentEnd as they do not have a segmentEnd as yet.

I do get the response now just struggling with the remaining portion to complete this.

thank you.

I just saw this in your previous post.

Yeah I am stuck at the moment.

This is the query that I am using currently.

{
 "interval": "2022-06-08T23:00:00.000Z/2022-06-09T23:00:00.000Z",
 "order": "desc",
 "orderBy": "conversationStart",
 "paging": {
  "pageSize": 25,
  "pageNumber": 1
 },
 "segmentFilters": [
  {
   "type": "and",
   "predicates": [
    {
     "type": "dimension",
     "dimension": "queueId",
     "operator": "matches",
     "value": "e1a1b5ff-6ad9-4547-a407-b16e229b4c82"
    },
    {
     "type": "dimension",
     "dimension": "purpose",
     "operator": "matches",
     "value": "acd"
    }
   ]
  }
 ],
 "conversationFilters": [
  {
   "type": "and",
   "predicates": [
    {
     "type": "dimension",
     "dimension": "conversationEnd",
     "operator": "notExists",
     "value": null
    }
   ]
  }
 ]
}

Don't forget the segmentEnd predicate.

What are you stuck on?

Thank you very much!!! This seams to do the trick

{
 "interval": "2022-06-08T23:00:00.000Z/2022-06-09T23:00:00.000Z",
 "order": "desc",
 "orderBy": "conversationStart",
 "paging": {
  "pageSize": 25,
  "pageNumber": 1
 },
 "segmentFilters": [
  {
   "type": "and",
   "predicates": [
    {
     "type": "dimension",
     "dimension": "queueId",
     "operator": "matches",
     "value": "e1a1b5ff-6ad9-4547-a407-b16e229b4c82"
    },
    {
     "type": "dimension",
     "dimension": "purpose",
     "operator": "matches",
     "value": "acd"
    },
    {
     "type": "dimension",
     "dimension": "segmentEnd",
     "operator": "notExists",
     "value": null
    }
   ]
  }
 ],
 "conversationFilters": [
  {
   "type": "and",
   "predicates": [
    {
     "type": "dimension",
     "dimension": "conversationEnd",
     "operator": "notExists",
     "value": null
    }
   ]
  }
 ]
}

I will continue with the flow and expressions and see how I get on.

I assume that I would need to have an out for conversationStart and then use an expression to calculate the duration?

would you be able to help me with the mapping by any chance>

This is failing

{
  "translationMap": {
    "totalHits": "$.totalHits",
    "conversationStart": "$.conversationStart"
  },
  "translationMapDefaults": {},
  "successTemplate": "{\n   \"calls\": ${conversationStart}\n}"
}

Oh, I didn't catch that you were doing this for a data action. I'm not sure if you can do this purely in Architect. I don't work with JSONPath expressions or Architect much; let me tag in some other folks.

thank you very much. Appreciate it. I have the same post in the data action category, however, no replies except for one stating that I should also post it here in the analytics and reporting category. I should have mentioned in the initial post, thanks again.

Hello,

Using Conversation Details Query:
POST /api/v2/analytics/conversations/details/query

If you are looking for the oldest conversations (when conversation started), which are currently in queue, you have to use an:
"order": "asc",
"orderBy": "conversationStart",

If you only need to retrieve the oldest conversation, which is currently in queue, you could limit the results to 1 with:
"paging": {
"pageSize": "1",
"pageNumber": 1
},

I would also recommend to use a filter on mediaType (as you mention "calls") - so that it only looks at the oldest voice conversations (if your Queueu manages multiple media types).

Conversation Details Query example for the 25 oldest conversations, currently in queue:

{
 "interval": "YOUR_INTERVAL",
 "order": "asc",
 "orderBy": "conversationStart",
 "paging": {
  "pageSize": "25",
  "pageNumber": 1
 },
 "segmentFilters": [
  {
   "type": "and",
   "predicates": [
    {
     "type": "dimension",
     "dimension": "queueId",
     "operator": "matches",
     "value": "YOUR_QUEUE_ID"
    },
    {
     "type": "dimension",
     "dimension": "purpose",
     "operator": "matches",
     "value": "acd"
    },
    {
     "type": "dimension",
     "dimension": "segmentEnd",
     "operator": "notExists",
     "value": null
    },
    {
     "type": "dimension",
     "dimension": "mediaType",
     "operator": "matches",
     "value": "voice"
    }
   ]
  }
 ],
 "conversationFilters": [
  {
   "type": "or",
   "predicates": [
    {
     "type": "dimension",
     "dimension": "conversationEnd",
     "operator": "notExists",
     "value": null
    }
   ]
  }
 ]
}

Data Action Contract and Configuration - oldestTimes and oldestConversations output parameter as arrays:

{
  "config": {
    "request": {
      "requestUrlTemplate": "/api/v2/analytics/conversations/details/query",
      "requestType": "POST",
      "headers": {
        "Content-Type": "application/json"
      },
      "requestTemplate": "{\n    \"interval\": \"${input.interval}\",\n    \"order\": \"asc\",\n    \"orderBy\": \"conversationStart\",\n    \"paging\": {\n        \"pageSize\": \"25\",\n        \"pageNumber\": 1\n    },\n    \"segmentFilters\": [\n        {\n            \"type\": \"and\",\n            \"predicates\": [\n                {\n                    \"type\": \"dimension\",\n                    \"dimension\": \"queueId\",\n                    \"operator\": \"matches\",\n                    \"value\": \"${input.queueId}\"\n                },\n                {\n                    \"type\": \"dimension\",\n                    \"dimension\": \"purpose\",\n                    \"operator\": \"matches\",\n                    \"value\": \"acd\"\n                },\n                {\n                    \"type\": \"dimension\",\n                    \"dimension\": \"segmentEnd\",\n                    \"operator\": \"notExists\",\n                    \"value\": null\n                },\n                {\n                    \"type\": \"dimension\",\n                    \"dimension\": \"mediaType\",\n                    \"operator\": \"matches\",\n                    \"value\": \"voice\"\n                }\n            ]\n        }\n    ],\n    \"conversationFilters\": [\n        {\n            \"type\": \"or\",\n            \"predicates\": [\n                {\n                    \"type\": \"dimension\",\n                    \"dimension\": \"conversationEnd\",\n                    \"operator\": \"notExists\",\n                    \"value\": null\n                }\n            ]\n        }\n    ]\n}"
    },
    "response": {
      "translationMap": {
        "nbHits": "$.totalHits",
        "timeStartArray": "$.conversations[*].conversationStart",
        "convIdArray": "$.conversations[*].conversationId"
      },
      "translationMapDefaults": {
        "nbHits": "0",
        "timeStartArray": "[]",
        "convIdArray": "[]"
      },
      "successTemplate": "{ \"nbWaiting\": ${nbHits}, \"oldestTimes\": ${timeStartArray}, \"oldestConversations\": ${convIdArray} }"
    }
  },
  "contract": {
    "input": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "interval": {
            "type": "string"
          },
          "queueId": {
            "type": "string"
          }
        },
        "additionalProperties": true
      }
    },
    "output": {
      "successSchema": {
        "type": "object",
        "properties": {
          "nbWaiting": {
            "type": "integer"
          },
          "oldestTimes": {
            "type": "array",
            "items": {
              "title": "Item 1",
              "type": "string"
            }
          },
          "oldestConversations": {
            "type": "array",
            "items": {
              "title": "Item 1",
              "type": "string"
            }
          }
        },
        "additionalProperties": true
      }
    }
  }
}

Conversation Details Query for the oldest conversation, currently in queue (only one returned)

Data Action Contract and Configuration - oldestTime and oldestConversation output parameter as strings:

{
  "config": {
    "request": {
      "requestUrlTemplate": "/api/v2/analytics/conversations/details/query",
      "requestType": "POST",
      "headers": {
        "Content-Type": "application/json"
      },
      "requestTemplate": "{\n    \"interval\": \"${input.interval}\",\n    \"order\": \"asc\",\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\": \"queueId\",\n                    \"operator\": \"matches\",\n                    \"value\": \"${input.queueId}\"\n                },\n                {\n                    \"type\": \"dimension\",\n                    \"dimension\": \"purpose\",\n                    \"operator\": \"matches\",\n                    \"value\": \"acd\"\n                },\n                {\n                    \"type\": \"dimension\",\n                    \"dimension\": \"segmentEnd\",\n                    \"operator\": \"notExists\",\n                    \"value\": null\n                },\n                {\n                    \"type\": \"dimension\",\n                    \"dimension\": \"mediaType\",\n                    \"operator\": \"matches\",\n                    \"value\": \"voice\"\n                }\n            ]\n        }\n    ],\n    \"conversationFilters\": [\n        {\n            \"type\": \"or\",\n            \"predicates\": [\n                {\n                    \"type\": \"dimension\",\n                    \"dimension\": \"conversationEnd\",\n                    \"operator\": \"notExists\",\n                    \"value\": null\n                }\n            ]\n        }\n    ]\n}"
    },
    "response": {
      "translationMap": {
        "nbHits": "$.totalHits",
        "timeStart": "$.conversations[0].conversationStart",
        "convId": "$.conversations[0].conversationId"
      },
      "translationMapDefaults": {
        "nbHits": "0",
        "timeStart": "\"\"",
        "convId": "\"\""
      },
      "successTemplate": "{ \"nbWaiting\": ${nbHits}, \"oldestTime\": ${timeStart}, \"oldestConversation\": ${convId} }"
    }
  },
  "contract": {
    "input": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "interval": {
            "type": "string"
          },
          "queueId": {
            "type": "string"
          }
        },
        "additionalProperties": true
      }
    },
    "output": {
      "successSchema": {
        "type": "object",
        "properties": {
          "nbWaiting": {
            "type": "integer"
          },
          "oldestTime": {
            "type": "string"
          },
          "oldestConversation": {
            "type": "string"
          }
        },
        "additionalProperties": true
      }
    }
  }
}

Using Queue Observation Query:
POST /api/v2/analytics/queues/observations/query

You could also use a Queue Observation Query, if you are interested in the longest time in Queue.
What I mean is that:
A customer (Customer 1) calls; the call is put into a Queue for 3 mn; the customer is connected to an Agent.
A second customer (Customer 2) calls; the call is put into a Queue.
While Customer 2 is waiting in the Queue, the Agent transfers Customer 1 back to the Queue.

With the Conversation Details Query from above, you would capture Customer 1 as the oldest call.
With the Queue Observation Query, you can capture Customer 2 as the oldest call in this Queue.

Note that the query response will include a list of ongoing observations with up to 50 oldest and up to 50 newest observations.

Here is an example of Data Action only getting the oldest observation.
To retrieve multiples, the approach may be different than the one I have used for Conversation Details Query above. In theory, the Observation Query could retrieve up to 100 values. I have never tried in Architect if that would be a problem for a Collection of Strings.

Queue Observation Query example:

{
    "filter": {
       "type": "and",
       "predicates": [
          {
      "type": "dimension",
      "dimension": "queueId",
      "operator": "matches",
      "value": "YOUR_QUEUE_ID"
     },
     {
      "type": "dimension",
      "dimension": "mediaType",
      "operator": "matches",
      "value": "chat"
     }
       ]
    },
    "metrics": ["oWaiting"],
    "detailMetrics": ["oWaiting"]
}

Data Action Contract and Configuration:

{
  "config": {
    "request": {
      "requestUrlTemplate": "/api/v2/analytics/queues/observations/query",
      "requestType": "POST",
      "headers": {
        "Content-Type": "application/json"
      },
      "requestTemplate": "{\n    \"filter\": {\n        \"type\": \"and\",\n        \"predicates\": [\n            {\n                \"type\": \"dimension\",\n                \"dimension\": \"queueId\",\n                \"operator\": \"matches\",\n                \"value\": \"${input.queueId}\"\n            },\n            {\n                \"type\": \"dimension\",\n                \"dimension\": \"mediaType\",\n                \"operator\": \"matches\",\n                \"value\": \"voice\"\n            }\n        ]\n    },\n    \"metrics\": [\n        \"oWaiting\"\n    ],\n    \"detailMetrics\": [\n        \"oWaiting\"\n    ]\n}"
    },
    "response": {
      "translationMap": {
        "nbHits": "$.results[0].data[0].stats.count",
        "timeQueued": "$.results[0].data[0].observations[0].observationDate",
        "convId": "$.results[0].data[0].observations[0].conversationId"
      },
      "translationMapDefaults": {
        "nbHits": "0",
        "timeQueued": "\"\"",
        "convId": "\"\""
      },
      "successTemplate": "{ \"nbWaiting\": ${nbHits}, \"oldestTime\": ${timeQueued}, \"oldestConversation\": ${convId} }"
    }
  },
  "contract": {
    "input": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "queueId": {
            "type": "string"
          }
        },
        "additionalProperties": true
      }
    },
    "output": {
      "successSchema": {
        "type": "object",
        "properties": {
          "nbWaiting": {
            "type": "integer"
          },
          "oldestTime": {
            "type": "string"
          },
          "oldestConversation": {
            "type": "string"
          }
        },
        "additionalProperties": true
      }
    }
  }
}

Regards,

1 Like

HI Jerome,

Thank you very much, this is exactly what I needed.

Thanks again.

Chris Carr

The only issue I am having is that I cannot use DateTimeDiff() with strings in my expression.

I believe you can use the ToDateTime function to convert a date time string to a DateTime typed variable.

Thanks Tim, I did give that a try before my post:
image