在 Google Cloud Function 中无需用户干预即可验证 GMail API

Authenticate GMail API without user intervention in Google Cloud Function

我是新手,请多多包涵。

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

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

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

UnpicklingError: invalid load key, '\xef'

这使得泡菜看起来在上传时得到 compressed/corrupted。

这甚至是一种理智的方法吗?我怎么能这样做?电子邮件地址是我的,所以我希望我可以验证一次并完成它。

顺便说一句,我无法使用域委托服务帐户 - 也无法使用 IMAP。

由于您无法使用域委托服务帐户,因此您可以尝试按照本指南设置 server side authorization. This sounds like what you want since it requires that the user authorizes the app once and then reuses that token. Here is a codelab,这将引导您完成身份验证部分。

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

但是,最简单 的解决方案可能是使用 app scripts. If you set up your cloud function to be triggered via an HTTP target, you can write an app script to ping that URL with the messages you want to send to GCS. 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);
    }
  }
}