はい。送信リスト、テンプレート、Google Apps Scriptの3つを用意すればできます。この記事では、送信上限の事前確認、送信済み管理、二重実行防止を含むコードを使います。
宛先ごとに「○○さん」のように名前や用件を差し込む仕組みを、メールマージと呼びます。数件の連絡を繰り返し送る業務を効率化できます。
最初から本番の宛先へ送らないでください。
まず宛先を自分のメールアドレス1件だけにし、件名、差し込み文字、改行、差出人を確認してから本番送信に進みます。
メールマージの仕組み
作るものは、スプレッドシート内の「送信リスト」シートと「テンプレート」シート、そしてそのファイルに紐付くApps Scriptです。
| 要素 | 役割 |
|---|---|
| 送信リスト | 名前、メールアドレス、件名、個別文、送信状態を管理 |
| テンプレート | すべての宛先に共通する本文を管理 |
| Apps Script | 各行を読み込み、文字を差し込んで送信 |
MailAppを使う理由
Apps Scriptにはメール送信用の MailApp と、Gmailのスレッドや下書きも操作できる GmailApp があります。今回は送信だけが目的のため、Gmailの受信トレイへアクセスせず、再認証が起きにくい MailApp を使います。
送信前に知っておきたい上限
Apps Scriptのメール送信には、アカウント種別ごとの日次宛先数上限があります。Google公式表の現行値は個人向けアカウントが1日100宛先、Google Workspaceが1日1,500宛先ですが、上限は変更される場合があります。
記事のコードは MailApp.getRemainingDailyQuota() で実行時の残り宛先数を取得し、足りなければ送信せず停止します。最新値はGoogle公式のApps Script割当量で確認できます。
スプレッドシートの準備
送信リストシートを作る
シート名を「送信リスト」にし、1行目へ次の5つの見出しを入力します。表記はコードが探す文字と合わせるため、変えずに使ってください。
| 名前 | メールアドレス | 件名 | 内容 | 送信状態 |
|---|---|---|---|---|
| 山田太郎 | taro@example.com | ご案内 | 8月の日程は10日です。 | |
| 佐藤花子 | hanako@example.com | ご案内 | 8月の日程は12日です。 |

「送信状態」は最初は空欄にします。送信に成功するとコードが「送信済み」と記録し、次回以降はその行をスキップします。
テンプレートシートを作る
別のシートを追加し、シート名を「テンプレート」にします。A1セルへ共通本文を入力し、名前を入れる場所に {{name}}、個別の内容を入れる場所に {{message}} と記載します。
{{name}}さん
お世話になっております。
{{message}}
どうぞよろしくお願いいたします。

Apps Scriptを起動してコードを記述
スプレッドシートに紐付くスクリプトを開く
- 1スプレッドシートの「拡張機能」を開きます。
- 2「Apps Script」を選びます。
- 3エディタの
Code.gsに次のコードを貼り付けます。 - 4プロジェクト名を入力し、保存します。

function sendMailMerge() {
const gate = LockService.getDocumentLock();
if (!gate.tryLock(5000)) {
SpreadsheetApp.getUi().alert('ほかの送信処理が実行中です。');
return;
}
try {
const activeBook = SpreadsheetApp.getActiveSpreadsheet();
const listSheet = activeBook.getSheetByName('送信リスト');
const templateSheet = activeBook.getSheetByName('テンプレート');
if (!listSheet || !templateSheet) {
throw new Error('シート名を確認してください。');
}
const values = listSheet.getDataRange().getDisplayValues();
if (values.length < 2) {
throw new Error('送信リストに宛先がありません。');
}
const labels = values.shift();
const namePos = labels.indexOf('名前');
const mailPos = labels.indexOf('メールアドレス');
const subjectPos = labels.indexOf('件名');
const messagePos = labels.indexOf('内容');
const statePos = labels.indexOf('送信状態');
const neededPos = [namePos, mailPos, subjectPos, messagePos, statePos];
if (neededPos.some(function (pos) { return pos < 0; })) {
throw new Error('1行目の見出しを確認してください。');
}
const templateText = templateSheet.getRange('A1').getDisplayValue();
const targetRows = [];
for (let pos = 0; pos < values.length; pos++) {
const line = values[pos];
if (line[mailPos] && line[statePos] !== '送信済み') {
targetRows.push(pos);
}
}
if (!targetRows.length) {
SpreadsheetApp.getUi().alert('未送信の宛先はありません。');
return;
}
const quota = MailApp.getRemainingDailyQuota();
if (targetRows.length > quota) {
throw new Error('本日の残り宛先数は' + quota + '件です。');
}
const ui = SpreadsheetApp.getUi();
const answer = ui.alert(
'送信前の確認',
targetRows.length + '件のメールを送信します。',
ui.ButtonSet.OK_CANCEL
);
if (answer !== ui.Button.OK) {
return;
}
let doneNum = 0;
for (let pos = 0; pos < targetRows.length; pos++) {
const dataPos = targetRows[pos];
const line = values[dataPos];
const name = line[namePos];
const mail = line[mailPos];
const subject = line[subjectPos];
const message = line[messagePos];
const body = templateText
.replaceAll('{{name}}', name)
.replaceAll('{{message}}', message);
MailApp.sendEmail(mail, subject, body);
listSheet.getRange(dataPos + 2, statePos + 1).setValue('送信済み');
SpreadsheetApp.flush();
doneNum++;
}
ui.alert(doneNum + '件のメールを送信しました。');
} finally {
gate.releaseLock();
}
}

