Google API Google Drive Node.js can´t upload file oAuth2 - node.js

Hey I tried for over 6h now and nothing working. I came this far..
I created a successfull connection to my api with this default code from the google api pages. I also enabled advanced features Google Drive at my console google page. I successfull created the token and it´s now stored at C:\Users\Administrator.credentials
var fs = require('fs');
var readline = require('readline');
var google = require('googleapis');
var googleAuth = require('google-auth-library');
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/drive-nodejs-quickstart.json
var SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly'];
var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
process.env.USERPROFILE) + '/.credentials/';
var TOKEN_PATH = TOKEN_DIR + 'drive-nodejs-quickstart.json';
// Load client secrets from a local file.
fs.readFile('client_secret.json', function processClientSecrets(err, content) {
if (err) {
console.log('Error loading client secret file: ' + err);
return;
}
// Authorize a client with the loaded credentials, then call the
// Drive API.
authorize(JSON.parse(content), listFiles);
});
/**
* Create an OAuth2 client with the given credentials, and then execute the
* given callback function.
*
* #param {Object} credentials The authorization client credentials.
* #param {function} callback The callback to call with the authorized client.
*/
function authorize(credentials, callback) {
var clientSecret = credentials.installed.client_secret;
var clientId = credentials.installed.client_id;
var redirectUrl = credentials.installed.redirect_uris[0];
var auth = new googleAuth();
var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, function(err, token) {
if (err) {
getNewToken(oauth2Client, callback);
} else {
oauth2Client.credentials = JSON.parse(token);
callback(oauth2Client);
}
});
}
/**
* Get and store new token after prompting for user authorization, and then
* execute the given callback with the authorized OAuth2 client.
*
* #param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
* #param {getEventsCallback} callback The callback to call with the authorized
* client.
*/
function getNewToken(oauth2Client, callback) {
var authUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES
});
console.log('Authorize this app by visiting this url: ', authUrl);
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('Enter the code from that page here: ', function(code) {
rl.close();
oauth2Client.getToken(code, function(err, token) {
if (err) {
console.log('Error while trying to retrieve access token', err);
return;
}
oauth2Client.credentials = token;
storeToken(token);
callback(oauth2Client);
});
});
}
/**
* Store token to disk be used in later program executions.
*
* #param {Object} token The token to store to disk.
*/
function storeToken(token) {
try {
fs.mkdirSync(TOKEN_DIR);
} catch (err) {
if (err.code != 'EEXIST') {
throw err;
}
}
fs.writeFile(TOKEN_PATH, JSON.stringify(token));
console.log('Token stored to ' + TOKEN_PATH);
}
/**
* Lists the names and IDs of up to 10 files.
*
* #param {google.auth.OAuth2} auth An authorized OAuth2 client.
*/
function listFiles(auth) {
var service = google.drive('v3');
service.files.list({
auth: auth,
pageSize: 10,
fields: "nextPageToken, files(id, name)"
}, function(err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
var files = response.files;
if (files.length == 0) {
console.log('No files found.');
} else {
console.log('Files:');
for (var i = 0; i < files.length; i++) {
var file = files[i];
console.log('%s (%s)', file.name, file.id);
}
}
});
}
When I rerun this script I get
Files:
sample file.mp4 (123456789sampelcode)
projektname (123456789sampelcode)
Getting started (123456789sampelcode)
To the connection now worked with the token because I don´t need to do reenter something. I really don´t understand now how to upload a file. When i try to include my own upload function I can´t use it because I can´t combine it with the login process. I saw that
function listFiles(auth) {
}
Was default execuded after the login. So I thought I enter my code in this function it would work . So created this
function listFiles(auth) {
var drive = google.drive('v3');
var fileMetadata = {
'name': 'photo.jpg'
};
var media = {
mimeType: 'image/jpeg',
body: fs.createReadStream('./photo.jpg')
};
drive.files.create({
resource: fileMetadata,
media: media,
auth: auth,
fields: 'id'
}, function(err, file) {
if(err) {
// Handle error
console.log(err);
} else {
console.log('File Id: ', file.id);
}
});
}
But nothing happen. My Terminal window is endless loading. No error no nothing.
Version 2 - This is my second version . also no log no nothing just endless loading. I turned of firewall so no way thats there a problem with the firewall or antivirus or somthing because in the default script I can see the files from my googledrive
const fs = require('fs');
const readline = require('readline');
const google = require('googleapis');
const googleAuth = require('google-auth-library');
const drive = google.drive('v3');
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/drive-nodejs-quickstart.json
var SCOPES = ['https://www.googleapis.com/auth/drive'];
var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
process.env.USERPROFILE) + '/.credentials/';
var TOKEN_PATH = TOKEN_DIR + 'drive-nodejs-quickstart.json';
// Load client secrets from a local file.
fs.readFile('client_secret.json', function processClientSecrets(err, content) {
if (err) {
console.log('Error loading client secret file: ' + err);
return;
}
// Authorize a client with the loaded credentials, then call the
// Drive API.
//authorize(JSON.parse(content), listFiles);
authorize(JSON.parse(content), real_upload_files);
});
/*
* Create an OAuth2 client with the given credentials, and then execute the
* given callback function.
*
* #param {Object} credentials The authorization client credentials.
* #param {function} callback The callback to call with the authorized client.
*/
function authorize(credentials, callback) {
var clientSecret = credentials.installed.client_secret;
var clientId = credentials.installed.client_id;
var redirectUrl = credentials.installed.redirect_uris[0];
var auth = new googleAuth();
var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, function(err, token) {
if (err) {
getNewToken(oauth2Client, callback);
//console.log('5')
} else {
oauth2Client.credentials = JSON.parse(token);
callback(oauth2Client);
// console.log('4')
}
});
} // function authorize(credentials, callback) {
function real_upload_files(auth) {
var fileMetadata = {
'name': 'photo.jpg'
};
var media = {
mimeType: 'image/jpeg',
body: fs.createReadStream('./photo.jpg')
};
drive.files.create({
resource: fileMetadata,
media: media,
auth: auth,
fields: 'id'
}, function(err, file) {
if(err) {
// Handle error
console.log(err);
} else {
console.log('File Id: ', file.id);
}
});
} // function real_upload_files(auth) {
Also If I would change auth: auth to auth: oauth2Client and change it also in the function then will be same result endless loading screen.
Can somebody explain me pls how to upload files or do other stuff with the oAuth2. I find as node.js newbie that there are to less sample codes to find for for node.js .. Please help me guys I strugggle so hard with this.. please help :D With dropbox it takes 10 min but there I easy used a API Key ..

