One Flow to Rule Them All – Mastering SharePoint Webhooks for Workflows – Part I

Welcome back SharePoint & Power Platform adventurers, sorry it’s been a while! As always there has been a few life events going which has taken my focus. However fear not for I am back with aplomb, this time showing you how to become the Gandalf of your SharePoint realm, through the use of a deceptive little feature called SharePoint Webhooks.

You have probably heard of them in the past, however what you may not know is that they can be used to solve a problem which I have frequently come across during my Power Automating…. How can you trigger the same workflow from multiple SharePoint lists?

It sounds such a simple thing to achieve! But unfortunately the SharePoint connector in Power Automate requires you to specify a specific site collection and list to enable it to trigger, meaning you are unable to create a single flow should you want to run the same logic from multiple SharePoint lists.

The workaround is to create copies of the logic flow and then bind each copy to every list you wish to trigger from thus creating a lovely ongoing management web of nightmares… yuck!

Enter SharePoint Webhooks to save the day!

This post is your enchanted map to mastering the mystical art of SharePoint webhooks with Power Automate. Say goodbye to the days of managing a labyrinth of copied flows across multiple SharePoint list or libraries. It’s time to centralise your power!

So thankfully there is a solution, a way to write the main logic you need once, and have multiple lists all call the same workflow, passing in the source so you are able to differentiate (if needed) where the workflow is being called from, step forth these noble SharePoint Webhooks.

So, what are SharePoint Webhooks anyway, is it a form of digital fishing ?

So according to this MS Learn article: SharePoint Webhooks enable developers to build applications that subscribe to receive notifications on specific events that occur in SharePoint. When an event is triggered, SharePoint sends an HTTP POST payload to the subscriber.

Webhooks are easier to develop and consume than Windows Communication Foundation (WCF) services used by SharePoint Add-in remote event receivers because webhooks are regular HTTP services (web API).

Right so what does that mean for us … in normal people speak you can setup a listener workflow which will be called when an event happens on a SharePoint list. In the above parlance our subscriber will be a Power Automate workflow, which will be the recipient of the HTTP POST payload when a Webhook event is triggered on our source list.

Typically a SharePoint webhooks implementation is done through pro code and azure functions however there is a way to stay within the “Low Code” world of Power Automate, this is where we will focus our attentions. Our web hooks solution forms three main parts, all of which are Power Automate workflows, with each covering a specific required aspect of the webhook world, these are as follows:

  1. The Scheduler
  2. The Handler
  3. The Deleter

So as you can see there are three amigos to the webhooks solution, this post will focus on the initial worker bee of the dynamic Webhook trilogy, “The Scheduler”, whose job is simple, create the subscription for each site and list, this is the configuration that says “when there is an update for a file go and notify this web address”.

And yes you have guessed correctly the web address that the webhook will notify will be that of our second actor in the set “The Handler”, more on that on the next post.

So for now lets focus on the setup of the scheduler which you will be glad to hear is relatively simple:

1. The Scheduler

So here we are scheduler creation, step 1 of a few.. The first thing to configure is to set the Power Automate as a manual trigger, passing in a value of the Handler URL, this value is used further down in the flow, when the SharePoint webhook is created. So far so simples!

The next step to SharePoint webhooks glory is to create a variable with a value of the current running flows name (it’s basically a UID); this is used later on in the scheduling process, as we need it to flag the source of the SharePoint webhook when its created. this is done simply through the following code:

workflow()?['name']

Once we have the flow name, the next step is to setup the HTTP headers, as we are using this couple of times in the process it makes sense to create a reusable variable for this, so we create an object with the following value:

{
"Accept":"application/json;odata=nometadata",
"Content-Type":"application/json"
}

With the HTTP headers sorted, then next step on the path to SharePoint webhooks greatness is to setup a collection of sites for which we want to schedule the webhook.

There may be a situation where you wish to configure the webhook to be triggered off many sites, to do this we create a collection of site addresses in an Array object and then loop each one, creating the SharePoint webhook for each, the code for this is pretty simple:

[
"FQ SharePoint site address"
]

Next on the list is the loop to actually run through each of the above sites so we simply just pass the output of the above configuration into an “Apply to Each”

