Flow Everything: Calling Synchronous Flows from CDS and D365
While I appreciate the recommendation to run my background workflows in Microsoft Flow, and will certainly do it whenever possible. It’s unfortunate that only my async processes can live in Flow since Microsoft hasn’t yet figured out the best way to execute synchronous Flows.
What’s happening here? It’s a bit of a bait and switch from Microsoft. Sorry, but that workflow engine you’ve relied on for so long isn’t getting much love anymore.
Microsoft Flow is the future of automation outside of just Dynamics and CDS but every business application in the Microsoft stack and possibly every business application in the world if Microsoft has it’s way…but lets step back from that for a second and talk about Dynamics 365.
What does it mean to us?
Ever wonder why the Business Application Process Flows have gotten so much attention when it came to the user experience and workflows are still stuck in the 2010s? Yeah. It’s because “we recommend using Microsoft Flow instead of background workflows” and pretty soon you’re probably going to have to make the switch whether you like it or not, but I’m sure you will like it once you’ve taken the leap.
Unfortunately, what Flows are great for are Background workflows, but you can’t use them in real-time which means you have to use a hybrid Async Flow and Real-time workflow solution if you’re ready to make the move.
Of course you wouldn’t be reading this article if that were completely true…
“I recommend using Microsoft Flow instead of Real-time workflows!” – Mike!
While there is no OOB solution for this today, a recent contribution to the open source community from Aiden Kaskela made his Workflow extension tool, Workflow Elements, open source. This was just in time for a feature I added that allows you to make use of real-time flows. Meaning you can start migrating all of your workflows to flow now.
What Are We Going to Build?
Let’s assume that you are building a Time Off Request application inside of CDS or D365 and you’ve created a new Time Off Request entity as well as configured an approval process which requires approval from a user’s manager when an employee creates a new Time Off Request. What we want to accomplish is filling in the employee’s manager’s email address on our Time Off Request record in real-time so we know who to send the approval to. Obviously, this may not be a real life scenario and there could be other ways to accomplish this requirement with async Flows, but it works for demonstration purposes.
Create The Synchronous Flow
To get started let’s create our Flow. Head over to flow.microsoft.com and Create a New Automated Flow from Blank. Give your Flow a Name (e.g. Get Manager’s Email) and skip choosing a Trigger for now.
Once your Flow has been created the first step (and the trick for executing a synchronous Flow) is to add an HTTP Request Trigger.
The HTTP Request Trigger is what allows us to call a Flow synchronously. Unlike other triggers in Flow this particular trigger will execute synchronously and the caller who sends the request can wait for a response from the Flow.
So, let’s configure our HTTP Request trigger. The information we need in order to find the manager’s email is the employee’s email. We need to define how this information will be supplied by the caller.
Click the Use sample payload to generate schema link on the Request trigger step and paste in this simple json payload and click Done.
Next we’ll add the step to get the Manager’s Email. Click New Step and Search for “Get Manager”. Then add the Get Manager (V2) action to your Flow and set the User (UPN) field to the PrimaryEmail from your HTTP Request Trigger.
The last step in our Flow will be to return the email from the Get Manager (V2) call to the client who made the HTTP Request. Click New step and search for Response to add an HTTP Response to your Flow. In the Body of your Response step add the following Json.
"ManagerEmail": "[Mail from Get Manager (V2) step]"
Your response should look like this.
That’s it for our Flow. Click Save and notice that your Request Trigger now has a url that the consumer of the Flow can use to trigger the Flow.
Copy the Url and save it somewhere as you’ll need it in a moment.
Call Your Synchronous Flow from CDS/D365
To get started with calling your Flow you’ll need to go download and install the latest version of Workflow Elements into your org. You’ll also want to download and install the sample solution for the Time Off Request app to provide the Time Off Request entity for your app. This solution also contains the workflow described below pre-configured. You can just plugin your flow url.
Once you have Workflow Elements and the sample solution installed you’re ready to call your Flow either via Custom Action or Workflow. We are going to focus on calling your Flow from, for now, from a synchronous workflow.
Start by creating a new synchronous workflow in Dynamics 365.
Set the workflow to run on After Create and After Assign of the Time off Request.
Once your done setting up your workflow it’s time to hook up your Flow to CDS/D365. By adding the following steps.
- Click Add Step -> Kaskela Workflow Elements -> Workflow – Get Metdata
- This will get us the current user information we need, including the email address, to send to our Flow in our Request
- Click Set Properties on the new step and verify it is executing as the workflow user
- Click Add Step -> Kaskela Workflow Elements -> Webhook – Call Webhook
- This new step I’ve added will allow you to call any REST Endpoint you want, but in this case we are going to be calling Flow specifically.
- Click Set Properties and set the following values
- Request Headers: Content-Type:application/json
- This is a semicolon delimited list of headers. In our case we’re only specifying a single header but you could combine headers using the syntax headerkey:headervalue;headerkey2:headervalue2…
- Request Url: Copy and paste the url of your Flow here
- Request Body:
- Request Headers: Content-Type:application/json
"PrimaryEmail":"[Insert Primary Email of the User Retrieved above]"
- Synchronous Mode: Synchronous
- Request Method: Post
- Here’s what your Properties should look like
- After we call our Flow we need to get the values and set them on our Time off Request to do this I added a new step called “Get Value From Json” that leverages JsonPath queries to extract data from the returned Json string. You can read more about JsonPath here.
- Click Add Step -> Kaskela Workflow Elements -> Webhook – Get Value From Json
- Click Set Properties and set the following Properties.
- Json String: Set to the response body from your Webhook call
- Json Path: ManagerEmail
- Since the Json structure of our response is simple we can retrieve the value returned simply by specifying the name of the property.
- Here’s what your Properties should look like
- The final step in our synchronous CDS/D365 Flow is to set the Manager’s Email on the Time Off Request record from Flow.
- Click Add Step -> Update Record
- Set the value of the Manager Email field to the value retrieved in the previous step (Single Value – Result as Text).
- Notice that there are multiple values returned from the previous step. This will ensure that any value returned when pulling values from your response are typed based on their format (e.g. string, int, guid, datetime etc.) to make it easier to use these values in your workflow.
- Here’s what your Update record step should look like
- Once you’re done Save and Activate your workflow.
- Create a new Time Off Request record and test your new synchronous Flow!
What does this mean for my upgrade path?
While our Flow was fairly simple there are much more complicated Flows that you can create and call with this method. It wasn’t shown here but creating associated records inside your flow is a perfectly supported function of Flow which you can now do synchronously if you choose.
Outside of the myriad of things you can do in Flow that you can’t in a CDS/D365 workflow you can create very robust synchronous Flows that call out to any number of systems which opens up a huge amount of possibility.
When you start creating these more complex flows you’ll begin to see the gains of using this method prior to official support of synchronous Flows by Microsoft because once official support is available you’ll only need to potentially change your trigger from HTTP Request to one of the supported methods for synchronous Flows and possibly replace your response with a direct update of CDS/D365 data. Meaning you will already be ready for a 100% Flow driven workflow system when parity arrives for Flow and Microsoft potentially takes away support for built in workflows.
The Fine Print
A couple of things to be aware of
- There are a few setup requirements you’ll need in place to use the example above including installing Workflow Elements and either installing the sample solution with the Time Of Request entity into your system or creating your own custom entity to test against. The workflow above also assumes that user’s managers are set in Office 365 in order to get that data into the workflow.
- Currently if your Webhook Request is unsuccessful an exception will be thrown by the custom workflow activity. There’s no ability to branch based on the response received. If you think it would work better that way drop me a line and I can change it, but for now an exception will be throw if anything but a success status is returned.
- There’s an additional Webhook CWA in this release which allows you to convert the entity on which the workflow is running to a json string which would allow you to pass the entire entity to your flow or other api endpoint. This wasn’t demonstrated in this article, but I’ll probably cover it in a subsequent post.
- Finally, this article covers calling Flows via the Webhook Custom Workflow Activity. However, the Activity was made as generic as possible to allow users to call out to any RESTful endpoint. Meaning you can now configure webhook calls in the user interface (previously can only be done OOB from Plugin Registration tool) and unlike the OOB Webhook functionality you can call these Webhooks synchronously and act on the results. There’s a huge amount of potential here and I suspect I’ll be writing a lot more posts in the very near future as use cases arise.
Interesting. Thanks for posting. Slight nit, the screenshot for “Set Manager Email on time off request” has the action being run Asynchronously whereas the text says Synchronously (see “Synchronous Mode” field). I’m assuming the screenshot is incorrect.