Showing posts with label Flow. Show all posts
Showing posts with label Flow. Show all posts

June 26, 2020

MS Flow: Simplest retry logic for SharePoint Online HTTP 400 errors

Problem

When setting SharePoint Online document properties from Flow, you will run into issues if the document is locked, i.e., someone has it open. In this case, SharePoint throws HTTP 400 that cannot be caught by the built-in retry-logic of the Update Item Flow action.

Solution

Simplest Do Until loop I came up with can be seen below. I didn’t find using Scope action necessary. In case you need to re-use this elsewhere in your Flow, it is quite straight forward to copy the Do Until action and paste it elsewhere. Just remember to add Set Variable action before each Do Until and set the fileLocked variable to true.

At first, the two Set variable actions were a bit confusing, the first one is only set to run after the SharePoint Update Item action has succeeded (and in that you set the fileLocked to false). The second one, however, is set to be run if the previous Set variable action is skipped (and in that you set the fileLocked to true), and as the first one is skipped if the Update Item fails, we then know it did NOT succeed.

It feels a bit weird to have the second Set variable (Set variable 2) as fileLocked variable value is not changing, but this is the high level logic people seem to do this so there may be some room for further improvement.

flowretry

May 14, 2020

Microsoft Flow: Using HTTP Webhook action with Azure Automation Runbook

Task

I needed to create new SharePoint Online Document Library and amongst other things set a Retention Label on that newly created Document Library using Microsoft Flow. Creating new doclib is straightforward using Flow, but I just couldn’t set the the Retention Label via REST from Flow. There is an API for that, but due to reasons I couldn’t get it to work from Flow.

We had an Azure Automation Runbook that was called at the end of the Flow anyway, so I decided to use that to set the Label on the SPO Library using SharePoint Online PnP’s Set-PnPLabel. No problem. However, it takes a while for the Label to be applied to the Library and as email was sent to users at the end of the Flow, they found themselves in the library too early, i.e., the Label was not yet set.

Solution

FLOW

I could’ve used  a “Do Until” loop in Flow and poll the list but that’s not something we like to do, right? We like events and triggers, so why not use the HTTP Webhook action, sounds exciting!


In the screenshot above, I’m calling the Azure Automation Runbook, but you can really call anything that is capable of listening to your request and at the and making a HTTP request back to the callback URL you define. You define your endpoint address in the Subscribe - URI field.

In the Subscribe - Body you must at least pass in the listCallbackUrl() so that you know the endpoint of this specific Flow instance you need to call in your backend code. Note that listCallbackUrl() is generated automatically, is specific to this running instance of the Flow, and can only be called once. Flow processing will halt at this action and it will continue when your backend code calls the listCallbackUrl(). You can define timeout of how long the action waits for the callback in the action settings.

Here I’m also passing in the title of the SharePoint Library as I’m also doing some tricks on the library but you would pass in anything you need in your scenario.

BACKEND

In the backend code you will do whatever you need, but when you’re done, make HTTP POST call to the URL you received as a parameter in your backend code, in my case that would look like this in PowerShell.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
param(
    [Parameter (Mandatory = $true)]
    [object]$webhookData
)

# If runbook was called from Webhook, WebhookData will not be null.
if ($WebhookData) {
    # Retrieve VMs from Webhook request body
    $body = (ConvertFrom-Json -InputObject $WebhookData.RequestBody)

    ####
    # Do something in your code...
    ###
    
    # ...and when you're done, call the callback URL
    Invoke-WebRequest $body.CallbackUrl -Method POST -UseBasicParsing
}

If you look at the Flow when it is running, you see it pause at the HTTP Webhook action, and continue as soon as the backend calls the callback URL. You can also manually call the callback URL using e.g., Postman, just paste in the callback URL and make sure method is POST. You will get HTTP 200 when the callback call succeeds.