①アドセンス系の広告は記事が読みにくくなるため入れていませんので、投げ銭応援をよろしくお願いいたします(クリックしたらページにうつります)。②多忙のためもろもろの受付を止めています。
PR

Google Apps Scriptで受信したGmailから必要な部分だけ抜き出して転送する

IT
この記事は約7分で読めます。

GASは初めて触ったため、後学のため残すことにしました。
こういった内容は生成AIで指示すればいくらでも出てくると思います。

今回はとりあえず動けば良い目的で作りました。
ご指摘事項ありましたらコメント頂きますと幸いです。

機能

未読のメールから該当する受信アドレスのメールの内容を抽出し、指定したアドレスに転送する

  • 変数searchCriteriaArray で指定した内容で検索ボックスの条件を入力しメールを抽出
    抽出数は未読20件分(1件目から順番に抽出)
  • 変数regexToExtractで指定したメールの本文を抽出
  • 変数recipientEmailの宛先に一度だけGmailを送る
    件名の欄に抽出したメールの本文を入力
    フラグ”自動転送済み”をつける

テスト結果は次の画像の通りです。
今は我が家で運用しています。

転送メール例:電車運行状況
転送メール例:かかりつけ病院関係

想定する状況

家族用のタブレットのような、受信したGmailを音声で読み上げたい端末があることを想定

【本記事の例】
次の受信したメールから必要部分を抽出して転送する

  • Yahoo!乗換案内から来た電車運行状況のメール
  • いつもいっているかかりつけの病院の予約のリマインドメール

コード

//
// searchCriteriaArrayの条件に該当するメールを抽出
// regexToExtractの部分だけを抜き出し
// recipientEmailに一度だけGmailを送る
//
function TransferGmailAfterPickUpBodyMessage() {
  //設定(初期化処理)
  //抽出対象のメールを絞り込むための検索条件
  const searchCriteriaArray =[/is:unread AND subject:(.*)Yahoo!路線情報/s,
                              'is:unread AND from:〇〇〇']; //○〇〇はメールアドレスを指定

  // メール本文から抽出する文言
  const regexToExtract =[/路線名:(.*)現在)/s,
                         /ご予約された診療日は(.*)ご来院お待ちしております。/s];

  // 抽出したテキストの転送先のメールアドレス
  const recipientEmail = '●●●';//●●●は転送先のメールアドレスを指定

  // 転送するメールの件名の先頭に付けるプレフィックス
  // 元の件名と区別しやすくするため指定
  const subjectPrefix = ['電車運行状況',
                         '【〇〇歯科】'];


  // 処理済みメールに付けるラベル名
  const processedLabelName = '自動転送済み';

  // 「自動転送済み」ラベルが存在しない場合は作成する
  let processedLabel = GmailApp.getUserLabelByName(processedLabelName);
  if (!processedLabel) {
    processedLabel = GmailApp.createLabel(processedLabelName);
  }

  // すべての検索条件を終わらせるまでループ
  for(let i=0; i<searchCriteriaArray.length; i++){
    
    // 未読の Gmail スレッドを取得
    const unreadThreads = GmailApp.search(searchCriteriaArray[i],0,19); //0件目から20件目まで取得

    // 各未読スレッドを処理
    unreadThreads.forEach(thread => {
      // thread は GmailThread オブジェクトです。

      // まだ「自動転送済み」ラベルが付いていないか確認
      if (!thread.getLabels().some(label => label.getName() === processedLabelName)) {
        // thread.getLabels() は、スレッドに付いているラベルの GmailLabel オブジェクトの配列を返す
        // some() メソッドを使って、配列内に指定の名前のラベルが存在するかどうかを確認する

        const messages = thread.getMessages();
        const firstMessage = messages[0]; // スレッド内の最初のメッセージ(通常は最新の受信メール)
        const body = firstMessage.getPlainBody(); // メール本文を取得

        // 正規表現を使ってテキストを抽出
        const match = body.match(regexToExtract[i]);

        if (match && match[1]) {
          const extractedText = match[0].trim(); //内容はデバッグで確認して指定
          const newSubject = subjectPrefix[i] + extractedText; //タイトルに必要な情報を全部入れる

          // 新しいメールを作成して送信
          GmailApp.sendEmail(recipientEmail, newSubject, "内容はタイトルの通り");

          // 処理済みのスレッドにラベルを付与
          thread.addLabel(processedLabel);
        }
      }
    });
  }
}

その他

  • プログラムの詳しい説明は省いています。
    上記のコードを生成AIにコピーして、条件の指定方法(ワールドカードなど)や関数の引数説明の内容などを聞いてみてください。
  • 関数化をしたい場合は内容を良いように煮るなり焼くなりしてください。

経緯

カワッター宅では私のGoogleアカウントで受信したメールを、我が家にあるAndroidタブレットへ、家に関係するメールだけ転送しています。
メールは基本的にテンプレ形式のものばかりです。

転送したメールは音声で読み上げるようにしています。
読み上げは適当な通知を読み上げてくれるアプリを使っています。

ここで問題が出てきました。
読み上げアプリは差出人・タイトル・本文という区分けができても、そこから必要な部分だけ抽出して読み上げる、というは難しい感じでした。
なので、メールの必要な部分だけ読んでほしいというかゆい部分に手を出したくなってきました。

特に、読み上げに関して、メールの本文は余計な情報が多いです。
必要な部分は2, 3行くらいなのですが、それ以外のところも延々と読み上げられると、肝心なところまで行きつくのに時間がかかるわ、その間の読み上げはタダのノイズにしか聞こえなくなるわであまり使えたものではありませんでした。
嫁さんから「何が言いたいかまったくわかんないんだけど!?」と苦情がきてしまいました。

それならGmailの必要な部分だけ抜き出したうえで、我が家のタブレットに転送すればいいじゃない!となりました。
せっかくなのでGoogle Apps Scriptで遊んでみようと思うに至りました。

変更履歴

2025/5/5

記事UP

コメント スパム対応をしたつもり、コメントは残す方向で頑張ってます

タイトルとURLをコピーしました