スプレッドシートから差し込みメールを、
「Gmailの下書き」で一括作成する。
案内・お礼・請求のお知らせなど、宛名と一部だけ違うメールを何十通も送る作業は、Google Apps Script(GAS)で下書きまで自動化するのが一番安全です。いきなり送信せず、Gmail の下書きフォルダに並べて、人が目で確認してから送るので誤送信が起きません。
1. シートの形
| A: メール | B: 会社名 | C: 氏名 | D: メモ | E: 状態 |
|---|---|---|---|---|
| taro@example.com | 山田商店 | 山田 太郎 | 先月初回注文 | (空欄) |
| hanako@example.com | 佐藤工務店 | 佐藤 花子 | 見積もり中 | (空欄) |
1行目は見出し。E列「状態」が空欄の行だけ処理し、下書きを作ったら「下書き作成済」と書き込みます(二回実行しても二重に作られません)。
2. 本文テンプレートは別シートに
シート「テンプレート」の A1 に件名、A2 に本文を書きます。{{会社名}} {{氏名}} のように1行目の見出しと同じ名前を二重波かっこで囲むと、その列の値に置き換わります。
A1: 【{{会社名}}様】10月の営業日のお知らせ
A2: {{会社名}}
{{氏名}} 様
いつもお世話になっております。
10月の営業日をお知らせいたします。
(以下略)
3. コード全文(コピペで動きます)
スプレッドシートの「拡張機能 → Apps Script」に貼り付けて、createMergeDrafts を実行します。初回だけ Gmail とスプレッドシートへのアクセス許可を求められます。
const SHEET = '宛先'; // 宛先リストのシート名
const TEMPLATE = 'テンプレート'; // A1=件名, A2=本文
const STATUS_COL = 5; // E列「状態」
const LIMIT_MS = 5 * 60 * 1000; // 6分制限の手前で止める
function createMergeDrafts() {
const start = Date.now();
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName(SHEET);
const tpl = ss.getSheetByName(TEMPLATE);
const subjectTpl = String(tpl.getRange('A1').getValue());
const bodyTpl = String(tpl.getRange('A2').getValue());
const values = sh.getDataRange().getValues();
const head = values[0].map(String);
let made = 0;
for (let r = 1; r < values.length; r++) {
if (Date.now() - start > LIMIT_MS) break; // 続きは次回
const row = values[r];
if (String(row[STATUS_COL - 1]).trim() !== '') continue; // 処理済み
const to = String(row[0]).trim();
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(to)) {
sh.getRange(r + 1, STATUS_COL).setValue('ERROR: メール不正');
continue;
}
const fill = s => s.replace(/\{\{(.+?)\}\}/g, (m, key) => {
const i = head.indexOf(key.trim());
const v = i >= 0 ? String(row[i]).trim() : '';
return v !== '' ? v : m; // 列が無い・空欄は差し込み漏れとして残す
});
const subject = fill(subjectTpl);
const body = fill(bodyTpl);
if (/\{\{.+?\}\}/.test(subject + body)) { // 置き換え漏れは作らない
sh.getRange(r + 1, STATUS_COL).setValue('ERROR: 差し込み漏れ');
continue;
}
GmailApp.createDraft(to, subject, body); // 送信はしない
sh.getRange(r + 1, STATUS_COL).setValue('下書き作成済 ' +
Utilities.formatDate(new Date(), 'Asia/Tokyo', 'MM/dd HH:mm'));
made++;
}
SpreadsheetApp.getActive().toast(made + '件の下書きを作成しました');
}
ポイントは3つ:①状態列で処理済みを管理(二重作成なし・止まっても続きから)、②差し込み漏れ(列名の違い・空欄で {{…}} が残った)行は作らずERROR表示、③createDraft なので絶対に送信されない。
4. 送るときの注意(送信上限)
- 下書きは Gmail 画面から1通ずつ確認して送ります。スクリプトで自動送信(
GmailApp.sendEmail)に切り替える場合、Apps Script からの送信には1日の宛先数の上限があります(無料の Gmail アカウントは約100件/日、Google Workspace は約1,500件/日)。残りはMailApp.getRemainingDailyQuota()で確認できます。 - 一斉送信の広告メールは特定電子メール法の対象です。取引のある相手への業務連絡に使い、宣伝目的の配信には同意取得と配信停止の案内を入れてください。
- BCCでまとめて送るより、1人1通の方が宛先の見落としや漏えいが起きにくく、返信も管理しやすくなります。
5. オプション:ChatGPTで「一言だけ」個別に添える
本文をまるごとAIに書かせると、事実と違う約束を書いたり、毎回言い回しが変わって確認が大変になります。おすすめは本文は固定テンプレート、D列「メモ」から冒頭の一言だけAIに作らせるやり方です。テンプレートに {{ひとこと}} を置き、F列を「ひとこと」列にして、先に次の関数で埋めます(空欄の行だけ)。
// プロンプト例(askAI は下の安全な共通関数のページを参照) const prompt = 'あなたは日本の中小企業の事務担当です。次のメモから、' + '取引先へのメール冒頭に添える自然な一文(40字以内)を1つだけ書いてください。' + 'メモに無い事実(日付・金額・約束)は書かないこと。\nメモ:' + memo;
APIキーの隠し方・429エラーの再試行・1日の上限つきの呼び出し関数は GASからChatGPT APIを安全に呼ぶ askAI() にまとめています。AIが作った一言もシート上で確認・修正してから下書きを作れるのが、この2段階方式の利点です。
下書きまで作る業務スクリプトを、まとめて使いたい方へ
このページと同じ「送信せず下書きまで」の考え方で作った、そのまま動く GAS 5本(Gmail 問い合わせの返信下書き・請求書PDF+送付メール下書き・議事録の要点とTODO整形 ほか)と日本語の導入手順書のセットです。
そのまま動くGAS5本+導入ガイド【PRO版・$39】を見る → 請求書PDFを一括作成して送付メールを下書き・拡張版($3)→ 決まった集計を毎朝メールで届けるGAS+シート一括AI処理(日本語版・$19)→手で貼って使うプロンプトだけ欲しい方へ:事務AIプロンプト集12種(無料・投げ銭歓迎)
Gumroad での販売です。このページの差し込みメールのコードは無料で、有料版には含まれていません。AI を使う機能には OpenAI の API キー(従量課金)が必要です。デジタル納品のため、ダウンロード後の返金はお受けできません(不具合時は誠実に対応します)。
自分で設定するのが不安な方へ(ココナラ・日本円):シート1列のAI一括処理と、当日分の自動サマリーメールのGAS2本+日本語手順書を、ココナラで販売しています(3,000円・税抜〜)。初期設定サポート(+4,000円)や、あなたの実データで自動化フローを1つ一緒に作る導入伴走(+12,000円)は任意のオプションです(いずれも税抜)。対応できるかは購入前の見積り相談で確認できます。
ココナラで導入相談・購入する →請求書PDF+AI添え状メール · Gmail問い合わせをAIで下書き返信 · GASからChatGPT APIを安全に呼ぶ · スプレッドシートに =AI() 関数を自作 · 無料本:GAS×ChatGPT事務自動化の基本