0

这是我在此的头一篇博文。如果是转发,我很抱歉,但我已经在所有网站和论坛中寻找解决我问题的答案一个多月了,直到现在......没有答案!

我的目标是让 Gmail 发布/订阅 watch() 在我收到新电子邮件时执行操作。

为此,根据开发者的网站,我需要每天使用以下代码订阅 Gmail watch():

request = {
  'labelIds': ['INBOX'],
  'topicName': 'projects/myproject/topics/mytopic'
}
gmail.users().watch(userId='me', body=request).execute()

到目前为止,我有一个使用服务帐户的工作计划任务,具有 INVOKER 权限。这部分工作正常。

在我的“初始自动化功能”中,我有:

const {google} = require('googleapis');

// Retrieve OAuth2 config
const oauth2Client = new google.auth.OAuth2(
  process.env.CLIENT_ID,
  process.env.CLIENT_SECRET,
  process.env.CALLBACK_URL
);

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 = oauth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: scopes,
    //prompt: 'none'// Required in order to receive a refresh token every time
  });
  return res.redirect(authUrl);

};

我现在的问题是访问令牌是第一次通过(提示)生成的,并且永远不会更新为新的(令牌在 1 小时后过期......)这意味着该代码在该时间段后停止工作并且“手动”干预是必需的。根据文档,我需要使用“离线”方法,并且在“提示”上我可以省略(仅在第一次请求权限)或无(从不询问),就像这里所说的那样。

我设法使它工作!明天我将继续这个过程。我应该在这里发布我的工作代码以供参考吗?

谢谢!

4

2 回答 2

0

您在评论中共享的文档并没有说您可以从服务帐户的标头中删除令牌,您还共享的 gmail API 文档也说您只能:

需要向 gmail-api-push@system.gserviceaccount.com 授予发布权限。您可以按照资源级访问控制说明使用Cloud Pub/Sub Developer Console 权限界面来执行此操作。

为了实现这一点,您需要设置两个云功能,第一个计划功能负责设置watch(),您可以查看此文档以了解如何部署计划功能,第二个功能由gmail 通知的 pubsub,您可以查看此文档以了解如何构建事件触发功能。这两个过程是相似的。

注意:我从来没有使用过 Gmail API,所以我不确定是否需要任何额外的步骤,但是文档再次暗示设置该服务帐户的权限足以使其正常工作。


编辑:

根据您分享的信息。问题可能是您没有正确设置服务帐户以使用云功能进行身份验证。根据文档中的描述,您必须向服务帐户授予Cloud Functions InvokerIAM 中的角色。

让我知道这是否解决了问题。

于 2020-09-28T15:20:12.477 回答
0

我将重新表述您说明的过程,以免产生歧义。

根据您推送的文档:

  1. 您不订阅 watch(),您调用 watch()
    watch() 是对 Gmail API 的 API 调用,它将启用对您定义的给定条件的发布/订阅主题的自动事件发布。你在看谁?在什么事件上?
  2. 您订阅了您之前的 watch() 调用所针对的 Pub/Sub 主题
    一个进程(例如:Google 云函数)订阅了该主题并将使用 Gmail API 发送的消息
  3. 通话至少每 7 天续订一次
    因为 Google 需要确保您仍需要监控目标收件箱,所以需要您续订。另一个 watch() 调用将执行此操作。
  4. 云调度程序将启用此定期续订
    ,此服务将触发您在问题中输入的续订脚本。为此,需要对托管脚本的平台进行身份验证。如果您的脚本托管在 google 服务(云功能、云运行等)中,并且身份验证类型取决于目标 URL 形式,则会更容易。在所有情况下,您的请求标头中都需要一个身份验证令牌。令牌是从您创建的具有调用脚本的正确权限的服务帐户生成的(例如:云运行调用程序)。默认情况下,调度程序有权从中生成令牌

到目前为止,一切都很好。现在是棘手的部分,你没有在你的问题中提到它。如何验证您的 gmail api 客户端?您无法监控某人的收件箱,除非此人允许您使用正确的 Oauth2 令牌调用 API。实际上,在您指出的视频中,他们使用此原理对用户进行身份验证,该原理在其代码中使用Express-oauth2-handler实现。因此,您将拥有一个云功能来初始化最终用户身份验证并查看他/她的收件箱。续订应该这样做,但问题是用户不会在那里接受最终用户的同意。离线访问来了但这超出了您的问题范围。最后,第二个函数将订阅 pubsub 主题并根据需要使用消息。查看他们填充电子表格的实现代码。

于 2020-09-28T15:27:50.640 回答