Gmailの下書き自動作成

Gmailの下書き自動作成を説明する女性
目次

誤送信リスクをゼロにする「下書き作成」運用のメリット

メール配信システムを構築する際、開発者が最も懸念すべきリスクは「誤送信」です。特に、プログラムによってループ処理で一斉送信を行う場合、ロジックの些細なミスが、顧客全員への誤った情報の送信や、CC/BCCの設定ミスによる個人情報漏洩(メールアドレスの流出)といった重大なインシデントに直結します。このようなリスクをシステム的に排除するための最適解が、「即時送信(sendEmail)」ではなく「下書き作成(createDraft)」を採用するアプローチです。

GASを用いてGmailの下書きフォルダにメールを作成することで、送信ボタンを押す最終決定権を人間に委ねる「Human-in-the-loop(人間がループの中に入る)」型のワークフローを構築できます。これにより、送信前に文面や宛先を目視で確認するプロセスを強制でき、心理的な安心感とセキュリティを担保できます。

また、APIの実行制限などで処理が途中で止まった場合でも、送信済みのメールと未送信のメールが混在する事態を防ぎやすく、リカバリーが容易になるという運用上のメリットもあります。本章では、スプレッドシートのリストに基づき、個別にカスタマイズされたメール下書きを大量に自動生成するシステムの設計と実装について解説します。

スプレッドシートによる配信リストとテンプレートの分離設計

メンテナンス性の高いシステムを構築するためには、データ(配信リスト)とロジック(スクリプト)、そしてコンテンツ(メール本文)を明確に分離する必要があります。メールの件名や本文をスクリプト内にハードコーディングしてしまうと、文面の修正が発生するたびにスクリプトエディタを開く必要があり、非エンジニアによる運用が困難になります。したがって、スプレッドシート上に「リスト管理シート」と「設定シート(テンプレート)」を分ける設計が推奨されます。

「リスト管理シート」には、送信対象者の会社名、氏名、メールアドレス、差し込み用の変数データ、そして作成ステータスを管理する列を用意します。「設定シート」には、メールの件名テンプレートと本文テンプレートをセルに入力しておきます。本文テンプレート内には {会社名}{氏名} といったプレースホルダー(置換用の目印)を配置し、GAS側でリストのデータと置換するロジックを組みます。

このようにMVC(Model-View-Controller)的な分離をスプレッドシート上で実現することで、キャンペーンごとの文面変更やリストの更新が容易になり、長期的に運用可能なシステムとなります。

GmailApp.createDraftメソッドの基本とオプション活用

GASで下書きを作成するための核心となるメソッドが GmailApp.createDraft(recipient, subject, body, options) です。引数の構成は sendEmail とほぼ同じであり、宛先、件名、本文(プレーンテキスト)を指定します。第4引数の options オブジェクトを利用することで、CC/BCCの設定、HTMLメール(htmlBody)の記述、添付ファイル(attachments)の指定などが可能です。

特に重要なのが htmlBody の活用です。ビジネスメールでは署名やリンクの装飾が求められることが多いため、プレーンテキストの body と併せてHTML形式の本文も設定することが一般的です。また、 attachments オプションにはBlobオブジェクトの配列を渡すことができるため、Googleドライブ上のファイルを動的に取得して添付することも可能です。

開発者は、このメソッドが返す GmailDraft オブジェクトを利用して、作成された下書きのIDを取得したり、さらに内容を更新したりすることができます。APIの仕様を理解し、要件に合わせて適切なオプションを構築する実装力が求められます。

テンプレートリテラルとreplaceメソッドによる動的コンテンツ生成

スプレッドシートから取得したテンプレート文字列に対し、顧客ごとのデータを差し込んでいく処理は、文字列操作の基本かつ重要なステップです。JavaScriptの replace メソッドや replaceAll メソッドを使用して、テンプレート内の {会社名} を実際の会社名データに置き換えていきます。

let body = templateBody;
body = body.replace(/{会社名}/g, rowData[companyIndex]);
body = body.replace(/{氏名}/g, rowData[nameIndex]);

このように、正規表現を使ってグローバル置換(全ての該当箇所を置換)を行うことで、本文中に複数回同じ変数が登場しても正しく処理されます。また、ES6以降のテンプレートリテラルを活用し、変数を埋め込むことも可能ですが、テンプレート自体がセルに入力された文字列である場合は replace による置換が最も柔軟で確実です。この処理をループ内で実行することで、1行ごとに異なる内容のメール本文をメモリ上で生成し、createDraft に渡します。

大量生成時のパフォーマンスとAPIレート制限への配慮

数百件、数千件の下書きを一気に作成する場合、GASのパフォーマンスとAPIのレート制限(Rate Limits)が課題となります。Gmail API(GASのGmailAppの裏側で動いているもの)は、短時間に大量のリクエストを受け取るとエラーを返すことがあります。また、createDraftsendEmail に比べて処理に時間がかかる傾向があり、単純なループ処理ではスクリプトの実行速度が低下します。

