/** * @OnlyCurrentDoc * * Gmailの特定のラベルと期間のメールをPDFとしてGoogleドライブに保存するスクリプト * * 1. PDF添付があるメール:PDF添付ファイルのみを保存します。 * 2. PDF添付がないメール:メール本文をPDFとして保存します。 */ // --- ユーザー設定 (ここを編集してください) --- /** * Gmailの検索対象ラベル名 */ const TARGET_LABEL = "000_Youtube"; /** * 保存先のGoogleドライブ フォルダID * フォルダIDは、Googleドライブで該当フォルダを開いたときのURL(.../folders/ココがフォルダID)から取得してください。 */ const DRIVE_FOLDER_ID = "**********************"; // 例: "1a2b3c4d5e6f7g8h9i0j..." /** * 検索開始日 (YYYY-MM-DD形式) */ const START_DATE = "2019-01-01"; /** * 検索終了日 (YYYY-MM-DD形式) * (この日付の23:59:59までが検索対象となります) */ const END_DATE = "2022-05-29"; // --- 設定はここまで --- /** * メインの実行関数 */ function saveEmailsToDriveAsPDF() { // ドライブフォルダの検証 let driveFolder; try { driveFolder = DriveApp.getFolderById(DRIVE_FOLDER_ID); } catch (e) { // Browser.msgBox()をLogger.log()に変更してエラーを回避 Logger.log(`[エラー] GoogleドライブのフォルダIDが見つかりません: ${DRIVE_FOLDER_ID}`); Logger.log("スクリプトを終了します。DRIVE_FOLDER_IDを確認してください。"); return; } // Gmailの検索クエリを構築 // 期間は after:START_DATE から before:END_DATE まで const query = `label:${TARGET_LABEL} after:${START_DATE} before:${END_DATE}`; Logger.log(`[検索] クエリ: ${query}`); let processedCount = 0; let failedCount = 0; try { // Gmailを検索 const threads = GmailApp.search(query); Logger.log(`[検索] ${threads.length} 件のスレッドが見つかりました。`); if (threads.length === 0) { Logger.log("[完了] 対象のメールは見つかりませんでした。"); return; } // 各スレッド(会話)を処理 threads.forEach(thread => { const messages = thread.getMessages(); // スレッド内の各メールを処理 messages.forEach(message => { try { processMessage(message, driveFolder); processedCount++; } catch (e) { Logger.log(`[エラー] メールの処理に失敗しました (件名: ${message.getSubject()}): ${e.message}`); failedCount++; } }); }); // 処理結果をLoggerに出力 Logger.log('--- 実行結果 ---'); Logger.log(`[完了] 処理済み: ${processedCount}件, 失敗: ${failedCount}件`); Logger.log(`[通知] ${processedCount} 件のメール(または添付PDF)がGoogleドライブに保存されました。`); } catch (e) { Logger.log(`[致命的なエラー] スクリプトが停止しました: ${e.message}`); } } /** * 1通のメールを処理する関数 * @param {GmailApp.GmailMessage} message 処理対象のGmailメッセージ * @param {DriveApp.Folder} driveFolder 保存先のGoogleドライブフォルダ */ function processMessage(message, driveFolder) { const attachments = message.getAttachments(); let pdfSaved = false; const subject = message.getSubject() || "無題"; // ファイル名の重複を避けるため、日付を付与 (JSTでフォーマット) const messageDate = Utilities.formatDate(message.getDate(), Session.getScriptTimeZone(), "yyyyMMdd"); // 1. PDF添付ファイルの確認と保存 if (attachments.length > 0) { attachments.forEach((attachment) => { // PDF形式の添付ファイルのみを対象とする if (attachment.getContentType() === 'application/pdf') { const blob = attachment.copyBlob(); // ファイル名を生成 (日付_件名_添付ファイル名) const fileName = `${messageDate}_${subject}_${attachment.getName()}`; driveFolder.createFile(blob).setName(fileName); Logger.log(`[保存] PDF添付ファイルを保存しました: ${fileName}`); pdfSaved = true; } }); } // 2. PDF添付がなかった場合、メール本文をPDF化して保存 if (!pdfSaved) { Logger.log(`[変換] PDF添付がなかったため、メール本文をPDFに変換します: ${subject}`); // メール本文(HTML)を取得 const htmlBody = message.getBody(); // ファイル名を生成 (日付_件名.pdf) const fileName = `${messageDate}_${subject}.pdf`; try { // HTMLをBlobとして作成し、PDFに変換 const htmlBlob = Utilities.newBlob(htmlBody, MimeType.HTML, `${subject}.html`); const pdfBlob = htmlBlob.getAs(MimeType.PDF); pdfBlob.setName(fileName); driveFolder.createFile(pdfBlob); Logger.log(`[保存] メール本文をPDFとして保存しました: ${fileName}`); } catch (e) { // PDF変換に失敗した場合(複雑なHTMLなど)、テキストファイルとして保存 Logger.log(`[エラー] 本文のPDF変換に失敗しました (件名: ${subject}): ${e.message}。テキストとして保存を試みます。`); const plainBody = message.getPlainBody(); const txtFileName = `${messageDate}_${subject}_(変換失敗).txt`; driveFolder.createFile(txtFileName, plainBody, MimeType.PLAIN_TEXT); } } }