[GAS] Gmailで一定期間経過したメールを自動で既読&アーカイブ

Google Apps Scriptを利用して、GMailのメールを自動的に既読&アーカイブします。

きっかけとしてはGoogleカレンダーから毎日送られてくる「本日の予定メール」なんですが、件名を見るだけで大体把握できてしまうためほとんど開かないんですよね。でも毎日送って欲しい。すると未読メールがどんどんたまっていくの気持ち悪い…が自分で定期的にアーカイブするのは面倒。というわけで自動化することにしたというわけです。

我ながら怠惰すぎるw

実際のコード

結論から言うと最終的なコードは以下です。

// ↓こいつをトリガー等で指定する
function go(){
  // 3日以上前のGoogleカレンダー通知をアーカイブ
  toArchive("in:inbox from:calendar-notification@google.com", 3);
}


/**
 * 指定メールのアーカイブ
 *
 * @param searchWord   {string}  - 検索する文字列 
 * @param [older_than] {integer} - n日前 (省略時は全期間)
 */
function toArchive(searchWord, older_than=null){
  let query = searchWord;

  // 期間指定(x日以前を対象)
  if(older_than !== null){
    query += ` older_than:${older_than}d`;
  }

  // 検索&アーカイブ
  const threads = GmailApp.search(query);  // 最大で500スレッドまで
  if( threads.length > 0 ){
    GmailApp.markThreadsRead(threads);          // 既読
    GmailApp.moveThreadsToArchive(threads);     // アーカイブ
  }
}

最近のJavaScriptの構文を使ってますのでV8エンジンを有効にしておく必要があります。 blog.katsubemakito.net

簡単な解説

GASでGmailを検索する

GMailの検索ボックスに入力する文字列をGmailApp.search()に渡すと、メールの検索結果が配列として返ってきます。検索結果が0件であれば空の配列になります。

const threads = GmailApp.search("Subject:Hello");

注意すべきはこの配列は1通1通のメールではなくスレッドである点です。GMailは返信されたメールがひとつにまとめられるスレッドという概念があるためです。

上記のサンプルでは件名(Subject)で絞り込んでいますが、その他に利用できる検索演算子は以下のページを参照ください。 support.google.com

500スレッド制限

検索結果は1度に500スレッド以上取得することができません。もし500件を超えてしまうと実行時エラーとなってしまいます。もし超える恐れがある場合は次のようにページングを行います。

// 0番目から500件を取得
const threads = GmailApp.search("Subject:Hello", 0, 500);

また1日あたりの読み取り上限もありますので、1日に何度も実行する場合はそちらの注意も必要です。  ※無料のGMailユーザーは1日2万件までです

日付を指定して検索

サンプルのようにolder_thanを付けて検索することにより指定した日よりも古いメールだけを対象とすることができます。

// 3日より前に受信したメールだけ対象
const threads = GmailApp.search("older_than:3d 検索したい文字列");

数字の後に日(d)、月(m)、年(y)をそれぞれ指定できます。older_than以外に日付で絞り込む検索演算子には次のような物があります。

検索演算子 説明
newer_than newer_than:3d 指定した日よりも新しいメール
older_than older_than:3d 指定した日よりも古いメール
after after:1980/01/01 指定した日よりも新しいメール(newerでも同様)
befor befor:2020/02/01 指定した日よりも古いメール(olderでも同様)

newer_than, older_thanは相対的な指定、after, beforは絶対的な日付の指定を行うことになります。また以下のように同時に指定することもできます。

// 2020年に受信したメールを検索
const threads = GmailApp.search("after:2020/01/01 befor:2020/12/31");

既読・アーカイブ

こちらはそのままですね。スレッドをまるごと既読、アーカイブしてくれます。

GmailApp.markThreadsRead(threads);          // 既読
GmailApp.moveThreadsToArchive(threads);     // アーカイブ

以下のようにメソッドチェーンも可能です。

GmailApp
  .markThreadsRead(threads)
  .moveThreadsToArchive(threads);

関連ページ