I am using passport, and would like to use the Google Contacts API version 3.0 to sync Google contacts with my application (which would suddenly become 10 times more useful).
Has anybody done this? If so, do you have some example code? Is it even possible to use passport authentication to get it all working?
This comes in two parts, authorization, and then the actual request.
It is basically using OAuth2 protocol, where you redirect the client to google url with scopes(You must at least have https://www.google.com/m8/feeds
in your scopes to be able to read and write contacts) and your client id/secret(get them by registering your app. Then google will redirect the user back with the access token on the URL.
You don't need to do this yourself, because there are different modules that already does this:
passport-google-oauth
This makes it easy and assuming you are already using passport, this probably what you want. It is written by the author of passportjs. Just follow the example in it for OAuth 2.0 strategy. Note that you need to you add the right scopes when you are calling passport.authenticate('google', ...)
. This module when it gets the token, it will get the user profile, so you have to have one of the 3 scopes below:
passport.authenticate('google', { scope: [ // One of the next three `auth` scopes are needed. 'https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/plus.login', 'https://www.google.com/m8/feeds' ] }),
googleapis
This is module is officially supported by google and created by google employees. You can use it to authenticate, but sadly it doesn't support gData, which contains google contacts. You can check the example to see how you can get the token. You only need the m8/feeds
scope with this module, no need for the other ones if you don't want to get the user profile.
gdata-js
This is a non-popular non-maintaining module, but it is more lightweight than the previous two modules. It might need a little polishing out of the box. I suggest also reading the source for understanding the api right.
Once you got the tokens, then you go for the slightly easier part, making the requests and getting the data.
If you read the docs, it's actually very easy. For example to get all contacts(almost all, it's paginated), you need to make a GET request to this url:
https://www.google.com/m8/feeds/contacts/default/full?alt=json&oauth_token=THE_ACCESS_TOKEN
Again there are many modules that can help you in this.
gdata-js Read the source to understand it's api. It's pretty easy actually:
var client = require('gdata-js')(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET); client.setToken({ access_token: accessToken, refresh_token: refreshToken }); client.getFeed('https://www.google.com/m8/feeds/contacts/default/full', function (err, result) { ... });
Google's official API for NodeJS doesn't support Contacts API, only the People API.
You can connect with Contacts API using the official googleapis library if you're already using it for other purposes by sending a request to the Contacts API after creating the auth client.
Given that you already have the access token of the user (e.g. if you generated it using Passport, here's the code:
const {google} = require("googleapis");
const authObj = new google.auth.OAuth2({
access_type: 'offline',
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
});
Refresh access token automatically before it expires
authObj.on('tokens', (tokens) => {
const access_token = tokens.access_token
if (tokens.refresh_token){
this.myTokens.refreshToken = tokens.refresh_token
// save refresh token in the database if it exists
}
this.myTokens.accessToken = tokens.access_token
// save new access token (tokens.access_token)
}
authObj.setCredentials({
access_token:this.myTokens.accessToken,
refresh_token:this.myTokens.refreshToken,
});
Make the request to Contacts API (Google uses Gaxios for making the requests to their APIs although it's not documented officially in googleapis, so just be aware that they might change remove/change the request call in the future without documenting it)
authObj.request({
headers:{
"GData-Version":3.0
},
params:{
"alt":"json",
//"q":"OPTIONAL SEARCH QUERY",
//"startindex":0
"orderby":"lastmodified",
"sortorder":"descending",
},
url: "https://www.google.com/m8/feeds/contacts/default/full"
}).then( response => {
console.log(response); // extracted contacts
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With