GASでGmailからCSVをGoogleDriveに保存する
Gmailにある受信メールからCSVをGoogleDriveへ抽出するGoogleAppsScriptです。
対象のラベルを作成する
受信メールの特定のフォルダ(ラベル)にある未読メールを自動で処理したいため、対象のフォルダを作成します。「a自動振り分け」というラベルを作成し、そのサブラベルとして「1処理前」を作成しました。
CSVファイルを抽出後は「2処理後」のラベルに移動します。
自動でラベリングするように設定する
フィルタを利用して、Fromや件名などで自動で「1処理前」にフィルタリングします。
スプレッドシートに紐付いたコンテナバインド型のGoogle Apps Script(GAS)
スプレッドシートに紐づくGASを作成しました。スプレッドシートのカスタムメニューから実行するようにします。
メニュー表示とシート表示のGAS
前半部分のメニュー表示と対象のシートをActiveにするGASです。
'use strict'
// getUserLabelByNameの場合はサブラベルは/で区切る
const FROM_LABEL_NAME1 = 'a自動振り分け/1処理前';
const TO_LABEL_NAME1 = 'a自動振り分け/2処理後';
const GET_THREADS_MAX1 = 50;//最大数を設定
const CSV_FOLDER_ID = '198v9WpSKNoA1j6grRoQzt5x9lgfdIRgC';
// スプレッドシートが開かれたタイミングでカスタムメニューを追加
function onOpen(e) {
SpreadsheetApp.getUi() // UI を取得
.createMenu('🍎追加したメニュー🍎') // 🍎追加したメニュー🍎という名前のメニューを作成
.addItem('受信メールの添付ファイルを抽出する', '受信メールの添付ファイルを抽出する') // 項目名: 項目1 実行関数: function1 のメニュー項目を作成
.addToUi(); // UI に追加
}
// 実行ユーザーの特定のフォルダにある受信メールの添付ファイルを抽出する
function 受信メールの添付ファイルを抽出する() {
対象のシートをアクティブにする();
メールからCSVを抽出する();
}
// 結果を実行時刻のyyyymmでシートに残すため、対象のシートをアクティブにする
function 対象のシートをアクティブにする() {
const yyyyMM = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyyMM');
const ss = SpreadsheetApp.getActiveSpreadsheet();
let sheet = ss.getSheetByName(yyyyMM);
if (!sheet) {
console.log('シートがないのでテンプレートをコピーして作成します。');
sheet = ss.getSheetByName('テンプレート').copyTo(ss);
sheet.setName(yyyyMM)
sheet.getRange(2, 1, 20, 10).clearContent();
SpreadsheetApp.setActiveSheet(sheet);
ss.moveActiveSheet(1);
} else {
SpreadsheetApp.setActiveSheet(sheet);
}
// フィルターを解除する
const fil1 = sheet.getFilter();
if (fil1) {
fil1.remove();
}
}
メールからCSVファイルを抽出するGAS
後半部分のメールから添付ファイルをGoogleDriveのフォルダに抽出するGASです。
function メールからCSVを抽出する() {
const fromlabel = GmailApp.getUserLabelByName(FROM_LABEL_NAME1);// ここで「Gmail に接続できません。」エラーがたまに発生する!
const tolabel = GmailApp.getUserLabelByName(TO_LABEL_NAME1);
const threads = fromlabel.getThreads(0, GET_THREADS_MAX1); // 読み込み数
const myFolder = DriveApp.getFolderById(CSV_FOLDER_ID);
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
// 対象フォルダの全スレッドを処理する
for (let i = 0; i < threads.length; i++) {
let thread = threads[i];
let messages = thread.getMessages();
let message;
try {
// ひとつのスレッド
for (let j = 0; j < messages.length; j++) { // message:null からプロパティ「length」を読み取れません。エラーあり。
message = messages[j];
if (!message.isUnread() || message.isInTrash()) {
//既読メール、またはゴミ箱のメールは処理しない
continue;
}
// 未読メールのみ処理する
// メール情報取得
let from = message.getFrom();
let to = message.getTo();
let date = message.getDate();
let subject = message.getSubject();
let body = message.getBody();
let attachments = message.getAttachments(); //添付ファイルを取得
if (!from.match(/sample@xxxxxxxx.jp/)) {
//fromがsample@xxxxxxxx.jpのみ処理する
continue;
}
if (subject.match(/Re:/)) {
//件名がReのものは対象外
continue;
}
// 2行目にログを追加
sheet.insertRowBefore(2);
sheet.getRange(2, 3).setValue(new Date());
sheet.getRange(2, 4).setValue(date);
sheet.getRange(2, 5).setValue(subject);
let attachmentsCount = 0
let hasNextError = 0;
let csvFileError = 0;
for (let k in attachments) {
attachmentsCount++;
let contents = myFolder.getFilesByName(attachments[k].getName());
// 環境によってはGoogleDrive上でxlsファイルとして認識されたため、明示的に指定
attachments[k].setContentType('text/csv');
if (contents.hasNext()) {
// すでに同名のファイルがあればエラー
hasNextError = 1;
} else if (attachments[k].getName().indexOf('.csv') == -1) {
//csvファイルでない場合エラー
csvFileError = 1;
} else {
sheet.getRange(2, attachmentsCount + 5).setValue(attachments[k].getName());
myFolder.createFile(attachments[k]);
}
}
if (attachmentsCount == 0) {
sheet.getRange(2, 10).setValue("エラー!添付ファイル数=" + attachmentsCount);
} else if (hasNextError == 1) {
sheet.getRange(2, 10).setValue("エラー!添付ファイル名重複!");
} else if (csvFileError == 1) {
sheet.getRange(2, 10).setValue("エラー!添付ファイル拡張子!");
} else {
sheet.getRange(2, 10).setValue(attachmentsCount);
sheet.getRange(2, 11).setValue('抽出しました!');
}
}
// 既読 これはメール単位に行う。
GmailApp.markMessageRead(message);
} finally {
// ラベリング処理 これはスレッド単位に行う。途中で予期せぬエラーが発生したときに、既読は付けずに、フォルダ移動する。
thread.removeLabel(fromlabel);
thread.addLabel(tolabel);
}
}
SpreadsheetApp.flush();
}
実行しました
Gmailを確認すると、メールがフォルダを移動し、既読になりました。
スプレッドシートを確認すると、ログが記録されました。
GoogleDriveを確認すると、対象のフォルダにcsvファイルが保管されていました。
以上です。
ディスカッション
コメント一覧
まだ、コメントがありません