Google Cloud Pub/Sub 用于观看 Gmail

问题描述 投票:0回答:3

简介
我希望使用 Pub/Sub API 来监控我们组织中帐户的收件箱。它只是一个普通的 Gmail 收件箱,但它会接收对我们业务很重要的 IT 相关通知。有些电子邮件的优先级不是那么高,可以在需要时自行检查,但是其他非常重要的电子邮件(例如我们的 ISP 进行维护)我们希望将以下事件通知办公室的公司团队成员:正在发生。

示例
例如,我们的 ISP 提醒我们(通过电子邮件)将于 2022 年 7 月 9 日中午 12 点至早上 6 点进行维护工作,我想将该电子邮件转发给我们的仓库经理让他知道正在进行的维护。

问题
我发现的所有文档和其他帖子通常都使用数据库来保存其“发布者”正在推送的消息,并使用自己的应用程序作为所推送事件的“订阅者”。我是否需要创建数据库和应用程序来执行我想要的功能?我是否想得太多了,让它变得比需要的更复杂,并且只需要进行一次或多次 API 调用

google-cloud-platform gmail google-cloud-pubsub
3个回答
2
投票

这是一个使用 Node 的示例。其中大部分来自 Google 文档

  1. 创建一个 PubSub 主题。

  2. 向主题添加推送订阅。将订阅的端点设为 HTTP 云函数。

注意:给予 [电子邮件受保护] 发布/订阅的发布权。

  1. “观看”邮箱。当邮箱收到邮件时,会通知主题并导致云函数触发。您可以通过云功能发送电子邮件或设置其他通知。

授权并观看:

const fs = require('fs').promises;
const path = require('path');
const process = require('process');
const {authenticate} = require('@google-cloud/local-auth');
const {google} = require('googleapis');

// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'];
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
const TOKEN_PATH = path.join(process.cwd(), 'token.json');
const CREDENTIALS_PATH = path.join(process.cwd(), 'credentials.json');

/**
 * Reads previously authorized credentials from the save file.
 *
 * @return {Promise<OAuth2Client|null>}
 */
async function loadSavedCredentialsIfExist() {
  try {
    const content = await fs.readFile(TOKEN_PATH);
    const credentials = JSON.parse(content);
    return google.auth.fromJSON(credentials);
  } catch (err) {
    return null;
  }
}

/**
 * Serializes credentials to a file compatible with GoogleAUth.fromJSON.
 *
 * @param {OAuth2Client} client
 * @return {Promise<void>}
 */
async function saveCredentials(client) {
  const content = await fs.readFile(CREDENTIALS_PATH);
  const keys = JSON.parse(content);
  const key = keys.installed || keys.web;
  const payload = JSON.stringify({
    type: 'authorized_user',
    client_id: key.client_id,
    client_secret: key.client_secret,
    refresh_token: client.credentials.refresh_token,
  });
  await fs.writeFile(TOKEN_PATH, payload);
}

/**
 * Load or request or authorization to call APIs.
 *
 */
async function authorize() {
  let client = await loadSavedCredentialsIfExist();
  if (client) {
    return client;
  }
  client = await authenticate({
    scopes: SCOPES,
    keyfilePath: CREDENTIALS_PATH,
  });
  if (client.credentials) {
    await saveCredentials(client);
  }
  return client;
}
// you can also use "me" instead of an email addy

/**
 * Watches a mailbox for changes
 *
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
async function watchUser(auth) {
    const gmail = google.gmail({version: 'v1', auth});
    const res = await gmail.users.watch ({
        userId: '[email protected]',
        topicName: 'projects/{project-id}/topics/your-gmail-topic',
        labelIds: ['INBOX']
    });

    console.log(res);
}

async function stopWatchUser(auth) {
    const gmail = google.gmail({version: 'v1', auth});
    const res = await gmail.users.stop ({
        userId: '[email protected]'
    });

    console.log(res);
}

authorize().then(watchUser).catch(console.error);

此方法不查看主题或正文,只是在特定文件夹中收到发送到特定地址的电子邮件(实际上是标签)。您可以设置过滤器,根据主题或其他条件将电子邮件转发到特定文件夹。


1
投票

如果您只需将电子邮件转发到已知地址,并且您已经知道发件人 (ISP) 的电子邮件以及主题和/或关键字,则根本不需要开发应用程序。您只需进入收件箱设置,创建过滤器,设置发件人地址和主题,最后将转发地址设置为仓库经理的电子邮件地址。


如果您正在做一些更复杂的事情,例如通过不同的渠道通知人们,或者您有一些自定义逻辑来检测电子邮件的内容对您是否重要,那么您必须编写一个应用程序。

通常,您会使用 Gmail API 在目标收件箱上创建观看请求。完成此操作后,您将收到一个

historyId
,它对应于收件箱的当前状态。您应该存储此 ID。每当您的收件箱有新的更改时,您的应用程序也将开始通过 Pub/Sub 接收通知。这些通知还包含历史 ID。

使用数据库来存储历史 id 的好处是,每次收到新通知时,您都可以从数据库中提取最后一个已知的 id 并调用 List History 方法/端点,将

startHistoryId
设置为您的 id刚刚从你的数据库得到。这将确保您只检索自上次处理通知以来收件箱发生的更改。换句话说,您只会处理新消息,这应该是一个比每次列出所有消息更小的变更集。如果不存储某种状态,您将重新扫描以前已经看过的消息。处理完差异中的所有新更改后,您可以使用新的历史记录 ID 更新数据库。

从技术上讲,您不需要做所有这些。您可以定期轮询收件箱,每次调用“列出消息”,但随后您需要考虑其他考虑因素,例如轮询频率以及每次要列出的消息数量。


0
投票
你让它工作了吗?我的项目有类似的用例,但我无法配置发布者/订阅者来观看 gmail 收件箱。任何帮助,将不胜感激!谢谢!

© www.soinside.com 2019 - 2024. All rights reserved.