10

I'm using node.js to create an app that gets a PUSH from Gmail each time an email is received, checks it against a third party database in a CRM and creates a new field in the CRM if the e-mail is contained there. I'm having trouble using Google's new Cloud Pub/Sub, which seems to be the only way to get push from Gmail without constant polling.

I've gone through the instructions here: https://cloud.google.com/pubsub/prereqs but I don't understand how exactly this is supposed to work from an app on my desktop. It seems that pub/sub can connect to a verified domain, but I can't get it to connect directly toto the .js script that I have on my computer. I've saved the api key in a json file and use the following:

var gcloud = require('gcloud');
var pubsub;

// From Google Compute Engine:
pubsub = gcloud.pubsub({
  projectId: 'my-project',
});

// Or from elsewhere:
pubsub = gcloud.pubsub({
  projectId: 'my-project',
  keyFilename: '/path/to/keyfile.json'
});

// Create a new topic.
pubsub.createTopic('my-new-topic', function(err, topic) {});

// Reference an existing topic.
var topic = pubsub.topic('my-existing-topic');

// Publish a message to the topic.
topic.publish('New message!', function(err) {});

// Subscribe to the topic.
topic.subscribe('new-subscription', function(err, subscription) {
  // Register listeners to start pulling for messages.
  function onError(err) {}
  function onMessage(message) {}
  subscription.on('error', onError);
  subscription.on('message', onMessage);

  // Remove listeners to stop pulling for messages.
  subscription.removeListener('message', onMessage);
  subscription.removeListener('error', onError);
});

However, I get errors as if it isn't connecting to server and on the API list I see only errors, no actual successes. I'm clearly doing something wrong, any idea what it might be?

Thank you in advance!

Sekoul
  • 1,361
  • 2
  • 14
  • 30
  • 1
    From the docs' endpoint setup 'Your server must be reachable via a DNS name and must present a signed SSL certificate'. So to receive pushes your endpoint must be on an public facing web server. Desktop apps can only receive pulls. – longplay Jul 23 '15 at 22:45

1 Answers1

4

TL;DR

Your cannot subscribe to push notifications from the client side.


Set up an HTTPS server to handle the messages. Messages will be sent to the URL endpoint that you configure, representing that server's location. Your server must be reachable via a DNS name and must present a signed SSL certificate. (App Engine applications are preconfigured with SSL certificates.)

Just subscribe to the push notifications on your server, and when you get the notification, you can figure out who it concerns. The data you will get from the notifications is what user that it concerns, and the relevant historyId, like so:

 // This is all the data the notifications will give you.
 {"emailAddress": "user@example.com", "historyId": "9876543210"}

Then you could e.g. emit an event through Socket.io to the relevant user if he is online, and have him do a sync with the supplied historyId on the client side.

Tholle
  • 108,070
  • 19
  • 198
  • 189
  • Thank you for the info! I don't have https on my domain so I tried to park my app on heroku (https://fast-scrubland-4839.herokuapp.com/). I've verified the domain and added it to the push section in Google's Developer console, as per the instructions above. From what I understand, I now need to create a subscription to a topic that receives pushes from gmail. How would I go about doing this? I'm usring `pubsub.getTopics({ pageSize: 3 }, function(err, topics, nextQuery, apiResponse) {});` to list existing topics but I don't see anything being displayed in logs... – Sekoul Jul 24 '15 at 16:38
  • 1
    @Sekoul Follow the steps outlined here, and you should be fine :) https://developers.google.com/gmail/api/guides/push You also need https on your server. Using express? Create a route that Google can push too also! – Tholle Jul 24 '15 at 16:57
  • Okay, if I understand correctly, the logical flow goes like this: I create a topic using something like `pubsub.createTopic()` -> I subscribe to the topic using `topic.subscribe()` -> I set publishing rights using `setIamPolicy()`. At this point, I'm subscribed to a topic which receives updates anytime anything happens on my gmail account. Then, I use `watch()` to track specific events that I'm interested in (in my case, a new message being received in inbox). Is this more or less correct? – Sekoul Jul 24 '15 at 17:26
  • 1
    @Sekoul That's exactly it :) If I'm not mistaken, quota will not be used if you are not `watch()`ing, so don't forget to `stop()` when your users logs off! – Tholle Jul 24 '15 at 18:02