Getting list of Google Calendar events using googleapis - node.js

Following googleapis documentation I've retrieved tokens including refresh_token:
{ access_token: 'ya29.Glv_LONG-STRING',
token_type: 'Bearer',
refresh_token: '1/7k6BLAH-BLAH-BLAH',
expiry_date: 1532141656948 }
How can I get list of Google Calendar events using this when access_token is not valid anymore, but I have the refresh_token?

You have already retrieved the refresh token. You want to retrieve an event list using Calendar API by the refresh token. If my understanding is correct, how about this sample script? In this script, it supposes the following points.
You have the refresh token which can use Calendar API.
The refresh token includes https://www.googleapis.com/auth/calendar or https://www.googleapis.com/auth/calendar.readonly for retrieving the event list using Calendar API in the scopes.
Calendar API has already been enabled at API console.
When you run the script, if the error occurs, please confirm above points.
Sample script :
const {google} = require('googleapis');
const calendar = google.calendar('v3');
var oauth2Client = new google.auth.OAuth2(
"### client ID ###",
"### client secret ###",
);
oauth2Client.setCredentials({
refresh_token: "### refresh token ###",
// access_token: "#####" // If you want to use access token, please use this.
});
calendar.events.list({
auth: oauth2Client,
calendarId: 'primary',
}, function(err, res) {
if (err) {
console.log(err);
} else {
console.log(res.data);
}
});
Note :
When you use this sample script, please set client ID, client secret, refresh token and calendarId for your environment.
I confirmed that this sample script works with the version 32.0.0 of googleapis.
Reference :
Calendar API
google-api-nodejs-client
If I misunderstand your question, I'm sorry.

Related

Authenticating Google Gmail API using access and refresh token

