こんにちは、とらのあなラボのnsdです。
今回はGoogle Apps Script(GAS) を使ってSlackにメール転送と通知を出す方法を紹介したいと思います。
やりたいこと
- Gmailで
- 過去24時間以内に
- 特定の送信元(From)から来たメールが
- 未読の場合に
- Slackへ転送と通知を出す
実現方法
- Gmailの操作:GAS関数のGmailAppを使用
- Slackの操作:Webhook URLを使用
目的
* 重要な送信元からのメールを見逃さないようにする
* メンバーにも確認を促す
事前の設定
まずは定数を定義しておきます。
function send_notification_to_slack_when_mail_arrived() { // SlackのWebhook URL const slack_webhook_url = 'https://hooks.slack.com/services/xxx/xxx/WebhookURL'; // 過去何時間のメールを検索するか指定(24時間) const hours = 24; // 通知したいメールのFrom(部分一致)を指定(配列で複数可) const fromMail = ['fromAddr1', 'fromAddr2'] // メールを転送するSlackチャンネルのメールアドレス const transferAddr = 'xxx@xxx.slack.com' // 通知メッセージを出力するSlackチャンネル const slackCh = 'チャンネル名'
条件を指定してメールを取得
続いてメールを検索するクエリを作成してメールの取得を行います。
■クエリ
after:{24時間前} from:fromAddr1 OR fromAddr2 is:unread
* after : 指定した日時以降のメールを対象とする(今回は24時間前の日時を指定)
* from : 指定した送信元のメールを対象とする
* is : unread(未読)のメールを対象とする
■メールの取得
GmailApp.search(query);
で指定のクエリに該当するメールの一覧が取得されます。
// 検索期間を指定するための日付を取得する let date = new Date(); // 現在の日時を取得 // メール検索条件に使うため、UNIX時に変換する let unixtime = Math.floor(date.getTime() / 1000); // 事前設定で指定された時間分、マイナスして検索の開始時間にする unixtime = unixtime - (hours * 3600); // メールを検索するための条件文を作る const query = 'after:' + unixtime + ' ' + 'from:' + fromMail.join(' OR ') + ' is:unread'; // Gmailからメールを取得する const threads = GmailApp.search(query); if (threads.length == 0) { // スレッド(メール)が1つも見つからない場合は処理を終了する return; }
GmailApp.searchによりメールが検索されたときのイメージ
Gmail画面の検索フォームからも同様のクエリで検索が可能。
このときの検索結果一覧がスレッド(threads = GmailApp.search(query);
)となる。
メッセージごとの情報を保持しつつ転送
続いて取得結果から1メールずつ情報の保持と転送をします。
■検索結果(スレッド)からメールを取得
threads[i].getMessages();
メールの情報を取得
■メールを転送(送信)
GmailApp.sendEmail(recipient, subject, body, options);
* recipient : 送信先のアドレス
* subject : 件名
* body : 本文
* options : 拡張(今回はname : メールの送信者の名前 を使用)
■メールを既読化
messages[j].markRead();
// メールから必要な部分を抜き出して格納するための配列を宣言する let result = []; // スレッドを1つずつ処理する for (let i = 0; i < threads.length; i++) { // 1スレッドに複数のメッセージ(=メール)が入っているので取得 let messages = threads[i].getMessages(); // メールを1通ずつ処理していく for (let j = 0; j < messages.length; j++) { // メールの差出人を取得する let mail_from = 'From : ' + messages[j].getFrom(); // スレッドには返信も含まれるため差出人が同じもののみ抽出する if (mail_from.includes(fromMail)) { // メールの件名を取得する let mail_subject = '件名 : ' + messages[j].getSubject(); // 結果用の配列に、差出人と件名を連結して追加する result.push(mail_from + ', ' + mail_subject); // Slackへメールを転送する GmailApp.sendEmail(transferAddr, messages[j].getSubject(), messages[j].getBody(), { name: messages[j].getFrom() }) // 転送が完了したら既読にする。 messages[j].markRead(); } } }
Slackに通知メッセージを送信
最後にSlackに出力するメッセージを組み立てて送信します。
// 結果の配列を改行で連結し、Slack投稿用テキストとする const text = result.join('\n'); // SlackのWebhook URLに投稿するデータをまとめる const json = { 'channel': slackCh, 'username': 'xxxからの未読メールがあります!', 'text': '<!channel>' + '\n' + 'メールを確認してください' + '\n' + 'この通知は以下のGASから送信しています' + '\n' + 'https://script.google.com/d/xxx/edit?usp=sharing' }; // SlackのWebhook URLに送信するデータをJSONに変換する const payload = JSON.stringify(json); // UrlFetchAppで使用するメソッドやコンテントタイプを指定 const options = { 'method': 'post', 'contentType': 'application/json', 'payload': payload }; // Slackに送信 UrlFetchApp.fetch(slack_webhook_url, options);
最後に
この転送と通知により大事なメールを見逃すことがなくなりました。
単純な転送であればGmailの転送機能を使うだけでもよいですが、
Slackに@chanel付きで通知を出すことで、自身だけでなくチームメンバーに確認を促すことができるのが便利なところです。
採用情報
虎の穴ラボでは一緒に働く仲間を募集中です!
この記事を読んで、興味を持っていただけた方はぜひ弊社の採用情報をご覧ください。
toranoana-lab.co.jp