Gmailboxを検索して対象のメールが受信できているか確認するツールを紹介

## はじめに
ヴェネクト株式会社のインターンメンバー 山岡です。
普段はエンジニアとして、社内業務を効率化するためのツールを開発しています。
今回は、私が過去インターンの業務で作成したGmailboxを検索して対象のメールが受信できているか確認できるツールを紹介します。

## ツールを作成した背景
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2598043/469d6832-b6cc-2e43-9081-d0541fc98070.png)

社内から、パートナー会社へ毎日必ず送信しないといけないメールの送信漏れを自動で検知できないかという要望がありました。
この要望（要件）を満たすために、Google Apps Script(GAS)を使い、GmailBox内のメールをチェックし、メールがもし送信できてない場合、社内Slackへ通知をするツールを作成することにしました。

## Google Apps Script(GAS)とは？
Google Apps Scriptとは、Googleが開発と提供をしているプログラミング言語のことで、以下のような利点があります。
- **JavaScript/TypeScriptで記述可能**
- **環境構築せず、GoogleWorkspace上で構築可能**
- **Gmail、Googleカレンダー、Googleフォームなど他のGoogleアプリと連携可能**

## 仕様
仕様は、今回の要望に合わせて、下記としました。
- 毎日指定の時間に、GASの関数を定期実行する（トリガー設定）
- 土日祝を覗いた営業日だけメール検知を実行する
- 検知方法は、対象のメールをCCに入れたMLのGmailBoxで受信できているかの有無(=送信できているか)で判定する
- もしメールを受信できてない場合、社内のslackチャンネルに通知する

## 実際のコード
```main.js
const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
const slackChannel = '対象のslackチャンネル名';
const targetMention = "メンション先";
const SLACK_URL = 'slackのWebHookURL';
const targetMailAdd = "検知対象のメールアドレス";
const today = new Date();

function main() {
    let businessDayFlag: boolean = isBusinessDay();
    if(businessDayFlag == true){
        checkGmail();
    }
}

function checkGmail() {
    const searchQuery = getSearchQuery();
    const gmailThreads = GmailApp.search(searchQuery);
    if(gmailThreads.length == 0){
        sendToSlack();
    }
}

//設定した条件から、対象のメールの有無を判定
function getSearchQuery(){
    const changeDateFormat: string = Utilities.formatDate(today,"JST", "yyyy/MM/dd");
    const targetStartSubject = "XXXXX";
    const targetEndSubject = "△△△△△";
    const query = `newer:${changeDateFormat} subject:${targetStartSubject} subject:${targetEndSubject}`;
    return query;
}

//slackで通知する
function sendToSlack(){
    const text = "<" + targetMention+ ">"+"メッセージ"
    const data = { "channel" : slackChannel , "username" : "メール確認BOT", "text" : text, "icon_emoji" : ":robot_face:" };
    const payload = JSON.stringify(data);
    const options = {
        "method" : "POST",
        "contentType" : "application/json",
        "payload" : payload
    };
    const response = UrlFetchApp.fetch(SLACK_URL, options);
}

//営業日判定
function isBusinessDay(){
    if (today.getDay() == 0 || today.getDay() == 6) {
        return false;
    }
    const calender = CalendarApp.getCalendarById('ja.japanese#holiday@group.v.calendar.google.com');
    if(calender.getEventsForDay(today).length > 0){
        return false;
    }
    return true;
}
```



## コード解説
### Gmail検知
GASにはGmailBox内にアクセスし、特定の条件に当てはまるメールを検知できる関数があります。今回はこちらの関数を使用しました。

```js
GmailApp.search(検索条件)
```
この関数の引数には、下記のような日付や件名など条件式として設定することができます。

| カテゴリ | 内容 | 書き方の例 |
|:-----------:|:------------:|:------------:|
|日付(期間)|特定の期間に受信したメールを指定|after::2022/01/24 , before:2022/01/25|
|日付(指定)|特定の日に受信したメールを指定(年:y/月:m/日:d)|older_than:5d , newer_than:2022y|
|件名|対象の文字が含まれているメール指定|subject:hoge|
|送信者|特定のメール送信者を指定|from:hogehoge@gmail.com"|
|未読|未読のメールを指定|is:unread|
|既読|既読のメールを指定|is:read|

複数条件を指定したい場合、今回実装したgetSearchQuery関数のように、1つの変数に条件式を繋げたものを代入し、GmailApp.search関数の引数に渡してあげることで検索可能です。

```js
function getSearchQuery(){
    const changeDateFormat: string = Utilities.formatDate(today,"JST", "yyyy/MM/dd");
    const targetStartSubject = "XXXXX";
    const targetEndSubject = "△△△△△";
    const query = `newer:${changeDateFormat} subject:${targetStartSubject} subject:${targetEndSubject}`;
    return query;
}
```
Gmail検索の条件式と合致するメールがある場合、変数のgmailThreadに代入するようになっています。
もし返ってこない場合、「メールを受信してない(=メールをパートナー会社へまだ送ってない)」ということになるので、slackで通知するようになっています。

```js
const gmailThreads = GmailApp.search(searchQuery);
   if(gmailThreads.length == 0){
       sendToSlack();
   }
```

### トリガーの設定
GASには、指定した時間に関数を定期実行するトリガー設定をすることができます。
今回は、毎日指定の時間に「main」関数を起動させるようにしています。
詳しい設定のやり方は、下記の記事を参考にさせて頂きました。

https://tonari-it.com/gas-trigger-set/


## まとめ
上記以外にも、Gmailの内容をスプレッドシートに移行したり、Gmailに記載されている予定をカレンダーに自動登録することがGASでできるそうです。
ぜひご自身の環境でも試してみてください。

## 参考文献
・Google Apps Script公式ドキュメント
https://developers.google.com/apps-script

・Google Apps Script「Class GmailApp 」
https://developers.google.com/apps-script/reference/gmail/gmail-app

・【GAS】Gmailに送られた過去のメールから特定条件のメールを検索して取得する
https://tonari-it.com/gas-gmail-search-thread/

・【GAS】GmailApp.searchを使ってGmailをさまざまな条件で取得する使い方
https://blog.8basetech.com/google-apps-script/gmailapp_search/

・Google Apps Scriptで営業日を判定してトリガーを作成する方法
https://tonari-it.com/gas-trigger-businessday/