GASでGmailをSlackに転送する


参考


元々IFTTTやZepierを使ってGmailをSlackと連携させていたのですが、
最近Gmail側のセキュリティ変更でうまく連携できなくなってきたので
Google Apps Script(GAS)を使って連携させることにしました。

GASでやることは
『5分周期でメールをチェックし、未読メールがあればSlackに転送して既読にする』
です。

SlackのWebHooks URLの取得

GASに限らず、API経由でSlackに通知を出したい時に使うURLを取得します。
これを取得しておけば自作botを作ったりできます。

こちらのページから自分のSlackチームにWebHooksを追加できます。
(要Slackログイン)
https://slack.com/apps/A0F7XDUAZ-incoming-webhooks

https://hooks.slack.com/services/AAAAAAA/BBBBBBB/CCCCCCCという形式のURLが取得できれば完了です。

ちなみに、今回のGASの話とは関係ないですけど
PHPからWebHooksを使ってメッセージ送信するライブラリを作っています。
全然誰にも使われてないですけど、参考までに載せておきます。
https://github.com/mildjester/slackwebhock

Google Apps Scriptの作成

まず、自分のGASのページを開きます。
https://script.google.com/u/0/home?hl=ja

そこで「新しいプロジェクト」をクリックしてください。

コード編集画面が開くので、「コード.gs」内を以下のように記載します。
最初の「初期設定」の部分は自分の環境に合わせて修正してください。

// 初期設定
const HOOK_URL = 'https://hooks.slack.com/services/AAAAAAA/BBBBBBB/CCCCCCC'; // 取得したWebHooks URL
const SEND_CHANNEL = 'general'; // Gmailの内容を送信したいSlackチャンネル

function main() {
  // 検索条件:受信トレイにある未読メールで10分以内に受信したもの
  var after = parseInt(((new Date()).getTime() - 10 * 60 * 1000) / 1000);  //10分前の時刻をUNIX時間で取得
  var searchTarget = 'in:inbox is:unread after:' + after;

  GmailApp
  .search(searchTarget)
  .forEach(function (thread) {
    thread.getMessages().forEach(function (message) {
      send(message);
    });
    thread.markRead();
  });  
}

function send(message) {
  var sendText = '【件名】\n' + message.getSubject()
               + '\n【本文】\n' + message.getPlainBody();
  
  var jsonData = {
    "icon_emoji": ':mailbox:',
    "channel" : SEND_CHANNEL,
    "username" : message.getFrom(),
    "text" : sendText
  };

  var options = {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : JSON.stringify(jsonData)
  };

  UrlFetchApp.fetch(HOOK_URL, options);
}

上記を記載したら「Ctrl + s」か上部メニューのフロッピーマークをクリックして保存します。
保存時にプロジェクト名を聞かれるので好きな名前を付けてください。
(例:Gmail2Slack)

Google Apps Scriptの自動実行設定

作成したスクリプトの自動実行設定をします。
上部メニューの時計マークをクリックしてください。

作成したスクリプトのトリガー画面が開くので、「トリガーを追加」をクリックしてください。

トリガー追加画面が開くので、以下のように入力して「保存」をクリックしてください。

項目 設定値
実行する関数 main
実行するデプロイ Head
イベントのソース 時間主導型
時間ベースのトリガーのタイプ 分ベースのタイマー
時間の間隔 5分おき

連携するGoogleアカウントの選択画面が開くので、Gmailを読み込むアカウントを選択します。
「このアプリは確認されていません」というアラート画面が開くので、下部の「詳細 > {作成したアプリ名}に移動」をクリックします。
次に権限の許可画面が開くので「許可」をクリックします。

これで5分おきにGmailがチェックされSlackに連携されるようになりました。

その他補足

Slackに送信される内容について

Slackに送信される内容は件名と本文だけにしています。
もし他の情報も取得したい場合はスクリプト内の「sendText」の内容を変更してください。
取得できる値はこちら参考。
Class GmailApp(公式ドキュメント)

なお、メール本文全てをSlackに流すとかなり長くなります。
Slackにはあくまで「こんなメール来てますよ」程度の通知を送りたいだけであれば
本文は適当な文字数で切った方が良いです。

例えば150文字で切る場合はこんな感じです。

var sendText = '【件名】\n' + message.getSubject()
             + '\n【本文】\n' + message.getPlainBody().substr(0, 150); //150文字で切る

Slackで表示される名前とアイコンについて

「jsonData」に設定している「username」と「icon_emoji」を変更することで
Slack通知時の名前とアイコンも変更できます。

タイマー設定時間について

今回作成したスクリプトは「5分周期で10分以内に受信した未読メールをチェックする」というものです。
5分周期で走るなら10分以内じゃなくて6分以内とかでも良いかもしれませんが、かなり余裕をもって設定しています。
もし大量にメールを受信している人の場合は処理が重くなるかもしれないので、その場合はいい感じに時間調整してください。