スプレッドシートの宛先リストから、名前入りのメールを1人ずつ送る方法(送る前に確認・二重送信なし)

記事
IT・テクノロジー
お客様や会員の方に、同じ案内を「〇〇様」と名前を入れて 1 通ずつ送りたい。でも手作業でコピーして貼り付けると、宛先や名前を間違えないか心配で、途中で何通目まで送ったかも分からなくなる。そんなときに、Google スプレッドシートと GAS(Google Apps Script)で、名前を差し込んだメールを送る手順をまとめました。

この記事の仕組みは、いきなり送らないのが特徴です。
・まず、差し込んだ後の件名と本文をシートに書き出して、目で確かめる
・送った行には「送信済み」と日時が入るので、もう一度実行しても同じ人に二重に送らない
・1 日に送れる数の上限に近づいたら、自動で止まる

■ 手順 1:宛先のシートを用意する
シートの名前を「宛先」にして、1 行目に見出しを入れます。
A 列:メールアドレス
B 列:名前
C 列:状態(最初は空のまま)
D 列:件名(確認用)
E 列:本文(確認用)

2 行目から、宛先と名前を入れていきます。

■ 手順 2:コードを貼る
メニューの「拡張機能」→「Apps Script」を開き、最初から入っている文字を消して、次のコードを貼り付けて保存します。

const CONFIG = {
  SHEET: '宛先',
  SUBJECT: '【ご案内】{名前}様 12月の営業日について',
  BODY: '{名前}様\n\nいつもありがとうございます。\n12月の営業日をお知らせします。\n\nよろしくお願いいたします。',
};

// 1. 確認用:差し込んだ件名・本文を D 列・E 列に書き出す(メールは送らない)
function previewMails() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(CONFIG.SHEET);
  const last = sheet.getLastRow();
  if (last < 2) return;
  const rows = sheet.getRange(2, 1, last - 1, 2).getValues();
  const out = rows.map(([to, name]) => to ? [fill(CONFIG.SUBJECT, name), fill(CONFIG.BODY, name)] : ['', '']);
  sheet.getRange(2, 4, out.length, 2).setValues(out);
}

// 2. 送信:C 列(状態)が空の行だけ送り、送ったら日時を書く
function sendMails() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(CONFIG.SHEET);
  const last = sheet.getLastRow();
  if (last < 2) return;
  const rows = sheet.getRange(2, 1, last - 1, 3).getValues();
  for (let i = 0; i < rows.length; i++) {
    const [to, name, status] = rows[i];
    if (!to || status) continue;
    const cell = sheet.getRange(i + 2, 3);
    if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(String(to).trim())) {
      cell.setValue('宛先エラー');
      continue;
    }
    if (MailApp.getRemainingDailyQuota() < 1) {
      Logger.log('今日の送信の上限に達したので止めました。明日もう一度実行してください。');
      return;
    }
    MailApp.sendEmail(String(to).trim(), fill(CONFIG.SUBJECT, name), fill(CONFIG.BODY, name));
    cell.setValue('送信済み ' + Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm'));
  }
}

function fill(text, name) {
  return text.split('{名前}').join(name || '');
}

件名と本文は、CONFIG の SUBJECT と BODY を書きかえます。{名前} と書いた所に B 列の名前が入ります。本文の改行は \n です。

■ 手順 3:送る前に確かめる
上の関数の選び方の欄で「previewMails」を選んで「実行」を押します。初めての実行では Google の許可の画面が出ます(「このアプリは Google で確認されていません」と出たときは、私の別の記事「GASで「このアプリはGoogleで確認されていません」と出たときの対処」で手順を書いています)。

実行すると、D 列と E 列に、名前を差し込んだ後の件名と本文が入ります。ここではメールは 1 通も送られません。名前の敬称が重なっていないか(「山田様様」など)、改行の位置はよいかを確かめてください。

■ 手順 4:まず自分あてに 1 通送ってみる
いきなり全員に送らず、2 行目に行を 1 つ挿入して自分のメールアドレスと名前を入れ、3 行目から下の C 列に仮で「保留」と入れておきます。この状態で「sendMails」を実行すると、自分あての 1 通だけが送られます。届いたメールの見え方を確かめたら、C 列の「保留」を消して、もう一度「sendMails」を実行します。

■ つまずきやすいところ
・C 列に何か入っている行は送られません。もう一度送りたい人がいるときは、その行の C 列を空にします
・メールアドレスの形がおかしい行(@ が無い、ドメインが途中で切れているなど)は「宛先エラー」と入って飛ばされます。直したら C 列を空にして、もう一度実行します
・1 日に送れる数には上限があります。Google の上限表では、無料の Gmail アカウントで 1 日 100 人が目安です(Google Workspace はもっと多い)。上限に近づくと途中で止まり、残りは C 列が空のままなので、翌日に同じ「sendMails」を実行すれば続きから送れます
・送信元は、コードを実行した人の Gmail です。送った後のメールは Gmail の「送信済み」にも残ります
・宣伝のメールを、受け取ることに同意していない人へ送るのはやめましょう。法律で決まりがあり、迷惑メールとして扱われる原因にもなります

■ 自分で作るのが大変なときは
「送った結果を別のシートに残したい」「添付ファイルを人ごとに変えたい」「フォームの回答が来たら自動で送りたい」など、条件が増えると作りが変わります。次の出品でお手伝いしています。
・GAS でスプレッドシートの転記・集計を自動化します:https://coconala.com/services/4455227
・Gmail の受信をスプレッドシートに記録する仕組み:https://coconala.com/services/4458787

あわせて読みたい:
・問い合わせメールに返信の「下書き」を自動で作る方法(GAS・送信はしない) https://coconala.com/blogs/6357864/841480
・GASで「このアプリはGoogleで確認されていません」と出たときの対処 https://coconala.com/blogs/6357864/828113

この記事は、AI(Claude)の助けを借りて書いています。コードは、テスト用のデータで動きを確かめてから載せています。
サービス数100万件のスキルマーケット、あなたにぴったりのサービスを探す