Now we looping! and can get to the fun part, we use the Send an HTTP request to SharePoint to go and find all the lists that are on that SharePoint site, to do this is relatively simple once you have the site address, the main things on this call is to ensure that you are using a “GET” method and a url as follows

_api/web/lists?filter=BaseType eq 1 and Hidden eq false

Also make sure to pass in your “Headers” variable we created previously! This will return a JSON formated list of all lists within the current SharePoint Site Collection, it will be a big list!

So, next on the SharePoint Webhooks hit parade we need to extract only the list titles from everything that is returned from the query above, to do this we run a selection action against the output from the above HTTP request. So we pass in the output value from the previous step and “Select” just the “Title” key using the below code:

item()?['Title']

Now, we have an array in a filtered list of lists….. or filtered list of “SharePoint lists”, specifically containing the titles, so the next step is used to filter that list to find the name of the list you want to focus on. This step could be excluded if you want to setup the webhook on all lists in your SharePoint site collection, however if there is a specific set you can filter them using this process.

If there are more you can just amend the filter query to include others with a logical function configuration using “or”, thanks Tom Rita, whose article helped with the syntax!

or(equals(item()?['Title'], 'Documents'),equals(item()?['Title'], 'Policies'))

However for this config we only want to focus on the “Documents” list.

So, we have filtered, we have filtered again …. sounds like a rather expensive alcoholic beverage…and now we do something with the filtering. The next step is to create the full path of the list which will be used in the next step to be able to find out what webhook subscriptions are currently enabled for that list.

concat('_api/web/getbytitle(''',item()?['Title'],''')/subscriptions')

Using the list title variable we build the HTTP query to find the subscription.

And now for the next step on the magic SharePoint webhooks train, here we loop through each of the potential outputs from the list subscription paths and run a HTTP GET request to get the full details for each list subscription.

We again use the headers variable to get the correct values back, and reference the parent loop “site” in the site address, with this structure we can loop through any number of sites and and number of lists.

Once we get the all the subscriptions, we then use these output details in the next step.

Now action step checks to see if there is any subscriptions that have been configured by this current workflow id; as we don’t want to create a subscription if there is has already been on scheduled by this workflow previously.

All we do to check there is no existing subscriptions is to filter the returned subscription details and look for values where the clientState value is set to the flow name variable we created at the beginning.

Once we have filtered the HTTP response to see if there are any matching subscriptions we then run a condition to check whether the body response has a value, if it does then we have a matching subscription. The code for this is as follows, coupled with an (“is equal to” false)

empty(body('Filter_clientState_values'))

If there is no response then there is no existing subscription present and we are free to set this up for the current SharePoint list within the current SharePoint site collection. So let’s move onto the final scheduling step!

And here we are, if you have made it this far then I salute you, it’s been a fair old trek to this point! We are finally at the point of achieving what we set out to do at the beginning, after lots of filtering and sorting and more filtering and extracting we have all the correct data to actually setup our new webhook!

To do the setup its a pretty easy affair, we simply run a POST request using the current site address and subscription address, which we have created previously and pass in a body with the relevant key values to setup the subscription.

There are a few parameters here to configure within the Body:

{
"resource":"",
"notificationUrl":"triggerBody()['text']",
"expirationDateTime":"addDays(utcNow(),180)",
"clientState":"variables('varFlowName')"
}

And with the web hook configured, we are job done and can move on, we can finally pass go and definitely collect the £200 as I think we have earned it…

The final piece of the scheduling puzzle is to return an HTTP response 200 “OK” message, this isn’t needed for a manual run of the scheduling workflow however it is needed when this workflow is run from the handler, (yes I know it sounds like an infinite loop, however there is a reason) which thankfully we will cover in the next post.

So in the intricate web of SharePoint webhooks, where workflows multiply like eager hobbits embarking on quests, I hope this first part in our trilogy stands as a beacon of wisdom. Much like the One Ring in Middle-earth, our new solution will unite disparate processes, binding them into a singular, powerful flow.

As Gandalf once intoned: “One Flow to rule them all, One Flow to find them, One Flow to bring them all and in efficiency bind them.” So there we have it, the first step in our super connected world of SharePoint web hooks and Power Automate is complete, stay tuned for the next post where we will delve deep into “The Handler”.

Scroll to Top