Friday, May 4, 2018

Use Microsoft Flow to implement approval of site pages


Photo by Zachary Nelson at Unsplash

Again I’m late to the party, but Microsoft has released an action to Flow called “Set content approval status”. This action enables you to add content approval not only to list elements and documents in SharePoint, but also to news pages.

Microsoft has talked about content approval for ECM scenarios with communication pages for a while, but until a proper UI is in place, you can get started today!

This is how.

First off navigate to the Site Pages library where you create your pages, and go to the versioning settings for the library.

Ensure you have turned on and least content approval and enabling major/minor versioning is also a good idea so that editors can save their work multiple times before hitting Publish for approval.

image

Next create a Flow which trigger on the Site Pages library. I like to start from the Flow UI, but you can start off any way you like.

Important! The user used for the connection in the SharePoint actions, has to be an owner on the site, in order to have approval rights for items – or given the approval right explicitly.

I will start with the SharePoint action “When an item is created or modified”. The reason for triggering on modified as well, is to cater for the major/minor versioning scenario – in order not to skip draft items.

If you’re advanced and adventurous you can check Serge Luca’s post which dives into how you can change the trigger to only trigger on items based on properties of the item.

As the Site Pages library will not list automatically for this action (nor will it for the file is created action), you have to manually enter the name or the guid of your list.

image

Choose “Enter custom value” and type the name of your Site Pages library.

image

The next step is to check for the Pending approval status, which is what we will act on. Any other approval state and we can exit the Flow.

Since I decided to complicate things with draft status, you currently have to use the new “Send an HTTP request to SharePoint” action in order to retrieve the approval status of the item, which can be done with the following REST query where the value is stored in the column _ModerationStatus, which is accessible via OData__ModerationStatus using REST.

_api/web/lists/getbytitle('Site%20Pages')/items(<id>)?$select=OData__ModerationStatus

image

In order to make it easier to check the value from the returned JSON I add a Parse JSON step with the following schema (generated from a test query)

{
    "type": "object",
    "properties": {
        "d": {
            "type": "object",
            "properties": {
                "__metadata": {
                    "type": "object",
                    "properties": {
                        "id": {
                            "type": "string"
                        },
                        "uri": {
                            "type": "string"
                        },
                        "etag": {
                            "type": "string"
                        },
                        "type": {
                            "type": "string"
                        }
                    }
                },
                "OData__ModerationStatus": {
                    "type": "number"
                }
            }
        }
    }
}

The Pending approval state has a value of 2, so for any other value we will terminate the Flow. This is easily accomplished by checking the value of the OData__ModerationStatus field.

To simplify my Flow I don’t add further commands in the Yes branch, but add them below for better readability.

image

The check is done, we know the page is in pending state, requiring someone to approve or reject it. And an easy approach to use is the Flow approval action.

image

Once the e-mail approval has taken place it’s time to use the “Set content approval status” action depending on if the approver approved or rejected the item.

When approving a page you need a value for the ETag field. To get a working ETag value use the “Get file metadata” action with the file identifier from the trigger action. One positive side of the approval action is that the Site Pages library automatically appear in the dropdown :-)

image

Looking back at the site pages library, you see the page is approved and will be visible by everyone.

image

Summary

Content approval is often an important feature of ECM, where not anyone can publish articles or news at random. Tapping into the old approval functionality in SharePoint and combining it with Microsoft Flow is a nice way to unblock this scenario. Once a user hits “Publish” on an article, we kick off an approval workflow, where the approver can approve the item directly from the e-mail message if they want to.

If you need scheduling as well, simply add a column to the Site Pages library put a date in it, and add a Delay action in your Flow to pause the actual setting of the Approval state.

The Flow today might seem a bit convoluted, but I expect a better UI integration in the future based on previous communications from Microsoft om the ECM story for Communication sites. The beauty is that this approval Flow is very generic and can be used on any site and for any library.

11 comments:

  1. You can use JSON light and simplify the response you get. Just add the following header to the HTTP action:

    accept: application/json; odata=nometadata

    Now, the response body will be simple:

    {
    "OData__ModerationStatus": 2
    }

    -Chaks

    ReplyDelete
    Replies
    1. Good one, maybe implement that in the action as a dropdown?

      Delete
  2. Hi, this helped me a lot. Thanks!
    One question, there should also be a value in OData__ModerationComments, but I only recieve NULL when trying to collect it. Should it be possible or am I misstaken?

    ReplyDelete
    Replies
    1. Didn't test. Did you try to add it to both the select query and to the JSON schema?

      Delete
    2. Yes, the query and schema are working as expected.

      I noticed something that I haven’t figure out the reason behind

      If the document has OData__ModerationStatus = 2 (Pending) then the OData__ModerationComments = NULL

      If the document has OData__ModerationStatus = 0 (Approved) then the OData__ModerationComments = “The comment made when approving the document”

      It looks like comments made when changing the document from Draft to Pending is not in ModerationComments, but comments made when going from Pending to Approved is in ModerationComments

      I will go deep diving in the lake of google and see if there are different ways the comments are handled when going from draft --> pending compared to pending --> approved

      Delete
  3. Thanks for your idea.

    I tried to use it on my flow but keep getting the same ERROR :

    {
    "status": 400,
    "message": "La expresión \"web/lists/getbytitle('Documentos aprobados')/items(%2fDocumentos+compartidos%2fA+Verificar%2fCIF.pdf)\" no es válida.\r\nclientRequestId: 83287bce-e2a0-4374-acd2-0100f0e08439\r\nserviceRequestId: a8e4c29e-a082-0000-52a9-e9e19e8f3196",
    "source": "https://XXXXXX.sharepoint.com/sites/qa/_api/web/lists/getbytitle('Documentos%20aprobados')/items(%252fDocumentos%2bcompartidos%252fA%2bVerificar%252fCIF.pdf)?select=OData__ModerationStatus",
    "errors": [
    "-1",
    "Microsoft.SharePoint.Client.InvalidClientQueryException"
    ]
    }

    Any idea what I am doing wrong?

    ReplyDelete
    Replies
    1. I see you try to load the item by path and not id. /items(...) takes an item id.

      Delete
  4. I am using "Id" from sharepoint info, but the error shows the path and not a number. If I force a number it works. Any help about why I am getting the path and not a number when selecting ID from sharepoint metadata?

    Thanks for your help

    ReplyDelete
    Replies
    1. Not sure. You could check the run on what values come into the trigger action and see if you can spot the item id in there.

      Delete
  5. I have a problem when the user clicks "Submit for approval" the page first saves a draft and then get submitted. That means the flow triggers by the draft version and then after some time it triggers again now on the pending version.

    Since I don't have any premium plans the delay between the draft and pending flows are about 5 minutes which is a bit slow for me. Do you have any thoughts about this?

    ReplyDelete
    Replies
    1. You can try some trickery like in https://sergeluca.wordpress.com/2018/04/11/trigger-your-flow-only-when-a-document-is-created-from-a-specific-content-type/ where you change the trigger to only trigger on pending states.

      Delete