対策として、ループ処理の中に Utilities.sleep(1000) などを挿入し、意図的に処理を一時停止(スリープ)させることで、APIへの負荷を分散させる手法が有効です。例えば、10件作成するごとに1秒待機するといった制御を入れることで、安定した動作を確保できます。また、不要なスプレッドシートの読み書き(getValue / setValue)をループ内で行わず、配列として一括取得・一括書き込みを行うことで、全体的な処理時間を短縮する工夫も不可欠です。

実行時間制限(6分の壁)を回避するバッチ処理の実装

GASのスクリプト実行時間は最大6分(Google Workspaceアカウントでも同様)という厳格な制限があります。大量の下書き作成処理がこの時間を超えると、処理は強制終了され、途中までしか下書きが作られていないという中途半端な状態になります。これを防ぐためには、処理の開始時刻を記録し、経過時間が一定(例えば5分)を超えた時点で処理を中断するロジックを組み込む必要があります。

具体的には、ループ処理の冒頭で (new Date().getTime() - startTime) > 300000 のような判定を行い、制限時間に近づいたらループを抜けます。中断する際、どこまで処理が進んだかを「ステータス列」に記録しておくことで、次回実行時に続きから処理を再開できます。さらに、ScriptApp.newTrigger を使って、中断と同時に自分自身を数分後に起動するトリガーを動的に生成すれば、全件完了するまで自動的に処理を継続させる「連鎖実行(Chain Execution)」の実装も可能です。

重複作成を防ぐためのステータス管理とロック機構

自動化システムにおいて「重複処理」は避けるべき事象です。同じ顧客に対して同じメールの下書きが何通も作成されてしまうと、送信担当者の確認作業が煩雑になるだけでなく、誤って重複送信してしまうリスクも高まります。これを防ぐために、スプレッドシートに「作成ステータス」列を設け、下書き作成が完了した行には「作成済み」や「Draft ID」を書き込む処理を徹底します。

スクリプト実行時には、まずこのステータス列を確認し、既に作成済みの行はスキップする条件分岐を入れます。また、複数のユーザーが同時にスクリプトを実行してしまった場合に備え、LockService.getScriptLock() を使用して排他制御を行います。これにより、ある処理が実行されている間は他の実行を受け付けないようにし、データの整合性を保ちます。堅牢なシステムには、こうした二重三重の防御策が組み込まれているものです。

添付ファイルの動的制御とドライブ連携

業務メールでは、請求書や見積書などのPDFファイルを添付するケースが多々あります。GASを使えば、スプレッドシートに記載された「ファイルID」や「フォルダURL」を元に、Googleドライブから該当ファイルを取得し、メールに添付することが可能です。

DriveApp.getFileById(fileId) でファイルオブジェクトを取得し、createDraftattachments オプションに渡します。ここで重要なのが、添付ファイルのサイズ制限(通常25MB)です。スクリプト内でファイルサイズを事前にチェックし、上限を超える場合は添付せずにGoogleドライブの共有リンクを本文に挿入するようロジックを分岐させることで、エラーによる処理停止を未然に防ぐことができます。

また、ファイルが存在しない場合のエラーハンドリング(try-catch)も実装し、ファイルが見つからない顧客だけエラーログに記録して処理を継続する設計が望ましいです。

差出人エイリアスの適用と署名の取り扱い

企業での運用では、個人のメールアドレスではなく、info@support@ といったグループアドレス(エイリアス)を差出人として下書きを作成したい場合があります。GmailApp.getAliases() で利用可能なエイリアスを取得し、createDraftoptions オブジェクト内の from プロパティに指定することでこれを実現できます。

ただし、createDraft で作成された下書きには、Gmailの設定で保存されている「署名」が自動的には挿入されません。署名が必要な場合は、テンプレート本文にあらかじめ署名を含めておくか、GASでユーザーの署名設定を取得して本文の末尾に結合する処理が必要です(ただし、署名取得のAPIは高度なサービスが必要になる場合があるため、テンプレートに含めるのが簡便です)。送信元のブランディングを統一するためにも、差出人アドレスと署名の管理は設計段階で考慮すべきポイントです。

ユーザーインターフェースの実装と運用フローの確立

開発したスクリプトを現場の担当者が使いやすくするために、スプレッドシートに「カスタムメニュー」を追加し、クリック操作だけで処理を実行できるようにします。onOpen トリガーを使ってメニューを表示し、「下書き一括作成」といった項目を作成します。

実行時には Browser.msgBox を使って「下書きを作成しますか?」といった確認ダイアログを表示し、誤操作を防止します。また、処理完了後には「〇〇件の下書きを作成しました」という完了メッセージを表示することで、ユーザー体験(UX)を向上させます。

運用フローとしては、「リストの準備」→「メニューから作成実行」→「Gmailの下書きフォルダで最終確認」→「送信ボタン押下」という手順をマニュアル化し、システムと人間の役割分担を明確にすることが、事故のない運用の鍵となります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次