Home 運用 Google Apps Script 轉發 Gmail 信件到 Slack
Post
Cancel

運用 Google Apps Script 轉發 Gmail 信件到 Slack

運用 Google Apps Script 轉發 Gmail 信件到 Slack

使用 Gmail Filter + Google Apps Script 在收到信件時自動將客製化內容轉寄至 Slack Channel

Photo by Lukas Blazek

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];
}
1
2
3
output:
version = 3.37.0
build = 2

執行看看

  • 回到 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 流程;不需要呆呆等待蘋果完成處理,又能串上自動化流程!

===

本文首次發表於 Medium ➡️ 前往查看

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

生產力工具 拋棄 Chrome 投入 Sidekick 瀏覽器的懷抱

2021 Pinkoi Tech Career Talk —  高效率工程團隊大解密

Comments powered by Disqus.