コードが行っていること
- 5つの見出し位置を名前で探す
- メールアドレスがあり、「送信済み」ではない行だけを対象にする
- 本日の残り宛先数より多ければ実行を止める
- 送信件数をダイアログで確認する
- 送信後に「送信済み」を記録し、再実行時の重複送信を防ぐ
- 連打や複数人の同時実行をドキュメントロックで防ぐ
MailAppの公式リファレンスには、CC、BCC、返信先、HTML本文、添付ファイルなどの追加設定も記載されています。
メール送信ボタンの設置
-
STEP1図形を作る
スプレッドシートの「挿入」から「図形描画」を開き、図形と「メール送信」などの文字を組み合わせて保存します。


-
STEP2スクリプトを割り当てる
図形をクリックし、右上のメニューから「スクリプトを割り当て」を選びます。関数名
sendMailMergeを括弧なしで入力します。

Google公式仕様では、図形や画像へ割り当てたスクリプトはWebブラウザでクリックしたときだけ実行されます。スマートフォン版Googleスプレッドではボタンとして動作しません。詳細はGoogle公式のカスタムメニュ解説を確認してください。
初回認証とテスト送信
初回はスクリプトを承認する
メール送信にはGoogleアカウントの承認が必要です。最初の実行時は承認画面が表示されるため、このスプレッドシートとスクリプトを作成したGoogleアカウントを選び、表示内容を確認して進めます。
承認画面の文言や順番はGoogle側の変更で変わるため、画面の色やボタン位置ではなく、自分で作ったプロジェクトか、送信権限の理由は適切かを確認してください。承認に関する現行仕様はGoogle公式の承認ガイドで確認できます。
自分宛ての1件でテストする
- 1送信リストを自分のメールアドレス1件だけにします。
- 2「送信状態」を空欄にし、図形ボタンをクリックします。
- 3確認ダイアログの件数が1件であることを確認し、実行します。
- 4受信したメールとGmailの送信済みトレイで、件名、本文、差出人を確認します。
- 5シートの「送信状態」が「送信済み」になったことを確認します。

テストが成功したら本番データを追加し、件数を再確認して実行します。受信者の同意を得ていない宣伝メールや、送信元を明らかにしない一方的な送信には使わないでください。
うまく送信できないとき
「シート名」または「見出し」のエラーが出る
シート名は「送信リスト」と「テンプレート」、1行目の見出しは「名前」「メールアドレス」「件名」「内容」「送信状態」にします。前後の空白や似た文字が入っていないかも確認します。
送信可能な残り宛先数が足りない
エラーに表示された残り宛先数以下に分割して実行するか、割当量がリセットされるのを待ちます。複数のアカウントに分けて上限を回避する運用はしません。
送信済みの行をもう一度送りたい
再送したい行の「送信状態」を空欄に戻すと再び対象になります。ただし、ほかの未送信行も同時に対象になるため、確認ダイアログの件数を必ず確認してください。
まとめ
- 送信リストとテンプレートを別シートで用意する
- 送信だけなら、権限範囲の狭い
MailAppを使う - 送信済み列と実行ロックで重複送信を防ぐ
- 実行前に残り宛先数と今回の送信件数を確認する
- 本番送信前に自分宛て1件テストする





