Synchronizing Clients with Gmail - gmail-api

What is Synchronizing client with gmail ? Can anybody give a detailed explanation, because i want to have a better understanding over this concept.

For example, if your client keeps any local cache of the Gmail mailbox data like the Message.Id and labels, or headers, or the entire email. Then in order to update your client you're synchronizing it with Gmail--pulling new updates down to your client. In cases of clients designed for offline use, then synchronizing may also mean pushing local updates back up to the server (e.g. label updates made by client while "offline" that get applied at some later point). That's the general definition of synchronizing.
For the Gmail API specific case, Gmail has a backend mailbox-wide history Id. Any change that affects that account in any way gets a history identifier and most (but not all) history changes affect the state of email messages. Like adding a new message, changing the labels on a message, or deleting a message. Clients of the Gmail API can poll the history Id and find out what's changed since the last time they synchronized and pull down updates to maintain their sync.

Related

Placing SQL Server generated emails in Outlook Outbox

We send monthly emails generated in SQL Server(2017) using sp_send_dbmail to clients containing sensitive data. Recently, there's been a breach where a client received something they shouldn't have received. The cause of this is honestly just bad code, but going forward we want to be able to screen emails more effectively. We are now avoiding the sensitive data issue by asking clients to log in to our system to look at this data instead. Whilst this would be perfectly normal procedure, certain people demand everything in an email. It's a security problem, but the client wants what they want, and the head honcho wants to give the client what they want.
We use Outlook, which has an outbox that nobody really uses anymore as far as I know. Is there a way to get SQL Server to place emails into a shared outbox account so that we can screen emails that contain sensitive data before we send them out?
For initial QA, data for emails containing alerts are generated via stored procedures and sent to QA analysts to check over. This is done by manually setting the recipients to the QA analysts for emails to all clients.
We don't expect them to cover every email as that would be insane, so we ask that they check a random selection to be confident enough that the data is accurate.
Once they are happy, we run the stored procedures again but we pass a parameter so that it cursors through a table that contains every email alert for each client and generates the tailored email for each client and is sent using sp_send_dbmail.
In other words, the email being screened by the QA analysts might not be the same as the email send to clients. This is how the breach occurred.
If we had a way to get these emails into a shared outbox, the QA work can be done on that shared outbox and then we can send the emails. Asking someone to hit send for a big bunch of emails would still be a pain, but perhaps a little less so than having another breach.
AFAIK sp_send_dbmail uses SMTP to send messages. If you want to place messages in the Drafts (or any other) folder of a particular mailbox, you will need to create messages (without sending) using Graph or EWS.

Webhook Subscription for AzureAd groups and Users not working

I have created a webhook subscription for Users and Groups by making a POST call to https://graph.microsoft.com/v1.0/subscriptions with the following as payload:
{
"changeType": "updated,deleted",
"notificationUrl": "https://a0317384.ngrok.io",
"resource": "groups",
"expirationDateTime": "2019-06-25T19:23:45.9356913Z",
"clientState": "<redacted>"
}
A Subscription is successfully getting created and I am returning verification token from my endpoint. I can also see it in the list of Subscriptions by making GET call on above URL.
When I am making some changes in Groups, like changing displayName or adding Members to the Group, I am not seeing notifications in real-time. Sometimes I am getting notifications in a bulk and other times the notifications do not arrive at all.
I have tried multiple times to delete and re-create the Subscription, but I still see the same behavior.
Can anyone tell why is it happening?
Notifications can be batched for performance optimizations and the delay to deliver notifications can vary based on service load and other factors.
While debugging you should also make sure there's no blocking conditions set by the IDE (like a break point for instance) that might block other incoming requests.
Lastly, it's pretty rare, but service outages can happen, in that case the best thing to do it to contact support.

Getting history events for just new messages?

