UNPKG

linagora-rse

Version:
138 lines (121 loc) 4.8 kB
'use strict'; var q = require('q'); var GOOGLE_CONTACT_URL = 'https://www.google.com/m8/feeds/contacts/default/full'; var GOOGLE_GDATA_VERSION = '3.0'; var MAX_CONTACT_PER_STACK = 50; var request = require('request'); var refresh = require('passport-oauth2-refresh'); var parseString = require('xml2js').parseString; module.exports = function(dependencies) { var googleContactToVcard = require('./mapping')(dependencies); var importContactClient = dependencies('contact-import').lib.import; var CONTACT_IMPORT_ERROR = dependencies('contact-import').constants.CONTACT_IMPORT_ERROR; var IMPORT_API_CLIENT_ERROR = CONTACT_IMPORT_ERROR.API_CLIENT_ERROR; function getRequestHeaders(options) { return { 'GData-Version': GOOGLE_GDATA_VERSION, Authorization: 'Bearer ' + options.accessToken }; } function googleAPIRequest(options, callback) { var startIndex = options.offset > 0 ? '&start-index=' + options.offset : ''; var opt = { method: 'GET', url: [GOOGLE_CONTACT_URL, '?max-results=', MAX_CONTACT_PER_STACK, startIndex].join(''), headers: getRequestHeaders(options) }; return request(opt, callback); } function getContactsPhoto(contact, requestOptions) { var defer = q.defer(); contact.link.map(function(link) { if (link.$.type === 'image/*') { if (!link.$['gd:etag']) { defer.resolve(contact); return; } var getImageOption = { method: 'GET', url: link.$.href, headers: getRequestHeaders(requestOptions), encoding: null }; request(getImageOption, function(err, response, body) { if (response.statusCode === 200) { contact.contactPhoto = 'data:image/png;base64,' + body.toString('base64'); } defer.resolve(contact); }); } }); return defer.promise; } function importContactperStack(requestOptions, options, defer) { if (requestOptions.offset > 1 && requestOptions.offset > requestOptions.totalResults) { defer.notify({ message: ['Import contacts finished:', requestOptions.totalResults, 'contacts imported'].join(' '), value: 100 }); defer.resolve(); } else { googleAPIRequest(requestOptions, function(err, response, body) { if (response.statusCode < 200 || response.statusCode > 299) { if (err) { return defer.reject(importContactClient.buildErrorMessage(IMPORT_API_CLIENT_ERROR, err)); } parseString(body, function(error, result) { if (error) { return defer.reject(error); } let errorObject = { statusCode: response.statusCode }; if (result.errors && result.errors.error && result.errors.error.length > 0) { errorObject = { statusCode: response.statusCode, message: result.errors.error[0].internalReason, code: result.errors.error[0].code, allErrors: result.errors.error }; } defer.reject(importContactClient.buildErrorMessage(IMPORT_API_CLIENT_ERROR, errorObject)); }); } else { parseString(body, function(err, res) { if (err) { defer.reject(err); } else { defer.notify({ message: 'Number of contacts imported ' + res.feed['openSearch:startIndex'][0], value: Math.round(res.feed['openSearch:startIndex'][0] * 100 / res.feed['openSearch:totalResults'][0]) }); requestOptions.totalResults = parseInt(res.feed['openSearch:totalResults'][0], 10); requestOptions.offset = parseInt(res.feed['openSearch:startIndex'][0], 10) + MAX_CONTACT_PER_STACK; q.all(res.feed.entry.map(function(value) { return getContactsPhoto(value, requestOptions).then(function(contact) { return importContactClient.createContact(googleContactToVcard.toVcard(contact), options); }); } )).then(function() { importContactperStack(requestOptions, options, defer); }); } }); } }); } } function importContact(options) { var defer = q.defer(); refresh.requestNewAccessToken('google-authz', options.account.data.refresh_token, function(err, accessToken) { if (err) { defer.reject(err); } else { var requestOptions = { accessToken: accessToken, offset: 0, totalResults: 0}; importContactperStack(requestOptions, options, defer); } }); return defer.promise; } return { importContact: importContact }; };