google-contacts-meteor
Version:
API wrapper for Google Contacts
238 lines (200 loc) • 5.59 kB
JavaScript
/**
* @todo: recursively send requests until all contacts are fetched
*
* @see https://developers.google.com/google-apps/contacts/v3/reference#ContactsFeed
*
* To API test requests:
*
* @see https://developers.google.com/oauthplayground/
*
* To format JSON nicely:
*
* @see http://jsonviewer.stack.hu/
*
* Note: The Contacts API has a hard limit to the number of results it can return at a
* time even if you explicitly request all possible results. If the requested feed has
* more fields than can be returned in a single response, the API truncates the feed and adds
* a "Next" link that allows you to request the rest of the response.
*/
var EventEmitter = require('events').EventEmitter,
_ = require('underscore'),
qs = require('querystring'),
util = require('util'),
url = require('url'),
https = require('https'),
querystring = require('querystring');
var GoogleContacts = function (opts) {
if (typeof opts === 'string') {
opts = { token: opts }
}
if (!opts) {
opts = {};
}
this.contacts = [];
this.consumerKey = opts.consumerKey ? opts.consumerKey : null;
this.consumerSecret = opts.consumerSecret ? opts.consumerSecret : null;
this.token = opts.token ? opts.token : null;
this.refreshToken = opts.refreshToken ? opts.refreshToken : null;
};
GoogleContacts.prototype = {};
util.inherits(GoogleContacts, EventEmitter);
GoogleContacts.prototype._get = function (params, cb) {
var self = this;
if (typeof params === 'function') {
cb = params;
params = {};
}
var req = {
host: 'www.google.com',
port: 443,
path: this._buildPath(params),
method: 'GET',
headers: {
'Authorization': 'OAuth ' + this.token
}
};
console.log(req);
https.request(req, function (res) {
var data = '';
res.on('end', function () {
if (res.statusCode < 200 || res.statusCode >= 300) {
var error = new Error('Bad client request status: ' + res.statusCode);
return cb(error);
}
try {
data = JSON.parse(data);
cb(null, data);
}
catch (err) {
cb(err);
}
});
res.on('data', function (chunk) {
//console.log(chunk.toString());
data += chunk;
});
res.on('error', function (err) {
cb(err);
});
//res.on('close', onFinish);
}).on('error', function (err) {
cb(err);
}).end();
};
GoogleContacts.prototype.getContacts = function (cb, contacts) {
var self = this;
console.log("this is what we think cb is: ");
console.log(cb);
this._get({ type: 'contacts' }, receivedContacts);
function receivedContacts(err, data) {
if (err){
return cb(err);
}
//if (data) {
self._saveContactsFromFeed(data.feed);
//}else {
//cb(null, self.contacts);
//}
var next = false;
data.feed.link.forEach(function (link) {
if (link.rel === 'next') {
next = true;
var path = url.parse(link.href).path;
self._get({ path: path }, receivedContacts);
}
});
if (!next) {
cb(null, self.contacts);
}
};
};
GoogleContacts.prototype._saveContactsFromFeed = function (feed) {
var self = this;
//console.log(feed);
feed.entry.forEach(function (entry) {
try {
var name = entry.title['$t'];
var email = entry['gd$email'][0].address; // only save first email
self.contacts.push({ name: name, email: email });
}
catch (e) {
// property not available...
}
});
console.log(self.contacts);
console.log(self.contacts.length);
}
GoogleContacts.prototype._buildPath = function (params) {
if (params.path) return params.path;
params = params || {};
params.type = params.type || 'contacts';
params.alt = params.alt || 'json';
params.projection = params.projection || 'thin';
params.email = params.email || 'default';
params['max-results'] = params['max-results'] || 2000;
var query = {
alt: params.alt,
'max-results': params['max-results']
};
var path = '/m8/feeds/';
path += params.type + '/';
path += params.email + '/';
path += params.projection;
path += '?' + qs.stringify(query);
return path;
};
GoogleContacts.prototype.refreshAccessToken = function (refreshToken, cb) {
if (typeof params === 'function') {
cb = params;
params = {};
}
var data = {
refresh_token: refreshToken,
client_id: this.consumerKey,
client_secret: this.consumerSecret,
grant_type: 'refresh_token'
}
var body = qs.stringify(data);
var opts = {
host: 'accounts.google.com',
port: 443,
path: '/o/oauth2/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': body.length
}
};
//console.log(opts);
//console.log(data);
var req = https.request(opts, function (res) {
var data = '';
res.on('end', function () {
if (res.statusCode < 200 || res.statusCode >= 300) {
var error = new Error('Bad client request status: ' + res.statusCode);
return cb(error);
}
try {
data = JSON.parse(data);
//console.log(data);
cb(null, data.access_token);
}
catch (err) {
cb(err);
}
});
res.on('data', function (chunk) {
//console.log(chunk.toString());
data += chunk;
});
res.on('error', function (err) {
cb(err);
});
//res.on('close', onFinish);
}).on('error', function (err) {
cb(err);
});
req.write(body);
req.end();
}
exports.GoogleContacts = GoogleContacts;