I'm following this example to access the Google Sheets API:
https://developers.google.com/sheets/api/quickstart/nodejs
Within the example code is the following method to fetch a new oauth token.
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);
});
});
}
This works fine on my local machine (manually visiting the page as prompted in the terminal, and entering the code in the command line). But this seems unpractical and doesn't work on Heroku. Is there any way to automate this? Maybe by fetching the URL (and token) in the nodeJS application and storing this somehow?
Thanks in advance.
Ok, so I ended up using a Service Account Key which can be generated at https://console.developers.google.com. This will generate a JSON file of which you need two values: private_key
and client_email
.
To test this locally you can download the dotenv npm module which will allow you to store Environment variables in a .env
file in your project root. Your .env
file will look like this:
GOOGLE_PRIVATE_KEY=<your-key-here-withouth-quotes>
GOOGLE_CLIENT_EMAIL=<your-email-here-withouth-quotes>
Don't forget to add the .env file to your .gitignore list when deploying your heroku app via git.
My auth.js
file looks like this:
const GoogleAuth = require('google-auth-library');
const SCOPES = ['https://www.googleapis.com/auth/spreadsheets.readonly'];
function authorize() {
return new Promise(resolve => {
const authFactory = new GoogleAuth();
const jwtClient = new authFactory.JWT(
process.env.GOOGLE_CLIENT_EMAIL,
null,
process.env.GOOGLE_PRIVATE_KEY.replace(/\\n/g, '\n'),
SCOPES
);
jwtClient.authorize(() => resolve(jwtClient));
});
}
module.exports = {
authorize,
}
Note the replace function behind the private key variable.
My app.js (main file) looks like this:
require('dotenv').config();
const google = require('googleapis');
const sheetsApi = google.sheets('v4');
const googleAuth = require('./auth');
const SPREADSHEET_ID = 'Your-spreadsheet-ID';
googleAuth.authorize()
.then((auth) => {
sheetsApi.spreadsheets.values.get({
auth: auth,
spreadsheetId: SPREADSHEET_ID,
range: "'Tab Name'!A1:H300",
}, function (err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return console.log(err);
}
var rows = response.values;
console.log(null, rows);
});
})
.catch((err) => {
console.log('auth error', err);
});
If you get the following error:
The API returned an error: Error: The caller does not have permission
Share the spreadsheet you are trying to load with the google_client_email and try again.
If everything works locally, add the Environment Variables to your heroku app by visiting your heroku account and going to settings
and click reveal config vars
and deploy the application. If all goes well, you should have access to the document.
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