Is this the right way to access the google calendar api using a refresh token? That's 2 weeks after a user gave me his consent.
const oauth2Client = new google.auth.OAuth2(
process.env.GOOGLE_OAUTH_CLIENT_ID,
process.env.GOOGLE_OAUTH_CLIENT_SECRET,
process.env.DOMAIN_NAME + "/google/oauth/callback"
);
oauth2Client.setCredentials({
refresh_token: refreshToken
})
const calendar = google.calendar({version: "v3", auth: oauth2Client});
calendar.events.watch({
auth: oauth2Client,
resource: {
id: makeid(10) + Date.now(),
token: process.env.GOOGLE_API_WATCH_TOKEN,
type: 'web_hook',
address: "https://" + process.env.DOMAIN_NAME + "/google/notifications"
},
calendarId: "primary"
}, function(error, response) {
if (error) {
defer.reject(error);
} else {
defer.resolve(response);
}
});
return defer.promise;
I'm not using jwt.
Your code shows a valid approach to token handling if it doesn't generate any issues. As an answer, I show below an alternative to OAuth 2.0 token handling.
This code will first read the token file with the readFile method. Then it will be fed to the authorize function. That function will set up the objects used on the authentication flow, and if it fails (due to an invalid token, per example) then it will call the getAccessToken function to gather new tokens.
const fs = require('fs');
const readline = require('readline');
const {
google
} = require('googleapis');
const SCOPES = ['{YOUR SCOPES HERE}'];
const TOKEN_PATH = 'token.json';
fs.readFile('credentials.json', (err, content) => {
if (err) return console.log('Error loading client secret file:', err);
authorize(JSON.parse(content), listEvents);
});
function authorize(credentials, callback) {
const {
client_secret,
client_id,
redirect_uris
} = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(
client_id, client_secret, redirect_uris[0]);
fs.readFile(TOKEN_PATH, (err, token) => {
if (err) return getAccessToken(oAuth2Client, callback);
oAuth2Client.setCredentials(JSON.parse(token));
callback(oAuth2Client);
});
}
function getAccessToken(oAuth2Client, callback) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
oAuth2Client.getToken(code, (err, token) => {
if (err) return console.error('Error retrieving access token',
err);
oAuth2Client.setCredentials(token);
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) return console.error(err);
console.log('Token stored to', TOKEN_PATH);
});
callback(oAuth2Client);
});
});
}
Please write back if you have doubts about this approach or your own.
Related
I currently have an application that requires me to call the google drive api from the client and the server. Right now, I've already authenticated the user on the front end with auth 2.0 and I can upload files just fine.
Most of the code for this section, I've scraped together from the documentation and various blog posts.
async function uploadDocGoogle() {
// get file
const fileChooser = document.getElementById('config-file-upload');
const file = fileChooser.files[0];
console.log("file", file);
const fileMetaData = {
'name': file.name,
'mimeType': file.type
};
var accessToken = gapi.auth.getToken().access_token; // Here gapi is used for retrieving the access token.
await setGoogleAPIToken(accessToken);
console.log(accessToken);
var form = new FormData();
form.append('metadata', new Blob([JSON.stringify(fileMetaData)], {type: 'application/json'}));
form.append('file', file);
var xhr = new XMLHttpRequest();
xhr.open('post', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id');
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
xhr.responseType = 'json';
xhr.onload = () => {
console.log(xhr.response.id); // Retrieve uploaded file ID.
console.log(xhr);
};
xhr.send(form);
}
var SCOPES = 'https://www.googleapis.com/auth/drive';
var authorizeButton = document.getElementById('config-google-test');
/**
* On load, called to load the auth2 library and API client library.
*/
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}
/**
* Initializes the API client library and sets up sign-in state
* listeners.
*/
function initClient() {
gapi.client.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES
}).then(function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
//authorizeButton.onclick = handleAuthClick;
}, function(error) {
appendPre(JSON.stringify(error, null, 2));
});
}
/**
* Called when the signed in status changes, to update the UI
* appropriately. After a sign-in, the API is called.
*/
function updateSigninStatus(isSignedIn) {
if (isSignedIn) {
console.log("Logged In");
} else {
console.log("Logged Out");
}
}
/**
* Sign in the user upon button click.
*/
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
/**
* Sign out the user upon button click.
*/
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
Now I need to make a call to the api from the backend written in NodesJS. However, I want to authorize these calls using what I already have from the front end. The auth token that is generated in the front end for the call seems to only be temporary and so I don't think i can send that to the backend to authorize calls. I was wondering if anyone knew another way to do it? I was wondering if anyone also knew how to initialise the google api to use that token to make a call.
You can use passport in NodeJS to integrate google auth 2.0, and then use that in frontend to authenticate and login users. Once a user logins you will get a token(from google auth) with other user data (name, email etc). And you can then store this in your database(or server variables/json-files).
Now, you can use session to preserve user state, or simply call the required api with the token attached(maintain its state in frontend, React Hooks? or simply cookies work too) and you can validate which user it is.
This is kind of a rough solution. But I have worked with it in a similar manner.
Try Below:
const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
const SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly'];
const TOKEN_PATH = 'token.json';// You can save token in dB as well
fs.readFile('credentials.json', (err, content) => {
if (err) return console.log('Error loading client secret file:', err);
// Authorize a client with credentials, then call the Google Drive API.
authorize(JSON.parse(content), listFiles);
});
function authorize(credentials, callback) {
const {client_secret, client_id, redirect_uris} = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(
client_id, client_secret, redirect_uris[0]);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, (err, token) => {
if (err) return getAccessToken(oAuth2Client, callback);
oAuth2Client.setCredentials(JSON.parse(token));
callback(oAuth2Client);
});
}
function getAccessToken(oAuth2Client, callback) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
oAuth2Client.getToken(code, (err, token) => {
if (err) return console.error('Error retrieving access token', err);
oAuth2Client.setCredentials(token);
// Store the token to disk for later program executions
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) return console.error(err);
console.log('Token stored to', TOKEN_PATH);
});
callback(oAuth2Client);
});
});
}
function listFiles(auth) {
const drive = google.drive({version: 'v3', auth});
drive.files.list({
pageSize: 10,
fields: 'nextPageToken, files(id, name)',
}, (err, res) => {
if (err) return console.log('The API returned an error: ' + err);
const files = res.data.files;
if (files.length) {
console.log('Files:');
files.map((file) => {
console.log(`${file.name} (${file.id})`);
});
} else {
console.log('No files found.');
}
});
}
'getAccessToken' can be simplified if you want to use front-end. When you will get a account authorize to google. Google will return back you a Code. Use that code in this function. This will achieve your objective.
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
oAuth2Client.getToken(code, (err, token) => {
if (err) return console.error('Error retrieving access token', err);
oAuth2Client.setCredentials(token);
// Store the token to disk for later program executions
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) return console.error(err);
console.log('Token stored to', TOKEN_PATH);
});
callback(oAuth2Client);
});
});
I am trying to fetch the primary calendar in my nodeJS application, but its giving
login required error
code: 401,
errors:
[ { domain: 'global',
reason: 'required',
message: 'Login Required',
locationType: 'header',
location: 'Authorization' } ] }
following is the code
calendar.middleware.js
const {google} = require('googleapis');
const oAuth2Client = new google.auth.OAuth2(
CLIENT_ID,
CLIENT_SECRET,
'http://localhost:8000/api/v1/google/callback' //YOUR_REDIRECT_URL
);
const SCOPES = [
'https://www.googleapis.com/auth/calendar'
];
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
module.exports = {
fetchToken: async function(req, res, next){
console.log("fetchToken");
const code = req.query.code;
try{
const token = await oAuth2Client.getToken(code);
req.token = token;
next();
}catch(e){
next(e);
}
},
fetchCalendars: async function(req, res, next){
console.log("fetchCalendars");
const token = req.token;
let cals;
oAuth2Client.setCredentials(token);
try{
const calendar = await google.calendar({version: 'v3', oAuth2Client});
cals = calendar.calendarList.get({calendarId: 'primary'});
console.log(cals);
next();
}catch(e){
next(e);
}
}
}
routes/index.js
...
router.route('api/v1/google/callback').get( calendarMiddleware.fetchToken,
calendarMiddleware.fetchCalendars,
calendarController.googleCallback);
...
For async/await, try this:
google.gmail({version: 'v1', auth: oAuth2Client});
Instead of:
google.gmail({version: 'v1', oAuth2Client});
before fetching labels or emails.
'Login Required',
Means that you are not properly authenticating your request. The following should be close
const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/calendar'];
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
const TOKEN_PATH = 'token.json';
// Load client secrets from a local file.
fs.readFile('credentials.json', (err, content) => {
if (err) return console.log('Error loading client secret file:', err);
// Authorize a client with credentials, then call the Google Calendar API.
authorize(JSON.parse(content), fetchCalendars);
});
/**
* 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) {
const {client_secret, client_id, redirect_uris} = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(
client_id, client_secret, redirect_uris[0]);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, (err, token) => {
if (err) return getAccessToken(oAuth2Client, callback);
oAuth2Client.setCredentials(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 for the authorized client.
*/
function getAccessToken(oAuth2Client, callback) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
oAuth2Client.getToken(code, (err, token) => {
if (err) return console.error('Error retrieving access token', err);
oAuth2Client.setCredentials(token);
// Store the token to disk for later program executions
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) return console.error(err);
console.log('Token stored to', TOKEN_PATH);
});
callback(oAuth2Client);
});
});
}
/**
* Lists the names and IDs of up to 10 files.
* #param {google.auth.OAuth2} auth An authorized OAuth2 client.
*/
function fetchCalendars(auth) {
const calendar = google.calendar({version: 'v3', auth});
cals = calendar.calendarList.get({calendarId: 'primary'}), (err, res) => {
if (err) return console.log('The API returned an error: ' + err);
const items = res.items;
if (items.length) {
console.log('Calendar:');
items.map((calendarList) => {
console.log(`${calendarList.description} (${calendarList.id})`);
});
} else {
console.log('No files found.');
}
});
}
The code above is pieced together form Node.js quickstart Google drive Its the best auth example for node.js that i know of.
I am using a combination of the examples provided to download a document to my filesystem, in the future directly to the server but that's the next step.
The code runs without errors but the worksheet created has 0 bytes and cannot be opened. Any ideas please? The documentation is giving me analysis paralysis.
I have consulted countless github posts and questions here but nothing seems to stick.
const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
// If modifying these scopes, delete credentials.json.
const SCOPES = ['https://www.googleapis.com/auth/drive'];
const TOKEN_PATH = 'token.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) {
const {
client_secret,
client_id,
redirect_uris
} = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(
client_id, client_secret, redirect_uris[0]);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, (err, token) => {
if (err) return getNewToken(oAuth2Client, callback);
oAuth2Client.setCredentials(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 for the authorized client.
*/
function getNewToken(oAuth2Client, callback) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
oAuth2Client.getToken(code, (err, token) => {
if (err) return console.error('Error while trying to retrieve access token', err);
oAuth2Client.setCredentials(token);
// Store the token to disk for later program executions
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) console.error(err);
console.log('Token stored to', TOKEN_PATH);
});
callback(oAuth2Client);
});
});
}
// Load client secrets from a local file.
fs.readFile('credentials.json', (err, content) => {
if (err) return console.log('Error loading client secret file:', err);
// Authorize a client with credentials, then call the Google Sheets API.
authorize(JSON.parse(content), grabFileFromDrive);
});
function grabFileFromDrive(auth) {
const drive = google.drive({
version: 'v3',
auth
});
var fileId = '<FILEIDHERE>';
var dest = fs.createWriteStream('/tmp/feedback-list.xlsx');
drive.files.export({
fileId: fileId,
mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
}, {
responseType: 'stream'
}), function(err, res){
res.data
.on('end', () => {
console.log('Done');
})
.on('error', err => {
console.log('Error', err);
})
.pipe(dest);
console.log(res);}
}
The document downloaded is corrupt/incorrectly formatted and has a 0 size value, how can I get a working excel sheet downloaded to my directory?
UPDATE: I have added working code below, I think the issue was token related and not being able to view the error produced within the downloaded document alerting me to insufficient scopes, either that or the response function wasn't in the right place, rebuilt it all again from documentation and a tutorial and somehow this works now. Hope it helps
const fs = require('fs');
const readline = require('readline');
const {
google
} = require('googleapis');
// If modifying these scopes, delete token.json.
const SCOPES = 'https://www.googleapis.com/auth/drive';
const TOKEN_PATH = 'token.json';
// Load client secrets from a local file.
fs.readFile('credentials.json', (err, content) => {
if (err) return console.log('Error loading client secret file:', err);
// Authorize a client with credentials, then call the Google Drive API.
authorize(JSON.parse(content), downloadDriveFile);
});
function authorize(credentials, callback) {
const {
client_secret,
client_id,
redirect_uris
} = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(
client_id, client_secret, redirect_uris[0]);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, (err, token) => {
if (err) return getAccessToken(oAuth2Client, callback);
oAuth2Client.setCredentials(JSON.parse(token));
callback(oAuth2Client);
});
}
function getAccessToken(oAuth2Client, callback) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
oAuth2Client.getToken(code, (err, token) => {
if (err) return console.error('Error retrieving access token', err);
oAuth2Client.setCredentials(token);
// Store the token to disk for later program executions
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) console.error(err);
console.log('Token stored to', TOKEN_PATH);
});
callback(oAuth2Client);
});
});
}
function downloadDriveFile(auth) {
const drive = google.drive({
version: 'v3',
auth
});
var fileId = 'xxxxxxxxxxxxxxx';
var dest = fs.createWriteStream('/tmp/feedback.csv');
// example code here
drive.files.export({
fileId: fileId,
mimeType: 'text/csv'
// excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
}, {
responseType: 'stream'
},
function (err, res) {
res.data
.on('end', () => {
console.log('Done');
})
.on('error', err => {
console.log('Error', err);
})
.pipe(dest);
})
///
}
I am trying to create a client-side script that allows someone to login to their Google Account and then access a Firestore database once they are authenticated. Everything works except for some reason after signing in using firebase.auth it isn't passing this data to firebase.firestore to say they are authenticated.
Here is the script that I am using, the only part that is failing is when I am trying to add to a Firestore collection.
const firebase = require ("firebase/app");
require("firebase/auth");
require("firebase/firestore");
const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
const util = require('util')
var config = {
**HIDDEN**
};
firebase.initializeApp(config);
const SCOPES = ['email','profile'];
const TOKEN_PATH = 'token.json';
fs.readFile('credentials.json', (err, content) => {
if (err) return console.log('Error loading client secret file:', err);
// Authorize a client with credentials, then call the Gmail API.
authorize(JSON.parse(content), listLabels);
});
function authorize(credentials, callback) {
const {client_secret, client_id, redirect_uris} = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(
client_id, client_secret, redirect_uris[0]);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, (err, token) => {
if (err) return getNewToken(oAuth2Client, callback);
oAuth2Client.setCredentials(JSON.parse(token));
callback(oAuth2Client);
});
}
function getNewToken(oAuth2Client, callback) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
oAuth2Client.getToken(code, (err, token) => {
if (err) return console.error('Error retrieving access token', err);
oAuth2Client.setCredentials(token);
// Store the token to disk for later program executions
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) return console.error(err);
console.log('Token stored to', TOKEN_PATH);
});
callback(oAuth2Client);
});
});
}
function listLabels(auth) {
var credential = firebase.auth.GoogleAuthProvider.credential(auth.credentials.id_token);
firebase.auth().signInAndRetrieveDataWithCredential(credential).catch(function(error) {
var errorCode = error.code;
var errorMessage = error.message;
var email = error.email;
var credential = error.credential;
console.log(errorCode);
console.log(errorMessage);
});
var firestore = firebase.firestore();
firestore.settings({
timestampsInSnapshots: true
});
firestore.collection("users").add({
test: "Hello"
});
firebase.auth().signOut();
}
And below is my rules for the database, if I change it to just if true; it works perfectly fine. But I want to make sure only an authenticated user can access that database.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
The method signInAndRetrieveDataWithCredential returns a promise, and you aren't waiting for it to finish before accessing the data on Firestore, so that is probably what is causing the issues. I believe this might work:
function listLabels(auth) {
var credential = firebase.auth.GoogleAuthProvider.credential(auth.credentials.id_token);
firebase.auth().signInAndRetrieveDataWithCredential(credential)
.then(user => {
var firestore = firebase.firestore();
firestore.settings({
timestampsInSnapshots: true
});
firestore.collection("users").add({
test: "Hello"
});
firebase.auth().signOut();
})
.catch(function (error) {
var errorCode = error.code;
var errorMessage = error.message;
var email = error.email;
var credential = error.credential;
console.log(errorCode);
console.log(errorMessage);
});
}
I am a beginner in Node JS and I want to upload a local file to google drive. I have followed the instructions from this URL. But when I am going to run it, It gives an error like "insufficient permissions." Please help me out what I am missing in it.
Here is my code.
const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
const OAuth2Client = google.auth.OAuth2;
const SCOPES = ['https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/drive.files.create',
'https://www.googleapis.com/auth/spreadsheets'];
const TOKEN_PATH = 'credentials.json';
// Load client secrets from a local file.
fs.readFile('client_secret.json', (err, content) => {
if (err) return console.log('Error loading client secret file:', err);
// Authorize a client with credentials, then call the Google Sheets API.
authorize(JSON.parse(content), real_upload_files);
});
function authorize(credentials, callback) {
const {client_secret, client_id, redirect_uris} = credentials.installed;
const oAuth2Client = new OAuth2Client(client_id, client_secret, redirect_uris[0]);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, (err, token) => {
if (err) return getNewToken(oAuth2Client, callback);
oAuth2Client.setCredentials(JSON.parse(token));
callback(oAuth2Client);});
}
function getNewToken(oAuth2Client, callback) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
oAuth2Client.getToken(code, (err, token) => {
if (err) return callback(err);
oAuth2Client.setCredentials(token);
// Store the token to disk for later program executions
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) console.error(err);
console.log('Token stored to', TOKEN_PATH);
});
callback(oAuth2Client);
});
});
}
function real_upload_files(auth) {
var drive = google.drive('v3');
var fileMetadata = {
'name': 'Studentdata.xlsx',
'mimeType': 'application/vnd.google-apps.spreadsheet'
};
var media = {
mimeType: 'text/csv',
body: fs.createReadStream('files/students.xlsx')
};
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);
}
});
}
Please help me out what I am missing in it. Looking forward.
What's happening here is that you're following the NodeJS Quickstart which uses the drive.files.list method which only uses the default 'read-only' scope:
https://www.googleapis.com/auth/drive.metadata.readonly
Now you modified the sample and decided to use upload method using files.create. Your default scopes won't work anymore because it's for 'read-only' (you're doing a 'write' command). You need to use the scopes mentioned in the files.create method, at least one of these:
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.file
After that, delete your previously saved credentials (somewhere in your directory where credentials are stored) for this project and re-do the authorization. This should work after that.