はじめに
アラートメールが大量に届く中で、特に重要なメールだけを選別し、それを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に通知を送ることができます。
コード作成
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); // キーワードも渡す
}
うまくいけばslackに通知くるよ。またメール既読になるようだった
5分毎に実行する設定
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); // キーワードも渡す
}