
Gmailを利用して業務を行う中で、下記のような要望をいただくことがあります。
- メールを効率よく一斉送信したい
- 宛名などの一部分だけ差し込みして送信したい
- 添付ファイルを宛先ごとに変えたい
これらを解決する、一斉送信・差し込み送信ツールを作ってみましたので、公開します。
*このツールを使用したことにより、ご利用者様、または第三者に損害・トラブル等が発生した場合でも、一切の責任を負いません。自己責任の上でのご利用をお願いいたします。
ツールの概要
Googleスプレッドシートで作成したツールです。スプレッドシート上に作成したリストを使って、テキストや添付ファイルを差し込みし、一斉送信することができます。


上記画像のように設定すると、下記のように、一部分だけ内容が異なる(差し込まれている)メールを一斉送信することができます。

* Gmailは1日に送信可能な件数などに制限があります。
大量に送信する予定の場合は、Googleのヘルプをご確認ください。
使い方
ツールを自分用にコピーする
*共有のリクエストをされても対応しません。必ず下記の手順通りに「コピーを作成」してください。
私が公開しているスプレッドシートを開き、コピーを作成します。


メールのテンプレート(ひな型)を作る
Mainシートの画面左のメールテンプレート部分に、基となるメールを作成しましょう。

発信者Email | あなたのメールアドレス (エイリアスを設定している人は、そのアドレスでもOK) |
発信者名 | あなたの名前(好きな名前にできます) |
メールタイトル | メールのタイトル 差し込みテキストを入れることも可能(後述します) |
本文 | メールの本文 差し込みテキストを入れることも可能(後述します) |
共通添付ファイル1~3 | 全あて先に送付する添付ファイルのファイル名 |
メールタイトルと本文には、テキストの差し込みをすることができます。
例えば、「こんにちは、鈴木 太郎様」のように、あて先によって内容を変えたい場合に活用できます。
テキストを差し込む場所に、$0 ~ $9 のいずれかを入力してください。
イメージがつかみにくい場合は、下図をみていただければわかるかと思います。

送り先データを作る
テンプレートができたら、次は、送り先データをDataシートに入力します。

グループ | メール一斉送信の際は、送信対象にグループを指定することができます。 その場合は、この欄にグループ名を入力します。(必須ではありません) |
宛先メールアドレス | 送信先のメールアドレス。 半角カンマで区切って複数入力することができます。 |
CCアドレス | ccに設定するメールアドレス。 半角カンマで区切って複数入力することができます。 |
BCCアドレス | bccに設定するメールアドレス。 半角カンマで区切って複数入力することができます。 |
差込 $0~$9 | メールタイトルまたは本文に差し込むテキストを入力。 |
個別添付ファイル名1~3 | 共通添付ファイル以外のファイルを追加で添付したい場合は、ファイル名を入入力。 |
処理結果 | 入力不要。 |
添付ファイルをGoogleドライブにアップロードする
メールにファイルを添付する場合は、添付ファイルをあらかじめGoogleドライブにアップロードしておく必要があります。
このツールの仕様上、添付ファイルは全て同じフォルダに格納してください。
また、添付ファイルを格納したフォルダのIDを控えておいてください。(後で使用します)

送信設定する
続いて、送信設定を行います。

