スプレッドシートからメールを一斉送信するには、宛先・名前・送信済みの列を用意し、GASでGmailから1人ずつ送ります。この記事では、名前の差し込み、自分宛てのテスト送信、送信済み日時の記録までできるコードと、AIで本文を作るプロンプトを紹介します。
スプレッドシートのメール一斉送信とBCCの違い
名前を差し込みたい場合は、宛先ごとに本文を作り、個別に送信します。この記事のコードは宛先を1件ずつToに指定するため、他の行の宛先は受信者に表示されません。
BCCでの一斉送信は、複数の宛先に共通の本文を送る用途です。BCCの宛先は他の受信者に表示されませんが、同じメール内で受信者ごとに名前を変えることはできません。
Googleスプレッドシートに宛先リストを作る
シート名を「送信リスト」にし、1行目に見出しを入れます。列の順番は変えないでください。
| A列:宛先 | B列:名前 | C列:送信済み |
|---|---|---|
| contact-a@example.com | 担当A | 空欄にする |
| contact-c@example.com | 担当C | 空欄にする |
上は架空の入力例です。C列の「空欄にする」という文字は入力せず、実際に空欄にします。A列は1セルにメールアドレス1件、B列は敬称なしの名前です。宛先の重複を削除し、C列には数式を入れません。
GASでメールを一斉送信するコード
対象のスプレッドシートで「拡張機能」から「Apps Script」を開き、次のコードを貼り付けて保存します。
GmailApp.sendEmailは宛先・件名・本文を指定して送信できます(Google公式リファレンス)。
function sendPersonalizedEmails() {
const TEST_MODE = true;
const TEST_TO = '自分のメールアドレスに変更';
const SUBJECT = '説明会のご案内';
const TEMPLATE = '{{名前}} 様\n\n業務改善の説明会をご案内します。\n参加をご希望の場合は、このメールにご返信ください。\n\n担当B';
const isEmail = value => /^[^\s@,;<>]+@[^\s@,;<>]+\.[^\s@,;<>]+$/.test(value);
const lock = LockService.getScriptLock();
if (!lock.tryLock(1000)) {
throw new Error('別の処理が実行中です。');
}
let row = 0;
try {
if (TEST_MODE && !isEmail(TEST_TO)) {
throw new Error('TEST_TOを自分のアドレスに変更してください。');
}
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('送信リスト');
if (!sheet) throw new Error('送信リストシートがありません。');
const values = sheet.getDataRange().getValues();
for (let i = 1; i < values.length; i++) {
row = i + 1;
const [rawTo, rawName, status] = values[i];
if (status !== '') continue;
const to = String(rawTo).trim();
const name = String(rawName).trim();
if (!to && !name) continue;
if (!isEmail(to) || !name) {
throw new Error('宛先または名前を確認してください。');
}
const body = TEMPLATE.split('{{名前}}').join(name);
if (TEST_MODE) {
GmailApp.sendEmail(TEST_TO, '[テスト] ' + SUBJECT, body);
console.log(row + '行目を自分宛てにテスト送信しました。');
return;
}
const cell = sheet.getRange(row, 3);
cell.setValue('要確認:送信処理開始');
SpreadsheetApp.flush();
GmailApp.sendEmail(to, SUBJECT, body);
cell.setValue(new Date());
SpreadsheetApp.flush();
}
console.log('対象行の処理が終了しました。');
} catch (error) {
throw new Error((row ? row + '行目で停止:' : '') + error.message);
} finally {
lock.releaseLock();
}
}自分宛てのテスト送信から本番へ
TEST_MODE = trueのまま、TEST_TOを自分が受信できるアドレスに変えます。- 関数
sendPersonalizedEmailsを選択して実行します。初回は承認画面が表示されるため、使うアカウントと要求される権限を確認して承認します。GmailAppはメール送信だけに限定された権限ではありません(公式の承認ガイド)。 - 最初の未送信行の名前を差し込んだメールが、自分宛てに1通だけ届きます。C列は更新しません。件名・本文・署名を確認します。
SUBJECTとTEMPLATEを目的に合わせて直し、再テストします。\nは改行です。- 宛先一覧を人が確認し、
TEST_MODE = falseに変えて実行すると、C列が空の行を順番に送信します。終了後はtrueに戻します。
送信元は実行したアカウントです。実行中は行の追加・並べ替え・編集をしないでください。同じスクリプトの重複実行はロックで抑止します。
入力例と出力例
前述の2行目を使ってテストすると、受信者はTEST_TOで指定した自分、件名は「[テスト] 説明会のご案内」です。
担当A 様 業務改善の説明会をご案内します。 参加をご希望の場合は、このメールにご返信ください。 担当B
本番ではA列の宛先に送り、成功した行のC列を送信日時に置き換えます。
送信済みフラグで二重送信を防ぐ仕組み
C列が空欄の行だけを処理し、値がある行はスキップします。送信直前に「要確認:送信処理開始」を書き込むのは、送信後に日時の保存が失敗しても、次の実行で同じ行を自動送信しないためです。
エラー時は「3行目で停止:…」のように表示され、その後の行は処理しません。宛先の形式不備なら該当行を修正します。「要確認」が残った行は、Gmailの送信済みメールと実行記録を照合してください。送信済みなら日時を手入力し、未送信と確認できた場合だけC列を空に戻して再実行します。不明なら空に戻さず確認を続けます。
ChatGPT等でメール本文を作るプロンプト
AIには宛先一覧を渡さず、案内の条件と架空の名前で下書きを作らせます。
次の条件で案内メールの下書きを作ってください。
目的:業務改善の説明会への参加意向を確認する
宛先:取引先の担当者(架空のA社)
差出人:担当B
確定事項:参加希望者はこのメールに返信する
未確定事項:開催日時・会場。推測せず本文に書かない
文体:簡潔で丁寧なです・ます調
出力:件名とプレーンテキスト本文を分ける
本文冒頭は「{{名前}} 様」とし、この差し込み文字を変えない
実在の個人情報・機密情報は使わない
件名は「説明会のご案内」。本文は署名を含め200字以内
事実・実績・期限・URLを追加しない人が事実確認し、件名をSUBJECT、本文をTEMPLATEに反映します。本文は改行を\nに置き換え、引用符やバックスラッシュを含む場合はJavaScriptの文字列として正しく記述してください。{{名前}}は残します。
送れないときのコツと送信上限の注意点
Apps Scriptには1日あたりのメール受信者数などの割り当てがあり、アカウントの種類で異なります。実行時間にも上限があります。テスト送信も含め、実行前にGoogle公式の割り当てを確認してください。BCCにしても上限の回避にはなりません。
受信できない場合は宛先の誤記、迷惑メール、エラー通知も確認します。
宛先リストの共有範囲を絞り、AIに顧客情報や機密情報を入力しないでください。
よくある質問
スプレッドシートのメール一斉送信はBCCでできますか?
できますが、BCCは共通本文を送る方法です。名前を差し込むなら、この記事のように1人ずつ送信します。
再実行すると全員にもう一度送られますか?
C列に値がある行はスキップします。ただし、C列を消した行や別行に登録した同じ宛先は送信対象になります。
自動で毎日送信できますか?
定期実行の設定は可能ですが、この記事は人がテストと宛先を確認して実行するレベル2の手順です。
添付ファイル CC0 ・ 自由に持ち帰れます
- スクリプト ・ 2.0 KB
- プロンプト ・ 714 B
会社のデータをAIに入れる前に、社内ルールを確認しましょう。
コメント 0
まだコメントはありません。質問や、試してみた感想を書いてみませんか?