I think that your script is no wrong. In my environment, your script works fine. So I propose following 2 modifications.
Modification points :
What terminal do you use for this? It seems that from C:\Users\Administrator.credentials of your question, you use windows OS. If it's so, can you use cmd.exe for this? If you don't use windows. Please don't change the terminal.
How about the use of readFile() for reading the file? readFile() can read whole data in the file to the memory. So I thought that the error might be avoided. But if the file size is large, I recommend to use createReadStream(). I confirmed that readFile() and createReadStream() can use to upload file to Google Drive using cmd.exe as a terminal with windows OS.
Modified script :
function real_upload_files(auth) {
fs.readFile('./photo.jpg', function(err, content){
var fileMetadata = {
'name': 'photo.jpg',
};
var media = {
mimeType: 'image/jpeg',
body: new Buffer(content, 'binary'),
};
drive.files.create({
resource: fileMetadata,
media: media,
auth: auth,
fields: 'id',
}, function(err, file) {
if (err) {
console.log(err);
} else {
console.log('File Id: ', file.id);
}
});
});
}
I don't know whether these lead to the solution. I'm sorry.

Related

Error: Unauthorized while working with the Youtube Data API

I have a web application through which I'd like to be able create playlists, add videos to a playlist, delete a video etc, to my youtube channel. I've followed the example YouTube API quickstart for nodejs and gotten everything working locally for the past almost 2 weeks but seemingly out of nowhere, I'm getting hit with Error: Unauthorized, every time I try to call the API to create a playlist for example.
{
message: 'Unauthorized',
status: undefined,
stackHighlighted: 'Error: Unauthorized\n' +
' at Gaxios._request (c:\\apps\\node\\myapp\\node_modules\\gaxios\\build\\src\\<mark>gaxios.js:89:23</mark>)\n' +
' at processTicksAndRejections (internal/process/<mark>task_queues.js:93:5</mark>)\n' +
' at async OAuth2Client.requestAsync (c:\\apps\\node\\myapp\\node_modules\\google-auth-library\\build\\src\\auth\\<mark>oauth2client.js:343:18</mark>)\n' +
' at async createPlaylist (file:///c:/apps/node/myapp/controllers/youtube.<mark>controller.js:76:22</mark>)'
}
Line 76 is where I'm calling youtube.playlists.insert.
The only thing that has changed is that I moved the app to a live server, so now both my local copy and the one on the server are both not working. My code basically works like the following.
var fs = require('fs');
var readline = require('readline');
var {google} = require('googleapis');
var OAuth2 = google.auth.OAuth2;
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/youtube-nodejs-quickstart.json
var SCOPES = ['https://www.googleapis.com/auth/youtube'];
var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
process.env.USERPROFILE) + '/.credentials/';
var TOKEN_PATH = TOKEN_DIR + 'youtube-nodejs-quickstart.json';
// Load client secrets from a local file.
fs.readFile('client_secret.json', function processClientSecrets(err, content) {
if (err) {
console.log('Error loading client secret file: ' + err);
return;
}
// Authorize a client with the loaded credentials, then call the YouTube API.
authorize(JSON.parse(content), getChannel);
});
/**
* Create an OAuth2 client with the given credentials, and then execute the
* given callback function.
*
* #param {Object} credentials The authorization client credentials.
* #param {function} callback The callback to call with the authorized client.
*/
function authorize(credentials, callback) {
var clientSecret = credentials.installed.client_secret;
var clientId = credentials.installed.client_id;
var redirectUrl = credentials.installed.redirect_uris[0];
var oauth2Client = new OAuth2(clientId, clientSecret, redirectUrl);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, function(err, token) {
if (err) {
getNewToken(oauth2Client, callback);
} else {
oauth2Client.credentials = JSON.parse(token);
callback(oauth2Client);
}
});
}
/**
* Get and store new token after prompting for user authorization, and then
* execute the given callback with the authorized OAuth2 client.
*
* #param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
* #param {getEventsCallback} callback The callback to call with the authorized
* client.
*/
function getNewToken(oauth2Client, callback) {
var authUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES
});
console.log('Authorize this app by visiting this url: ', authUrl);
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('Enter the code from that page here: ', function(code) {
rl.close();
oauth2Client.getToken(code, function(err, token) {
if (err) {
console.log('Error while trying to retrieve access token', err);
return;
}
oauth2Client.credentials = token;
storeToken(token);
callback(oauth2Client);
});
});
}
/**
* Store token to disk be used in later program executions.
*
* #param {Object} token The token to store to disk.
*/
function storeToken(token) {
try {
fs.mkdirSync(TOKEN_DIR);
} catch (err) {
if (err.code != 'EEXIST') {
throw err;
}
}
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) throw err;
console.log('Token stored to ' + TOKEN_PATH);
});
}
/**
* Lists the names and IDs of up to 10 files.
*
* #param {google.auth.OAuth2} auth An authorized OAuth2 client.
*/
function getChannel(auth) {
var service = google.youtube('v3');
service.channels.list({
auth: auth,
part: 'snippet,contentDetails,statistics',
forUsername: 'GoogleDevelopers'
}, function(err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
var channels = response.data.items;
if (channels.length == 0) {
console.log('No channel found.');
} else {
console.log('This channel\'s ID is %s. Its title is \'%s\', and ' +
'it has %s views.',
channels[0].id,
channels[0].snippet.title,
channels[0].statistics.viewCount);
}
});
}
I don't understand why this is. Any insight would be much appreciated.

