【问题标题】:Accessing Gmail API through Cloud Functions通过 Cloud Functions 访问 Gmail API
【发布时间】:2018-11-23 02:33:09
【问题描述】:

我正在尝试构建一个响应 gmail pubsub 消息的电子邮件解析器。我目前能够接收和解析 pubsub 消息并提取 historyId,但我无法验证我对 gmail api 的请求。这是我到目前为止所拥有的:

  //function defined outside the scope of the main function
  //used to create auth client
  function getAuthClient(event, callback) {
    var GoogleAuth = require('google-auth-library');

    var authFactory = new GoogleAuth();

    authFactory.getApplicationDefault(function (err, authClient) {
     if (err) {
       console.log('Unable to get application default credentials.');
       callback(err);
       return;
     }

     // Create the oAuth scopes you need
     if (authClient.createScopedRequired && authClient.createScopedRequired()) {
    console.log('creating scoped client');
      authClient = authClient.createScoped([
          'https://mail.google.com/'
      ]);
    }
   callback(null, authClient);
  });
}

exports.gmailParser = function gmailParser (event, callback) {
 var path = require('path');
 var base64 = require('base-64');

 // Set your service account key file into the environment for the auth lib 
to pick up
 process.env['GOOGLE_APPLICATION_CREDENTIALS'] = path.resolve(__dirname, 
'auth_credentials.json');
 console.log(process.env['GOOGLE_APPLICATION_CREDENTIALS']);


 console.log(__dirname);

 //parse pubsub message
 var pubsubMessage = event.data;
 var baseMessage = pubsubMessage.data;
 var decodedMessage = base64.decode(baseMessage);
 var messageJSON = JSON.parse(decodedMessage);

 // Extract emailAddress and historyId from gmail pubsub message
 var historyId = messageJSON.historyId;
 var email = messageJSON.emailAddress;

 getAuthClient(null, function(err, authClient) {

   //import necessary libraries
   var google = require('googleapis');
   var gmail = google.gmail('v1');

   if(err) {
     callback(err);
   }

  // Construct a params object
  var params = {
    userId: email,
    startHistoryId: historyId
 };


//Attempt to call gmail api. This is where the error occurs.
gmail.users.history.list(params, function(error, response) {
  if (error) {  
    console.log('Encountered error', error);
    callback(error);
  } else {
    console.log('Response', response);
    callback(response);
  }
});
 });
};

代码运行成功,但出现以下错误:

"Error: Login Required
at Request._callback (/user_code/node_modules/googleapis/node_modules/google-auth-library/lib/transporters.js:85:15)
at Request.self.callback (/user_code/node_modules/googleapis/node_modules/request/request.js:188:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request.<anonymous> (/user_code/node_modules/googleapis/node_modules/request/request.js:1171:10)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
at IncomingMessage.<anonymous> (/user_code/node_modules/googleapis/node_modules/request/request.js:1091:12)
at IncomingMessage.g (events.js:291:16)
at emitNone (events.js:91:20)"   

我尝试将 authClient 添加到 param 对象,但它返回“错误请求”错误。我已经尝试更改导入的顺序,创建了新的凭据,但我无法到达任何地方。如果有人有任何指点,将不胜感激。

【问题讨论】:

  • 由于您使用的是 Gmail API 和 NodeJS,您是否尝试过使用 Gmail Node.js Quickstart 中的登录流程
  • 我做了,但是当我尝试使用 json 文件时,我收到以下错误:错误:传入的 JSON 对象不包含 client_email 字段
  • @kevinivan05 这意味着您的 json 文件有问题。您能否确保您使用的是正确的文件,按照快速入门中的步骤获得? json 文件应如下所示{"installed":{"client_id":"your_id","project_id":"your_project_name","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"your_secret","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
  • 你找到解决办法了吗?
  • 您的回调似乎从未使用过它的authClient。您是否尝试将google.gmail('v1'); 替换为google.gmail({version:'v1', auth: authClient); 之类的东西?

标签: node.js gmail-api google-oauth google-cloud-functions google-api-nodejs-client


【解决方案1】:

这篇博文可能会有所帮助。它包含有关使用 nodejs 和 Cloud Functions 获取 OAuth 令牌的详细信息。我试过了,效果很好。

https://cloud.google.com/blog/products/application-development/adding-custom-intelligence-to-gmail-with-serverless-on-gcp

代码:https://github.com/GoogleCloudPlatform/cloud-functions-gmail-nodejs

以下代码 sn-p 请求 OAuth 2.0 授权码

exports.oauth2init = (req, res) => {
  // Define OAuth2 scopes
  const scopes = [
    'https://www.googleapis.com/auth/gmail.modify'
  ];

  // Generate + redirect to OAuth2 consent form URL
  const authUrl = oauth.client.generateAuthUrl({
    access_type: 'offline',
    scope: scopes,
    prompt: 'consent' // Required in order to receive a refresh token every time
  });
  return res.redirect(authUrl);
};

以下代码 sn -p 从 OAuth 授权码中获取访问令牌

exports.oauth2callback = (req, res) => {
  // Get authorization code from request
  const code = req.query.code;

  // OAuth2: Exchange authorization code for access token
  return new Promise((resolve, reject) => {
    oauth.client.getToken(code, (err, token) =>
      (err ? reject(err) : resolve(token))
    );
  })

【讨论】:

  • 是否也可以使用我们在应用内签名时获得的现有访问令牌来获取刷新令牌?请提供任何代码示例或文章。
猜你喜欢
  • 2020-02-08
  • 2015-06-12
  • 2019-01-10
  • 2021-04-08
  • 1970-01-01
  • 2018-11-23
  • 2016-11-30
  • 2015-08-13
  • 1970-01-01
相关资源
最近更新 更多