I have searched for an answer to this specifically but can't seem to find it. Apologies if it's a repeat.
I have the access token and the refresh token and want to send the emails using these tokens. The tokens are generated using the passport.js library and I am storing them in the DB along with other profile data. Like this
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_APP_CLIENT_ID,
clientSecret: process.env.GOOGLE_APP_CLIENT_SECRET,
callbackURL: process.env.GOOGLE_APP_CALLBACK_URL,
passReqToCallback: true
},(request:any,accessToken: string, refreshToken: string, profile: any, done: any)=>{
//save credentials in database
}));
Now using the access token and the refresh token I want to access the Gmail API. Contrary to the example (https://developers.google.com/gmail/api/quickstart/nodejs) provided by Google. In which they are providing the Oauth client created from executing Oauth2 flow.
What is needed is something like this
const gmail = google.gmail({version: 'v1', auth:{accessToken,refreshToken});
In summary: Pretty much what DalmTo said in his comment. You need to also add the client ID, secret and redirect URL.
Explanation: It may be a little hard to see but the sample that you provided does show how to authenticate with locally stored information. I'll try to simplify it.
The most relevant parts are under the authorize() function:
//first create a google.auth.OAuth2 object
//for this you still have to use your app's client_id, client_secret and redirect_uri
const oAuth2Client = new google.auth.OAuth2(
client_id, client_secret, redirect_uris[0]);
The sample app creates a token.json file that it uses to reauthenticate. It's just a simple object with the tokens (there are a couple additional fields which I removed since they are not relevant to this):
{
"access_token":"ya29...",
"refresh_token":"1//..."
}
Then the sample shows that you have to call setCredentials() on the oAuth2Client object using this token file that was created.
oAuth2Client.getToken(code, (err, token) => {
if (err) return console.error('Error retrieving access token', err);
oAuth2Client.setCredentials(token);
Then once you have set the credentials to the oAuth2Client object you can use it to authorize the API:
const gmail = google.gmail({version: 'v1', oAuth2Client});
The sample works with a locally stored file, but since you store the tokens in your database in your case it might look more like this:
//get the tokens from somewhere in your database
const tokens = {
"access_token" : ACCESS_TOKEN,
"refresh_token" : REFRESH_TOKEN
}
const oAuth2Client = new google.auth.OAuth2(
process.env.GOOGLE_APP_CLIENT_ID,
process.env.GOOGLE_APP_CLIENT_SECRET,
process.env.GOOGLE_APP_CALLBACK_URL
);
oAuth2Client.setCredentials(tokens);
const gmail = google.gmail({version: 'v1', oAuth2Client});
You'll probably also need to handle reauthorization in case that the refresh token has expired or the user has revoked access but I hope this gives you a general idea.
More info: Google API's Node.js Client

Can't get user google account gender and birthday fields with google People API. (Using OAuth2client)

I am implementing authentication with google in my mobile flutter app. I get the access_token in my app, and then I send it to backend which is written with Node.js. And thene I need to fetch user basic info + birthday and gender. In Google Cloud Platform console I did all configs, I added certain scopes,'https://www.googleapis.com/auth/user.birthday.read', 'https://www.googleapis.com/auth/user.gender.read',. I enabled Google People API. But I still can not get birthday and gender. Here is backend part from.
const token =
"HARDCODED_ACCESS_TOKEN";
var google = require("googleapis").google;
var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2();
oauth2Client.setCredentials({
access_token: token,
scope: "https://www.googleapis.com/auth/user.gender.read",
});
var oauth2 = google.oauth2({
auth: oauth2Client,
version: "v2",
});
oauth2.userinfo.get(function (err, res) {
if (err) {
console.log(err);
} else {
console.log(res.data);
}
});
And here what I got in response.
I tried almost everything, but still couldn't get gender and birthday.
In order to get information about gender and birthdays from the authenticated user, you can call People API's people.get with resourceName=people/me and personFields=genders,birthdays:
oauth2Client.setCredentials({
access_token: token,
});
const service = google.people({version: 'v1', auth: oauth2Client});
service.people.get({
resourceName: 'people/me',
personFields: 'genders,birthdays'
}, (err, res) => {
// Do your thing
});
Notes:
You didn't provide the code for most of the authentication process, but please note that the scopes have to be provided before retrieving the access_token, since the access token depends on those scopes. Also, I'd suggest you to set a refresh_token, since the access_token will expire in an hour. For more information about the OAuth process, please take a look at the Node.js quickstart.
It is assumed that both genders and birthdays are added to the authenticated user's account.

Refresh token for Google APIs to keep user logged in

I am developing an App on Actions on Google that uses Google Calendar. At the start of a user's first interaction, they are prompted to link their Google account for access to the calendar. But then for nearly every future interaction, the user has to authenticate again.
My code to get the access token from the user data is below. I'm not sure if there's a way to get the refresh token to add to the credentials. I've seen you should include "access_type": "offline" in the request in other answers, but I'm not sure where I'd put it in my code. Any help would be greatly appreciated!
const googleAuth = require('google-auth-library');
function getAuth(app) {
var accessToken = app.getUser().accessToken;
var clientId = CLIENT_ID;
var clientSecret = CLIENT_SECRET;
var redirectUrl = 'https://oauth-redirect.googleusercontent.com/r/my_app_name';
var auth = new googleAuth();
var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);
var token = {
"access_token": accessToken,
"refresh_token": "",
"access_type": "offline", //Not sure if these attributes should be here
"approval_prompt": "force",
"immediate": true,
"token_type": "Bearer"
};
oauth2Client.credentials = token;
return oauth2Client;
}
calendar.freebusy.query ({
auth: getAuth(app), //need a Google OAuth client here for API request
headers: { "content-type" : "application/json" },
resource:{
items: [
{
id: "primary"
}
],
timeMin: startDate.format(),
timeMax: endDate.format(),
timeZone: timeZoneId
}, function(err, response) {
console.log('Success!');
}
});
Not sure if this helps, but on the very first interaction a user has to select an account and agree to the calendar permission, but on subsequent interactions they just have to tap "link account to Google" and it automatically authenticates them.
EDIT:
This is a screenshot of the prompt I get on every new interaction with the app. It was my understanding that account linking is only done on the very first interaction with the app, then the accounts are linked for good and the user need not be prompted again. I am not receiving any errors, I was just wondering if and how I can modify my current code to not prompt the user to link their account on every single interaction.

How to get email and profile information from OAuth2 Google API?

I'm trying to retrieve the name of a logged in user using Google API Node.js Client, using OAuth2 API.
Following the usage example, I managed to do the login, but I can't find a way to get the profile information.
I'm not using People API nor Plus API, cause as far as i know, OAuth2 includes https://www.googleapis.com/auth/userinfo.profile, which should be enough for the task.
I have seen some similar questions and tried the solutions of this one but it didn't work, maybe it's too old (?)
With the npm package googleapis how do I get the user's email address after authenticating them?
Looking at other API's like Google Sheets, it's possible to call their functions like this:
var google = require('googleapis');
var sheets = google.sheets('v4');
...
sheets.spreadsheets.values.get({
auth: auth,
spreadsheetId: file_id,
range: my_ranges,
}, function(err, response){
...
}
);
But it seems that OAuth2 doesn't work like that...
You can use Quickstart for node.js. The detail information is https://developers.google.com/gmail/api/quickstart/nodejs. Using a sample script from Quickstart, you can retrieve access token by OAuth2, and retrieve email and user profile.
Before it runs a sample of Quickstart, please confirm Prerequisites, Step 1 and Step 2.
You can use by changing listLabels(auth) as follows. The scope is https://www.googleapis.com/auth/gmail.readonly.
Script :
var gmail = google.gmail({
auth: auth,
version: 'v1'
});
gmail.users.getProfile({
auth: auth,
userId: 'me'
}, function(err, res) {
if (err) {
console.log(err);
} else {
console.log(res);
}
});
gmail.users.messages.get({
'userId': 'me',
'id': 'mail ID',
'format': 'raw'
}, function (err, res) {
console.log(new Buffer(res.raw, 'base64').toString())
});
gmail.users.getProfile retrieves user profile.
gmail.users.messages.get retrieves email.
If I misunderstand your question, I'm sorry.
Added :
Please change above to following script. Scope is https://www.googleapis.com/auth/userinfo.profile.
Script :
var oauth2 = google.oauth2({
auth: auth,
version: 'v2'
});
oauth2.userinfo.v2.me.get(
function(err, res) {
if (err) {
console.log(err);
} else {
console.log(res);
}
});
Result :
{
id: '#####',
name: '#####',
given_name: '#####',
family_name: '#####',
link: '#####',
picture: '#####',
gender: '#####',
locale: '#####'
}
2021 Solution
This answer may divert from the originally asked question but I think it will be useful for some people who are getting google user information in the backend by generating AuthUrl and sending it to the client side and then receiving the data response in the call back URL after the user gives permission from the client side.
Some global declarations
import { google } from "googleapis";
const Oauth2Client = new google.auth.OAuth2(
googleCredentials.CLIENT_ID,
googleCredentials.CLIENT_SECRET,
googleCredentials.REDIRECT_URI
);
Generate the Auth URL with the scopes
const SCOPE = [
'https://www.googleapis.com/auth/userinfo.profile', // get user info
'https://www.googleapis.com/auth/userinfo.email', // get user email ID and if its verified or not
];
const auth_url = Oauth2Client.generateAuthUrl({
access_type: "offline",
scope: SCOPE,
prompt: "consent",
state: "GOOGLE_LOGIN",
});
return res.json({ url: auth_url }); // send the Auth URL to the front end
Get the user data in the callback
let code = req.query.code; // get the code from req, need to get access_token for the user
let { tokens } = await Oauth2Client.getToken(code); // get tokens
let oauth2Client = new google.auth.OAuth2(); // create new auth client
oauth2Client.setCredentials({access_token: tokens.access_token}); // use the new auth client with the access_token
let oauth2 = google.oauth2({
auth: oauth2Client,
version: 'v2'
});
let { data } = await oauth2.userinfo.get(); // get user info
console.log(data); // you will find name, email, picture etc. here
Feel free to discuss in the comments if there's any confusion or error
You can also look into PassportJS. They have multiple strategies, including OAuth2 and 3 different Google Auth strategies. My answer doesn't really answer your question but maybe even taking a peek at Passport's code, you may get your answer.
http://passportjs.org/

how to get people info using google api in node js?

I want to verify user google id on server side.So i want user google info by using google api.I have gone through all documentation but i stuck.I have seen this code,its working fine:
var google = require('googleapis');
var plus = google.plus('v1');
var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URL);
// Retrieve tokens via token exchange explained above or set them:
oauth2Client.setCredentials({
access_token: 'ACCESS TOKEN HERE',
refresh_token: 'REFRESH TOKEN HERE'
});
plus.people.get({ userId: 'me', auth: oauth2Client }, function(err, response) {
// handle err and response
});
but this is for google plus.I want to fetch user google profile with id not google plus info. Please help.
For googleapis version 19.0.0, you're gonna have to do something like this:
const googleapis = require('googleapis');
googleapis.people('v1').people.get({
resourceName: 'people/me',
personFields: 'emailAddresses,names',
auth: oauth2Client,
(err, response) => {
// do your thing
}
});
The fields resourceName and personFields are the ones that you might get error for saying that these are mandatory. You can find details on these here https://developers.google.com/people/api/rest/v1/people/get.
As for the scopes, following should be enough for this code snippet:
https://www.googleapis.com/auth/userinfo.email and
https://www.googleapis.com/auth/userinfo.profile

Resources