NodeJS & Gmail API - Access last 3 emails based on "To:" recipient

I am currently utilising NodeJS and the Gmail API to access my gmail account and return the last email I've received which is obviously only going to be 1 email using this code: (which is a slightly modified version of the example seen here: https://www.codediesel.com/nodejs/how-to-access-gmail-using-nodejs-and-the-gmail-api/
var fs = require('fs');
var readline = require('readline');
var {google} = require('googleapis');
// If modifying these scopes, delete your previously saved credentials
// at TOKEN_DIR/gmail-nodejs.json
var SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'];
// Change token directory to your system preference
var TOKEN_DIR = ('./');
var TOKEN_PATH = TOKEN_DIR + 'gmail-nodejs.json';
var gmail = google.gmail('v1');
//exports.confirmationEmailFinal;
// Load client secrets from a local file.
fs.readFile('client_secret.json', function processClientSecrets(err, content) {
if (err) {
console.log('Error loading client secret file: ' + err);
return;
}
// Authorize a client with the loaded credentials, then call the
// Gmail API.
authorize(JSON.parse(content), getRecentEmail);
});
/**
* Create an OAuth2 client with the given credentials, and then execute the
* given callback function.
*
* #param {Object} credentials The authorization client credentials.
* #param {function} callback The callback to call with the authorized client.
*/
function authorize(credentials, callback) {
var clientSecret = credentials.installed.client_secret;
var clientId = credentials.installed.client_id;
var redirectUrl = credentials.installed.redirect_uris[0];
var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2(clientId, clientSecret, redirectUrl);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, function(err, token) {
if (err) {
getNewToken(oauth2Client, callback);
} else {
oauth2Client.credentials = JSON.parse(token);
callback(oauth2Client);
}
});
}
/**
* Get and store new token after prompting for user authorization, and then
* execute the given callback with the authorized OAuth2 client.
*
* #param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
* #param {getEventsCallback} callback The callback to call with the authorized
* client.
*/
function getNewToken(oauth2Client, callback) {
var authUrl = oauth2Client.generateAuthUrl({access_type: 'offline', scope: SCOPES});
console.log('Authorize this app by visiting this url: ', authUrl);
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('Enter the code from that page here: ', function(code) {
rl.close();
oauth2Client.getToken(code, function(err, token) {
if (err) {
console.log('Error while trying to retrieve access token', err);
return;
}
oauth2Client.credentials = token;
storeToken(token);
callback(oauth2Client);
});
});
}
/**
* Store token to disk be used in later program executions.
*
* #param {Object} token The token to store to disk.
*/
function storeToken(token) {
try {
fs.mkdirSync(TOKEN_DIR);
} catch (err) {
if (err.code != 'EEXIST') {
throw err;
}
}
fs.writeFileSync(TOKEN_PATH, JSON.stringify(token));
console.log('Token stored to ' + TOKEN_PATH);
}
/**
* Lists the labels in the user's account.
*
* #param {google.auth.OAuth2} auth An authorized OAuth2 client.
*/
function listLabels(auth) {
gmail.users.labels.list({auth: auth, userId: 'me',}, function(err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
var labels = response.data.labels;
if (labels.length == 0) {
console.log('No labels found.');
} else {
console.log('Labels:');
for (var i = 0; i < labels.length; i++) {
var label = labels[i];
console.log('%s', label.name);
}
}
});
}
/**
* Get the recent email from your Gmail account
*
* #param {google.auth.OAuth2} auth An authorized OAuth2 client.
*/
function getRecentEmail(auth) {
// Only get the recent email - 'maxResults' parameter
gmail.users.messages.list({auth: auth, userId: 'me', maxResults: 1,}, function(err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
// Get the message id which we will need to retreive tha actual message next.
var message_id = response['data']['messages'][0]['id'];
// Retreive the actual message using the message id
gmail.users.messages.get({auth: auth, userId: 'me', 'id': message_id}, function(err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
// Access the email body content, like this...
try {
const message_raw = response.data.payload.body.data;
data = message_raw;
buff = new Buffer.from(data, 'base64');
text = buff.toString();
console.log(text);
}
catch (err){
const message_raw = response.data.payload.parts[0].body.data;
console.log('error');
data = message_raw;
buff = new Buffer.from(data, 'base64');
text = buff.toString();
console.log(text);
}
});
});
}
Although this works perfectly fine, I am looking to find the 3 latest emails (not just 1) based on the email's "TO:" recipient which I currently have stored as the email variable.
Any help would be appreciated!
Have a look at here: https://developers.google.com/gmail/api/guides/filtering.
You can search or filter files using the messages.list and
threads.list methods. These methods accept the q parameter which
supports the same advanced search syntax as the Gmail web-interface.
Use filters via q property:
const email = 'myEmail#example.com';
gmail.users.messages.list({
auth: auth,
userId: 'me',
maxResults: 1,
q: `to:${email}`
}
Beside to:address you can use all other search/filter params, like is:unread etc.

YouTube account authentication nodejs

I am making an application that searches for YouTube videos, and creates a playlist with those videos.
I've figured how to search for videos just using the API key provided, but am completely lost on how to do stuff as a user. At first, I thought that I could just use a service account to host all of the playlist, but I've learned quickly that YouTube doesn't support that.
My ultimate goal is to just create a playlist on my personal YouTube account, so I want that account to be hardcoded in.
I am struggling on changing it from using a service account to my personal account. Many other solutions I've seen use an express server with a frontend component, neither of which I have.
import { google } from 'googleapis';
import fs from 'fs';
const config = JSON.parse(fs.readFileSync('config.json', 'utf8'));
const key = require('./credentials.json');
const scopes = "https://www.googleapis.com/auth/youtube";
const jwt = new google.auth.JWT(key.client_email, null, key.private_key, scopes);
jwt.authorize((err, response) => {
const yt = google.youtube({
version: 'v3',
auth: jwt,
});
yt.search.list({
part: 'snippet',
q: 'study music | zen music -livestream -live',
maxResults: 1,
}, (err, data) => {
if (err) console.error(err);
if (data) {
console.log(data.data.items);
// TODO: create playlist with these items
}
});
});
Currently, it's using a service account to search for videos. I haven't done the playlist creation part yet because it would just keep giving an error as I'm using a service account.
The YouTube API does not support service accounts. You will need to use Oauth2 and save the refresh token. You can then use your refresh token to request a new access token whenever you need.
I recommend following quickstart
var fs = require('fs');
var readline = require('readline');
var {google} = require('googleapis');
var OAuth2 = google.auth.OAuth2;
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/youtube-nodejs-quickstart.json
var SCOPES = ['https://www.googleapis.com/auth/youtube.readonly'];
var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
process.env.USERPROFILE) + '/.credentials/';
var TOKEN_PATH = TOKEN_DIR + 'youtube-nodejs-quickstart.json';
// Load client secrets from a local file.
fs.readFile('client_secret.json', function processClientSecrets(err, content) {
if (err) {
console.log('Error loading client secret file: ' + err);
return;
}
// Authorize a client with the loaded credentials, then call the YouTube API.
authorize(JSON.parse(content), getChannel);
});
/**
* Create an OAuth2 client with the given credentials, and then execute the
* given callback function.
*
* #param {Object} credentials The authorization client credentials.
* #param {function} callback The callback to call with the authorized client.
*/
function authorize(credentials, callback) {
var clientSecret = credentials.installed.client_secret;
var clientId = credentials.installed.client_id;
var redirectUrl = credentials.installed.redirect_uris[0];
var oauth2Client = new OAuth2(clientId, clientSecret, redirectUrl);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, function(err, token) {
if (err) {
getNewToken(oauth2Client, callback);
} else {
oauth2Client.credentials = JSON.parse(token);
callback(oauth2Client);
}
});
}
/**
* Get and store new token after prompting for user authorization, and then
* execute the given callback with the authorized OAuth2 client.
*
* #param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
* #param {getEventsCallback} callback The callback to call with the authorized
* client.
*/
function getNewToken(oauth2Client, callback) {
var authUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES
});
console.log('Authorize this app by visiting this url: ', authUrl);
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('Enter the code from that page here: ', function(code) {
rl.close();
oauth2Client.getToken(code, function(err, token) {
if (err) {
console.log('Error while trying to retrieve access token', err);
return;
}
oauth2Client.credentials = token;
storeToken(token);
callback(oauth2Client);
});
});
}
/**
* Store token to disk be used in later program executions.
*
* #param {Object} token The token to store to disk.
*/
function storeToken(token) {
try {
fs.mkdirSync(TOKEN_DIR);
} catch (err) {
if (err.code != 'EEXIST') {
throw err;
}
}
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) throw err;
console.log('Token stored to ' + TOKEN_PATH);
});
console.log('Token stored to ' + TOKEN_PATH);
}
/**
* Lists the names and IDs of up to 10 files.
*
* #param {google.auth.OAuth2} auth An authorized OAuth2 client.
*/
function getChannel(auth) {
var service = google.youtube('v3');
service.channels.list({
auth: auth,
part: 'snippet,contentDetails,statistics',
forUsername: 'GoogleDevelopers'
}, function(err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
var channels = response.data.items;
if (channels.length == 0) {
console.log('No channel found.');
} else {
console.log('This channel\'s ID is %s. Its title is \'%s\', and ' +
'it has %s views.',
channels[0].id,
channels[0].snippet.title,
channels[0].statistics.viewCount);
}
});
}

