Google Apps Script を使って Gmail の新着メールを LINE WORKS に通知する (Incoming Webhook アプリ)

Google Apps Script (GAS) を使って Gmail の新着メールをチェックし、特定の条件に一致するメールを LINE WORKS の Incoming Webhook アプリで通知するスクリプトを紹介します。
![l_1517737_3661_c811760e60d6eed092d592cd9a4a370b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/258482d2-45f7-e2ff-82f4-ef655cf19254.png)

### LINE WORKS の Incoming Webhook アプリ

LINE WORKS の Incoming Webhook アプリが提供開始されました。管理画面から通知用の Bot を簡単に準備できます。

### スクリプトの機能
Gmail を自動でチェックして、特定の条件に一致するメールを LINE WORKS のトークルームに通知します。社外からの問い合わせアドレスを監視して、グループ トークルームで通知を受けたり、対応を共有したりできます。

このスクリプトは以下の機能を持っています：
### 新着メールのチェック：
前回のチェック以降に受信したメールを確認します。
### 条件の指定：
件名に特定のキーワードが含まれているか、特定の送信者からのメールかをチェックします。
### Webhook 通知：
条件に一致するメールがあった場合、LINE WORKS の Webhook に通知を送信します。
### メールスレッドへのリンク：
該当するメールスレッドへのURLを含むボタンを通知に追加します。
### 本文の省略：
本文が長すぎる場合、指定した文字数に制限し、「...」で省略します。
### 処理日時の保存：
最後に処理した日時を保存し、次回の実行時に使用します。

# スクリプト
```javascript:GmailToLineWorksNotifier.gs
function checkGmailAndNotifyWebhook() {
  const keyword = ""; // 件名に含まれるキーワード（空の場合は無視）
  const senderEmail = ""; // 特定の送信者のメールアドレス（空の場合は無視）
  const numThreadsToProcess = 20; // 処理するスレッド数を指定
  const webhookUrl = "https://webhook.worksmobile.com/message/ed01d020-c8c7-44fe-bf85-1b5db0114df5";
  const lastProcessedDateKey = 'LAST_PROCESSED_DATE';
  const maxBodyLength = 150; // 本文の最大文字数（冒頭で設定可能）

  // 日付をフォーマットする関数
  function formatDate(date) {
    const yyyy = date.getFullYear();
    const mm = ('0' + (date.getMonth() + 1)).slice(-2);
    const dd = ('0' + date.getDate()).slice(-2);
    const HH = ('0' + date.getHours()).slice(-2);
    const MM = ('0' + date.getMinutes()).slice(-2);
    return `${yyyy} 年 ${mm} 月 ${dd} 日 ${HH} 時 ${MM} 分`;
  }

  // 前回の処理日時を取得
  const properties = PropertiesService.getScriptProperties();
  const lastProcessedDate = properties.getProperty(lastProcessedDateKey);
  const lastProcessedTimestamp = lastProcessedDate ? new Date(lastProcessedDate).getTime() : 0;

  Logger.log("開始: メールのチェックを開始します。前回の処理日時: " + lastProcessedDate);

  try {
    const threads = GmailApp.getInboxThreads(0, numThreadsToProcess); // 指定した数のスレッドを取得
    Logger.log("取得したスレッド数: " + threads.length);

    let newLastProcessedTimestamp = lastProcessedTimestamp; // 新しい最後の処理日時を初期化

    for (let i = 0; i < threads.length; i++) { // スレッドを順に処理
      Logger.log("処理中のスレッド: " + (i + 1));
      const messages = threads[i].getMessages();
      const threadId = threads[i].getId(); // スレッドIDを取得
      const threadUrl = "https://mail.google.com/mail/u/0/#inbox/" + threadId; // スレッドURLを生成

      for (let j = 0; j < messages.length; j++) { // メッセージを順に処理
        Logger.log("処理中のメッセージ: " + (j + 1));
        const message = messages[j];
        const messageDate = message.getDate().getTime();

        // メッセージが前回の処理日時以降であるかチェック
        if (messageDate > lastProcessedTimestamp) {
          const subject = message.getSubject();
          const from = message.getFrom();
          let body = message.getPlainBody();
          if (body.length > maxBodyLength) {
            body = body.substring(0, maxBodyLength) + "...";
          }
          const formattedDate = formatDate(new Date(messageDate));

          Logger.log("メールの件名: " + subject);
          Logger.log("送信者: " + from);

          // 条件をチェック
          const keywordMatch = !keyword || subject.includes(keyword);
          const senderMatch = !senderEmail || from.includes(senderEmail);

          if (keywordMatch && senderMatch) {
            Logger.log("条件に一致するメールを発見: 件名: " + subject + ", 送信者: " + from);

            // メールが条件を満たす場合にWebhookへ通知
            const payload = {
              "title": "新着メールのお知らせ",
              "body": {
                "text": "件名:\n" + subject + "\n\n" +
                        "送信者:\n" + from + "\n\n" +
                        "日付:\n" + formattedDate + "\n\n" +
                        "本文:\n" + body
              },
              "button": {
                "label": "Gmail で見る",
                "url": threadUrl
              }
            };
            const options = {
              "method": "post",
              "contentType": "application/json",
              "payload": JSON.stringify(payload)
            };

            try {
              const response = UrlFetchApp.fetch(webhookUrl, options);
              Logger.log("Webhook通知を送信しました: 件名: " + subject);
              Logger.log("Webhook応答: " + response.getContentText());
            } catch (e) {
              Logger.log("Webhook通知の送信に失敗しました: 件名: " + subject + ", エラー: " + e.toString());
            }
          }

          // メッセージの日時を新しい最後の処理日時として更新
          if (messageDate > newLastProcessedTimestamp) {
            newLastProcessedTimestamp = messageDate;
          }
        }
      }
    }

    // 新しい最後の処理日時を保存
    properties.setProperty(lastProcessedDateKey, new Date(newLastProcessedTimestamp).toISOString());
    Logger.log("完了: メールのチェックを完了しました。新しい最後の処理日時: " + new Date(newLastProcessedTimestamp).toISOString());

  } catch (e) {
    Logger.log("メールの取得中にエラーが発生しました: " + e.toString());
  }
}
```

# 実行方法
### Google Apps Script エディタを開く：
1. Google ドライブで「新規」→「その他」→「Google Apps Script」を選択します。
新しいプロジェクトを作成：

2. 「無題のプロジェクト」という名前のプロジェクトが作成されます。プロジェクト名を適切に変更します（例：「Gmail to LINE WORKS Notifier」）。
3. コードを貼り付ける：
上記のスクリプトをエディタに貼り付けます。

### スクリプトを保存：
右上の保存アイコンをクリックしてスクリプトを保存します。

### 関数を実行：
実行したい関数（例：checkGmailAndNotifyWebhook）を選択し、再生ボタンをクリックして関数を実行します。

### ログを確認：
メニューから「表示」→「ログ」を選択して、スクリプトの実行結果を確認します。

#トリガーの設定
定期的にスクリプトを実行するために、時間ベースのトリガーを設定します。
### 時計アイコンをクリック：
スクリプトエディタの上部にある時計アイコンをクリックします。
### トリガーを追加：
「トリガーを追加」をクリックし、関数として checkGmailAndNotifyWebhook を選択します。
### 時間ベースのトリガーを設定：
イベントの種類として「時間主導型」を選択し、例えば「5分おき」などの頻度でトリガーを設定します。

# LINE WORKS Incoming Webhook アプリの準備
https://qiita.com/mmclsntr/items/b2960c2f630b02e4af99
こちらの記事の手順を参照してください。