スプレッドシートの宛先リストから、GASで名前を差し込んだメールを送る方法があります。
公式のリファレンスと割り当てをもとに、使うクラスと、1日の上限を整理しました。
- 送信には MailApp か GmailApp を使う
- 1日の上限は、受信者数で数える
- 無料アカウントは100、Google Workspaceは1,500が目安(公式の割り当て表)
- 残りの枠は、MailApp.getRemainingDailyQuota() で確認できる
公式資料に基づく説明と掲載コードのローカル検証を掲載しています。
上限や仕様は、Googleの都合で変わることがあります。
数値は、公式ページで最新を確かめてください。
MailAppとGmailApp
| MailApp | GmailApp | |
|---|---|---|
| 用途 | メール送信だけ | 送信に加え、Gmailの読み書きもできる |
| 必要なスコープ | script.send_mail | mail.google.com(権限が広い) |
送信だけなら、必要な権限が小さい MailApp が向いています。
宛名を差し込んで送る
function sendMails() {
const DRY_RUN = true; // 最初はtrue。確認後にfalseへ変更すると送信します。
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('送信練習');
if (!sheet) throw new Error('「送信練習」シートを作成してください。');
const lock = LockService.getScriptLock();
if (!lock.tryLock(5000)) throw new Error('別の送信処理が実行中です。');
try {
const lastRow = sheet.getLastRow();
if (lastRow < 2) return;
const rows = sheet.getRange(2, 1, lastRow - 1, 3).getValues();
const pending = [];
const seen = new Set();
rows.forEach(function (row, index) {
const name = String(row[0]).trim();
const mail = String(row[1]).trim();
const state = String(row[2]).trim();
if (!name && !mail && !state) return;
if (state) return; // 送信済み・送信中など、状態のある行を再送しない
if (!name || !/^[^\s@,;]+@[^\s@,;]+\.[^\s@,;]+$/.test(mail)) {
throw new Error((index + 2) + '行目の名前と宛先を確認してください。');
}
const key = mail.toLowerCase();
if (seen.has(key)) throw new Error('未送信の宛先が重複しています。');
seen.add(key);
pending.push({row: index + 2, name: name, mail: mail});
});
if (!DRY_RUN && pending.length > MailApp.getRemainingDailyQuota()) {
throw new Error('残りの送信枠が足りません。今回は送信していません。');
}
pending.forEach(function (item) {
const subject = 'ご案内';
const body = item.name + ' 様\n\nお世話になっております。';
if (DRY_RUN) {
console.log(JSON.stringify({row: item.row, to: item.mail, subject: subject, body: body}));
return;
}
const state = sheet.getRange(item.row, 3);
state.setValue('送信中');
SpreadsheetApp.flush();
MailApp.sendEmail(item.mail, subject, body);
state.setValue('送信済み');
SpreadsheetApp.flush();
});
} finally {
lock.releaseLock();
}
}表の準備と送信前のプレビュー
- 「送信練習」シートを作り、1行目にA列「名前」、B列「メールアドレス」、C列「状態」と入力します。
- 2行目に自分の名前と自分のメールアドレスを入れ、C列は空にします。
- スプレッドシートの「拡張機能」→「Apps Script」にコードを保存します。
- DRY_RUNがtrueのままsendMailsを実行し、ログに出る宛先・件名・本文を確認します。
- 自分宛の1行で確認できたらDRY_RUNをfalseにして実行し、受信とC列の「送信済み」を確認します。
プレビューはメールを送らず、状態も変更しません。
ログには宛先が表示されるため、共有やスクリーンショット掲載の前に個人情報を除いてください。
テストは、自分のアドレスだけを入れて、先に試してください。
1日の上限
| 項目 | 無料アカウント | Google Workspace |
|---|---|---|
| メールの受信者数/日 | 100 | 1,500 |
| ドメイン内の宛先/日 | 100 | 2,000 |
上限は、メールの通数ではなく、受信者の人数で数えられます。
送る前に、残りの枠を確かめられます。
Logger.log(MailApp.getRemainingDailyQuota());一斉送信は、送り先の同意があるものに限ってください。
Gmail側の、1通あたりの宛先数の上限は、この記事では確認していません。
まとめ
- 送信だけなら MailApp
- 上限は受信者数。無料は100、Workspaceは1,500が目安
- 本番の前に、残りの枠と自分宛のテストを確かめる
参考:Google Apps Script「Mail Service」「Gmail Service」「Quotas for Google Services」(2026年9月30日確認)。
再実行と途中停止の扱い
空の行と状態が入った行は処理しません。
未送信行の宛先重複や入力不足は、送信を始める前に止めます。
宛先の正規表現は入力ミスを見つける簡易チェックで、メールアドレスの存在や配信成功は保証しません。
送信する直前に「送信中」を保存し、sendEmailが戻った行を「送信済み」にします。
エラーや時間切れで「送信中」が残った行は、送信結果が不明なため、自動では再送しません。
送信履歴や受信側で結果を確認してから、再送が必要な行だけC列を空に戻してください。
「送信済み」は送信処理が戻った記録で、相手の受信箱への到着確認ではありません。
停止するときはDRY_RUNをtrueに戻し、設定した時間主導トリガーがあれば対象だけ削除します。
送信済みメールは、シートやスクリプトを戻しても取り消せません。
確認した範囲と公式資料
2026年10月2日に公式資料と掲載コードを照合しました。
コードの分岐はGoogleのサービスを代替したローカルテストで確認し、実サービスでの実行とは区別しています。
GAS上の認可・トリガー発火・同時実行・実メール送信は未検証です。