添付ファイル格納フォルダID | 添付ファイルを格納したフォルダのID (ファイルを添付しない場合は入力不要) |
送信対象グループ | 一斉送信の対象とするグループの名前 (未指定の場合はDataシートの全宛先に送信します) |
送信モード | テスト送信 または 本番送信 を選択します。 テスト送信の場合、すべて発信者Email宛てに送信します。 |
送信する
ここまでの手順で準備は整いました。
メール送信をクリックすれば、メールが差し込み一斉送信されます。
処理が終了したら、Dataシート一番右の処理結果を必ず確認してください。
*初めてこのツールを使う時は、承認作業を行う必要があります。
その手順は、過去の他の記事にまとめていますので、ご参照ください。
参考:GASソースコード
// *** メイン処理 *** function sashikomiGmailSend(){ // * スプレッドシートの取得 const ss = SpreadsheetApp.getActiveSpreadsheet(); const wsMain = ss.getSheetByName("Main"); const wsData = ss.getSheetByName("Data"); // * 処理結果列をクリアする wsData.getRange(2, 18, wsData.getMaxRows(), 18).clearContent(); // * 送信設定の取得 const folderId = wsMain.getRange("E2").getValue(); const targetGroup = wsMain.getRange("E3").getValue(); const sendMode = wsMain.getRange("E4").getValue() ? wsMain.getRange("E4").getValue() : "テスト送信"; if ( sendMode !== "テスト送信" && sendMode !== "本番送信" ){ Browser.msgBox("送信モードを選択してください"); return; } // * 実行確認メッセージ const select = Browser.msgBox( `${sendMode}モードでメールを一括送信します。よろしいですか?`, Browser.Buttons.OK_CANCEL); if (select == "cancel") { Browser.msgBox("キャンセルしました"); return; } // * メールテンプレートの取得 const senderEmail = wsMain.getRange("B2").getValue(); const senderName = wsMain.getRange("B3").getValue(); const title = wsMain.getRange("B4").getValue(); const letterBody = wsMain.getRange("B5").getValue(); // * メールテンプレート(共通添付ファイル)の取得 const commonAttachments = []; for ( let row = 6; row <= 8; row++ ){ const fileName = wsMain.getRange(row, 2).getValue(); if ( fileName ){ const response = getAttachement(folderId, fileName); if ( !response.errMsg ){ commonAttachments.push(response.attachement); } else { Browser.msgBox(`${response.errMsg}処理を中断します。`); return; } } } // * 差込データの取得・メール送信 const data = wsData.getDataRange().getValues(); // 0件の場合は処理終了 if ( data.length <= 1 ) { Browser.msgBox("送信対象が存在しないため、処理を中断します。"); return; } for ( let i = 1; i < data.length; i++ ){ // 送信対象グループの宛先 または 送信対象グループ未設定の場合はメール送信 if ( data[i][0] === targetGroup || !targetGroup ){ // 差込処理 let recipient = data[i][1]; const processedTitle = insertionText(title, data[i].slice(4,14)); const processedLetterBody = insertionText(letterBody, data[i].slice(4,14)); // 個別添付ファイルの取得 const additionalAttachments = []; let additionalAttachmentsErrMsg = ""; for ( let col = 14; col <= 16; col++ ){ const fileName = data[i][col]; if ( fileName ){ const response = getAttachement(folderId, fileName); if ( !response.errMsg ){ additionalAttachments.push(response.attachement); } else { additionalAttachmentsErrMsg = response.errMsg; break; } } } // 個別添付ファイルの取得エラー時はスキップする if ( additionalAttachmentsErrMsg ){ wsData.getRange(i + 1, 18).setValue(additionalAttachmentsErrMsg); continue; } // テストモードの場合、処理継続するか確認し、あて先メールアドレスを送信者のアドレスに変更する if ( sendMode === "テスト送信" ){ const select = Browser.msgBox( `<テストモード>Dataシート${i + 1}行目:${recipient}に送信予定のメールを${senderEmail}にテスト送信します。よろしいですか?`, Browser.Buttons.YES_NO ); if (select == "no") { Browser.msgBox("テスト送信を中断しました。"); break; } recipient = senderEmail; } // メール送信処理 const options = { from: senderEmail, name: senderName }; if ( data[i][2] ){ options.cc = data[i][2] }; if ( data[i][3] ){ options.bcc = data[i][3] }; if ( commonAttachments || additionalAttachments ){ options.attachments = commonAttachments.concat(additionalAttachments); } try { GmailApp.sendEmail( recipient, processedTitle, processedLetterBody, options ); wsData.getRange(i + 1, 18).setValue(`送信成功(${sendMode})`); } catch(e) { wsData.getRange(i + 1, 18).setValue(`送信失敗(${sendMode}):${e}`); } } else { // 指定グループ以外の行の場合はスキップ wsData.getRange(i + 1, 18).setValue("送信対象外"); } } // 終了メッセージ表示 Browser.msgBox("処理が終了しました。処理結果は、Dataシートの「処理結果」列で確認してください。"); } // *** フォルダID、ファイル名を元にファイルを取得する *** function getAttachement(folderId, fileName){ const response = {}; const files = DriveApp.getFolderById(folderId).getFilesByName(fileName); if ( files.hasNext() ){ response.attachement = files.next(); if ( files.hasNext() ){ // 名称が合致するファイルが複数あった場合は処理中断 response.errMsg = `送信失敗:添付ファイル取得エラー・・・「${fileName}」が複数存在します。` ; } } else { // 名称が合致するファイルが存在しない場合は処理中断 response.errMsg = `送信失敗:添付ファイル取得エラー・・・「${fileName}」が存在しません。`; } return response; } // *** テンプレートテキストの$部分にテキストを差し込む *** function insertionText(text, afterTexts){ afterTexts.forEach( (afterText, index) => { const before = new RegExp("\\$" + index, "g"); const after = afterText; text = text.replace(before, after); }) return text; }
コメント
はじめまして!
最高のツールをありがとうございます。
送信ではなく下書き保存をするように、GmailApp.createDraftに書き換えたバージョンも作って活用しています。
1点質問させてください。
テキストを差し込む変数の$0、$1….のコードが分かりませんでした。
https://web-breeze.net/gas_sashikomi-gmail/ こちらのページのコードであれば理解できたのですが…。
と言いますのも、アメリカ向けの作業で金額をメールに記載すルケースが多く、$0などの文字列が変数になっていると、誤変換されてしまいます。
確かに、ドルで金額を示すケースですと使えなくなってしまいますね・・・
差し込み用の変数を$0、$1・・・ではなく、★1、★2・・・にするという方法はどうでしょう。
上記の部分を
というコードに書き換えてお試しいただければと思います。
いけました!
変数を指定しているコードがイマイチ分かっていなかったため、明示いただけてすんなり解決しました。
早速試してみたのですが、少し補足説明をよろしくお願いします。
すべての送信者に、同じファイルを添付する場合は、メインシート欄にある、共通テンプシートの所に、ファイルを設定するかと思いますが、ファイルを設定の仕方がわかりません。
以前は、グーグルドライブに添付ファイルを置いておき、そのファイルのリンクをコピーで必要な文字列をコピペして置いていたのですが、その方法では、送信されていませんでした。
なので、添付ファイルをGoogleドライブの同じフォルダにアップロードして、メインシート欄にある、添付ファイル格納フォルダIDにグーグルドライブの必要な文字列を記入して、先ほどの共通添付シート欄は空欄にしてみたのですが、それでもファイルを添付したメールを送信できませんでした。
改めて、添付ファイルの補足説明をいただけると助かります。よろしくお願いします。
以前の記事のツールとは使い方が少し変わっていますので、詳細はこの記事をご覧いただければと思います。
添付ファイルについては、下記3点が要点になります。
1.添付ファイルをGoogleドライブ上の1つのフォルダに入れてください
2.ツール右上の「添付ファイル格納フォルダID」にフォルダのIDを入れてください
3.ツール内の添付ファイルを入力する欄には、IDではなくファイル名を入力してください。
一点質問です。
メールを送信する際に
<テストモード>Dataシート●●行目:●●@●●.jpに送信予定のメールを●●@●●.jpにテスト送信します。よろしいですか?
という文言が出てきて、はいを押すと送信されると思うのですが、
たとえば50人に一斉送信をする際、上記のポップアップが50回表示され、
50回はいを押さないと送信されません。(結構時間がかかります。)
この動作を省く方法はございますか?
すみません、もう一点なのですが、
DataシートのB列、宛先メールアドレスに
送信先のメールアドレスを入力しても、
その方にメールが飛ばず自分のメールアドレスがtoになってしまいます。
どちらのご質問も、「テスト送信」モードで実行されているためだと思います。
「テスト送信」で送信されるメールのイメージを確認できたら、「本番送信」に切り替えて実行してください。
できました。とても助かりました。ありがとうございます。
質問になります。
本文中の文字色・サイズ・太字等を反映させることは可能でしょうか。
教えて頂けますと幸いです。
ご期待に沿えず申し訳ないのですが、このツールそのままでは文字の書式等を設定することができません。
Google Apps ScriptでHTMLメールを送信することは可能なようですので、もしツールの修正にチャレンジされる場合はこちらの記事が参考になりそうかと思いました。
公開いただいてるツールですとファイルは3つまで添付できますが、それ以上増やすことは出来ますでしょうか。もし可能であればやり方をご教示いただけますと幸いです。
例えば、共通添付ファイルを5つにしたい場合は・・・
①Mainシートの9行目、10行目に共通添付ファイル4、5の入力欄を作る
②スクリプトエディタから、下記部分のソースを修正する
・修正前
・修正後
row = 6; row <= 10 は 6~10行目が添付ファイルの入力欄であることを意味していますので、5つより更に多くする場合は、10の部分の数字を増やしてください。 * 検証せずにコメントしていますので、実施される場合は必ずテスト送信をしてください。
とても助かっています!
たまにファイルが添付されないケースがあります。ファイル名が違ったり、格納フォルダIDが間違っていることが原因です。
一つでもファイル添付がされない場合は、エラーでストップするようには出来ないでしょうか?
P.S. 送信ボタンに加え、下書き作成ボタンを追加して使用しています。上記のエラーを防ぐこともありますが、メール本文の装飾や、送信前の最終確認に使用しています。
ご指摘ありがとうございます。
共通添付ファイルの誤り時はストップする仕様だったのですが、個別添付ファイルの誤り時にはそのまま送信されるようになっていました。
公開しているツールを修正、ブログに掲載しているコードを修正しました。
便利なツールを提供いただきありがとうございます。
送信を行い、結果をみると毎回Exception: 無効な引数というエラーにより送信失敗してしまいます。
どのような可能性が考えられるでしょうか?
送信先数は1400件ほど。Googleworkspaceを使用しているので、ドメインがgmail.com
ではないです。
とても便利なツールを公開していただきありがとうございます!
とても助かっています!
1点質問がありまして、
添付ファイルのエクセルやワードにも
変数差し込みすることは可能でしょうか?
もし可能であればやり方をご教示いただけますと幸いです。
至急:
送信失敗(本番送信):Exception: 1 日にサービス email を実行した回数が多すぎます。
と出て操作ができません。
テスト送信した時点でこうなってしまいました。
どうしたら、直ぐに送信作業が出来ますか?
送りたい件数は140件、添付なし。
大変分かりやすい説明でした!知識0でも送信までこぎつけました。
ただ、スパム扱いされて迷惑メールに振り分けられてしまいます…何とか振り分けられない方法を模索中です。
分かりやすい内容をありがとうございます!
GASは初めてでしたが、何とか構築することができました。
1点質問ですが、コードを追加することで
本文中に画像を埋め込むことは可能でしょうか?
まさにこれというツールでした!
何度か使用させていただいて非常に助かっております。
1点可能か確認お願いしたいのですが、Gmailでの送信予約は出来ますでしょうか?
お手数ですがご確認いただけると幸いです。
よろしくお願いいたします。
とても助かっています。ありがとうございます。
一つ質問のですが、差し込みを増やしたいのですが、どうしたら追加できますでしょうか。
教えてください。
よろしくお願いいたします。
シンプルで使いやすいアプリを公開していただき有難うございます。差し込みのセルが一部空欄であっても、NA表示等が出ないのが良いと思いました。
試しに自分宛に送ってみて気づいた点を共有させてください。
1)Sashikomi Gmail Toolを2つ以上開かないこと:メールが送信されません。複数のフォームのために、複数のファイルを作成することがあると思いますが、送信時は開いているファイルは送信対象のものだけにする必要があるようです。
2)添付ファイル送付時の注意点:Dataシートには必ずグループ名を付し、MainシートのE3でそのグループ名を選択する。
良きツールを発見!と思い、作成してみましたが、
どうしてもうまくいきません。
何度実行しても、
Exception: DriveApp オブジェクトでの getFolderById メソッドまたはプロパティの取得中に予期しないエラーが発生しました。
となります。
原因と思われるものは何でしょうか?
応答いただけると幸いです。
よろしくお願いします。
恐らく、E2セルのフォルダIDが入力されていないか、誤っているかだと思います。
見直してみてください
業務で使用したく、GASを勉強しております。素敵なツールありがとうございます。
コードの54.55が自分の中でわからず(4,14)は具体的に何を指しているのでしょうか。
const processedTitle = insertionText(title, data[i].slice(4,14));
const processedLetterBody = insertionText(letterBody, data[i].slice(4,14));
GAS今回初めてのため、ド素人の質問で申し訳ありません。
data[i]
には、Data
シートのi行目のデータが、配列として格納されています。下記のような感じです。
["Group1", "taro@gmail.com", "", "", "鈴木太郎", "2020年12月27日", "13時30分", "東京本社", 以下省略・・・]
data[i].slice(4, 14)
は、上記のような配列の、[4]~[14]の部分のみを取り出すイメージです。["鈴木太郎", "2020年12月27日", "13時30分", "東京本社", 以下省略・・・]
*配列は[0]から始まります。
insertionText関数にて、$0を”鈴木太郎”に置換、$1を”2020年12月27日”に置換・・・というように、置換処理をしています。