[改訂版]ChatGPT製Gmailプロモからのメルアド一括ピックアップGASを元にメルマガ定期的一括削除スケジュールをGASでやってみた #ChatGPT

Gmailのプロモーション欄の未読量が10000に至る程度の量となっていたために定期的な削除要件を見直してみました。また、プロモーションへ届いたメールマガジン等からメールアドレスと件名の組み合わせでピックアップする処理をChatGPTに出させて、且つ削除リストに転用できるように手修正をいれてみました。
2023.04.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

定期的なメールマガジンの一掃を始めてからもうすぐで約1年。当時7000程度まで減らしていたプライベートGmailアドレスのプロモーション未読件数は10000件にギリギリ至らない程度になっていました。減るはずが増えてるんですね

幾つかの未読件名とメールアドレスを確認していたところ、新規購読もあればシステムからの単純通知元用メールアドレスとメールマガジン配信元メールアドレスが同一になっているものも多数ありました。約1年前に自動掃除用スクリプトを記事にしましたが、件名も合わせて絞らないと駄目なパターンがあったようです。

今回、少し修正した版を書いてみました。

改訂版

1つのメールアドレスに対して件名に複雑なパターンマッチの適用も考えましたが、マッチ失敗にて実は消せてなかったという状況を防ぐため、件名毎に設定をいれる想定としています。部分マッチのため断片をいれるだけでも適合します。

function getConfig() {
  const sheet = SpreadsheetApp.getActiveSheet(); 
  const values = sheet.getDataRange().getValues();
  values.reverse()
  values.pop()
  values.reverse()
  Logger.log(values)
  return values
}

function cleaningMail() {
    const config = getConfig()
    config.forEach(function(data) {
      var search_param = Utilities.formatString(
        "from:%s older_than:%s -is:starred", data[0], data[1])
      if (data[2] != "") {
        search_param = search_param + Utilities.formatString(" subject:%s", data[2])
      }
      Logger.log(search_param);
      var deleteThreads = GmailApp.search(search_param);

      for (var i = 0; i < deleteThreads.length; i++) {
          deleteThreads[i].moveToTrash();
      }
    })
}

設定例は以下の通り。

処理候補のプロモーションメールと件名を自動ピックアップする

意図せずにメールマガジンを購読していたケースをどうにかピックアップできないものかと考え、プロモーションの未読メールからメールアドレスを機械的にダンプする仕組みを試してみました。折角なので流行りのChatGPTによるコード生成です。

function getEmails() {
  var days = 30; // 取得する期間(日数)
  var threads = GmailApp.search("is:unread category:promotions older_than:" + days + "d"); // 一定期間以上未読のプロモーションカテゴリのメールを取得する
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート2"); // 出力するシートを指定する
  var existingData = sheet.getDataRange().getValues(); // 既存のデータを取得する
  var data = [];

  for (var i = 0; i < threads.length; i++) {
    var messages = threads[i].getMessages();
    for (var j = 0; j < messages.length; j++) {
      var message = messages[j];
      var subject = message.getSubject();
      var from = message.getFrom();
      var found = false;
      for (var k = 0; k < existingData.length; k++) {
        if (existingData[k][0] == from && existingData[k][1] == subject) {
          found = true;
          break;
        }
      }
      if (!found) {
        data.push([from, '1m', subject]); // 重複しない場合はデータを配列に追加する
      }
    }
  }

  if (data.length > 0) {
    var lastRow = sheet.getLastRow(); // 最終行を取得する
    sheet.getRange(lastRow + 1, 1, data.length, data[0].length).setValues(data); // 最終行にデータを追記する
  }
}

シート2を追加しておきます。そのままクリーニング用には転用しないためヘッダ行は不要です。当初の削除用スクリプトにコピペ対応できるよう、配列データに1mが追加されるように変更をいれています。実行すると以下のような構成で出力されます。

SCRAP <mailmg@scrapmagazine.com>,1m,世界初! 食の知識が深まる『ひみつのグルメBOX』!! 東リベコラボ『東京卍會渋谷大抗争からの脱出』渋谷で開催中! その他今週末遊べるリアル脱出ゲーム情報をお届け! 【SCRAPからのお知らせ】
Apple TV <appletv@insideapple.apple.com>,1m,今月のApple Arcade新ゲームを紹介します
Kickstarter Games <email@em.kickstarter.com>,1m,New in Games: Everdate - Let's Play: The Dating Game

メールアドレスが名前とアドレスを組み合わせた構成になっていますが、Gmailの検索は問題なく機能します。件名を汎用な構成に変更した後、クリーニング用一覧に転記して完了です。

あとがき

特定の機密に類する要件がない程度でGASで可能な処理ならば、とりあえずChatGPTでひな形を作ってみるのもよさそうです。ChatGPTへの指示にてゆらぎそうな表現になる部分は手作業でやってしまうほうが早いかもしれません。