Looking for PowerObjects? Don’t worry, you’re in the right place! We’ve been part of HCL for several years, and we’ve now taken the final step in our acquisition journey: moving our website to the HCL domain. Nothing else is changing – we are still fanatically focused on Microsoft Business Applications!

PowerObjects Blog 

for Microsoft Business Applications

|

Extending Customer Voice and Omnichannel to report on Agent and Queue Satisfaction

Post Author: Jay Leffue |

Omnichannel for Customer Service has a great out-of-the-box configuration using Microsoft Customer Voice to present a post-conversation survey once an Omnichannel session has ended. You can find the documentation for this implementation here.

While Customer Voice is a useful tool, the out-of-the-box version does not link to the conversation. Thus, if an Omnichannel Manager would like to get survey metrics about the satisfaction of their agents, or of queues that they manage, there is not an easy was to pull the data today. The actual survey responses from the end user are all stored in a json object array on the “Customer Voice Survey Response” table, so we will need to parse json to read the responses. The information to link a Survey Response to a conversation is stored in json on another related table, the “Survey Invite,” that is automatically created when a chat session ends. So, most of the work is just parsing json in Power Automate which is easily accomplished.

1. Customize the Customer Voice Survey Response Table

In a solution for custom development add the Customer Voice Survey Response Table. Also add the Main Form for the table in this step.

For this example, we are looking to have a rollup Aggregate CSAT score for all the questions that were asked on the survey - this could be used for other metrics, as well.

Create a new column called “Average CSAT” that is a Floating Point Number as shown in the following image:

 

Next, create a column called “Conversation” that is a Lookup to the Conversation table:

 

Add the two new fields to the main form so your users can see the information, then save and publish your changes. This is all the table customization needed!

2. Create the Power Automate Flow

Now that we have the necessary data structures in place, the only thing left to do is create a flow that runs whenever a new Customer Voice Survey Response is created in the system. You can rename the steps to something appropriate, but for this tutorial they will remain as the out-of-the-box titles for demonstration purposes.

To do this, navigate to https://flow.microsoft.com and open the same solution your customizations were made in. Create a new Cloud Flow called “Customer Voice Survey Response – Create – Aggregate CSAT”.

The trigger for this flow will be the Microsoft Dataverse trigger “When a row is added, modified or deleted”. The settings are:

  • Change Type – Added
  • Table name – Customer Voice survey responses

Add a New Step that is a Dataverse “Get a row by ID” step.

  • Table name – Customer Voice survey Invites
  • Row ID – The “Survey Invite (Value)” from the previous step
  • Select columns – msfp_otherproperties

Add an “Initialize variable” step. This will be where we store accumulated scores.

Name – vTotalScore

Type – Float

Value – 0

Add a second “initialize variable” step for a counter of CSAT responses.

Name – vCounter

Type – int

Value – 0

Since a survey could come in from sources other than Omnichannel, it’s a good idea to filter out surveys sent for any other purpose. To do so add a “Condition” control where the condition is “Other Properties” from the “Get a row by ID” step, “contains”, “msdyn_ocliveworkitem”.

We will ignore the “no” branch, as that is for surveys not relating to Omnichannel. In the “Yes” branch, add a data operation to “Parse JSON” to objectize “Details of the Survey Response”. This will get the actual responses from the json object.

Content – “Satisfaction Metric Value” from “When a row is added”

Schema –

<code>
{
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "id": {
                "type": "string"
            },
            "type": {
                "type": "string"
            },
            "value": {
                "type": "string"
            },
            "decimalValue": {
                "type": "string"
            }
        },
        "required": [
            "id",
            "type",
            "value",
            "decimalValue"
        ]
    }
}
</code>

Next, add another data operation to “Parse JSON” to objectize “Other Properties” of the Survey Invite. The required schema is provided here to make things easier.

Content – “Other Properties” from “Get a row by ID”

Schema –

<code>
{
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "regardingidkey": {
                "type": "string"
            },
            "extInviteSourceId": {
                "type": "string"
            }
        },
        "required": [
            "regardingidkey",
            "extInviteSourceId"
        ]
    }
}
</code>

The two Parse JSON steps should look like the following:

Create an “Apply to each” step for the “Body” of first “Parse JSON”. This will loop through each answer in the survey. Since we are aggregating only CSAT survey scores in this example we will need to filter only responses associated to a question that is a CSAT question. So, add a Condition inside the Apply to Each where “type” “is equal to” “csat”.

In the “yes” branch, add an “Increment variable” Operation Step. This will get the total score for all CSAT survey response.

Name – vTotalScore

Value – Enter an Expression “int(items('Apply_to_each')['value'])”

Add a second “Increment variable” Operation Step. This will get the count of items that are a CSAT response type.

Name – vCounter

Value – 1

Finally, outside the “Apply to each” at the end of the yes branch add an “Update a Row” step from Dataverse.

Table name – Customer Voice survey responses

Row ID – “Activity” Dynamic Content from the original “When a row is added”

Average CSAT – Expression “div(variables('vTotalScore'),variables('vCounter'))”

Conversation - /msdyn_ocliveworkitems(exInviteSourceId) where exInviteSourceId is the Dynamics Expression from “Parse Json 2”.

Once you add “exInvitedSourceId” Power Automate will put this Update step inside an “Apply to each” control, which is perfectly fine.

The flow from a high level now should look like the following:

Save the flow and test it out with post-conversation surveys attached to Omnichannel Chat Sessions. The conversation and the Average Score will be recorded directly on the Survey Response instead of buried in json on multiple records. This will make the data easily usable my customer service managers and any reporting needs around the overall score of the various agents or the queues themselves. Enjoy!

Joe CRM
By Joe D365
Joe D365 is a Microsoft Dynamics 365 superhero who runs on pure Dynamics adrenaline. As the face of PowerObjects, Joe D365’s mission is to reveal innovative ways to use Dynamics 365 and bring the application to more businesses and organizations around the world.

Leave a Reply

Your email address will not be published. Required fields are marked *

PowerObjects Recommends