Webhooks v/s polling for all users drives' within an Org (multi-tenant) - MS Graph - microsoft-graph-api

We are going to have a multi-tenant application that is going to be scanning files for each user per organization for multiple orgs. We would like to get notification if any user uploads/changes a file in the drive. There are at-least 2 options to retrieve those: either store delta link for each user and poll periodically to get the change or subscribe using webhooks to get notification on change. If we have 10k+ users, I am not sure if the first option is feasible. For the latter one, my only concern with webhook is do I have to register for each user separately? ie., does the resource need to be /users//drive/root or should it just be /drive/root? Since there is a limitation of no. of webhooks per app/tenant, I am not sure if creating webhooks for each user is a right approach.
Please advise.

The limitation applies to the users/groups objects (i.e. if you wanted to subscribe to users/groups being updated), not to the drives.
Yes, you need to subscribe to each drive individually, and to renew the subscriptions individually as well. If you want to save the number of roundtrips, you can group those operations in a batch.
You can also combine the delta + webhooks: do the initial sync with delta and store the token, register your webhook. And then trigger querying the delta link upon receiving a change notification. This way you get the best of both features and avoid regularly polling delta when there might not be any change.

Related

How to make external api call more efficient

I’m building a shipment tracking system. I have an external service that I can make an API call to get the shipment status. Whenever a shipment status changed, I wanna get notified.
What would be the most efficient way to call the external api to check the status of the shipments? Imagine I have 1 million shipments to track.
You should try to set up a webhook from the external service to your server. When a shipment changes status, the external API should call an endpoint on your server. This is a very common practice for use cases like yours where statuses change and you need to be notified.
Otherwise, you'll just have to poll the API periodically. I'd suggest fitting your calls to the expected pattern of status updates (e.g. if a shipment typically takes a minimum of 2 days to update, then wait 2 days before checking for a status update)

How to start using Delta function in Microsoft graph by skipping initial data

Microsoft recommends to use delta function in combination with Subscriptions/Notifications to synchronize mailbox. So my plan is:
Create subscription
Receive notification about new mail in inbox
Use delta function to get latest changes in the inbox
My mailbox already has several thousands of letters. If I run the query
https://graph.microsoft.com/v1.0/users/{id}/mailFolders/inbox/messages/delta
It will return in response #odata.nextLink with $skiptoken param many times and only after I get all the thousands of emails in my mailbox I will receive response with $deltatoken to track new changes.
Is there a way to get deltatoken after the first request? I don't want to synchronize the old messages. I want to skip all old messages in inbox and have a fresh start.
Today the delta query functionality does not support this scenario. To request new features please post ideas to uservoice
This is supported for some endpoints. You can use $deltaToken=latest to get just a deltaToken without any resource data. It's not, as far as I can tell, available for mailboxes… but who knows, maybe it will be soon.
This is not documented anywhere in the documentation for the specific APIs that do support it, but is instead documented in the Overview for change tracking. Why? Because Microsoft wants you to be sad all the time.

How can I poll the OneNote API frequently without hitting rate limits?

I have a use case where I need to poll the OneNote API approximately every minute in order to respond to text added to pages by the user.
(Aside: I'd LOVE to use webhooks to get notifications only when something changes, but that's only supported for consumer notebooks at this time, as far as I can tell.)
Polling with this frequency works for a few users (5 or so), but then, with more users who authorized the same Microsoft application, the app seems to hit an application-level rate limit and begins receiving 429 Too Many Requests responses.
How can I ensure polling will still work as the number of users grows? And are there any rate limits that can be made public or shared in confidence for valid use cases?
So it is possible to register for webhooks on the sharepoint notebooks as onedrive items - as a notebook page gets updated the notificationUrl fires and you can then using delta calls to determine which sections (section.one files) have been updated.
I would then use the onenote-api to get the pages in the updated notebook sections GET https://www.onenote.com/api/v1.0/me/notes/sections/{id}/pages
An alternative would be to treat the sharepoint drive as a webdav server and use the propfind method with the getlastmodified property to poll the drive determine which sections of various notebooks have been updated.
But I agree it would be easier if onenote webhooks were extended to sharepoint.

Microsoft Graph API: No web-hooks for some emails

We use Microsoft Graph to subscribe to webhooks from emails. Additionally, as a backup procedure we also crawl the messages directly.
We crawl around 5 million emails a day, and we see that each day consistently around 1%-2% of these emails are not sent to us via the webhook, although the subscription for this principal is active (and other email notifications from this user are indeed sent).
Is there any logic on the Microsoft Graph side to not send webhooks for certain types of emails by design? or is it just a problem on the notification mechanism?
(Obviously crawling them, as we do now, is a viable backup option, but that also means the processing of the email will be delayed)
I currently have a similar webhook setup and we get around 200-300 emails and I notice that the subscription service usually misses out on 1-2 per day since sometimes some emails come around at the same time. I have also noticed that the data structure is an array of objects when we get two or more emails at the same time. What we have put into place is basically a cron scheduled script that checks the mailbox on specific time intervals, such as every 5 minutes, every 10 minutes and so on. This is the only solution that has worked for my application to capture every single email.

signalr notifications based on nonweb originating events

Our system has two servers (S1) one is running processesing and data storage (basically DB) and the other one is a webserver (WS).
There are two types of even that can happen in the system:
User A pings User B. In this case we check if user B is logged in and we push a notification to User B client throw SignalR. It works.
Services constantly running on S1 and generating new data that concenrs multiple users. My goal is as soon as a new data important for user A is generated I immediately want to dispatch a signalR notification to user A client provided he/she is logged in.
This part 2 is not quite clear for me how to design. My thought right now is to start an indefinite process on webserves that monitors our DataBase and checks if new records are generated fpr this user and then push a SignalR message.
That would be fine, but now we have 10k users logged in and I don't think the right decision would be run 10k threads monitoring activities.
Basically, my question is what would a proper way do design signalR based notification mechanism that is based on events that are not originated on our webserver.
I would use a service bus or mq, for example this Free MQ https://www.rabbitmq.com/
You can proxy the messages direcly to the Clients using this proxy library (I'm the author).
Doc's here https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/wiki
Demo https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/tree/master/SignalR.EventAggregatorProxy.Demo.MVC4
You can also set up a sql dependency that triggers a message to your signalr clients,
http://techbrij.com/database-change-notifications-asp-net-signalr-sqldependency
This link is the one that I based my code on.
couple of things to watch for, the setup of the table. You cannot use 3 part table names
"SELECT [CMRID],
[SolutionID],
[CreateDT],
[ModifyDT]
**FROM [dbo].[Case]**
WHERE [ModifyDT] > " + LastExecutionDateTime;
Also, and this is very important, you MUST reset the event handler every time the dependency triggers, if not it will work the first time and then stop working.
I hope this helps you.

Resources