Best practice for syncing mailbox state, Deltas vs. Subscriptions - microsoft-graph-api

I am building a CRM which handles email exchange in the app by processing emails sent to the Office365 accounts of the users using Microsoft Graph API. What is the best practice to keep track of emails in the actual mailbox? Should I use delta's or subscriptions?
From what I can tell, Delta's are URLs which give data about the current state of the mailbox, but deltas need to be triggered on a regular basis (I'd use a CRON job) but then I'd be running the process a lot more than needed because users don't receive that many emails per day.
Alternatively if I use a subscriptions that will let me know when a new email is received and I can process using a webhook in my app.
From the Microsoft Graph documentation it seems like deltas are the way to keep track of changes, but I feel like since all I need is to know when a new email is received so that it can be processed accordingly, delta's would be overkill in a sense.

You use a combination of the two.
The webhook tells you the mailbox has changed, the delta tells what has changed in the mailbox. When you receive a notification, you pull the delta to retrieve the changes to the mailbox.
There are many reasons for doing this, but the primary one is that the id of an email can change. This is because Message IDs are a composite value that includes the folder it is stored in. So if the message gets moved, the Id you received in the notification will be invalid. Historically this was a somewhat rare race condition, but with the advent of interactive mobile notifications, it is now commonplace for an email to come in and instantly get "archived". By relying on webhooks for notifications and deltas for content, you avoid a CRON job while mitigating the Id changing before you can process the message.

Related

Restrict outgoing Twilio SMS messages to Verified Caller IDs

By default, Twilio trial accounts can only send SMS to numbers that are listed as Verified Caller IDs in the Twilio console. These numbers have to be added manually, and require a verification message before they can receive SMS. This is an excellent feature for development, as it prevents accidentally sending SMS to wrong numbers.
My problem, is that I am developing for a client whose account is already out of trial status. I don't want the software in development to be able to send text messages to any number, because there is a risk of sending dev messages to the client's actual customers. However, we need to be able to send to some numbers for testing. Is there any way to turn the trial behavior back on? That is, can we somehow configure Twilio to only allow sending SMS to verfied numbers, even if it is not a trial account?
If this isn't possible, I think I can query the Outgoing Caller IDs resource from my program to verify the recipient number against the list before sending. However, this puts the responsibility back on my development team, and the possibility for mistakes remains. I'd like to be able to block the behavior at the Twilio level.
This behavior is only applied for trial accounts, however I'll pass this feedback on internally.
You'll need to replicate this behavior yourself for your applications using an upgraded account.
As you mentioned, you can query the Outgoing Caller IDs to get the phone numbers you have already verified with Twilio and use that as an accept list.
However, for your use case, you can store and fetch the accept list using whatever way is most convenient for you, like in code, file, database, etc.
Depending on your needs, you could embed this logic directly into your app, or use a single shared library, or create a web API that all other apps have to use to send texts.
Good luck! We can't wait to see what you build!
Update after getting internal feedback.
You can create a new trial account, even with the same Twilio profile, which would give you promotional credits and the same verified Caller ID limits again.
The promotional credit should last you a long time for test scenarios.

Graph Subscription Email Resource For All Emails

I am working on a system that allows the user to log their email conversation to our CRM.
This uses MS Graph subscriptions that create a subscription to a given email conversation. We then process the Graph notifications. When creating the subscriptions we set the resource like this:
/users/{id}/mailFolders('inbox')/messages
/users/{id}/mailFolders('sentItems')/messages
This gives us notifications for when the user sends or receives an email on that conversation thread.
This works great, but we discovered that if the user has a rule set up to send items with a certain subject to a different folder, when receiving a new email that they have subscribed to, we don't receive a notification.
I am guessing that this is due to us subscribing to the inbox and sentitems but not the custom folder that they have their rule directed to.
I noticed that there is also a way to set the resource as:
/users/{id}/messages
Can someone tell me whether this will set up the subscription to receive emails from all folders?
If this is the case, we wouldn't want to receive notification for example when the user deletes and email.
Additionally, we currently create 2 separate subscriptions. Is there a way to create a subscription for more than 1 resource (e.g.inbox and sentitems) under the same subscription?
thanks
The resource path users/{id}/messages is just a shortcut to the one with the inbox mark folder. A subscription to it will only notify you of emails going to that folder.
A subscription only allows you to subscribe to one resource at a time. You could use JSON batching to create/maintain multiple subscriptions in the same call, but that would only be beneficial to reduce the number of http requests.
You'll need to subscribe to each folder you want to get notified for, a request to users/{id}/mailFolders should give you a list of the folders for the inbox.

How to identify the customer on a server-sent event for Apple subscriptions?

