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
- You are already have a running a Nimbus Service that meets Nimbus Power Automate Connector preconditions.
- To learn how to design and post Adaptive Cards we strongly recommend checking out our Best Practices - Designing Adaptive Cards for Nimbus and MS Teams.
- In context of this Use Case we assume that a connection to your CRM (in this example “Salesforce”) exists. 💡We also store the CRM ID back into Nimbus to create a record association.
- You have already set-up a running flow that identifies your callers from your CRM instance → 🔍 Use Cases for Customer Identification in other Systems:
- Use Case - Looking Up Phone Numbers via Search.ch API
- Use Case - Looking Up Caller Data From a Simple Excel List
- Use Case - Looking Up Caller Information in HubSpot
- Use Case - Looking Up Caller Information from Zendesk
- Use Case - Looking up caller information in BSI CRM
- Use Case - Looking Up a Caller to Open Dynamics 365 Contact Context
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: |
---|---|
Once we click on send email, we're sending out an email with the current agent: |
The card offers the following buttons:
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
- Create a new Cloud flow with the name "Nimbus MyService - OnTerminated - Missed Call - send adaptive card".
-
Add Nimbus flow trigger "GetOnUpdatedTasks" with event=Terminated to begin with the flow.
-
Add two initialize variables which we will be using later in the flow:
- LastConnectedUserId holds the same entitled field from the Nimbus trigger.
- 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')}. </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' ) | |
|
Message: Click here to expand...
|
|
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"
|
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 |
---|---|---|
|
Message: Content of adaptive card JSON
|
|
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"
|
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
|
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:
- A Call with a known customer (use a PSTN number which has a contact in your CRM)
- 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.