Adaptive Cards for Teams to collect data from users using Power Automate | SharePoint Lists

Adaptive Cards is something so cool and works like magic!! I’m sure there are so many creative ways to use it.

Here’s an example – Use Adaptive Cards to gather data from Microsoft Teams Users and populate it automatically to SharePoint List.

Scenario

Let’s say, you have a set of data to collect from your employees – for instance, planning a trip (or any other event for that matter) where you have to take data from employees in order to better plan the logistics.

So, in my example, I want to plan an event for which I need to ask each employee their T-Shirt size, food preference and any allergies to be taken care of.

It’s better to let the users answer at their own accord. You simply need to create a SharePoint list and list out all the Employees whom the short questionnaire should be sent to.

Adaptive Cards (https://adaptivecards.io/)

As their website says, Adaptive Cards are platform-agnostic snippets of UI, authored in JSON, that apps and services and open exchange.

It’s a superb way to make these cards pop-up in Teams, Outlook, Bot Framework etc.

In this post, we’ll ask Microsoft Teams users to submit some info which will be automatically populated to the SharePoint List.

In https://adaptivecards.io/designer/, you can design your own Adaptive Card by looking at the samples already provided on the website.

SharePoint List

Let’s say, you’ve prepared a SharePoint List called ‘Employee Preferences‘ which looks like the below. And you need to get info from them on their Allergies, Food Preference and T-Shirt size in order to prepare for the event

Power Automate

Next step, is to create a Flow in PowerAutomate to send out these Adaptive Cards to the Teams member in their Chat so that they can send back their preferences which is automatically updated in the SharePoint List.
Let’s begin –
(Before we begin, it’s up to you to decide when should the Power Automate trigger, whether on create of Each Item, or all at once when the SP List is ready. I just chose the later. So, see what’s most suitable to you.)

  1. Let’s say my first step is to get all the items from the SharePoint List I created, called ‘Employee Preferences


    And then, set the below preferences –


  2. Next, I’ll loop through each of the SP items and initiate an Teams action to send Adaptive Card and wait for the response.

  3. Now, in Adaptive Card you’ve selected for the user of the Team, I’ve used the Email field from the SP list so that I can use it in the recipient field to send the Adaptive Card to that Teams user.

    And paste the content from Adaptive Card editor in Message field.


  4. You can use dynamic data at the right places to populate you Adaptive Card wherever needed.


  5. Finally, you can have an Update message filled in. This is shown once the User Submits back the Adaptive Card with data.
    Should update card should be selected to Yes so that it doesn’t stay like that and the user knows that the response has been captured.


  6. Then, you need to update the captured response back to the SP List.



  7. At this point, your Adaptive Card is ready! Let’s test.

Adaptive Card in Microsoft Teams

Once this is run, the Teams user gets the below in the chat.

  1. User receives and Adaptive Card in their Teams Chat.

    Let’s zoom a little and see how it looks. Notice that we had populated the name dynamically in the Adaptive Card body.

  2. Now, click on Fill Out information and the card will expand to expose the form

  3. Now, I’ll fill the information as below and Submit the same

  4. Once I click Submit, I’ll see the below message. Remember, this populated from Update message field in the Adaptive card options.

  5. And when you check back the SharePoint List, the data has been updated in the same.

    And that’s it!!
    Hope this helped!

Here are some Power Automate / Flow posts you might want to look at –

  1. ChildFlowUnsupportedForInvokerConnections error while using Child Flows [SOLVED] | Power Automate
  2. BPF Flow Step as a Trigger in CDS (Current Environment) connector | Power Automate
  3. http://flowPause a Flow using Delay and Delay Until | Power Automate
  4. Generate Dynamics 365 record link in a Flow using CDS connector | Power Automate
  5. Text Functions in a Flow | Power Automate
  6. Loop through array of objects in a Flow & Create records in CDS | Power Automate
  7. Get Count of records retrieved in CDS connector in a Flow | Power Automate
  8. Number Formatting in a Flow | Power Automate
  9. Call a Dynamics 365 Action from Flow [Bound and Unbound Actions] | Power Automate
  10. Setting Retry Policy for an HTTP request in a Flow | Power Automate
  11. Switch-Case in a Flow | Power Automate
  12. Make HTTP request from Flow in Power Automate

Thank you for your time!

ChildFlowUnsupportedForInvokerConnections error while using Child Flows [SOLVED] | Power Automate

Often times, if you are using Child Flows and but you see some unexpected while Saving your parent Flows upon adding a Child Flow, which usually look like the below
undefined

Assuming, you are aware of using Child Flows and that they can only be created inside a Solution. (Of course, that’s why you could encounter this issue since you’re able to set a Child Flow already 😊)

Reason Issue

Let’s say this is your Child Flow as shown below in Power Automate. It uses a connection for Approvals. (It could be any other connection in your case.)
undefined

Now, open Run only users section as shown below
undefined

It’ll show that my Approvals connection is relying on Provided by run-only user in Power Automate. To learn more about Run only Users, refer this post – https://www.serverlessnotes.com/docs/sharing-flows-as-owners-and-run-only-users

Now, I switch to Use this connection (<Connector>)
undefined

It’ll ask for a confirmation as per below
undefined

Once this is set for all respective connections, you’ll have no issues in adding a Child Flow to your parent Flow and saving your parent Flow!

Here are some more Power Automate / Flow posts you might want to look at –

  1. BPF Flow Step as a Trigger in CDS (Current Environment) connector | Power Automate
  2. Pause a Flow using Delay and Delay Until | Power Automate
  3. Generate Dynamics 365 record link in a Flow using CDS connector | Power Automate
  4. Get Count of records retrieved in CDS connector in a Flow | Power Automate
  5. Loop through array of objects in a Flow & Create records in CDS | Power Automate
  6. Call a Dynamics 365 Action from Flow [Bound and Unbound Actions] | Power Automate
  7. Number Formatting in a Flow | Power Automate
  8. Text Functions in a Flow | Power Automate
  9. Setting Retry Policy for an HTTP request in a Flow | Power Automate
  10. Make HTTP request from Flow in Power Automate

Hope this quick tip helps!

Generate Dynamics 365 record link in a Flow using CDS connector | Power Automate

There are several ways to formulate a Dynamics 365 record URL and make it clickable in a Flow in Power Automate.

Here’s one of the ways I follow for most scenarios – Let’s say I want to open a PSA Time Entry record from my Flow, here’s how I do it

Get record action to retrieve URL

Since this post is focused on CDS connector, I can get the D365 record link in body of Get record action for Common Data Service connector.

Unfortunately, I didn’t see this if the trigger was a CDS action, so I made a separate Get record call.
undefined

undefined
But, we’ll retrieve the same without having to select/parse body object. So let’s see –

Generating Link

First, I’ve initialized a variable that’ll hold the String format of the end URL
undefined
Now, first – I’ve appended https://. This won’t come directly using the uriHost() method

Then, the uriHost() holds the formula ‘uriHost(body(‘Get_record’)?[‘@odata.id’])

Meaning, get the uriHost name i.e. Environment name itself.
undefined

Then, I’ve appended options for the window to open which are mentioned below in this post.

Finally, I’ve appended the Primary Key of the record itself at the end
undefined

Options

Now, let’s talk about the options –

  1. cmdBar = [true | false]
    It’ll show the ribbon on the record. If false is chosen, it’ll be hidden
    undefined
  2. navBar = [off | on]
    It’ll show the Navigation Bar on top if on. If off, it’ll be hidden
    undefined
  3. newWindow=[true | false]
    This didn’t affect in my case. It anyway opened in a new tab. This could be different is the link is not opened from Email but is used elsewhere
    undefined
  4. pagetype=entityrecord
    Since we are targeting a Dynamics 365 entity record, the above is used.
    undefined
  5. etn= [name of the entity]
    Name of the entity
    undefined
  6. id
    GUID of the record itself.
    undefined

Here’s an Email that I composed to show how the URL will end up looking –
undefined

Which will result in Email like this

undefined

And open the record like this.
undefined
As per my settings in the URL I created, I don’t have the Nav Bar or Command Bar visible. It’s up to you to decide your preference

Here are some more Power Automate / Flow content you might want to check –

  1. Text Functions in a Flow | Power Automate
  2. Loop through array of objects in a Flow & Create records in CDS | Power Automate
  3. Get Count of records retrieved in CDS connector in a Flow | Power Automate
  4. Number Formatting in a Flow | Power Automate
  5. Call a Dynamics 365 Action from Flow [Bound and Unbound Actions] | Power Automate
  6. Make HTTP request from Flow in Power Automate
  7. Switch-Case in a Flow | Power Automate
  8. Setting Retry Policy for an HTTP request in a Flow | Power Automate

Hope this helps!!

Text Functions in a Flow | Power Automate

As I was looking at some String/Text operations in Flow recently, here’s what I discovered.

Looks like there are a lot more to come, so let’s look at some initial ones.

undefined

Find text position

A pretty simple feature to find the position the Search Text starts from in a String.
undefined

Here, I’m trying to find where does ‘yes’ in string ‘Priyesh’ starts from in the given text. And the answer was 3. [Text Index starting from 0]
undefined

If the text doesn’t exist, the result is -1
undefined

Substring

Here’s another important Text function called Substring.

This will return the substring with starting index of 3 and the length of the string from the starting character.
undefined

In this case, it’ll return the string “yes”
undefined

If your Starting Position in Substring is out of the range i.e. exceeding the length of the entire string, you’ll see and error like below stating the issue.
Also, the same error will be displayed if the Length of the Substring chosen falls out of range i.e. the index exceeding end of the string.
undefined

Here are some more Power Automate / Flow posts you might want to look at

  1. Loop through array of objects in a Flow & Create records in CDS | Power Automate
  2. Get Count of records retrieved in CDS connector in a Flow | Power Automate
  3. Number Formatting in a Flow | Power Automate
  4. Call a Dynamics 365 Action from Flow [Bound and Unbound Actions] | Power Automate
  5. Switch-Case in a Flow | Power Automate
  6. Setting Retry Policy for an HTTP request in a Flow | Power Automate
  7. Using Parse JSON to read individual List Records in Flow|Power Automate
  8. Make HTTP request from Flow in Power Automate
  9. Enable Flow button on D365 Ribbon
  10. Button Flow in Power Automate to replicate a Quick Create Form in D365 CE

Get Count of records retrieved in CDS connector in a Flow | Power Automate

In several applications, you need to know how many record were retrieved in the List records Action in a Common Data Service connector in order to take a decision.

Scenario

Typically, let’s say I know only 1 record should exist in order to take that record forward and do an action. But how do I know when only 1 record was received? That’s when you use Control

Check Count

Now, let’s say you want to want to retrieve Accounts and know how many were returned (Perhaps, you want to proceed only if at least 1 or more were retrieved)

  1. This is my List Records action and I’ve named it as Get All Records.
    defaultListRecords
  2. And just to display how many records are retrieved, I’ll use a variable. Usually, you would use this in condition (which we’ll get to in a bit)
    initVar
  3. So, in the expressions to set the Variable, under Dynamic Content, I’ll write –
    writeHereand write the below expressioncountactualExpression
    which is set to the variable
    setVar
  4. And here are the results. I have 101 Accounts
    count

Using it for comparison

This is one of the typical use cases where you want to proceed only if you have at least 1 record –
typicalUseCase

Here are some more Flow related topics you might want to take a look at –

  1. Number Formatting in a Flow | Power Automate
  2. Get N:N records in a Canvas Power App using Common Data Service connector | Power Platform
  3. Switch-Case in a Flow | Power Automate
  4. Setting Retry Policy for an HTTP request in a Flow | Power Automate
  5. Retrieve only active Dynamics 365 CE licensed Users in CDS connector in Power Automate
  6. Button Flow in Power Automate to replicate a Quick Create Form in D365 CE
  7. Make HTTP request from Flow in Power Automate
  8. Create a To-Do List Item of Important Outlook Emails using Power Automate

Hope this quick tip helps!

Number Formatting in a Flow | Power Automate

Quite obviously this is one of the most common asks in Flow to format a number. Here are some ways to do so using Format number Action in Flow (Power Automate).

This is available in Format number action in a Flow in Power Automate. This is available in Number Functions connector.
numActions

Commas and Decimals

  1. For a standard simple number, you can simply denote by # and commas or other symbols where needed. Here, I won’t select any locale.
    standardNumberBody
  2. And it would render into this –
    standardNumber

Phone Number

  1. US phone is an example where it is denoted by brackets and dashes in between. I’ll select English (United States) (en-US) in the locale among others. So, my format would be.
    isPhoneBody
  2. And the resultant phone number will be set as below
    usPhone

Currency Input

For currency, this is what I did –

  1. Added ₹ followed by ##,###,###. I’ll select English (India) (en-IN) in the Locale field.
    indCurrencyBody
  2. So even though my number value i.e. (50000) is in thousands and not hundred-thousands as I covered in my format, it’ll consider the correct format used and my output will be – indCurrency

Here’s where you can look at other ways to format numbers –
1. Standard numeric format strings
2. Custom numeric format strings

If you’re looking for some more posts on Flow / Power Automate, I’ve written some in the past. Check these –

  1. Create a To-Do List Item of Important Outlook Emails using Power Automate
  2. Get N:N records in a Canvas Power App using Common Data Service connector | Power Platform
  3. Call a Dynamics 365 Action from Flow [Bound and Unbound Actions] | Power Automate
  4. Switch-Case in a Flow | Power Automate
  5. Setting Retry Policy for an HTTP request in a Flow | Power Automate
  6. Make HTTP request from Flow in Power Automate
  7. Using Parse JSON to read individual List Records in Flow|Power Automate
  8. Secure Input/Output in Power Automate Run History
  9. Button Flow in Power Automate to replicate a Quick Create Form in D365 CE
  10. Enable Flow button on D365 Ribbon

Hope this helps!

 

Call a Dynamics 365 Action from Flow [Bound and Unbound Actions] | Power Automate

Ever wondered how to call an Action from a Flow using the new Common Data Service (Current Environment) connector? There are 2 actions to perform this –

Here’s a quick post to demonstrate that and the difference between Perform a bound action and Perform an unbound action in the CDS (Current Environment) connector.

Note that the connector used here is Common Data Service (Current Environment) connector which is available only if you are creating a Flow inside a Solution, not outside.
currentEnv
Check more on this connector here – Selecting (Current) in Environment in Power Automate CDS connector and why it matters

 

Unbound Action

Bound Action meaning calling an Action in Dynamics 365 that is bound to any one entity i.e. which is not a Global Action
BoundAction

  1. In this example. I’m creating a Flow that will call a Bound Action which runs on Account entity.
    insideBoundAction_Body
  2. And the InputName field shown above will simply take a string field and reflect the same as it is in Output
  3. Now, I am using Perform a bound action Action from the Common Data Service (Current Environment) connector as shown below-
    selectBount
  4. Once you select Perform a bound action, you’ll need to select what entity the Action is tied to with the following properties –
    Entity Name: Name of the entity the Action is bound to
    Action Name: Name of the action (not Display Name)
    Item ID: Guid of the record of that entity. Typically this is dynamically retrieved from other operations above this step (I’ve simply hard-coded one)
    Parameters: In my example, I’m passing a parameter called ‘InputName’ and I’m passing a string called “Account Name”
    boundBody
  5. Operation-Now, once my Bound Action is executed, I can see the below results which it will return i.e. OutputName field after composing with InputName inside the Action
    boundOutput
  6. Further, you can use the following Output from the Bound Action i.e. the Response or the Output parameters the Action is sending.
    showBoundResponse

Unbound Action

Unbound Action meaning calling an Action that is not bound to any entity in Dynamics 365 and is set to None (Global)
CreateUnboundAction

 

  1. In my Unbound Action, I am simply passing InputName through to the OutputName field as is.
    insideUnboundAction_Body
  2. Now, I’ll use Perform an unbound action from the Actions in Common Data Service (Current Environment) connector
    selectUnbound
  3. Once you select this action, you simply need to select the name of the Action from Dynamics 365 itself (Again, not Display Name) and pass along any Input parameters for the same, if any.
    unboundBody
  4. Operation – Now, once you execute this, the Action will execute and give you a response as below
    unboundOutput
  5. Further, you can select what you want to use from the response of the action step i.e. either the Response itself or the Output Parameters, if any.
    showUnboundResponse

 

Here are some other Power Automate / Flow posts that might interest you –

  1. Switch-Case in a Flow | Power Automate
  2. Enable Flow button on D365 Ribbon
  3. Secure Input/Output in Power Automate Run History
  4. Setting Retry Policy for an HTTP request in a Flow | Power Automate
  5. Using Parse JSON to read individual List Records in Flow|Power Automate
  6. Make HTTP request from Flow in Power Automate
  7. Retrieve only active Dynamics 365 CE licensed Users in CDS connector in Power Automate
  8. Create a To-Do List Item of Important Outlook Emails using Power Automate
  9. RSS notifications to your phone using Power Automate
  10. Selecting (Current) in Environment in Power Automate CDS connector and why it matters
  11. Button Flow in Power Automate to replicate a Quick Create Form in D365 CE
  12. Approval Process using Power Automate

Hope this simple example helps explain the actions!

Switch-Case in a Flow | Power Automate

Some of the common operations / decision making one wants to perform in terms of programming is definitely switch-case!

Here’s how you can do it in power automate

Scenario

To keep things simple, I will simply reflect the name of the OptionSet value in a variable in Flow –

    1. Here’s my OptionSet called Account Type with values Customer [1], Vendor [2] & Partner [3]
      optionSet

 

    1. My Flow will be called on update of Account record’s Account Type field change
      updateOfAccountType

 

    1. I’m simply using a variable to store the value of the selection made on the field.
      initVariable

 

Using Switch

Now, let’s get to the important part –

    1. If you search for Switch under Control, you’ll see as below
      switchControl

 

    1. This will first ask you what the Switch should be on, in this case, it’s the Account Type value to be selected from the dynamics values
      accountTypeChosen

 

    1. Now, I can start entering the Cases one by one as shown below and setting the variable I created above. For value in Equals 1, I’ll set variable as Customer
      firstCase&Default
      case1DetClicking on the + [Plus] sign in between Case and Default will let you add more cases.
      addCase

 

    1. Finally, once all the cases are entered, the Flow will start looking something like this from a hawk-eye-view with the Default case appearing in the end.
      hawkEye

 

Working

Let’s look at how Switch-Case would work –

    1. I updated the Account Type field with Vendor
      d365Updated

 

    1. Switch on the Account Type Value (selected from Dynamic Values) will reflect the value of 2
      2Selected

 

    1. And Case 2 will execute simply reflecting what is stored in the variable. Rest of the cases will not run
      result

 

Pretty Easy! Hope this helps!

Setting Retry Policy for an HTTP request in a Flow | Power Automate

Often times, There could be an issue where your HTTP request isn’t hitting well. So, to overcome this, you might want your Flow to Retry after a certain duration and for some number of times.

You want to setup a Retry policy for the same. Here’s how you do it!

Setting Retry Policy

Follow this to setup a Retry Policy of your Flow

  1. Locate your HTTP step and navigate to Settings
    openSettings

  2. Once you’re in Settings pane, scroll below and look for Retry Policy.
    retryPolicyLocation

  3. Default type is set by default, if you expand it, you can select what should be the Retry Type. In  this example, I’ve set to Fixed Interval for simplicity
    Default is set to 4 retries at an exponential interval. (Exponential increment type is a little confusing to explain, you can check this post as users discuss how exponential time increments work – )fixedInterval
  4. In Fixed Interval type, I’ve set number of retry count to be 3 and duration between each retry should be 30 seconds (represented in ISO-8601 format)
    sampleRetrySet
  5. With that, the policy is set. And the HTTP request step will try for 3 times at the interval of 30 seconds each.

 

If you want to test using some HTTP request, you can sample HTTP requests from here – https://httpstat.us/

How it works

Look for Failed Runs to see the result –

  1. Open a Failed Run where you know HTTP request could have failed
    openFailedRun
  2. Now, look for your HTTP request where you set the policy on. Expand the same.
    openHTTPCallThatFailed
  3. Upon expanding, you can see that there were 3 retries and it failed due to a timeout i.e. 408
    failedRetries
  4. You can also check on the right hand side of the page which says that the total duration of all these retries were 1 min 30 seconds
    totalFixedTime

If you observe the Flow Runs, you can find the the Flow did consistently try to run at an interval for the number of times specified.

In case you’re looking for more Flow/Power Automate related posts, check below –

  1. Make HTTP request from Flow in Power Automate
  2. Using Parse JSON to read individual List Records in Flow|Power Automate
  3. Selecting (Current) in Environment in Power Automate CDS connector and why it matters
  4. Retrieve only active Dynamics 365 CE licensed Users in CDS connector in Power Automate
  5. Secure Input/Output in Power Automate Run History
  6. Approval Process using Power Automate
  7. Create a To-Do List Item of Important Outlook Emails using Power Automate
  8. RSS notifications to your phone using Power Automate
  9. Enable Flow button on D365 Ribbon
  10. Button Flow in Power Automate to replicate a Quick Create Form in D365 CE

Hope this helps!!

Using Parse JSON to read individual List Records in Flow|Power Automate

This is a scenario I came across when I was using Common Data Service connector [not Common Data Service (Current Environment)] connector to read Opportunities tied to an Account.

Example

In this scenario, I wanted to retrieve the Opportunities tied to an Account. So, my filter query was _parentaccountid_value(‘ACCOUNT_IDENTIFIER’)

Here’s my Flow starts. I want to read Opportunities that are tied to my Account in context –

baseQuery

Flow Inside a solution vs. Outside a Solution

Inside a Solution

Now, when I had this Flow inside a solution, the result didn’t have a body and instead just gave me Status Reason value as below –

missingData

Outside a Solution

Whereas, outside the Solution, I was able to get the array of Objects i.e. Opportunity data in the Body in the Output itself.
outsideSolutionResult

So, what can we do about the Flow which is used inside a Solution and you want to actually see what was the output? You may or may not require to see the records (depending on your implementation)

But let’s say you want to see what was returned, let’s just parse these results as is using Parse JSON to see what we got.

Use Parse JSON from Data Operation

Another way to read what you’re retrieving is using Parse JSON Data Operation.

  1. Search Parse JSON and you’ll see the result in Data Operation type of Actions as shown below –useParseJSON
  2. Now, you have to apply this to Current item from the retrieved List records in Apply to each operation. In case you don’t have the schema or not sure what to put it in. Simply use {} in Schema field. This will just pass through as is.
    applyParseJSON

Checking Result

Now, let’s test using the above and see if we can get the results

  1. Now, you can actually see the Inputs and Output of Parse JSON which is basically the same. This is useful if you want to visually see what’s going on through your Flow.
    visibleResult

But, if you don’t want to see what’s being passed through when in Production? You can Secure Input/Output in Power Automate Run History

Hope this helps you!!