やりたいこと
Gmailで『ML/alert』というラベルが付いている昨日のメールを抽出し、FromとToで除外したいものと重複を除いて、SpreadSheetにFrom、To、Subjectの一覧を書き出したい。
準備
『除外』という名前のシートを作り、除外したいFromとToの対を書く。
(Toが空欄の場合はToに関わらず除外する)
コード
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
配列を順番に見ていくことでも処理できます。(し、そっちの方が簡単な気がしますが、せっかくなので使用例ということで…)