Error missing end time when create event on google calendar api using NodeJS

I have a problem creating an event in google calendar api using nodejs. Specifically, I successfully took a list of events in the google calendar but could not create the event and it showed a "Missing end time" error. Below is my code, I have reference to the google calendar api instructions:
var express = require('express');
var router = express.Router();
var fs = require('fs');
var readline = require('readline');
var google = require('googleapis');
var googleAuth = require('google-auth-library');
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/calendar-nodejs-quickstart.json
var SCOPES = [
'https://www.googleapis.com/auth/calendar'
];
var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE) + '/.credentials/';
var TOKEN_PATH = TOKEN_DIR + 'quickstart.json';
console.log(TOKEN_PATH);
// Load client secrets from a local file.
fs.readFile('client_secret.json', function processClientSecrets(err, content) {
if (err) {
console.log('Error loading client secret file: ' + err);
return;
}
// Authorize a client with the loaded credentials, then call the
// Google Calendar API.
authorize(JSON.parse(content), listEvents);
authorize(JSON.parse(content), addEvents);
});
/**
* Create an OAuth2 client with the given credentials, and then execute the
* given callback function.
*
* #param {Object} credentials The authorization client credentials.
* #param {function} callback The callback to call with the authorized client.
*/
function authorize(credentials, callback) {
var clientSecret = credentials.installed.client_secret;
var clientId = credentials.installed.client_id;
var redirectUrl = credentials.installed.redirect_uris[0];
var auth = new googleAuth();
var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, function(err, token) {
if (err) {
getNewToken(oauth2Client, callback);
} else {
oauth2Client.credentials = JSON.parse(token);
callback(oauth2Client);
}
});
}
/**
* Get and store new token after prompting for user authorization, and then
* execute the given callback with the authorized OAuth2 client.
*
* #param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
* #param {getEventsCallback} callback The callback to call with the authorized
* client.
*/
function getNewToken(oauth2Client, callback) {
var authUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES
});
console.log('Authorize this app by visiting this url: ', authUrl);
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('Enter the code from that page here: ', function(code) {
rl.close();
oauth2Client.getToken(code, function(err, token) {
if (err) {
console.log('Error while trying to retrieve access token', err);
return;
}
oauth2Client.credentials = token;
storeToken(token);
callback(oauth2Client);
});
});
}
/**
* Store token to disk be used in later program executions.
*
* #param {Object} token The token to store to disk.
*/
function storeToken(token) {
try {
fs.mkdirSync(TOKEN_DIR);
} catch (err) {
if (err.code != 'EEXIST') {
throw err;
}
}
fs.writeFile(TOKEN_PATH, JSON.stringify(token));
console.log('Token stored to ' + TOKEN_PATH);
}
/**
* Lists the next 10 events on the user's primary calendar.
*
* #param {google.auth.OAuth2} auth An authorized OAuth2 client.
*/
function listEvents(auth) {
var calendar = google.calendar('v3');
calendar.events.list({
auth: auth,
calendarId: 'primary',
timeMin: (new Date()).toISOString(),
maxResults: 10,
singleEvents: true,
orderBy: 'startTime'
}, function(err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
var events = response.items;
if (events.length == 0) {
console.log('No upcoming events found.');
} else {
console.log('Upcoming 10 events:');
for (var i = 0; i < events.length; i++) {
var event = events[i];
var start = event.start.dateTime || event.start.date;
var end = event.end.dateTime || event.end.date;
console.log('%s - %s', start, event.summary);
console.log('%s', end);
}
}
});
}
function addEvents(auth){
var calendar = google.calendar('v3');
var event = {
'summary': 'Drinking beer with friends',
'start': {
'dateTime': '2018-02-09T09:00:00+07:00'
},
'end': {
'dateTime': '2018-02-09T17:00:00+07:00'
}
};
calendar.events.insert({
auth: auth,
calendarId: 'primary',
resource: event,
}, function(err, event) {
if (err) {
console.log('There was an error contacting the Calendar service: ' + err);
return;
}
console.log('Event created: %s', event.htmlLink);
});
}
/* GET home page. */
/*console.log('ok');
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});*/
module.exports = router;
I tried to fix but the code still says "Missing end time" error when I create event, 1 week elapsed I can not fix it yet. Looking forward to your help.
I have the same problem, I am just revoked my access from Third-party apps with account access. and it's work for me
Make the following changes -
var {google} = require('googleapis'); instead of var google = require('googleapis');
Write var OAuth2 = google.auth.OAuth2; instead of var googleAuth = require('google-auth-library');
Do not npm install google-auth-library. If you did, remove it from your package.json and do npm install again.
Make sure you have the latest version of googleapis package. If you do not - do npm install googleapis#27 to get it. (Also add it to the package.json for future).
For any callback - instead of response.items, do response.data.items. You do not necessarily need the callback output when you create an event but you definitely need it when you list events. So do not forget to make this change there.
I don't think there would be any issue once you follow all these steps. If there still is, just reply to this. I will try my best to get it resolved!

