{"id":780,"date":"2016-09-13T00:00:00","date_gmt":"2016-09-13T00:00:00","guid":{"rendered":"http:\/\/officedevblogs.wpengine.com\/?p=780"},"modified":"2016-09-13T00:00:00","modified_gmt":"2016-09-13T00:00:00","slug":"onedrive-webhooks-and-large-uploads-with-microsoft-graph","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/onedrive-webhooks-and-large-uploads-with-microsoft-graph\/","title":{"rendered":"OneDrive Webhooks and Large Uploads with Microsoft Graph"},"content":{"rendered":"<div id=\"body-content\">\n<p>This week we&#8217;re happy to announce two new Microsoft Graph features for OneDrive files: webhook notifications and large file uploads. This functionality is available on the Microsoft Graph beta endpoint, https:\/\/graph.microsoft.com\/beta.<\/p>\n<h2>Webhook Notifications<\/h2>\n<p>By creating a subscription on a drive&#8217;s root item, your app will receive a webhook notification whenever files within that drive are created, deleted, or modified. To create a subscription, your app needs to specify the <strong>Files.ReadWrite<\/strong> permission scope and request a subscription type of &#8216;updated&#8217;. We&rsquo;ve included an example create request, response, and notification below. Make sure to visit our documentation for more details on using <a href=\"https:\/\/developer.microsoft.com\/graph\/docs\/api-reference\/beta\/resources\/webhooks\">webhooks<\/a> with the Microsoft Graph.<\/p>\n<h2>Subscription Create Request<\/h2>\n<p>To create a new Webhook notification subscription, your application sends a POST request to the subscriptions collection:<\/p>\n<p>POST https:\/\/graph.microsoft.com\/beta\/subscriptions<\/p>\n<p>Content-Type: application\/json<\/p>\n<p>{<\/p>\n<p>&#8220;changeType&#8221;: &#8220;updated&#8221;,<\/p>\n<p>&#8220;notificationUrl&#8221;: &#8220;<a href=\"https:\/\/webhookapp12345.azurewebsites.net\/api\/notifications\">https:\/\/webhookapp12345.azurewebsites.net\/api\/notifications<\/a>&#8220;,<\/p>\n<p>&#8220;clientState&#8221;: &#8220;My client state&#8221;,<\/p>\n<p>&#8220;resource&#8221;: &#8220;me\/drive\/root&#8221;,<\/p>\n<p>&#8220;expirationDateTime&#8221;: &#8220;2016-08-26T23:08:37Z&#8221;<\/p>\n<p>}<\/p>\n<p>Note: In the subscription create request it is important to use the &ldquo;updated&rdquo; change type as it is the only supported type for the drive resource.<\/p>\n<h2>Subscription Create Response<\/h2>\n<p>HTTP\/1.1 200 OK<\/p>\n<p>Content-Type: application\/json<\/p>\n<p>{<\/p>\n<p>&#8220;id&#8221;: &#8220;aa269f87-2a92-4cff-a43e-2771878c3727&#8221;,<\/p>\n<p>&#8220;resource&#8221;: &#8220;me\/drive\/root&#8221;,<\/p>\n<p>&#8220;changeType&#8221;: &#8220;updated&#8221;,<\/p>\n<p>&#8220;clientState&#8221;: &#8220;My client state&#8221;,<\/p>\n<p>&#8220;notificationUrl&#8221;: &#8220;<a href=\"https:\/\/webhookapp12345.azurewebsites.net\/api\/notifications\">https:\/\/webhookapp12345.azurewebsites.net\/api\/notifications<\/a>&#8220;,<\/p>\n<p>&#8220;expirationDateTime&#8221;: &#8220;2016-08-26T23:08:37Z&#8221;<\/p>\n<p>}&nbsp;<\/p>\n<p>Your app should track the resulting subscription ID and the user who subscribed, so that when a notification is received you can connect the notification to the user\/drive to request the changes to the drive.<\/p>\n<h2>Notification<\/h2>\n<p>When a notification is triggered, the Graph API will POST a request to your registered notification URL, similar to the following:<\/p>\n<p>POST https:\/\/webhookapp12345.azurewebsites.net\/api\/notification<\/p>\n<p>Content-Type: application\/json<\/p>\n<p>{<\/p>\n<p>&nbsp; &#8220;subscriptionId&#8221;: &#8220;aa269f87-2a92-4cff-a43e-2771878c3727&#8221;,<\/p>\n<p>&nbsp; &#8220;clientState&#8221;: &#8220;My client state&#8221;,<\/p>\n<p>&nbsp; &#8220;changeType&#8221;: &#8220;updated&#8221;,<\/p>\n<p>&nbsp; &#8220;resource&#8221;: &#8220;me\/drive\/root&#8221;,<\/p>\n<p>&nbsp; &#8220;subscriptionExpirationDateTime&#8221;: &#8220;2016-08-26T23:08:37.00+00:00&#8221;,<\/p>\n<p>&nbsp; &#8220;resourceData&#8221;: null<\/p>\n<p>}<\/p>\n<p>As you can see in the notification example, the resource data returned is null &#8211; you will need to use the <a href=\"https:\/\/developer.microsoft.com\/graph\/docs\/api-reference\/beta\/api\/item_delta\">delta<\/a> functionality (\/me\/drive\/root\/delta) on the target drive&rsquo;s root object to track state and find what changed. This ensures that a dropped notification does not result in any loss of state.<\/p>\n<p>&nbsp;<\/p>\n<h2>Large File Uploads<\/h2>\n<p>This week we&rsquo;re also adding the createUploadSession method to driveItem. This allows your application to request an upload session which allows uploading files larger than 4 MB through Graph API. To upload larger files, your application POSTs a request to createUploadSession to create a new upload session for a file.<\/p>\n<p>POST https:\/\/graph.microsoft.com\/beta\/me\/drive\/root:\/file.mp4:\/createUploadSession<\/p>\n<p>This returns a URL which your application can use to upload the contents of the file.<\/p>\n<p>{<\/p>\n<p>&#8220;uploadUrl&#8221;: &#8220;https:\/\/contoso.sharepoint.com\/_api\/v2.0\/uploadsessions123191&#8221;,<\/p>\n<p>&#8220;expirationDateTime&#8221;: &#8220;20160916T21:00:12Z&#8221;<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>Next your app logically breaks the file into fragments, each of which must be a multiple of 320KiB. For example, you could choose a fragment size of 4,259,840 bytes (approximately 4 MB) for good performance. Then, your application sequentially makes a PUT request to the <strong>uploadUrl<\/strong> and writes the uploads the contents of the next fragment. Your app must use the Content-Range header to specify which part of the file you are uploading, and must upload the file&rsquo;s contents sequentially.<\/p>\n<p>If the upload of one part of the file is unable to complete (say the connection is dropped), your app can resume the upload by remembering the <strong>uploadUrl<\/strong>. Your app can query for the current status of the upload URL by performing a GET request on the <strong>uploadUrl<\/strong>, which will return the <strong>expirationDateTime<\/strong> and <strong>nextExpectedRanges<\/strong> values, which indicate which parts of the file should be uploaded next.<\/p>\n<p>When the last part of the file is uploaded, the session is committed and the file appears inside the user&rsquo;s drive.<\/p>\n<p>We&rsquo;re excited to be rolling out this functionality to make it easier to use Microsoft Graph API for all scenarios where your app interacts with OneDrive content. Happy coding!<\/p>\n<p>&nbsp;<\/p>\n<p>Ryan Gregg, Principal Program Manager, OneDrive\/SharePoint and Matt Geimer, Program Manager II, Microsoft Graph<\/p>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>This week we&#8217;re happy to announce two new Microsoft Graph features for OneDrive files: webhook notifications and large file uploads. This functionality is available on the Microsoft Graph beta<\/p>\n","protected":false},"author":69077,"featured_media":25159,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3],"tags":[35],"class_list":["post-780","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microsoft-graph","tag-onedrive"],"acf":[],"blog_post_summary":"<p>This week we&#8217;re happy to announce two new Microsoft Graph features for OneDrive files: webhook notifications and large file uploads. This functionality is available on the Microsoft Graph beta<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/780","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/users\/69077"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/comments?post=780"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/780\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media\/25159"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media?parent=780"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/categories?post=780"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/tags?post=780"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}