I'd like to monitor a users gmail account for new messages and take an appropriate action. Is there a way to fetch the history events for just new messages but NOT for things like starring an email or changing its labels, etc.?
So I ended up using messages.list and storing the timestamp of the most recent message. Then on subsequent calls to messages.list I'd supply a query of "after:theMostRecentTimestampIKnowOf" to find new messages since the last time we synced.
Another route I've seen done, is if you have the ability to add a filter (e.g. user's can do that, or use the Google Admin SDK for Google Apps users, or do it through HTML/DOM hacking) then you can simply setup a filter to apply a label to all new messages. Then just messages.list(labelId=THAT_LABEL) when you do your polling (and remove it after you process them).
There is not any ability now to filter history based on change type, though it's something that would be nice to provide at some point.

AngularJS: combine REST with Socket.IO

In the single page webapp I've recently built I'm getting data for my models using Restangular module. I'd like to add real-time updates to the app so whenever any model has been changed or added on the server I can update my model list.
I've seen this working very well in webapps like Trello where you can see the updates without refreshing the web page. I'm sure Trello webclient uses REST API.
What is a proper way to architect both server and client to archive this?
First of all, your question is too general and can have a lot of solutions that depend
on your needs and conditions.
I'll give you a brief overview for a single case when you want to leave REST APIs
and add some realtime with web sockets.
Get all data from the REST -- Sokets for notifications only.
Pros: Easy to implement both server side and client side. You only need to emit events on the server with
info about modified resource (like resource name and ID), and catch these events on the client side and fetch
data with REST APIs.
Cons: One more request to the server on every notification. That can increase traffic dramaticaly when you have a lot of active clients for a single resource (they will generate a lot of reverse requests to the server).
Get initial load from the REST -- Sockets for notifications with data payload.
Pros: All info comes with the notification and will not cause new requests to the server, so we have less traffic.
Cons: Harder to implement both server side and client side. You will need to add data to all the events on the server. You will need to fetch data from all the events on the client side.
Updated according to the comment
As for handling different types of models (just a way to go).
Client side.
Keep a factory for each model.
Keep in mind that you need realtime updates only for displayed data (in most cases), so you can easily
use memory caching (so you can find any entity by its ID).
Add listener for every type of changes (Created, Updated, Deleted).
In any listener you should call some initObject function, that will find entity in the cache by ID and extend it, if there is no entity with such ID, just create a new one and add it to cache.
Any Delete just removes an entity from the cache.
Any time you need this resource, you should return the link to cache object in order to keep two way databinding (that is why I use extend and not =). Of course, you need to handle the cases like: "User is editing the resource while notification about deleting comes".
Server side.
It is easier to send all the model then just modified fields (in both cases you must send the ID of resource).
For any Create, Update, Delete event push event to all engaged users.
Event name should contain action name (like New, Update, Delete) and the name of resource (like User, Task etc.). So, you will have NewTask, UpdateTask events.
Event payload should contain the model or just modified fields with the ID.
Collection changes can be handled in two ways: with add/update/remove items in collection or changing all the collection as a whole.
All modifications like PUT, POST, DELETE are made with REST of course.
I've made a super simple pseudo gist for the case 1). https://gist.github.com/gpstmp/9868760 but it can be updated for case 2) like so https://gist.github.com/gpstmp/9900454
Hope this helps.

Getting Channel Client ID for RequestFactory requests

Is there any way to get the Channel ID on the server or transmit it inside a RequestFactory call?
Situation:
User starts the application, a channel is being opened.
User persists an entity with RequestFactory (requests.persist().using(...).fire(...)).
The persist() method on the server pings all connected clients to tell them that the entity has been updated.
But the user that made the initial change doesn't have to be pinged. Is there a way to find out which client made the change? It's not enough to know the user, because one user may have opened several windows (channels).
Honestly I haven't used Channel API yet but according to documentation each client is treated as separate user. So the solution lies beyond GAE API and I think you have two options:
Create logical User ID on the client that will be mapped to possibly multiple channels. That way you'll know what channels to skip.
Ping all channels anyway but send numeric Version of newly persisted entity. Then client will compare received version with what it has and if it's higher it means it needs to call findModel(id) again.

Resources