Gmailの予約送信ミスを送信前に発見|GASで宛先・日時をdry-run監査

Gmailの予約送信ミスを送信前に発見|GASで宛先・日時をdry-run監査

Gasおじ|GoogleアカウントをAIエージェント化

Gasおじ|GoogleアカウントをAIエージェント化

予約送信の事故は、送信処理そのものより「宛先の空欄」「過去日時」「同じ内容の二重登録」から起きがちです。この記事ではメールを送らず、スプレッドシート上の送信計画だけを検査する無料GAS例を紹介します。

先に知っておきたいこと

  • このコードはメールを送信せず、下書きも作りません。
  • 宛先、件名、予約日時、実行可否を入力検証し、結果を監査ログへ出します。
  • メール本文や認証情報はログへ残しません。
  • 実運用へ移す前に、必ずコピーしたシートと少量の架空データで確認してください。

準備するシート

送信計画シートの1行目へ、to、subject、scheduled_at、enabled の4列を用意します。scheduled_at はスプレッドシートの日時形式、enabled は TRUE または FALSE にしてください。

監査ログという名前のシートも作ります。存在しない場合はコードが作成しますが、送信計画の値は変更しません。

コピーして使える最小コード

const DRY_RUN = true;

function auditGmailSchedulePlanFree() {
  if (!DRY_RUN) throw new Error('この無料例はdry-run専用です');

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName('送信計画');
  if (!sheet) throw new Error('送信計画シートがありません');

  const values = sheet.getDataRange().getValues();
  if (values.length < 2) throw new Error('検査するデータ行がありません');

  const headers = values[0].map(String);
  const required = ['to', 'subject', 'scheduled_at', 'enabled'];
  const index = Object.fromEntries(required.map(name => [name, headers.indexOf(name)]));
  const missing = required.filter(name => index[name] < 0);
  if (missing.length) throw new Error('不足列: ' + missing.join(', '));

  const now = new Date();
  const seen = new Set();
  const results = [];

  values.slice(1).forEach((row, offset) => {
    const rowNumber = offset + 2;
    const to = String(row[index.to] || '').trim().toLowerCase();
    const subject = String(row[index.subject] || '').trim();
    const scheduledAt = row[index.scheduled_at];
    const enabled = row[index.enabled] === true;
    const reasons = [];

    if (!to || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(to)) reasons.push('宛先形式');
    if (!subject || subject.length > 100) reasons.push('件名');
    if (!(scheduledAt instanceof Date) || isNaN(scheduledAt.getTime())) reasons.push('日時形式');
    if (scheduledAt instanceof Date && scheduledAt <= now) reasons.push('過去日時');
    if (!enabled) reasons.push('実行対象外');

    const key = [to, subject, scheduledAt instanceof Date ? scheduledAt.toISOString() : 'invalid'].join('|');
    if (seen.has(key)) reasons.push('重複候補');
    seen.add(key);

    results.push([new Date(), rowNumber, reasons.length ? 'HOLD' : 'READY', reasons.join(' / ')]);
  });

  const log = ss.getSheetByName('監査ログ') || ss.insertSheet('監査ログ');
  log.clearContents();
  log.getRange(1, 1, 1, 4).setValues([['checked_at', 'row', 'status', 'reason']]);
  log.getRange(2, 1, results.length, 4).setValues(results);
  console.log(JSON.stringify({ checked: results.length, hold: results.filter(r => r[2] === 'HOLD').length }));
}

実行手順

1. 元ファイルをコピーし、架空の宛先と件名を2〜3行だけ入力します。

2. 拡張機能からApps Scriptを開き、コードを貼り付けます。

3. auditGmailSchedulePlanFree を選び、実行します。

4. 監査ログのHOLD理由を確認し、送信計画側を手動修正します。

5. READYでも自動送信へ直結させず、宛先・日時・タイムゾーンを人が再確認します。

失敗しやすい点と停止条件

  • スプレッドシートとApps Scriptのタイムゾーンが違う場合は停止します。
  • 実在する個人情報を検証用シートへ入れないでください。
  • 監査ログには本文を出しませんが、宛先も出力しない設計です。
  • GmailやApps Scriptの利用上限、組織ポリシーを別途確認してください。
  • この例へ送信命令や時間主導トリガーを足す場合は別の安全審査が必要です。

公開前チェックリスト

  • 元データのコピーで試した
  • DRY_RUN が true のままになっている
  • 過去日時、空欄、重複候補がHOLDになる
  • ログへ本文・認証情報・宛先を残していない
  • 自動送信や自動削除を追加していない

まとめ

予約送信を安全に始める第一歩は、送信機能を作ることではなく、入力の不備を送信前に止めることです。まずはdry-run監査で宛先・件名・日時・重複を確認し、最終判断を人に残してください。

下書きを安全に整える関連Tipsを見る

GasおじのTips商品一覧を見る

※学習・検証用の例です。Google公式・Google公認の商品ではありません。実データへ適用する前に、権限、利用規約、組織ポリシー、送信先の同意を確認してください。


あなたも記事の投稿・販売を
始めてみませんか?

Tipsなら簡単に記事を販売できます!
登録無料で始められます!

Tipsなら、無料ですぐに記事の販売をはじめることができます Tipsの詳細はこちら
 

この記事のライター

Gasおじ|GoogleアカウントをAIエージェント化

おう、Gasおじだ。 AIツールとSaaSに散々突っ込んで遠回りした結果、最後に強かったのは「今あるGoogleアカウント」だった。 今ではAIエージェントであらゆるタスクを自動化して無双してるぞ。 GAS、スプレッドシート、フォーム、Gmail、AIエージェントを組み合わせれば、個人でも小さな会社でも、手作業だらけの業務はかなり自動化できる。 ここでは机上のAI論じゃなく、現場で動くテンプレ、コード、手順だけを置いていくぞ。 高いツールを増やす前に、まずお前さんのGoogleアカウントを仕事するエージェントに変えようじゃないか。

このライターが書いた他の記事

  • Gmailの定型連絡を「送信せず」まとめて下書き化する|Gmail下書きテンプレGAS Pro

    ¥2,980
    1 %獲得
    (29 円相当)
  • GASのtry-catch入門|元データを守るエラー処理とログの実装例

  • あとで見るURLを二重登録しない|GASで読書・動画ウォッチリストをdry-run監査

関連のおすすめ記事

  • Gmailの定型連絡を「送信せず」まとめて下書き化する|Gmail下書きテンプレGAS Pro

    ¥2,980
    1 %獲得
    (29 円相当)
    Gasおじ|GoogleアカウントをAIエージェント化

    Gasおじ|GoogleアカウントをAIエージェント化

  • 【Python】 Con-Que 【データベース接続】

    ¥3,000
    1 %獲得
    (30 円相当)
    GoGorilla

    GoGorilla

  • USBメモリで持ち運べるLinux Mint 22.1と永続的な書き込み領域の作成法【Rufus だけで作成する方法を初心者向けに徹底解説】

    ¥500
    1 %獲得
    (5 円相当)
    SmartSenior

    SmartSenior