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 :)
1 Answer 1
- You want to create new event to the Google Calendar using the service account.
- credentials.jsonis 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.JWTinstead ofgoogle.auth.getClient.
- In your script, clientis given toaddEvent(eventData, client). But atfunction addEvent(event) {},clientis not used.
- About path.join(__dirname, 'credentials.json';,)is required to be added. And I think thatconst 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.bodycan be used forresourceofcalendar.events.insert().
- Is TIME_ZONEdeclared 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:
2 Comments
Explore related questions
See similar questions with these tags.