Post

Google Apps Script 教学|自动转发 Gmail 邮件到 Slack Channel 客制化通知

透过 Gmail 筛选器结合 Google Apps Script,自动抓取指定邮件并转成自订格式推送到 Slack,解决等待 App Store 处理时间长、CI/CD 流程卡关问题,提升工作效率与即时通知掌握度。

Google Apps Script 教学|自动转发 Gmail 邮件到 Slack Channel 客制化通知

Click here to view the English version of this article.

點擊這裡查看本文章正體中文版本。

基于 SEO 考量,本文标题与描述经 AI 调整,原始版本请参考内文。


运用 Google Apps Script 转发 Gmail 信件到 Slack

使用 Gmail Filter + Google Apps Script 在收到信件时自动将客制化内容转寄至 Slack Channel

Photo by [Lukas Blazek](https://unsplash.com/@goumbik?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText){:target="_blank"}

Photo by Lukas Blazek

起源

最近在优化 iOS App CI/CD 的流程,使用 Fastlane 作为自动化工具;打包上传后如果要继续完成自动送审步骤 ( skip_submission=false ),就需要等苹果完成 Process 大概需要浪费 30~40 mins 的 CI Server 时间,因为苹果 App Store Connect API 并不完善,Fastlane 也只能每分钟去检查一次上传的 Build 是否处理完成,非常浪费资源。

  • Bitrise CI Server: 限制同时 Builds 数量及最大执行时间 90 mins,90 mins 是够,但会卡著一条 Build 阻碍其他人执行。

  • Travis CI Server: 依照 Build Time 收费,这样更不能等了,钱直接打水漂。

换个思路

不等了,上传完直接结束!靠处理完成的信件通知触发后续动作。

不过最近我都没收到这封信了,不知道是设定问题还是苹果不再发此类通知。

本文将以 Testflight 已经可以开始测试的信件通知为例。

完整流程如上图所示,原理上可行;但不是本文要讨论的重点,本文将著重在收到信件、使用 Apps Script 转发至 Slack Channel 部分。

如何转发收到的 Email 到 Slack Channel

不管是付费或是免费的 Slack 专案都能使用不同方法达成 Email 转发到 Slack Channel or DM 功能。

可参考官方文件进行设置: 传送电子邮件至 Slack

不管哪种方法效果都如下:

预设折叠信件内容,点击后可以展开查看全部内容。

优点:

  1. 简单快速

  2. 零技术门槛

  3. 即时转送

缺点:

  1. 无法对内容进行客制

  2. 显示样式无法更改

客制转发内容

就是本篇要介绍的重点。

将信件内容资料转译成自己想呈现的样式,如上图范例。

先上一张完整运作流程图:

  • 使用 Gmail Filter 对要转发信件加上辨识 Label

  • Apps Script 定时获取被标记成该 Label 的信件

  • 读取信件内容

  • 渲然成想要的显示样式

  • 透过 Slack Bot API 或直接用 Incoming Message 发送讯息到 Slack

  • 移除信件 Label (代表已转发)

  • 完成

首先,要在 Gmail 中建立筛选器

筛选器可以在收到符合条件信件时自动化做一些事,例如:自动标记已读、自动标记 Tag、自动移入垃圾邮件、自动归入分类…等等操作

在 Gmail 点击右上进阶搜寻图标按钮,输入要转发的信件规则条件,例如来自: no_reply@email.apple.com + 主题是 is now available to test. ,点击「Search」查看筛选结果是否如预期;如果正确可以点击 Search 旁的「Create filter」按钮。

或直接在信件里上方点 Filter message like these 就能快速建立筛选条件

或直接在信件里上方点 Filter message like these 就能快速建立筛选条件

这按钮设计很反人类,第一次找一直没看到。

下一步设定符合此筛选条件是的动作,这边我们选「Apply the label」建立一个独立新辨识用 Label 「forward-to-slack」,点击「Create filter」完成。

尔后被标上这个 Label 的信都会被转发到 Slack。

取得 Incoming WebHooks App URL

首先我们要加入 Incoming WebHooks App 到 Slack Channel,我们会透过此媒介来传送讯息。

  1. Slack 左下角「Apps」->「Add apps」

  2. 右边搜寻匡搜寻「incoming」

  3. 点击「Incoming WebHooks」->「Add」

选择讯息想要传到的 Channel。

记下最上方的「Webhook URL」

往下滑可设定传送讯息时,传送 Bot 显示的名称及大头贴;改完记得按「Save Settings」。

备注

请注意官方建议使用新的 Slack APP Bot API 的 chat.postMessage 来传送讯息,Incoming Webhook 简便的这个方式之后会弃用,这边偷懒没有使用,可搭配下一章「汇入员工名单」会需要 Slack App API 一起调整成新方法。

撰写 Apps Script 程式

贴上以下基本程式并修改成你想要的版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
function sendMessageToSlack(content) {
    var payload = {
      "text": "*您收到一封信件*",
      "attachments": [{
          "pretext": "信件内容如下:",
          "text": content,
        }
      ]
    };
    var res = UrlFetchApp.fetch('贴上你的Slack incoming Webhook URL',{
      method             : 'post',
      contentType        : 'application/json',
      payload            : JSON.stringify(payload)
    })
}

function forwardEmailsToSlack() {
    // 参考自:https://gist.github.com/andrewmwilson/5cab8367dc63d87d9aa5

    var label = GmailApp.getUserLabelByName('forward-to-slack');
    var messages = [];
    var threads = label.getThreads();
  
    if (threads == null) {
      return;
    }

    for (var i = 0; i < threads.length; i++) {
        messages = messages.concat(threads[i].getMessages())
    }

    for (var i = 0; i < messages.length; i++) {
        var message = messages[i];
        Logger.log(message);

        var output = '*New Email*';
        output += '\n*from:* ' + message.getFrom();
        output += '\n*to:* ' + message.getTo();
        output += '\n*cc:* ' + message.getCc();
        output += '\n*date:* ' + message.getDate();
        output += '\n*subject:* ' + message.getSubject();
        output += '\n*body:* ' + message.getPlainBody();

        sendMessageToSlack(output);
   }

   label.removeFromThreads(threads);
}

进阶:

EX:爬取 Testflight 审核成功信件内的版本号资讯:

信件标题:Your app XXX has been approved for beta testing.

信件内容:

我们想得到 Bundle Version Short String 还有 Build Number 后面的值

1
2
3
4
5
6
7
var results = subject.match(/(Bundle Version Short String: ){1}(\S+){1}[\S\s]*(Build Number: ){1}(\S+){1}/);
if (results == null \\|\\| results.length != 5) {
  // not vaild
} else {
  var version = results[2];
  var build = results[4];
}

执行看看

  • 回到 Gmail 随便找一封信,手动帮他加上 Label — 「forward-to-slack」

  • 在 Apps Script 程式码编辑器上选择「forwardEmailsToSlack」然后点击「执行」按钮

若出现 「Authorization Required」则点选「Continue」完成验证

在身份验证的过程中会出现「Google hasn’t verified this app」这是正常的,因为我们写的 App Script 没有经过 Google 验证,不过没关系这是写给自己用的。

可点选左下角「Advanced」->「Go to ForwardEmailsToSlack (unsafe)」

点击「Allow」

转发成功!!!

设置触发器(排程)自动检查&转发

在 Apps Script 左方选单列,选择「触发条件」。

左下角「+ 新增触发条件」。

  • 错误通知设定:可设定当脚本执行遇到错误时,该如何通知你

  • 选择您要执行的功能:选择 Main Function sendMessageToSlack

  • 选取活动来源:可选择来自日历或是时间驱动(定时或指定)

  • 选取时间型触发条件类型:可选特定日期执行或每分/时/日/周/月执行一次

  • 选取分/时/日/周/月间隔:EX: 每分钟、每 15 分钟…

这边为了示范设定成每分钟执行一次,我觉得信件的即时程度可以设每小时检查一次就好。

  • 再次回到 Gmail 随便找一封信,手动帮他加上 Label — 「forward-to-slack」

  • 等待排程触发

自动检查&转发成功!

完工

借由此功能便能达成客制化信件转发处理,甚至是再当成触发器使用,例如:收到 XXX 信时自动执行某脚本。

回到第一章起源,我们便可以使用此机制,完善 CI/CD 流程;不需要呆呆等待苹果完成处理,又能串上自动化流程!

延伸阅读

有任何问题及指教欢迎 与我联络


Buy me a beer

本文首次发表于 Medium (点击查看原始版本),由 ZMediumToMarkdown 提供自动转换与同步技术。

Improve this page on Github.

This post is licensed under CC BY 4.0 by the author.