In this article, you can learn how to build an enterprise document approval process for Modern SharePoint with Microsoft Flow.
Introduction
Microsoft Flow Approvals are great for simple approval processes, but
Microsoft is working on a deeper integration of Approval w
Business usecase
Let's look at our real world customer usecase. My goal is to give you as much information as possible on the implementation steps, the core concepts of the solution and the overall solution, so you can avoid some traps and get value out of my experiences, which I had to pay myself for ;-)
In the past, the customer was using SharePoint2010 OOTB approval workflows. Nothing was customized in SPD. Workflow was just bound to library and basic configuration was set. Users initialized the workflow manually and defined the workflow initialization settings like approvers, type of approval, due date, etc. and started the workflow. So each workflow had a individual run context and was run on the pretty old but still fancy SharePoint2010 workflow engine on SharePoint Online.
Users didn't like the style of the quite cryptic e-mail notifications, but loved the flexibility of the OOTB functionality. If to look a bit deeper under the hood, this thing was quite powerful and more expensive 3rd party solutions weren't always needed. The engine could be extended pretty easily with managed code and custom actions, to integrate other systems and services.
Things should actually be easier nowadays, but sometimes new and different complexity is hitting us hard
As we arrived in the "modern" episode of it technology where all is decentralized, everything became a service and is talking to everything, client side code owns the world and data is structured and interacted within a Graph.
Key requirements
Some of the key requirements an enterprise level document approval process typically requires.
The Flow insiders know, that this list contains a lot of challenges and the main challenge is to connect all the individual ingridients to one final pie:
Parallel and serial approval task flow
Dynamic number of approvers
Approval due date
Automated reminder e-mail based on approval date
Approval escalation/timeout when no response
Centralized and "immutable" approval log
Enforced versioning, versioning comments
SharePoint integrated via Flow launch panel
Advanced error handling with notification to initiator
Solution Overview
SharePoint Integration
Modern Document Library
Custom Metadata
Flow Launch Panel
Dynamics Initialization Context
SharePoint Column Formatting
Azure Storage Queues
Storage Queues are providing us with enterprise software capabilities at our fingertips for a very reasonable price. The impact on the solution stability of this robust, highly scalable and easy to use lego brick, is insane.
Azure Storage Queues are a very cost effective solution. These connectors belong to the set of Standard Connectors and don't require a premium plan for each user. As for example the HTTP connectors will require starting from spring 2019. This makes a huge difference in price, as 1GB of queue storage costs about $0.07 and max message size is 64k.
JSON used as a data exchange format for the state object, is very flexible and can basically contain any data, even binary.
So, which Queues do we need actually need for our solution? Basically every Flow get's a Queue. So we are talking about a 1:1 mapping between Flows and Queues.
Approval Controller
Parallel Approval
Sequential Approval
Approval Logger
Approval Error
Microsoft Flow
Approval Controller
Parallel Approval
Sequential Approval
Approval Logger
Approval Error
Solution Overview
I visualized the high level solution architecture in color, so you can get an idea of the whole thing and come back, when reading the details later on.
Step 1: Create Azure Storage Account
As we are using Azure Storage to pass state object between controller and worker, we need to create our needed queues.
Please find all details here: https://docs.microsoft.com/en-us/azure/storage/common/storage-quickstart-create-account?tabs=azure-portal
Step 2: Create Azure Storage Queues
https://docs.microsoft.com/en-us/azure/storage/common/storage-quickstart-create-account?tabs=azure-portal
For our scenario, we need to create the following queues:
approval-controller
parallel-approval
sequential-approval
approval-logger
Step 3: Create Azure Storage Table
https://docs.microsoft.com/en-us/azure/cosmos-db/table-storage-overview
Step 4: Controller Flow
The Controller Flow is the main entity, handling the overall state of the process and being stateless itself. Compared to software development practices, this could be seen as the main routine of your application.
In this section you will learn how to implement it and all it's dependencies. If you want to learn more on the theory, please start with the Introduction or the the basics of the Controller Flow.
Flow Overview
Beauty often lies in simplicity. So, let's see how it's done. As you can see based on the sample implementation, this Flow has a very clear and easy to read and understand structure and is scalable in all dimensions.
Part 1: Initialization
Let's start with implementing the queue trigger and store the state message object data in the Flow context.
1. Create a new Flow As a frist action, we need to create a new Flow. I suggest you create a Flow from blank and add your triggers and actions later on. For our scenario
2. Configure trigger action Use "When new message in queue" trigger from the Azure Queue actions and connect it to your storage account. Then choose the "approval controller" queue, which we created in the steps before as your trigger.
3. Initialize messageItem variable Create a new variable of type string to store the state message object. As value, set the "Message Text" property of the Azure Queue trigger to catch the message from the queue and prepare it for next steps.
As variables can't be initialized in a scope, add it, directly after the trigger and before the "Main" scope, which are going to create next.
Part 2 - Main Scope / Global Error Handling
Let's build our main Flow structure. As we want to do things right, we implement two scopes to group our actions and implement proper error handling based on the "Run after" configuration of the error handling scope.
Step 1: Create Main Scope
Add a new scope and name it as you like. I call it "Main" as the main appplication logic get's added in here. Add the scope directly under the messageItem variable.
Step 2: Create Global Error Handling Scope
A aproach to error handling in #Flow ist to make use of scopes and define their run after condition
Create a first scope to wrap your actions and with that define your error scope and granularity of error notification. Basically every action could have a separate error handling condition, but obviously this doesnt make any sense and you wouldn't to that in code eigther.
Create a second scope to put your error handling activities like logging to a #SharePoint list or any repository or send e-mail notifications
Step 3: Configure "Run after" properties
Configure the "run after condition" on the second "Error handling" scope to run only if the first "Main" scopehas an error
This simply catches the error and you can notify the process initiator and owner, so they can inspect the issue in the #Flow run history.
Parse JSON object input, write to variable
Add a switch to handle messageType
Add another switch to handle messagePayload
Create queue message for worker Flow
Comments