How To Call Azure Function From SharePoint List Using Webhook

Ahamed Fazil Buhari
 
Senior Developer
December 18, 2018
 
Rate this article
 
Views
5499

Hello everyone,

In my previous articles we’ve seen more on azure function and I hope you are now familiar with it. Now it’s time to make use of Azure Function in your SharePoint. In real time application, it’s important to integrate your SharePoint List and Azure function, one of the better approach is to make use of SharePoint list webhooks. Well, I have already written an article on webhook create, read, update and delete – CRUD on SharePoint List Webhook using Postman, and now we need to create a webhook azure function which will be subscribed to SharePoint List.

Azure Function v1.x works better with SharePoint stuff because Azure Function v2.x is in .NET Core 2 framework and if you Azure Function is v2.x and there’s no way to change the version from UI then you can change it from Azure CLI, please refer this article – How to change Azure Function App version using Azure CLI

Here, I have my azure function which is v1.x and I create a function from Generic webhook template,

 

 

Nothing has been added so far and my webhook works fine

 

We need to change little bit on the code, because to make our azure function as notification URL, then we need to return validationToken (within 5 seconds).

 #r "Newtonsoft.Json"
 
 using System;
 using System.Net;
 using Newtonsoft.Json;
 
 public static async Task<object> Run(HttpRequestMessage req, TraceWriter log)
 {
     log.Info($"Webhook was triggered!");
     // Get the validationToken URL parameter
     string validationToken = req.GetQueryNameValuePairs()
         .FirstOrDefault(q => string.Compare(q.Key, "validationtoken", true) == 0)
         .Value;
 
     if (validationToken != null)
     {
       log.Info($"Validation token {validationToken} received");
       var response = req.CreateResponse(HttpStatusCode.OK);
       response.Content = new StringContent(validationToken);
       return response;
     }
     log.Info($"SharePoint triggered our webhook");
     var content = await req.Content.ReadAsStringAsync();
     log.Info($"Received following payload: {content}");
 
     var notifications = JsonConvert.DeserializeObject<ResponseModel<NotificationModel>>(content).Value;
     log.Info($"Found {notifications.Count} notifications");
 
     if (notifications.Count > 0)
     {
         log.Info($"Processing notifications...");
         foreach(var notification in notifications)
         {
             // add message to the queue
             log.Info($"Before adding a message to the queue. Message content: {notification}");
             // Process your request here - better way to user ChangeToken to get latest update from SharePoint
             // Add this notification to Azure Queue and let it take care rest
             log.Info($"Triggered time is {DateTime.Now.ToUniversalTime()}");
         }
     }
 
     // if we get here we assume the request was well received
     return new HttpResponseMessage(HttpStatusCode.OK);
 }
 
 // supporting classes
 public class ResponseModel<T>
 {
     [JsonProperty(PropertyName = "value")]
     public List<T> Value { get; set; }
 }
 
 public class NotificationModel
 {
     [JsonProperty(PropertyName = "subscriptionId")]
     public string SubscriptionId { get; set; }
 
     [JsonProperty(PropertyName = "clientState")]
     public string ClientState { get; set; }
 
     [JsonProperty(PropertyName = "expirationDateTime")]
     public DateTime ExpirationDateTime { get; set; }
 
     [JsonProperty(PropertyName = "resource")]
     public string Resource { get; set; }
 
     [JsonProperty(PropertyName = "tenantId")]
     public string TenantId { get; set; }
 
     [JsonProperty(PropertyName = "siteUrl")]
     public string SiteUrl { get; set; }
 
     [JsonProperty(PropertyName = "webId")]
     public string WebId { get; set; }
 }
 
 public class SubscriptionModel
 {
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
     public string Id { get; set; }
 
     [JsonProperty(PropertyName = "clientState", NullValueHandling = NullValueHandling.Ignore)]
     public string ClientState { get; set; }
 
     [JsonProperty(PropertyName = "expirationDateTime")]
     public DateTime ExpirationDateTime { get; set; }
 
     [JsonProperty(PropertyName = "notificationUrl")]
     public string NotificationUrl {get;set;}
 
     [JsonProperty(PropertyName = "resource", NullValueHandling = NullValueHandling.Ignore)]
     public string Resource { get; set; }
 }
 

Well, inside notification foreach loop, we can make use of Azure Queue to add the data and process it in different function, instead of processing inside the webhook function itself.

And I changed my function mode to Standard and authorization level to Anonymous (for simplicity) and click on Save.

 

Now I need to get URL of my function and that URL as notificationUrl

when we create subscription for SharePoint List, please refer this article to know more about, CRUD on SharePoint List Webhook using Postman . I am using postman to send subscription request, make sure you have provided values for Headers (namely – Accept, Content-Type, Authorization)

Once we click on Send, our webhook will be triggered and it will return back the validationToken

And in the post man you will receive following response

Now whenever I add or update or delete an item in my SharePoint list with the id: 1d1b350e-9f9d-4474-a8cd-a25f20afb77c, then this Azure Webhook will be notified. For other functionalities like update, read and delete subscription you need to change the Method please refer this article to know more -> CRUD on SharePoint List Webhook using Postman

 

Happy Coding

Ahamed

Category : Azure

Author Info

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Ahamed is a Senior Developer and he has very good experience in the field of Microsoft Technologies, especially SharePoint, Azure, M365, SPFx, .NET and client side scripting - JavaScript, TypeScript, ...read more
 

Leave a comment