1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Google Apps ScriptでGmailとSlackを連携!自動通知の設定方法

Last updated at Posted at 2024-10-06

はじめに

アラートメールが大量に届く中で、特に重要なメールだけを選別し、それをSlackに転送したいと考えています。このプロセスのゴールは、膨大なアラートメールの中から、本当に必要なものだけを即座にSlackで確認できるようにすることです。これにより、作業の効率が向上し、緊急の対応が必要な場合に見落としを防ぐことができます。

slackの設定

まずAppの設定がいるので済ませましょう。slack使ってない人はダウンロードして部屋作成も必要。

Google Apps ScriptでGmailとSlackを連携

機能概要

Slackへのメッセージ送信 (sendToSlack 関数):

  • メッセージをSlackの指定されたWebHook URLに送信します。
  • メッセージが未定義の場合、デフォルトメッセージを送信します。
  • Slackに通知が成功したかどうかをログに出力します。

Gmailのメールをチェック (checkEmailAndSendToSlackIfKeywordFound 関数):

  • 指定された検索クエリ (searchQuery) に基づいてGmailのメールを検索します。ここでは、5分以内に受信した未読メールが対象です。
  • メールの本文に特定のキーワード (keyword) が含まれている場合、そのメールをSlackに通知します。
  • メールが通知された後、メールを既読としてマークします。

main 関数:

  • WebhookのURL、Gmail検索クエリ、キーワード、Slackに送るメッセージの内容を設定します。
  • これらの設定をもとに checkEmailAndSendToSlackIfKeywordFound 関数を呼び出し、Gmailから該当するメールをチェックし、Slackに通知を送ります。

主な変数:

  • webhookUrl: Slackに通知を送るためのWebHookのURL。
  • searchQuery: Gmailで検索する条件。ここでは「5分以内に受信した未読メール」を対象としています。
  • keyword: メール本文に含まれているべき特定のキーワード(ここでは「test」)。
  • messageText: Slackに送信するメッセージの本文。該当するメールが見つかった場合に送信されます。

想定される利用シナリオ:

このスクリプトは、特定の重要なメール(たとえば「test」というキーワードが含まれるメール)をリアルタイムで確認し、Slackで通知を受け取りたい場合に有効です。また、5分ごとにメールをチェックする設定ができるため、リアルタイムで監視を続ける必要があるシナリオに適しています。


実行方法:

このスクリプトをGoogle Apps Scriptに配置し、トリガーを設定することで、5分ごとに自動的にGmailをチェックし、該当するメールがあればSlackに通知を送ることができます。

コード作成

image.png

function sendToSlack(messageText, webhookUrl) {
  Logger.log("sendToSlackで渡されたWebhook URL: " + webhookUrl);  // Webhook URLが正しく渡されているか確認

  if (!messageText) {
    messageText = "デフォルトメッセージ"; // デフォルトメッセージ
  }

  var payload = {
    "text": messageText.trim() // メッセージをトリム
  };

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

  try {
    var response = UrlFetchApp.fetch(webhookUrl, options);
    Logger.log("Response Code: " + response.getResponseCode());
    Logger.log("Response Body: " + response.getContentText());
  } catch (e) {
    Logger.log("Error: " + e.message);
  }
}

function checkEmailAndSendToSlackIfKeywordFound(webhookUrl, messageText, searchQuery, keyword) {
  Logger.log("checkEmailAndSendToSlackIfKeywordFoundで渡されたWebhook URL: " + webhookUrl);  // Webhook URLが正しく渡されているか確認
  Logger.log("検索クエリ: " + searchQuery);  // 検索クエリが正しく渡されているか確認
  var threads = GmailApp.search(searchQuery);
  Logger.log("スレッド数: " + threads.length);

  if (threads.length === 0) {
    Logger.log("指定された期間内に受信したメールがありません。");
    return;
  }

  var messages = GmailApp.getMessagesForThreads(threads);

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

    for (var j = 0; j < threadMessages.length; j++) {
      var message = threadMessages[j];
      var messageDate = message.getDate(); // メールの受信時刻を取得
      Logger.log("メールの受信時刻: " + messageDate); // メールの受信時刻をログに記録

      var plainBody = message.getPlainBody() || message.getBody();
      if (plainBody.indexOf(keyword) !== -1) {  // mainで定義されたキーワードで条件チェック
        var bodyPreview = plainBody.substring(0, 500).replace(/[\r\n]+/g, ' ');
        var slackMessage = messageText + "\n" +  // メイン関数で渡されたmessageTextを使用
                           "件名: " + message.getSubject() + "\n" +
                           "受信時刻: " + messageDate + "\n" + // 受信時刻を追加
                           "本文(先頭500文字): " + bodyPreview;

        sendToSlack(slackMessage, webhookUrl); // Slackに通知
        message.markRead(); // メールを既読に
      }
    }
  }
}

