使用 Codelabs 教程通过 Cloud Functions 访问 Gmail API

Posted

技术标签:

【中文标题】使用 Codelabs 教程通过 Cloud Functions 访问 Gmail API【英文标题】:Accessing Gmail API through Cloud Functions using Codelabs Tutorial 【发布时间】:2020-02-08 01:57:54 【问题描述】:

我正在逐步关注这个link,通过云功能访问gmail API。

当 gmail 收到一封电子邮件时,它将在 pub/sub 上发布一条消息。

我已经完成了步骤#5的过程,当我触发该功能时,登录屏幕显示为步骤#5所示,但是当我触发云功能时,它会自动重定向到谷歌帐户登录页面并在提供凭据后, 它要求以下权限 1. 代表您发送电子邮件 2.查看和修改但不删除您的电子邮件 允许后给出错误“授权过程中发生错误”。

授权过程中出现错误。

用于云功能的 index.js

    // express-oauth is a Google-provided, open-source package that helps automate
    // the authorization process.
    const Auth = require('@google-cloud/express-oauth2-handlers');
    // googleapis is the official Google Node.js client library for a number of
    // Google APIs, including Gmail.
    const google = require('googleapis');
    const gmail = google.gmail('v1');

    // Specify the access scopes required. If authorized, Google will grant your
    // registered OAuth client access to your profile, email address, and data in
    // your Gmail and Google Sheets.
    const requiredScopes = [
      'profile',
      'email',
      'https://www.googleapis.com/auth/gmail.modify',
      'https://www.googleapis.com/auth/spreadsheets'
    ];

    const auth = Auth('datastore', requiredScopes, 'email', true);

    const GCP_PROJECT = process.env.GCP_PROJECT;
    const PUBSUB_TOPIC = process.env.PUBSUB_TOPIC;

    // Call the Gmail API (Users.watch) to set up Gmail push notifications.
    // Gmail will send a notification to the specified Cloud Pub/Sun topic
    // every time a new mail arrives in inbox.
    const setUpGmailPushNotifications = (email, pubsubTopic) => 
      return gmail.users.watch(
        userId: email,
        requestBody: 
          labelIds: ['INBOX'],
          topicName: `projects/$GCP_PROJECT/topics/$pubsubTopic`
        
      );
    ;

    // If the authorization process completes successfully, set up Gmail push
    // notification using the tokens returned
    const onSuccess = async (req, res) => 
      let email;

      try 
        // Set up the googleapis library to use the returned tokens.
        email = await auth.auth.authedUser.getUserId(req, res);
        const OAuth2Client = await auth.auth.authedUser.getClient(req, res, email);
        google.options(auth: OAuth2Client);
       catch (err) 
        console.log(err);
        throw err;
      

      try 
        await setUpGmailPushNotifications(email, PUBSUB_TOPIC);
       catch (err) 
        console.log(err);
        if (!err.toString().includes('one user push notification client allowed per developer')) 
          throw err;
        
      

      res.send(`Successfully set up Gmail push notifications.`);
    ;

    // If the authorization process fails, return an error message.
    const onFailure = (err, req, res) => 
      console.log(err);
      res.send(`An error has occurred in the authorization process.`);
    ;

    // Export the Cloud Functions for authorization.
    exports.auth_init = auth.routes.init;
    exports.auth_callback = auth.routes.cb(onSuccess, onFailure);

package.json


  "name": "gcf-gmail-codelab-auth",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "repository": 
    "type": "git",
    "url": ""
  ,
  "author": "",
  "license": "Apache-2.0",
  "dependencies": 
    "@google-cloud/express-oauth2-handlers": "^0.1.2",
    "express": "^4.16.4",
    "googleapis": "^37.2.0"
  


env_vars.yml

GOOGLE_CLIENT_ID: (gave my client id)
GOOGLE_CLIENT_SECRET: (gave my client secret)
GOOGLE_CALLBACK_URL: (gave my callback function trigger URL )
PUBSUB_TOPIC: (gave my pub/sub topic name)

【问题讨论】:

您好!在您提供的文本之前,您的错误中是否还有其他信息?您能否仔细检查一下您是否完成了指南第 4 步中的所有操作? 没有,我触发auth_init函数后,除了授权过程中的错误,没有其他错误。是的,我已经非常仔细地遵循了程序,我的一位同事也面临同样的错误.... 您在 Gmail 帐户上更改了哪些设置以允许这样做?使用详细信息编辑您的问题。从这里开始support.google.com/accounts/answer/6010255?hl=en 和这里developers.google.com/gmail 当我触发云功能时,它会自动重定向到谷歌帐户登录页面,并在提供凭据后,它会要求以下权限 1. 代表您发送电子邮件 2. 查看和修改但不删除您的电子邮件允许后给出错误“授权过程中发生错误”。 【参考方案1】:

问题在于它是在节点 8 中编写的。节点 10 有一个微妙的突破性变化,通过将环境变量从硬代码中取出并使用参考格式来识别和访问工作目录之外的资源,产生了巨大的影响。

尽管此更改很棒,但它确实会在您的代码中产生几乎不可见的错误。主要是因为由于语法正确,linters 大多不会捕获它,但格式和结构导致它从上下文中读取。其中很多与 oauth2 相关,与env.vars 的连接如 GOOGLE_APPLICATION_CREDENTIALS 未设置并在函数外使用会导致问题。此外,env_vars 文件也不是必需的,应在函数的初始启动命令期间由环境实现替换,而不是在目录中硬编码授权引用。

您可能安装的大多数软件包在节点 8 中无法正常运行。我能够使其正常运行的唯一方法是直接在云 shell 中实际完成所有编码。我实际上正在通过客户端库来获取所有涉及的资源,以组合一个更新的版本。 Google 迫切需要更新文档,但这可能非常困难,同时还要努力跟上所有技术的最新动态。

【讨论】:

如果您能清楚地将解决问题所需的操作与解释区分开来,那就太好了。

以上是关于使用 Codelabs 教程通过 Cloud Functions 访问 Gmail API的主要内容,如果未能解决你的问题,请参考以下文章

包 cloud_firestore 没有匹配的版本 >=0.7.0 <0.8.0 派生自

教程 | 没有博士学位,照样玩转TensorFlow深度学习

分页库使用示例的 Proguard 问题(在 Google Codelabs 中)

Spring Cloud Stream教程消费群体

Spring Cloud Config教程客户端使用

定期停止获取后台位置更新