Advertisement
commodore73

https://deliverystack.net/2021/04/02/part-i-use-update-webhook-handlers-to-update-entries-in-content

Apr 2nd, 2021 (edited)
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.23 KB | None | 0 0
  1. namespace azfwhook
  2. {
  3.     using System;
  4.     using System.IO;
  5.     using System.Net;
  6.     using System.Threading.Tasks;
  7.  
  8.     using Microsoft.AspNetCore.Mvc;
  9.     using Microsoft.AspNetCore.Http;
  10.     using Microsoft.Azure.WebJobs;
  11.     using Microsoft.Azure.WebJobs.Extensions.Http;
  12.     using Microsoft.Extensions.Logging;
  13.  
  14.     using Newtonsoft.Json;
  15.     using Newtonsoft.Json.Linq;
  16.  
  17.     public static class WebHooks
  18.     {
  19.         //TODO: SECURE THIS ENDPOINT!!!!!!!
  20.         //  [HttpPost] // only handle POST (get support is handy for smoke testing in a browser)
  21.         [FunctionName("AnyEntryUpdated")] // API method name (Webhook handler)
  22.         public static async Task<IActionResult> Run(
  23.             [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest webhookRequest,
  24.             ILogger logger)
  25.         {
  26.             try
  27.             {
  28.                 // webhook JSON payload from CMS
  29.                 string sWebhookBody = await new StreamReader(webhookRequest.Body).ReadToEndAsync();
  30.  
  31.                 if (String.IsNullOrWhiteSpace(sWebhookBody))
  32.                 {
  33.                     // no JSON payload
  34.                     return new StatusCodeResult((int)HttpStatusCode.BadRequest);
  35.                 }
  36.  
  37.                 JObject webhookBody = JObject.Parse(sWebhookBody);
  38.  
  39.                 // ID of saved entry
  40.                 JToken uid = webhookBody.SelectToken("$.data.entry.uid");
  41.  
  42.                 if (uid == null || String.IsNullOrWhiteSpace(uid.ToString()))
  43.                 {
  44.                     // no entry UID
  45.                     return new StatusCodeResult((int)HttpStatusCode.BadRequest);
  46.                 }
  47.  
  48.                 // collect entry validation error messages
  49.                 string validationMessages = String.Empty;
  50.  
  51.                 // when this process last ran
  52.                 JToken lastRan = webhookBody.SelectToken("$.data.entry.lastran");
  53.  
  54.                 if (lastRan == null)
  55.                 {
  56.                     validationMessages += "The lastran field does not exist." + Environment.NewLine;
  57.                 }
  58.                 else if ((!String.IsNullOrEmpty(lastRan.ToString()))
  59.                     && DateTime.Parse(lastRan.ToString()).AddSeconds(1)
  60.                     > DateTime.Parse(webhookBody.SelectToken("$.data.entry.updated_at").ToString()))
  61.                 {
  62.                     // logic ran against entry within the previous second;
  63.                     // avoid infinite update webhook/handler recursion
  64.                     return new StatusCodeResult((int)HttpStatusCode.OK);
  65.                 }
  66.  
  67.                 // CMS API endpoint for entry
  68.                 //TODO: shouldn't be hard-coded
  69.                 string url = "https://api.contentstack.io/v3/content_types/authors/entries/" + uid;
  70.                 HttpRequestHandler wfStageReqHandler = new HttpRequestHandler();
  71.                 JObject wfStageBody = JsonConvert.DeserializeObject<JObject>(
  72.                     await wfStageReqHandler.ProcessRequest(url + "?include_workflow=true"));
  73.  
  74.                 // current workflow stage of entry
  75.                 JToken wfStage = wfStageBody.SelectToken("$.entry._workflow.name");
  76.  
  77.                 if (wfStage == null)
  78.                 {
  79.                     validationMessages += "The entry has no workflow stage." + Environment.NewLine;
  80.                 }
  81.                 else if (wfStage.ToString() != "validation")
  82.                 {
  83.                     // only validate in validation workflow stage or no workflow stage
  84.                     return new StatusCodeResult((int)HttpStatusCode.OK);
  85.                 }
  86.  
  87.                 validationMessages += ValidateDates(
  88.                     webhookBody.SelectToken("$.data.entry.dateone"),
  89.                     webhookBody.SelectToken("$.data.entry.datetwo"));
  90.  
  91.                 if (String.Equals(validationMessages, webhookBody.SelectToken("$.data.entry.validationmessages").ToString()))
  92.                 {
  93.                     // no updates to commit
  94.                     return new StatusCodeResult((int)HttpStatusCode.OK);
  95.                 }
  96.  
  97.                 // update the entry with the new validation results and record time of operation for use avoiding recursion
  98.                 JObject postBody = new JObject(
  99.                 new JProperty("entry", new JObject(
  100.                     new JProperty("validationmessages", validationMessages),
  101.                     new JProperty("lastran", new DateTime(DateTime.UtcNow.Ticks, DateTimeKind.Utc)))));
  102.                 HttpRequestHandler requestHandler = new HttpRequestHandler();
  103.                 string discard = await requestHandler.ProcessRequest(url, postBody);
  104.             }
  105.             catch (Exception)
  106.             {
  107.                 //TODO:...
  108.                 return new StatusCodeResult((int)HttpStatusCode.InternalServerError);
  109.             }
  110.  
  111.             return new StatusCodeResult((int)HttpStatusCode.OK);
  112.         }
  113.  
  114.         private static string ValidateDates(JToken dateOne, JToken dateTwo)
  115.         {
  116.             string result = String.Empty;
  117.  
  118.             if (dateOne == null)
  119.             {
  120.                 result += "The first date field does not exist." + Environment.NewLine;
  121.             }
  122.             else if (string.IsNullOrWhiteSpace(dateOne.ToString()))
  123.             {
  124.                 result += "The first date field does not contain a value." + Environment.NewLine;
  125.             }
  126.  
  127.             if (dateTwo == null)
  128.             {
  129.                 result += "The second date field does not exist." + Environment.NewLine;
  130.             }
  131.             else if (string.IsNullOrWhiteSpace(dateTwo.ToString()))
  132.             {
  133.                 result += "The second date field does not contain a value." + Environment.NewLine;
  134.             }
  135.  
  136.             // if there are any validation messages already,
  137.             // it might not be possible to compare the dates (potential null reference).
  138.             // otherwise, compare the dates
  139.             if (String.IsNullOrWhiteSpace(result)
  140.                 && DateTime.Parse(dateOne.ToString())
  141.                     > DateTime.Parse(dateTwo.ToString()))
  142.             {
  143.                 result += "The second date must follow the first date." + Environment.NewLine;
  144.             }
  145.  
  146.             return result;
  147.         }
  148.     }
  149. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement