无法使用Node.js验证Google服务帐户

时间:2020-03-11 23:57:22

标签: node.js google-calendar-api service-accounts

我的目标是允许人们通过我的网站(当前使用Firebase)将事件添加到日历中。我试图允许他们将事件添加到服务帐户中;但是,我在获取服务帐户身份验证时遇到问题。当我尝试部署代码时,我在await google.auth.getClient部分收到“意外令牌Google”错误。我在全球安装了Google API工具。

//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;
  });

}); 

我一直在关注这两个教程的结合: 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

我花了很多时间在搜索可能出什么问题的地方,但是老实说,这个Google身份验证的东西使我感到困惑。我将不胜感激,谢谢:)

1 个答案:

答案 0 :(得分:1)

  • 您要使用服务帐户向Google日历创建新活动。
  • credentials.json是服务帐户的凭据文件。
  • 您要使用带有Node.js的googleapis实现此目的。
  • 您已经可以使用Calendar API。

如果我的理解是正确的,那么该修改如何?请认为这只是几个可能的答案之一。

修改点:

  • 使用服务帐户时,可以使用google.auth.JWT代替google.auth.getClient
  • 在您的脚本中,client被赋予addEvent(eventData, client)。但是在function addEvent(event) {},不使用client
  • 关于path.join(__dirname, 'credentials.json';,需要添加)。而且我认为还需要添加const path = require("path");

修改后的脚本:

//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;
    });
});

注意:

  • 此修改后的脚本假定request.body的对象可用于resource的{​​{1}}。
  • calendar.events.insert()是否在其他地方声明?请注意这一点。
  • 如果服务帐户的电子邮件未与Google Spreadsheet共享,则无法创建事件。所以请注意这一点。

参考文献:

如果我误解了你的情况,而这不是你想要的方向,我深表歉意。