0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Google App Script(GAS)でメールを抽出してSpreadSheetに書き出す

Posted at

やりたいこと

Gmailで『ML/alert』というラベルが付いている昨日のメールを抽出し、FromとToで除外したいものと重複を除いて、SpreadSheetにFrom、To、Subjectの一覧を書き出したい。

準備

『除外』という名前のシートを作り、除外したいFromとToの対を書く。
(Toが空欄の場合はToに関わらず除外する)
スクリーンショット 2020-06-03 16.01.40.png

コード

function getMail() {
  var label = 'ml-alert';
  var fromDate = getDate(1);
  var toDate = getDate(0);
  var query = 'label:' + label + ' after:' + (fromDate.getTime() / 1000) + 'before:' + (toDate.getTime() / 1000);
  
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var exceptionSheet = ss.getSheetByName('除外');
  var exceptions = exceptionSheet.getRange(1, 1, exceptionSheet.getLastRow(), 2).getValues();
  
  var threads = GmailApp.search(query);
  var data = [];
  threads.forEach(function(thread) {
    var messages = thread.getMessages();
    messages.forEach(function(message) {
      var date = message.getDate();
      if (date < fromDate || toDate < date) {
        // 対象の日付じゃないのでスルー
        return;
      }
      var from = message.getFrom().replace(/^.*<(.*?)>.*$/, '$1');
      var toArr = message.getTo().split(/,\s*/);
      // 除外シートから除外対象を探す
      var fromFinder = exceptionSheet.createTextFinder(from);
      block_check: {
        while (range = fromFinder.findNext()) {
          if (range.getColumn() != 1) {
            // 1列目じゃないので次へ
            continue;
          }
          var foundRow = exceptions[range.getRow() - 1];
          if (foundRow[1] == '') {
            // Toが指定されていないのでそのまま除外
            break block_check;
          }
          for (var i = 0; i < toArr.length; i++) {
            if (toArr[i] === foundRow[1]) {
              // Toが一致するので除外
              break block_check;
            }
          }
        }
        // 除外対象ではないのでdata配列に保存
        var subject = message.getSubject();
        data.push([from, toArr.join(), subject]);
      }
    });
  });
  
  if (data.length) {
    // 対象のメールがあったら日付のシートに書き出す
    var ymd = fromDate.getFullYear() + '/' + (fromDate.getMonth() + 1) + '/' + fromDate.getDate();
    var sheet = ss.getSheetByName(ymd);
    if (sheet) {
      // すでにシートがある場合は内容を削除
      sheet.clearContents();
    } else {
      // シートを新規作成
      sheet = ss.insertSheet(ymd, 0);
      sheet.setColumnWidths(1, 2, 190).setColumnWidth(3, 500);
      sheet.setFrozenRows(1);
    }
    sheet.getRange("A1:C1").setValues([['From', 'To', 'Subject']]);
    var range = sheet.getRange(2, 1, data.length, 3);
    range.setValues(data);
    range.removeDuplicates();
    range.sort([1, 2, 3]);
  }
}

/* days日前の午前0時のDateオブジェクトを返す */
function getDate(days) {
  var date = new Date();
  date.setDate(date.getDate() - days);
  date.setHours(0, 0, 0, 0);
  return date;
}

ポイント

  • GmailApp.search(query)のqueryで、ネストになっているラベルは『-』で繋げる
  • GmailApp.search(query)はスレッドを検索するので、日付を指定しても対象外のものが含まれるため、メッセージ単位で日付のチェックをする
  • 重複は、すべてシートに書き出した後にremoveDuplicates()で取り除く

createTextFinder()を使いましたが、exceptions配列を順番に見ていくことでも処理できます。(し、そっちの方が簡単な気がしますが、せっかくなので使用例ということで…)

0
2
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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?