Google Apps ScriptでCustomers Mail CloudのWebhookを受けとったメールをSlackへ投稿する

Customers Mail Cloudではプログラム側からデータを取得したり、メールを送信するWeb APIの他に、Customers Mail Cloudでメールを受信した時にイベントを伝えてくれるWebhook APIが用意されています。

Webhook APIを使うことで、自前でメールサーバを立てずにメール受信のタイミングでシステムを起動させられるようになります。メールサーバを安定して動作させ続けるのはメンテナンスコストが大きいですが、Customers Mail Cloudを使うことで簡単にメールと連携したシステムが作れるようになるでしょう。

今回はGoogle Apps ScriptとWebhook APIと組み合わせて、受け取ったメールをSlackへ投稿します。

フォーマットはJSONとマルチパートフォームデータ

Webhookの形式として、JSONとマルチパートフォームデータ(multipart/form-data)が選択できます。この二つの違いは、添付ファイルがあるかどうかです。JSONの場合、添付ファイルは送られてきません。Google Apps Scriptで使う場合、添付ファイルは使えないのでJSONを選択してください。

Webhook設定ダイアログ

内容を確認するためのコード

今回は送られてくる内容を確認するため、bodyを出力してみます。

function doPost(e) {
  const params = JSON.parse(e.postData.getDataAsString());
  console.log(params);
}

この状態でメールを送ってみます。

ログを確認する

ログはApps Script ダッシュボードの他、Googleスプレッドシートなどに出力してもいいでしょう。送られてきた params の内容は次のようになっています。

{
    "filter": "info",
    "headers": [
        {
            "name": "Return-Path",
            "value": "<from@smtps.jp>"
        },
        {
            "name": "DKIM-Signature",
            "value": "v=1;...=="
        },
        {
            "name": "X-Google-DKIM-Signature",
            "value": "v=1;...=="
        },
        {
            "name": "X-Persimmon",
            "value": "[%%...%%]"
        },
        {
            "name": "Received",
            "value": "by ..."
        },
        {
            "name": "X-Google-Smtp-Source",
            "value": "ABd...cA="
        },
        {
            "name": "From",
            "value": "Test User <tester@smtps.jp>"
        },
        {
            "name": "Message-ID",
            "value": "<CAM...com>"
        },
        {
            "name": "MIME-Version",
            "value": "1.0"
        },
        {
            "name": "Date",
            "value": "Mon, 24 Aug 2020 11:50:34 +0900"
        },
        {
            "name": "Subject",
            "value": "Test subject"
        },
        {
            "name": "Delivered-To",
            "value": "info@smtps.jp"
        },
        {
            "name": "X-Received",
            "value": "by..."
        },
        {
            "name": "To",
            "value": "info@smtps.jp"
        },
        {
            "name": "X-Gm-Message-State",
            "value": "AOA...hTm"
        },
        {
            "name": "Content-Type",
            "value": "multipart/alternative; boundary=\"000000000000304fba05ad96a7c7\""
        }
    ],
    "subject": "Test subject",
    "envelope-to": "info@smtps.jp",
    "server_composition": "sandbox",
    "html": "<div dir=\"ltr\">これはテストの本文です。<div><br></div><div>改行します。</div><div><br clear=\"all\"><div><div dir=\"ltr\" class=\"gmail_signature\" data-smartmail=\"gmail_signature\"><div dir=\"ltr\"><div><div dir=\"ltr\"><div><div>--</div><div>Test User - <a href=\"mailto:tester@smtps.jp\" target=\"_blank\">atsushi@moongift.jp</a></div></div><div><br></div></div></div></div></div></div></div></div>",
    "text": "これはテストの本文です。\r\n\r\n改行します。\r\n\r\nTest User - tester@smtps.jp",
    "envelope-from": "info@smtps.jp"
}

Slackへ投稿する

Slackへ投稿する際にはSlackアプリを作り、そのIncoming Webhooksを使います。

特定のチャンネルを指定することで、そのチャンネル宛のURLが生成されます。これをコピーします。

そして、以下のようにGoogle Apps Scriptで処理を記述します。詳細はコメントを参照してください。

const url = 'https://hooks.slack.com/services/YOUR_TOKEN';
function doPost(e) {
  // 受け取ったメールのデータ
  const params = JSON.parse(e.postData.getDataAsString());
  // Slackにポストするメッセージを作成
  const message = `メールが届きました:${params.subject}
  To: ${params['envelope-to']}
  From: ${params.headers.filter(o => o.name == 'From')[0].value}\n\n${params.html}`;
  // Slackへ投稿
  postToSlack(message);
  // 完了の通知を作成
  const output = ContentService.createTextOutput();
  output.setMimeType(ContentService.MimeType.JSON);
  output.setContent(JSON.stringify({ message: "success!" }));
  return output;
}

// Slackへ投稿する関数
function postToSlack(text) {
  const options = {
    method: 'POST',
    contentType: 'application/json',
    payload: JSON.stringify({ text }),
    muteHttpExceptions: false
  };
  return UrlFetchApp.fetch(url, options);    
}

これで受け取ったメールをSlack上の任意のチャンネルで確認できます。

まとめ

Google Apps Scriptならば、無料でサーバレスな仕組みが実現できます。今回のようにSlackへのポストの他、データの保存先としてもGoogleスプレッドシートなどが選択でき、便利です。ぜひCustomers Mail Cloudと組み合わせてみてください。

Webhook | Customers Mail Cloud