Implementing subscriptions on an iOS app means we want to handle SSEs in case of subscription status change, as to manage the user's rights inside the service.
The Apple documentation doesn't show an explicit customer GUID.
They provide, in each SSE's payload, receipts, e.g. the latest one.
The question is: how can an API server uniquely identify customers?
Should the API server keep track of every receipt, in an inheritance way?
I.e. should the API persist every receipt, and a link to the previous receipt, up to the first
one that was emitted (which can be linked to a customer through the iOS app the user used to initiate its subscription), and re-trace this history on every SSE?
Per this thread, the applicationUsername service-side UUID (used by apple, for "irregular activity checking") isn't a solution, as it isn't provided in receipts or SSEs. The thread hints that using the transaction IDs is still the best way to identify a SSE, as it is ultimately tied to a user, and it is up to the service to keep track of transactions made by the user on the Apple platform for the given service.
Isn't there an easier, more direct, way, to establish the relationship between a SSE, its apple customer, and the service's user?
After digging for a while and asking around, I reached the following conclusion:
There is only one way to tie a transaction event to a user, and that is by the
restoration mechanism one has to implement on their application.
For this reason, you need to at least keep track of original transaction IDs,
so when the restoration mechanism is triggered on your app, you can check the
currently logged user on your app, and call your back-end with the logged user,
and a list of original transaction IDs.
Usually, when a user subscribes, it is mainly done from within your app, so you
can do this link in a trivial way.
But, because you can "re-subscribe" from the AppStore after a while, without
going through your app, Apple may send a SSE to your back-end which would contain
a new (hence unknown) original transaction ID, since this new subscription is
has a new transaction.
In short,
You need to keep at least a DB of original transaction IDs you receive as SSEs
You need to implement the restoration mechanism as to contact your server every
time the app starts, with the list of transaction IDs / original transaction IDs Apple gives you
You need to accept having transactions stored in your backend without a link
to a user (because the user may have re-subscribed without launching the app yet)

Managing PushSubscriptions within shared browsers

Working on ironing out some UX considerations around a push notification system using WebPush and ServiceWorkers. Additionally, this system should gracefully handle multiple users sharing the same browser.
More concretely, I have the following constraints:
1) A user should not be able to see notifications which are not intended for them.
2) The state of a user's push subscription should be opaque to and immutable by other users. i.e. the state of my push subscription should not be based on the behavior/actions of anybody but my own.
Satisfying the first constraint was quite straightforward. I decided to store the currently logged-in user id in IndexedDB and include the id of the intended user within the push payload. It is then straightforward to only show the push notification to the user if those 2 ids match.
However, satisfying constraint 2 has proved to be quite elusive. So far I've tried:
1) One-to-one mapping between users and push subscriptions. This was the first thing I tried, as it struck me as the most natural mapping. However, this ends up falling flat on its face as creating a new push subscription will invalidate the subscription for the previous user, thus requiring the original user to create another subscription on subsequent logins, thus failing the second constraint.
2) Shared push subscription. This has the benefit of not invalidating the push subscriptions, so subsequent logins for the original user will behave as expected. However, none of the subsequent users will actually need to grant permission to the browser, thus failing the second constraint.
3) Even if I was able to get something working with one of the above 2 options, there is still nothing preventing another user from simply going to the browser settings and disallowing notifications, thus nuking all push subscriptions. However, I imagine that this is just something I will have to live with that will have no elegant solution.
I'm certain there have been many brilliant minds working on the above problem, so I'm all ears with regards to how constraint 2 above has effectively been satisfied.
Thanks.
I had the same problem when I was developing Pushpad. We tried different solutions and some of them, such as the many to many relation between users and browsers, became a nightmare very soon. So I would recommend the following approach, which proved to be the best one for us.
Each subscription (endpoint) is a device (browser) and can be associated at most to one user at a time. Whenever possible try to keep data associated to users and not to devices. In this way a subscription (endpoint) can be transferred to a different user and you don't loose data when the endpoint expires or gets replaced. Then when you need to send a notification filter your audience based on the user data, find the recipients and send the notification to the associated devices.
The only data that you may want to associate to devices are device preferences and device preferences are global to all the users that use that browser. This is consistent with the fact that the browser permission (allow / block) is global to all users.
The above solution partially meets your requirements:
1) A user should not be able to see notifications which are not intended for them.
Yes:
when a user logs out you can remove the association between the user and the device
when a browser (user) logs in with a different account on your website you associate the device to the new user (and you remove the previous association)
2) The state of a user's push subscription should be opaque to and immutable by other users.
Yes, because you don't keep data associated to the device. You associate data to the users in your database.
There is no way to satisfy both constraints. You will need to choose either the one-to-one mapping (1) or the shared push subscription (2). You cannot use the browser to deliver your push notifications and at the same time expect certain behaviour (w.r.t. permissions, nuking) from that very same browser...

Slack: How to track when team members log out?

I'm using Slack's Real Time Messaging API to track when my team members log into or out of Slack. Using the presence_change and manual_presence_change events I am notified when someone explicit changes their presence state (or if they're automatically set to "Away" after a period of inactivity).
But if a team members logs out (e.g. closes the Slack app) I do not receive any type of notification. Am I missing something or is there no way to be notified when someone logs into or out of Slack? I really don't want to have to resort to polling.

Resources