Use Case - Posting Interactive Custom Adaptive Cards to Agents

Learn how to implement a custom adaptive card.

In this use case, we want to show you how to implement a custom a adaptive card ( 🔍 See: https://adaptivecards.io/ ). We want to receive a customized adaptive card in the Teams channel of the service when the call was missed. The following scenarios are covered:

  • Trigger when a call has been terminated:
    • If the customer is known to our CRM system, we want to see who had been calling, and draft a pre-filled email, to which we can make changes before it will be sent out to the customer.
    • If the customer can't be identified in our CRM system, then we want to see an adaptive card suggesting to create the customer in Salesforce. 💡 Of course you can substitute Salesforce with your CRM of choice.

Overview

 
 

PRECONDITIONS

 

INC Icon Legend Accordion

Show Icon Legend

💡 = A hint to signal learnings, improvements or useful information in context. 🔍 = Info points out essential notes or related page in context.
☝ = Notifies you about fallacies and tricky parts that help avoid problems. 🤔 = Asks and answers common questions and troubleshooting points.
❌ = Warns you of actions with irreversible / data-destructive consequence. ✅ = Intructs you to perform a certain (prerequired) action to complete a related step.
 
 

Design the Adaptive Cards

With the tool provided by https://adaptivecards.io/designer/ you can visually create your own adaptive cards.

In our case, we want to create an adaptive card that looks like the following:

For known customers:
For unknown customers:

The card offers the following buttons:

  1. Send Email: Sends out an email with the contents filled in the form
  2. Open Contact in SF: Opens the customer view in Salesforce CRM.
  3. Cancel: Abords and finished the Power Automate flow.

Once we click on send email, we're sending out an email with the current agent:

The card offers the following buttons:

  1. Create contact in SF: Create a new customer in Salesforce CRM.
  2. Cancel: Abords and finished the Power Automate flow.

Once we click on "Create in SF" we want to reply with another adaptive card that returns the Salesforce Url to the new contact:

Start Building the Power Automate Flow

  1. Create a new Cloud flow with the name "Nimbus MyService - OnTerminated - Missed Call - send adaptive card".
  2. Add Nimbus flow trigger "GetOnUpdatedTasks" with event=Terminated to begin with the flow.   
  3. Add two initialize variables which we will be using later in the flow:
    1. LastConnectedUserId holds the same entitled field from the Nimbus trigger.
    2. SalesForceContactId holds the id of the sales force contact saved by the identification flow which is a pre requirement of this flow = triggerOutputs()?[ 'body/customer/customFields/SalesForceContactID' ]

Verify if It is a Missed Call

Start with LastConnectedUserId first to determine if the call was a missed.

When LastConnectedUserId does not exist in the object if the call has been missed. An "is greater than" and leave field empty will do the trick. → By doing so the flow will not post any adaptive card in the "If true" branch.

Verify if the Caller is a Known Customer

Now continue in the "If no" branch.

Check on SalesForceContactId to determine if caller is a known to the CRM. → It is empty if the caller was unknown.

Known Customer

An overview of the steps of the branch:

Overview

 
 

Element by element description:

Description
Code
Element
Add a Compose element which holds the pre-filled email content

Inputs:

Compose Content

<html>

Dear @{triggerOutputs()?['body/customer/displayName']},

</br>

I am sorry that I missed your call at @{formatDateTime(triggerOutputs()?['body/created'], 'g')}.
May I help you this way?

</br>

Yours,</br>

@{triggerOutputs()?['body/serviceDisplayName']}

</html>

 
 
Add a Compose element which holds the Salesforce URL concat( 'https://my-salesforce/lightning/r/Contact/' ,triggerOutputs()?[ 'body/customer/customFields/SalesForceContactID' ], '/view' )
  1. Add a Post adaptive card AND wait for response element which will post the adaptive card to the channel.
    1. Copy and paste your adaptive card design in the message field.
    2. Use the compose elements to set the content of the action buttons.

Message:

Click here to expand...

{
                                                            "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                                                            "type": "AdaptiveCard",
                                                            "version": "1.4",
                                                            "body": [
                                                                {
                                                                    "type": "TextBlock",
                                                                    "size": "Medium",
                                                                    "weight": "Bolder",
                                                                    "id": "Title",
                                                                    "text": "Missed Call from @{triggerOutputs()?['body/customer/displayName']}",
                                                                    "horizontalAlignment": "Left"
                                                                },
                                                                {
                                                                    "type": "TextBlock",
                                                                    "text": "Do you want to notify the customer per email?",
                                                                    "wrap": true
                                                                },
                                                                {
                                                                    "type": "ColumnSet",
                                                                    "columns": [
                                                                        {
                                                                            "type": "Column",
                                                                            "width": "auto",
                                                                            "items": [
                                                                                {
                                                                                    "type": "TextBlock",
                                                                                    "text": "Recipient",
                                                                                    "wrap": true
                                                                                },
                                                                                {
                                                                                    "type": "TextBlock",
                                                                                    "text": "Subject",
                                                                                    "wrap": true
                                                                                },
                                                                                {
                                                                                    "type": "TextBlock",
                                                                                    "text": "Content",
                                                                                    "wrap": true
                                                                                }
                                                                            ]
                                                                        },
                                                                        {
                                                                            "type": "Column",
                                                                            "width": "stretch",
                                                                            "items": [
                                                                                {
                                                                                    "type": "Input.Text",
                                                                                    "placeholder": "Please enter customer email here",
                                                                                    "style": "text",
                                                                                    "isMultiline": false,
                                                                                    "maxLength": 75,
                                                                                    "id": "recipient",
                                                                                    "value": "@{triggerOutputs()?['body/customer/email']}"
                                                                                },
                                                                                {
                                                                                    "type": "Input.Text",
                                                                                    "placeholder": "Lunifico missed your call",
                                                          "id": "subject",
                                                                                    "value": "Lunifico missed your call"
                                                                                },
                                                                               {
                                                                                    "type": "Input.Text",
                                                                                    "placeholder": "Email Content goes here",
                                                                                    "style": "text",
                                                                                    "isMultiline": true,
                                                                                    "maxLength": 455,
                                                                                    "id": "content",
                                                                                    "value": "@{outputs('Compose')}"
                                                                                },
                                                                            ]
                                                                        }
                                                                    ]
                                                                }
                                                            ],
                                                            "actions": [
                                                                {
                                                                    "type": "Action.Submit",
                                                                    "title": "Send Email"
                                                                },
                                                            {
                                                                    "type": "Action.Submit",
                                                                    "title": "Notify me"
                                                                },
                                                                {
                                                                    "type": "Action.OpenUrl",
                                                                    "title": "Open contact in SF",
                                                        "url": "@{outputs('ContactUrl')}"
                                                                },
                                                           {
                                                                    "type": "Action.Submit",
                                                                    "title": "Cancel"
                                                                }
                                                            ]
                                                        }

 

 
 
Add a Compose element which will hold the reponse of the card.

Inputs:   
 

outputs( 'Post_adaptive_card_and_wait_for_a_response' )

 

Add another Compose element which will store the action chosen by the agent when clicking on one of the buttons on the card.

Inputs:   
 

outputs( 'Response' )?[ 'body/submitActionId' ]

Add a Switch to switch on the submitted action

On:   
 

outputs( 'SubmittedAction' )

 

Case 1: "Send Email"

  1. Add a Compose element which holds the data of the response of the adaptive card.
  2. Then add a "Send an email (V2)" element to the flow and set the inputs accordingly by using the Submitted Data compose element.

Compose Inputs:   
 

outputs('Response')?['body/data']

Send an Email (V2) Inputs:

To: outputs('SubmittedData')?['recipient']

Subject: outputs('SubmittedData')?['subject']

Body: outputs('SubmittedData')?['content']"

Case 2: "Notify me"   
 

Implement according to your needs.

Implement according to your needs.

Case 3: Open Salesforce URL.

💡 This case does not have to be implemented. The action works as defined on the adaptive card.

N/A

N/A

Unknown Customer

An overview of the steps of the branch:

Element by element description:

Description
Code
Element
  1. Add a Post adaptive card and wait for response 2 element which will post the adaptive card to the channel.
  2. Copy and paste your adaptive card design in the message field. The action button is a simple submit-action.

Message:

Content of adaptive card JSON

{
                                                        "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                                                        "type": "AdaptiveCard",
                                                        "version": "1.4",
                                                        "body": [
                                                        {
                                                        "type": "TextBlock",
                                                        "size": "Medium",
                                                        "weight": "Bolder",
                                                        "id": "Title",
                                                        "text": "Missed Call from @{triggerOutputs()?['body/microsoftCallerId']} ",
                                                        "horizontalAlignment": "Left"
                                                        },
                                                        {
                                                        "type": "TextBlock",
                                                        "text": "Do you want to create the customer in Salesforce?",
                                                        "wrap": true
                                                        },
                                                        {
                                                        "type": "ColumnSet",
                                                        "columns": [
                                                        {
                                                        "type": "Column",
                                                        "width": "auto",
                                                        "items": [
                                                        {
                                                        "type": "TextBlock",
                                                        "text": "Firstname",
                                                        "wrap": true
                                                        },
                                                        {
                                                        "type": "TextBlock",
                                                        "text": "Lastname",
                                                        "wrap": true
                                                        },
                                                        {
                                                        "type": "TextBlock",
                                                        "text": "Phone",
                                                        "wrap": true
                                                        }
                                                        ]
                                                        },
                                                        {
                                                        "type": "Column",
                                                        "width": "stretch",
                                                        "items": [
                                                        {
                                                        "type": "Input.Text",
                                                        "placeholder": "Firstname",
                                                        "id": "firstname",
                                                        "value": "Unknown"
                                                        },
                                                        {
                                                        "type": "Input.Text",
                                                        "placeholder": "Lastname",
                                                         "id": "lastname",
                                                        "value": "Unknown"
                                                        },
                                                        {
                                                        "type": "Input.Text",
                                                        "placeholder": "@{triggerOutputs()?['body/microsoftCallerId']}",
                                                        "id": "phone",
                                                        "value": "@{triggerOutputs()?['body/microsoftCallerId']}"
                                                        },
                                                        ]
                                                        }
                                                        ]
                                                        }
                                                        ],
                                                        "actions": [
                                                        {
                                                        "type": "Action.Submit",
                                                        "title": "Create contact in SF"
                                                        },
                                                        {
                                                        "type": "Action.Submit",
                                                        "title": "Cancel"
                                                        }
                                                        ]
                                                        }

 

 
 

 

Add Compose to save the response to.

Inputs:   
 

outputs('Post_adaptive_card_and_wait_for_a_response_2')

Add Compose to store the submitted action to.   
 

Inputs:   
 

outputs('Response_2')?['body/submitActionId']

Add a Switch to react on the submitted action.

On:   
 

outputs('SubmittedAction_2')

Case 1: "Create contact in SF"

  1. Add a Create Record element to create the customer in Salesforce.   

     
  2. Then add a "Compose" element to the flow and create the url to the new entry in your CRM.

Contact Last Name:   
 

outputs('Response_2')?['body/data/lastname']

Contact First Name:

outputs('Response_2')?['body/data/firstname']

Contact Business Phone:

outputs('Response_2')?['body/data/phone']

Inputs:

concat('https://mysalesforce/lightning/r/Contact/',outputs('Create_record')?['body/Id'],'/view')

 

Case 1 (continued): At the end we want to reply with an adaptive card and the link to the newly created user in Salesforce.

Adaptive Card:

JSON content for adaptive card

{
                                                                                                                    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                                                                                                                    "type": "AdaptiveCard",
                                                                                                                    "version": "1.4",
                                                                                                                    "body": [
                                                                                                                        {
                                                                                                                            "type": "ColumnSet",
                                                                                                                            "columns": [
                                                                                                                                {
                                                                                                                                    "type": "Column",
                                                                                                                                    "width": 2,
                                                                                                                                    "items": [
                                                                                                                                        {
                                                                                                                                            "type": "TextBlock",
                                                                                                                                            "text": "Contact successfully created in Salesforce.",
                                                                                                                                            "weight": "Bolder",
                                                                                                                                            "size": "ExtraLarge",
                                                                                                                                            "spacing": "None",
                                                                                                                                            "wrap": true
                                                                                                                                        },
                                                                                                                                        {
                                                                                                                                            "type": "TextBlock",
                                                                                                                                            "text": "I created a new contact @{outputs('Response_2')?['body/data/firstname']} @{outputs('Response_2')?['body/data/lastname']} in Salesforce. Please review and complete it.",
                                                                                                                                            "size": "Small",
                                                                                                                                            "wrap": true,
                                                                                                                                            "maxLines": 3
                                                                                                                                        }
                                                                                                                                    ]
                                                                                                                                },
                                                                                                                                {
                                                                                                                                    "type": "Column",
                                                                                                                                    "width": 1,
                                                                                                                                    "items": [
                                                                                                                                        {
                                                                                                                      "type": "Image",
                                                                                                                                            "url": "https://www.salesforce.com/content/dam/web/en_is/www/images/campaigns/sem/sales-cloud/sfdc_primary_logo_rgb_v1.png",
                                                                                                                                            "size": "Stretch",
                                                                                                                                            "altText": "Salesforce logo"
                                                                                                                                        }
                                                                                                                                    ]
                                                                                                                                }
                                                                                                                            ]
                                                                                                                        }
                                                                                                                    ],
                                                                                                                    "actions": [
                                                                                                                        {
                                                                                                                            "type": "Action.OpenUrl",
                                                                                                                            "title": "Open contact in SF",
                                                                                                                "url": "@{outputs('NewContactUrl')}"         }
                                                                                                                    ]
                                                                                                                }
 
 

Adding this flow action ....

 

...will result in:

Test It

Call your service to simulate missed calls. → This should post two different cards into the channel:

  1. A Call with a known customer (use a PSTN number which has a contact in your CRM)
  2. A Call with an unknwon customer (use internal Teams for instance)

Call and Accept a call. → This should not post any card in the channel.

GOOD TO KNOW

💡A pending Adaptive Card waits for input for 30 days. The flow runs until an input has been provided or after 30 days of execution.

 

Table of Contents