无需用户干预Google Cloud Function即可对GMail API进行身份验证

时间:2019-11-24 21:20:34

标签: python oauth-2.0 google-cloud-functions gmail-api

我是新手,所以请多包涵。

我正在尝试设置一个Google Cloud Function,以访问同一域中的单个GMail帐户,下载一些电子邮件并将其推送到Cloud Storage。老实说,我只想在脚本中使用电子邮件和密码(使用Google KMS / w环境变量?),但我知道这是不可能的,并且需要OAuth2。

我已在GCP中设置了OAuth客户端,并且已运行GMail API Python Quickstart指南。在本地运行它时,系统会提示我允许访问,并且令牌已保存,因此后续运行无需提示即可。

我用pickle文件部署了Cloud Function,以测试刷新令牌是否仍然有效,并计划在以后弄清楚如何使用KMS使其更安全。但是加载泡菜有一个问题:

UnpicklingError: invalid load key, '\xef'

这似乎使泡菜在上载时被压缩/损坏。

这甚至是理智的方法吗?我该怎么办?该电子邮件地址是我的,因此我希望我只需进行一次身份验证即可完成。

我无法使用通过域授权的服务帐户,也不能使用IMAP。

1 个答案:

答案 0 :(得分:2)

由于您无法使用域委派的服务帐户,因此可以尝试按照本指南设置server side authorization。这听起来像您想要的,因为它要求用户对应用程序进行一次授权,然后再使用该令牌。这是一个codelab,它将带您完成auth部分。

或者,您可以使用推送通知。听起来您当前的设计是轮询Gmail API以定期查找新电子邮件,这还涉及在Cloud Function中授权访问该帐户。但是,如果您利用“推送通知”功能,则既可以实时获取数据,又可以避免授权Cloud Function读取Gmail API。 See guide here.

但是,最简单的解决方案可能是使用app scripts。如果您将云功能设置为通过HTTP目标触发,则可以编写应用程序脚本以使用要发送到GCS的消息来ping通该URL。 Docs here

function getEmails() {
  let inbox = GmailApp.getInboxThreads(0, 50);
  // Inbox Threads
  for (i=0; i < inbox.length; i++){ 
    let threadMessages = inbox[i].getMessages();
    // Thread Messages
    for (j=0; j < threadMessages.length; j++){
      let message = threadMessages[j].getBody();
      let subject = threadMessages[j].getSubject();

      var options = {
        'method' : 'post',
        'contentType': 'application/json',
        'payload' : JSON.stringify({"message": message, "subject": subject})
    };
     UrlFetchApp.fetch('YOUR_FUNCTION_TRIGGER_URL', options);
    }
  }
}