Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Getting notified by SharePoint with the webhook functionality

203 views

Published on

SharePoint development is finally catching up with industry standards when it comes to implementing new functionality on your sites. Webhook is one of these standards that has been introduced in 2016 for SharePoint Online. It gives your organisation the ability to get notified when something happens in your list or library, but it involves a new way of processing these notifications. This session is for you if you want to learn to work with this newly introduced functionality like subscribing to a webhook, event processing, getting the latest changes, and more.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Getting notified by SharePoint with the webhook functionality

  1. 1. Elio Struyf | Trainer @ U2U – MVP | June 24th, 2017 Getting notified by SharePoint with the webHook functionality
  2. 2. Thanks to the Sponsors!
  3. 3. #SPSLondon - @eliostruyf What are WebHooks?
  4. 4. #SPSLondon - @eliostruyf What are WebHooks? • Event driven notifications AKA callbacks from the web • Universal model used by many services: GitHub, Slack, MailChimp, … • Pushing mechanism  asynchronous! • Implemented in various Office 365 Services • Microsoft Graph • Connectors • SharePoint
  5. 5. #SPSLondon - @eliostruyf WebHooks in SPO went GA in January 2017
  6. 6. #SPSLondon - @eliostruyf Where can you use them? • SharePoint • List • Libraries • Microsoft Graph • Messages, events, contacts, conversations in groups, OneDrive root items
  7. 7. #SPSLondon - @eliostruyf The good and the bad • WebHooks are asynchronous mechanism • Retry mechanism • 5 times with a delay of 5 minutes • More secure, no event information is passed • No support for event-ing events  only RER can be used • Add-ing, update-ing, delete-ing • Requires some setup, but once done, it is easy to maintain
  8. 8. #SPSLondon - @eliostruyf Remote event receivers vs WebHooks Remote event receivers • Synchronous (-ing) and/or async (-ed) • One request • One change = one request • Changes are inside the request body • 2 minutes to respond • Indefinitely • One try WebHooks • Async only • Retry logic: 5 times • Batched requests • Only notification  more secure • 5 seconds to respond • Needs subscription renewal • When it fails, you can try again later Both use the same base principle: call an external URI when something happens
  9. 9. #SPSLondon - @eliostruyf How to start using WebHooks?
  10. 10. #SPSLondon - @eliostruyf By subscribing to a WebHook! Notification service 1. Create a subscription 4. SharePoint responds with subscription info
  11. 11. #SPSLondon - @eliostruyf Important things about subscribing Subscribing: POST - /_api/web/lists/getbytitle('Title')/subscriptions { "resource": "https://tenant.sharepoint.com/sites/site/_api/web/lists/getbytitle('Title')", "notificationUrl": "Your notification service URL – HTTPS is required", "expirationDateTime": "Date value - maximum 6 months", "clientState": "String value for validation (optional)" }
  12. 12. #SPSLondon - @eliostruyf Important things about subscribing SharePoint calls your notification service: POST - https://notification-service?validationToken={random-guid} Respond with: Important: notification service needs to respond in < 5 seconds Status: 200 Body: validationtoken
  13. 13. #SPSLondon - @eliostruyf Important things about subscribing When validation is done, SharePoint returns the subscription information
  14. 14. #SPSLondon - @eliostruyf Local development and testing: ngrok - Secure tunnels to localhost https://ngrok.com/
  15. 15. #SPSLondon - @eliostruyf Demo Subscribing to a WebHook
  16. 16. #SPSLondon - @eliostruyf More about the notification service
  17. 17. #SPSLondon - @eliostruyf Notification service details • You choose the technology: Web API, Node.js, … • Respond in < 5 seconds and with status: 200-299 range • Retry mechanism  5 times (5 minute in between) • Not for the validation process • Receives minimal information, just a message “something” happened • Service has to gather the changes from SharePoint
  18. 18. #SPSLondon - @eliostruyf Minimal notification information?
  19. 19. #SPSLondon - @eliostruyf This is what you will receive { "value": [ { "subscriptionId":"2e7f9cd7-5cdb-4d57-b4d5-edc083202378", "clientState":null, "expirationDateTime":"2017-08-16T10:38:54.3440000Z", "resource":"465b36fc-e778-4047-8425-3f906497dfc3", "tenantId":"9fee8694-d491-4e3e-b10b-a81ee76dfad9", "siteUrl":"/sites/Webhooks", "webId":"e363e4e9-0161-495f-a652-15c618e2e963“ }] }
  20. 20. #SPSLondon - @eliostruyf How do I know what happened? • SPList.GetChanges method • POST - `/_api/web/lists(guid'${resource}')/getchanges` • Specify a change query + change token { "Item": true, "Add": true, "Update": true, "DeleteObject": true, "Restore": true, "ChangeTokenStart": { "StringValue": "1;3;465b36fc-e778-4047-8425-3f906497dfc3;636307008298500000;60877869" } } ChangeQuery properties: http://elst.es/2rib2q7
  21. 21. #SPSLondon - @eliostruyf Anatomy of the change token 1;3;465b36fc-e778-4047-8425-3f906497dfc3;636307008298500000;60877869 Version information (currently always 1) Scope of the change. 3 = List & library changes. Resource ID, can be retrieved from the subscription notification Timestamp in ticks Change number in the event cache table. You can start with -1.
  22. 22. #SPSLondon - @eliostruyf Using the change token • Using GetChanges without ChangeToken would return everything • By specifying a change token, you control what you need
  23. 23. #SPSLondon - @eliostruyf Things to know about the change token • First time, create it yourself (ex.: get all changes of the last hour) • Per GetChanges request, you get the latest change token • Store the latest change token, use it for the next call { "ChangeToken": { "StringValue":"1;3;465b36fc-e778-4047-8425-3f906497dfc3;636307074435230000;60879219" }, "ChangeType": 2, "SiteId": "1432d309-9f6a-4dae-8d35-532dec332b86", "ItemId": 3, … }
  24. 24. #SPSLondon - @eliostruyf GetChanges response value • Notice the ChangeType, it is an enumeration • 1 = added, 2 = updated, 3 = deleted { "ChangeToken": { "StringValue":"1;3;465b36fc-e778-4047-8425-3f906497dfc3;636307074435230000;60879219" }, "ChangeType": 2, "SiteId": "1432d309-9f6a-4dae-8d35-532dec332b86", "ItemId": 3, "ServerRelativeUrl":"", … "WebId":"e363e4e9-0161-495f-a652-15c618e2e963" } More information about the ChangeTypes - http://elst.es/2ruAfKn
  25. 25. #SPSLondon - @eliostruyf Supported event types • Added • Updated • Deleted • CheckedOut • CheckedIn • UncheckedOut • AttachmentAdded • AttachmentDeleted • FileMoved • VersionDeleted • FileConverted
  26. 26. #SPSLondon - @eliostruyf Creating your notification service
  27. 27. #SPSLondon - @eliostruyf Tokens, all about the OAuth tokens • Azure AD app registration • Generate a certificate • SharePoint requires access tokens with appidacr property set to 2 • Application Authentication Context Class Reference • 0 = Public client • 1 = Identified by a client id and secret • 2 = Identified by a certificate
  28. 28. Azure AD application manifest Store this in a separate file (privatekey.pem) Fingerprint is also require to get the access token
  29. 29. #SPSLondon - @eliostruyf public getAppOnlyAccessToken(config: IConfig): Promise<any> { return new Promise((resolve, reject) => { const certificate = fs.readFileSync(path.join(__dirname, 'privatekey.pem'), { encoding : 'utf8'}); const authContext = new adal.AuthenticationContext(config.adalConfig.authority); authContext.acquireTokenWithClientCertificate(config.adalConfig.resource, config.adalConfig.clientID, certificate, config.adalConfig.fingerPrint, (err, tokenRes) => { if (err) { reject(err); } const accesstoken = tokenRes.accessToken; resolve(accesstoken); }); }); } Get an access token via a certificate and private key with ADAL for JS
  30. 30. #SPSLondon - @eliostruyf Important APIs • Retrieve all list / library subscriptions GET - /_api/web/lists/getbytitle('ListTitle')/subscriptions • Update a subscription PATCH - /_api/web/lists/getbytitle('ListTitle')/subscriptions('${subId}') Body: { "expirationDateTime": "New expiration date" } • Delete a subscription DELETE - /_api/web/lists/getbytitle('ListTitle')/subscriptions('${subId}')
  31. 31. #SPSLondon - @eliostruyf Demo Sample application
  32. 32. #SPSLondon - @eliostruyf A real life setup and configuration SPO config page HTTP Triggered function Queue triggered function 1. Subscribe 2. Validate 3. Trigger change 4. Notify service 5. Put notification message on a queue6. Respond with 200 Use the page to: - Check subscriptions - Update subscriptions - Delete subscriptions 7. Trigger another Azure function that will do change handling 8. Retrieve latest change token10. Store latest change token
  33. 33. #SPSLondon - @eliostruyf Demo SPFx + Azure Functions
  34. 34. #SPSLondon - @eliostruyf Recap • Notification service has to respond in < 5 seconds • Retry mechanism  5 times (5 minute delay) • Not for the validation process • Subscription expiration date: 6 months • Create a check or renewal process in your subscription processor • You need to ask for the changes that happened  minimal information is send • Get the changes only what you are interested in • No synchronous events for SPO  event-ing events
  35. 35. Questions?
  36. 36. Office Servers & Services MVP Azure / Office 365 / SharePoint @eliostruyf www.eliostruyf.com info@estruyf.be Elio Struyf Lead trainer and architect
  37. 37. #SPSLondon - @eliostruyf Resources Certificate creation process with makecert - http://elst.es/2rhveZc Keycred GitHub - http://elst.es/2pW77vm All about the Change token - http://elst.es/2runG1M ChangeType enumeration - http://elst.es/2ruAfKn ChangeQuery properties - http://elst.es/2rib2q7 C# Sample application - http://elst.es/2qUYg0M Node.js / TypeScript sample application - http://elst.es/2qVpTqT or http://elst.es/2cycM82 SharePoint List WebHooks docs - http://elst.es/2qwl1as - http://elst.es/2quVjD0

×