Store Events List from Google Calendar Node.js Example in Express.js Application

Being a javascript/node.js/express.js newbie, I'm banging my head on this one. Looking at "Google Calendar API Node.js Quickstart", I've been able to sucessfully print a list of upcoming events when running node quickstart.js. I'd now like to present this data in the browser by passing it into the view renderer. I've copied over the code from quickstart.js into my routes/calendar.js file. This is what routes/calendar.js currently looks like:
var express = require('express');
var router = express.Router();
var fs = require('fs');
var readline = require('readline');
var google = require('googleapis');
var googleAuth = require('google-auth-library');
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/calendar-nodejs-quickstart.json
var SCOPES = ['https://www.googleapis.com/auth/calendar.readonly'];
var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
process.env.USERPROFILE) + '/.credentials/';
var TOKEN_PATH = TOKEN_DIR + 'calendar-nodejs-quickstart.json';
/**
* Create an OAuth2 client with the given credentials, and then execute the
* given callback function.
*
* #param {Object} credentials The authorization client credentials.
* #param {function} callback The callback to call with the authorized client.
*/
function authorize(credentials, callback) {
var clientSecret = credentials.installed.client_secret;
var clientId = credentials.installed.client_id;
var redirectUrl = credentials.installed.redirect_uris[0];
var auth = new googleAuth();
var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, function(err, token) {
if (err) {
getNewToken(oauth2Client, callback);
} else {
oauth2Client.credentials = JSON.parse(token);
callback(oauth2Client);
}
});
}
/**
* Get and store new token after prompting for user authorization, and then
* execute the given callback with the authorized OAuth2 client.
*
* #param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
* #param {getEventsCallback} callback The callback to call with the authorized
* client.
*/
function getNewToken(oauth2Client, callback) {
var authUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES
});
console.log('Authorize this app by visiting this url: ', authUrl);
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('Enter the code from that page here: ', function(code) {
rl.close();
oauth2Client.getToken(code, function(err, token) {
if (err) {
console.log('Error while trying to retrieve access token', err);
return;
}
oauth2Client.credentials = token;
storeToken(token);
callback(oauth2Client);
});
});
}
/**
* Store token to disk be used in later program executions.
*
* #param {Object} token The token to store to disk.
*/
function storeToken(token) {
try {
fs.mkdirSync(TOKEN_DIR);
} catch (err) {
if (err.code != 'EEXIST') {
throw err;
}
}
fs.writeFile(TOKEN_PATH, JSON.stringify(token));
console.log('Token stored to ' + TOKEN_PATH);
}
function listEvents(auth) {
var calendar = google.calendar('v3');
calendar.events.list({
auth: auth,
calendarId: 'primary',
timeMin: (new Date()).toISOString(),
maxResults: 10,
singleEvents: true,
orderBy: 'startTime'
}, function(err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
var events = response.items;
if (events.length == 0) {
console.log('No upcoming events found.');
} else {
console.log('Upcoming 10 events:');
for (var i = 0; i < events.length; i++) {
var event = events[i];
var start = event.start.dateTime || event.start.date;
console.log('%s - %s', start, event.summary);
}
}
});
}
/* GET events listing. */
router.get('/', function(req, res, next) {
fs.readFile('client_secret.json', function processClientSecrets(err, content) {
if (err) {
console.log('Error loading client secret file: ' + err);
return;
}
// Authorize a client with the loaded credentials, then call the
// Google Calendar API.
authorize(JSON.parse(content), listEvents);
});
// TODO: How can I pass 'events' from 'listEvents' into the view renderer?
res.render('calendar', { title: 'TS Calendar', current: 'calendar', events: events });
});
module.exports = router;
When I visit http://localhost:3000/calendar in my browser, I do get an error about 'events' not being defined, but my console does print out the calendar events, so I know it's working on at least some level.
It seems to me to be just a mess of callbacks, and I can't quite wrap my head around how to extract/store var events = response.items; from within listEvents() so it's usable within router.get(). Any suggestions? A good example would be fantastic.
Also, for bonus points, I'm a little weary of including all this logic/code into the routes/calendar.js file. Is there a more expressjs-esque or appropriate place for it?
I'm thinking I was in the wrong mindset here. Instead, I went with client-side javascript and used the quickstart guide for that. I've made progress going this route, but I have a feeling I'm going to quickly find out it's not going to lend itself nicely to a kiosk application where a keyboard isn't present to authenticate. Might need to ask that question when I get to that point.

Resources