Keeping up with the Microsoft Flow run history of your SharePoint item

With Microsoft Flow, there isn’t an out-of-the-box way to view the run history of your Flow belonging to one specific SharePoint item like SharePoint Designer workflows and Nintex does. The Flow portal only provides you with an overview of all of the Flow runs for each item. This is very inconvenient if you want to see the when and what of your SharePoint item.

Luckily, there is a way to achieve this which I will explain in this blog post.

Configuring SharePoint

First of all, we need to configure your SharePoint list/library so that we can store the Flow run history. It will be stored in a Multiple lines of text column that has Rich text enabled. Make sure you don’t select the Enhanced rich text option, because that may screw up the format of your column. You can give it any name you want that suits you best. I named mine ‘Approval Flow’.

That’s basically it. You can also do some other customization like disabling Quick Edit (through List settings – Advanced Settings) and altering your New, Edit and View forms (with PowerApps) so that no one can edit this column.

Configuring the Flow

Now that we have SharePoint configured, we can proceed and start configuring our Flow. This consists of 3 parts:

  1. Your actual Flow
  2. Storing the Flow run history into your list item
  3. Error handling

Flow

The configuration of this part is completely up to you. It will contain each action that you need for your Flow to function correctly. If you want to use error handling, please make sure you place your entire Flow into a Scope. A scope is nothing more than a container that contains all of your actions and can be found at Control > Scope.

Storing Flow run history

To store the Flow run history, we must add a final Update item action outside of our Scope. Within this action you need to give your Site address, List name and Id (and maybe some more information, based on the columns that you’ve set up). The multiple lines of text column you created earlier will contain the Flow run history.

Building up the history

To make sure we store the entire Flow run history and not just the current run, we need to append the previous run history but only if it exists. You can do this by using the following expression:

if(
	empty(
		outputs('Get_item')?['body/ApprovalFlow']
	),
	null,
	concat(
		outputs('Get_item')?['body/ApprovalFlow'],
		'<br/>'
	)
)

This expression checks if the multiple lines of text column is empty. You can combine expressions with Dynamic content by switching tabs. This way you can easily select your multiple lines of text column

If the column is empty, a null value (which is an empty string) will be stored meaning that there are no previous runs. If not, the existing run history combined with an HTML line break (by using the concat() function) will be stored to make sure each run history is stored on a new line.

Storing the date

Next, we need to store the date of the Flow run. You can do this by using the formatDateTime() expession, combined with utcNow() and the desired date format (e.g. dd-MM-yyyy), but if you don’t live in the UTC timezone, you might want to use your own timezone by using the expressions above, combined with the convertFromUTC() expression. The expression I used was:

formatDateTime(
	convertFromUtc(
		utcNow(),
		'W. Europe Standard Time'
	),
	'dd-MM-yyyy HH:mm'
)

It’s pretty straight-forward: the UTC timezone will be converted into the timezone of your choice. Since I live in the Netherlands, I use the Western European timezone. A full list of the time zones that can be used can be found here. Make sure you use the value from the Time zone name column.

The converted date-time will then be formatted into a date format of your choice, such as ‘dd-MM-yyyy HH:mm’ as I used.

Providing the link to your flow run

Last, but not least we need to store the link that will redirect us to the Flow run history page of the corresponding Flow run.

I found out that there was a workflow() expression beneath the Workflow functions section and was wondering what this was exactly, so I put it into a Compose action to see what the output would be. It gave me the following output:

{
  "id": "/subscriptions/71b6eb3f-48a4-46b7-9df4-8ec119fc2a11/resourceGroups/D9B63FB4F80B43EDBFBB047407293686-70FEA1C23120463AB91F430C481D473F/providers/Microsoft.Logic/workflows/6c98ff63-6436-4a81-848b-4a59cf5b8a7b",
  "name": "6c98ff63-6436-4a81-848b-4a59cf5b8a7b",
  "type": "Microsoft.Logic/workflows",
  "location": "westeurope",
  "tags": {
    "flowDisplayName": "Flow run history demo - Approval",
    "environmentName": "Default-d9b63fb4-f80b-43ed-bfbb-047407293686",
    "logicAppName": "6c98ff63-6436-4a81-848b-4a59cf5b8a7b",
    "environmentFlowSuspensionReason": "Default:2Dd9b63fb4:2Df80b:2D43ed:2Dbfbb:2D047407293686-None",
    "flowTemplateName": "64cb6f364936458b8f23652b6951fb28"
  },
  "run": {
    "id": "/subscriptions/71b6eb3f-48a4-46b7-9df4-8ec119fc2a11/resourceGroups/D9B63FB4F80B43EDBFBB047407293686-70FEA1C23120463AB91F430C481D473F/providers/Microsoft.Logic/workflows/6c98ff63-6436-4a81-848b-4a59cf5b8a7b/runs/08586339359719448384626120488CU86",
    "name": "08586339359719448384626120488CU86",
    "type": "Microsoft.Logic/workflows/runs"
  }
}

This triggered my into being able to generate the Flow run URL from this expression, since the Flow run URL is like this:

https://emea.flow.microsoft.com/manage/environments/<ENVIRONMENTID>/flows/<FLOWID>/runs/<RUNID>

The Environment ID is stored as tag > environmentName in the output, the Flow ID is stored as name and the Run ID is stored as run > name.

Knowing this, we can generate the Flow run URL by encapsulating the following expression into an <a href> HTML tag:

concat(
	'https://emea.flow.microsoft.com/manage/environments/',
	workflow()['tags']['environmentName'],
	'/flows/',
	workflow()['name'],
	'/runs/',
	workflow()['run']['name']
)

This will combine all different parts of the URL into a single URL. Please note that the first part of the URL (emea.flow.microsoft.com) may differ, based on the location of your tenant.

Final result

Putting all of the above together into the Update item action will lead to the following:

Error handling

Basically, the Flow is complete at this point. But it would be a lot easier to find out if a Flow has completed successfully or if it has failed.

This is where our Scope we created earlier comes in place. We need to do the exact same Update item action (except that the ‘Completed’ value should be ‘Failed’) after an error has occurred. To do this, we can copy the Update item action by using the Copy to my clipboard functionality that has been introduced recently:

Next we need to add a parallel branch next to our Update item action by selecting the + symbol above the Update item action and selecting Add a parallel branch:

From the Choose an action menu, go to My clipboard and select the action you just copied:

Now we need to change the ‘Completed’ value into ‘Failed’ and set the Run after conditions of this new Update item action so that this action will only run if the previous action (which is the Scope) has failed or timed out. You can do this by selecting the ellipsis symbol of the action and clicking Configure run after. You need to select the has failed and has timed out check boxes and click Done:

That’s it, the Flow is complete and should look something like this:

The result

When your Flow runs, it will write the run history each time the Flow has completed. Whether it was successful or it has failed. Clicking the link (from the Properties pane in SharePoint) will redirect you to the Flow portal and show you the entire Flow run:

Leave a Reply

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