1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

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

Posted at

Google Apps Script (GAS) を使って Gmail の新着メールをチェックし、特定の条件に一致するメールを LINE WORKS の Incoming Webhook アプリで通知するスクリプトを紹介します。
l_1517737_3661_c811760e60d6eed092d592cd9a4a370b.png

LINE WORKS の Incoming Webhook アプリ

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

スクリプトの機能

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

このスクリプトは以下の機能を持っています:

新着メールのチェック:

前回のチェック以降に受信したメールを確認します。

条件の指定:

件名に特定のキーワードが含まれているか、特定の送信者からのメールかをチェックします。

Webhook 通知:

条件に一致するメールがあった場合、LINE WORKS の Webhook に通知を送信します。

メールスレッドへのリンク:

該当するメールスレッドへのURLを含むボタンを通知に追加します。

本文の省略:

本文が長すぎる場合、指定した文字数に制限し、「...」で省略します。

処理日時の保存:

最後に処理した日時を保存し、次回の実行時に使用します。

スクリプト

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
こちらの記事の手順を参照してください。

1
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?