1

My goal is to allow people to add events to a calendar through my website (which uses Firebase currently.) I'm attempting to allow them to add the events to a service account; however, I'm having issues getting the service account authenticated. When I attempt to deploy my code, I get an 'unexpected token google' error at the await google.auth.getClient part. I have google API tools installed globally.

//ADD CALENDAR EVENT
const {google} = require('googleapis');
const calendar = google.calendar('v3');
//Authenticate Service Acounnt
function getCredentials() {
 const filePath = path.join(__dirname, 'credentials.json';
 if (fs.existsSync(filePath)) {
 return require(filePath)
 }
 if (process.env.CREDENTIALS) {
 return JSON.parse(process.env.CREDENTIALS)
 }
 throw new Error('Unable to load credentials')
}
//Create Calendar Event
function addEvent(event) {
 return new Promise(function(resolve, reject) {
 calendar.events.insert({
 calendarId: 'primary',
 resource: {
 'summary': event.eventName,
 'description': event.description,
 'start': {
 'dateTime': event.startTime,
 'timeZone': TIME_ZONE,
 },
 'end': {
 'dateTime': event.endTime,
 'timeZone': TIME_ZONE,
 },
 },
 }, (err, res) => {
 if (err) {
 console.log('Rejecting because of error');
 reject(err);
 }
 console.log('Request successful');
 resolve(res.data);
 });
 });
}
//Add Event To Service Acount 
exports.addEventToCalendar = functions.https.onRequest((request, response) => {
 const eventData = {
 eventName: request.body.eventName,
 description: request.body.description,
 startTime: request.body.startTime,
 endTime: request.body.endTime
 }; 
 const credentials = getCredentials();
 const client = await google.auth.getClient({
 credentials,
 scopes: 'https://www.googleapis.com/auth/calendar',
 }) 
 addEvent(eventData, client).then(data => {
 response.status(200).send(data);
 return;
 }).catch(err => {
 console.error('Error adding event: ' + err.message); 
 response.status(500).send(ERROR_RESPONSE); 
 return;
 });
}); 

I've been following a combination of these two tutorials: https://medium.com/zero-equals-false/integrating-firebase-cloud-functions-with-google-calendar-api-9a5ac042e869 https://dev.to/mornir/create-a-service-account-to-authenticate-with-google-5b1k

I've spent a lot of time googling what could be wrong, but to be honest, this google authentication stuff confuses the heck out of me. I'd appreciate whatever help I can get, thanks :)

asked Mar 11, 2020 at 23:57

1 Answer 1

2
  • You want to create new event to the Google Calendar using the service account.
  • credentials.json is the credential file of the service account.
  • You want to achieve this using googleapis with Node.js.
  • You have already been able to use Calendar API.

If my understanding is correct, how about this modification?

Modification points:

  • When the service account is used, you can use google.auth.JWT instead of google.auth.getClient.
  • In your script, client is given to addEvent(eventData, client). But at function addEvent(event) {}, client is not used.
  • About path.join(__dirname, 'credentials.json';, ) is required to be added. And I think that const path = require("path"); is also required to added.

Modified script:

//ADD CALENDAR EVENT
const { google } = require("googleapis");
const path = require("path"); // Added
// --- I added below script.
const key = require(path.join(__dirname, 'credentials.json'));
const jwtClient = new google.auth.JWT(
 key.client_email,
 null,
 key.private_key,
 ["https://www.googleapis.com/auth/calendar"],
 null
);
const calendar = google.calendar({ version: "v3", auth: jwtClient });
// ---
//Create Calendar Event
function addEvent(event) {
 return new Promise(function(resolve, reject) {
 calendar.events.insert(
 {
 calendarId: "primary",
 resource: {
 summary: event.eventName,
 description: event.description,
 start: {
 dateTime: event.startTime,
 timeZone: TIME_ZONE
 },
 end: {
 dateTime: event.endTime,
 timeZone: TIME_ZONE
 }
 }
 },
 (err, res) => {
 if (err) {
 console.log("Rejecting because of error");
 reject(err);
 return;
 }
 console.log("Request successful");
 resolve(res.data);
 }
 );
 });
}
//Add Event To Service Acount
exports.addEventToCalendar = functions.https.onRequest((request, response) => {
 const eventData = {
 eventName: request.body.eventName,
 description: request.body.description,
 startTime: request.body.startTime,
 endTime: request.body.endTime
 };
 addEvent(eventData) // Modified
 .then(data => {
 response.status(200).send(data);
 return;
 })
 .catch(err => {
 console.error("Error adding event: " + err.message);
 response.status(500).send(ERROR_RESPONSE);
 return;
 });
});

Note:

  • This modified script supposes that the object of request.body can be used for resource of calendar.events.insert().
  • Is TIME_ZONE declared elsewhere? Please be careful this.
  • When the email of service account is not shared with the Google Spreadsheet, the event cannot be created. So please be careful this.

References:

halfer
20.2k19 gold badges110 silver badges207 bronze badges
answered Mar 12, 2020 at 0:49
Sign up to request clarification or add additional context in comments.

2 Comments

Wow! That really helped! I didn't realize I could use a JWT client. Thanks a ton; I really appreciate the answer.
@Cartesius Thank you for replying. I'm glad your issue was resolved.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.