function main() {
  var webhookUrl = "https://hooks.slack.com/services/XXXX; // Webhook URLをmainで定義
  var messageText = "特定のキーワードを含むメールが見つかりました"; // 送信するメッセージをmainで定義
  var searchQuery = 'is:unread newer_than:5m (from:@gmail.com OR from:otheremail@example.com)'; // 複数のメールアドレスを対象にするクエリ
  var keyword = 'test';  // 条件としてのキーワードをmainで定義
  Logger.log("Main内のWebhook URL: " + webhookUrl);  // Webhook URLの確認用ログ

  checkEmailAndSendToSlackIfKeywordFound(webhookUrl, messageText, searchQuery, keyword); // キーワードも渡す
}
  • mainの変数は用途に合わせて修正が必要だよ
  • mainが実行されるように注意しよう。たまにほかのメソッドになっている
    image.png

うまくいけばslackに通知くるよ。またメール既読になるようだった

image.png

5分毎に実行する設定

image.png

image.png

実行履歴も見れた
image.png

ToDO

  • 受信から5分以内のメールを対象にしたいが、未読のメールがすべて対象になっている。testかどうかは判断されている。ようはnewer_than:5mが機能していない。一度受信してslack通知したメールも、未読に戻せば通知対象に戻ってしまう。通知すれば既読になるので、通知の無限ループに陥ることはなさそう

複数キーワードを設定する場合、未検証

function checkEmailAndSendToSlackIfKeywordFound(webhookUrl, messageText, searchQuery, keywords) {
  Logger.log("checkEmailAndSendToSlackIfKeywordFoundで渡されたWebhook URL: " + webhookUrl);  // Webhook URLが正しく渡されているか確認
  Logger.log("検索クエリ: " + searchQuery);  // 検索クエリが正しく渡されているか確認
  var threads = GmailApp.search(searchQuery);
  Logger.log("スレッド数: " + threads.length);

  if (threads.length === 0) {
    Logger.log("指定された期間内に受信したメールがありません。");
    return;
  }

  var messages = GmailApp.getMessagesForThreads(threads);

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

    for (var j = 0; j < threadMessages.length; j++) {
      var message = threadMessages[j];
      var messageDate = message.getDate(); // メールの受信時刻を取得
      Logger.log("メールの受信時刻: " + messageDate); // メールの受信時刻をログに記録

      var plainBody = message.getPlainBody() || message.getBody();
      var found = keywords.some(function(keyword) { 
        return plainBody.indexOf(keyword) !== -1;  // 複数キーワードで条件チェック
      });

      if (found) {
        var bodyPreview = plainBody.substring(0, 500).replace(/[\r\n]+/g, ' ');
        var slackMessage = messageText + "\n" +  // メイン関数で渡されたmessageTextを使用
                           "件名: " + message.getSubject() + "\n" +
                           "受信時刻: " + messageDate + "\n" + // 受信時刻を追加
                           "本文(先頭500文字): " + bodyPreview;

        sendToSlack(slackMessage, webhookUrl); // Slackに通知
        message.markRead(); // メールを既読に
      }
    }
  }
}

function main() {
  var webhookUrl = "https://hooks.slack.com/services/XXXX"; // Webhook URLをmainで定義
  var messageText = "特定のキーワードを含むメールが見つかりました。"; // 送信するメッセージをmainで定義
  var searchQuery = 'is:unread newer_than:5m (from:@gmail.com OR from:otheremail@example.com)'; // 複数のメールアドレスを対象にするクエリ
  var keywords = ['test', 'urgent', 'action required'];  // 複数条件のキーワードを配列で定義
  Logger.log("Main内のWebhook URL: " + webhookUrl);  // Webhook URLの確認用ログ

  checkEmailAndSendToSlackIfKeywordFound(webhookUrl, messageText, searchQuery, keywords); // キーワードも渡す
}

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?