Gmail一斉送信・差し込み送信ツール(スプレッドシート)

Gmailを利用して業務を行う中で、下記のような要望をいただくことがあります。

  • メールを効率よく一斉送信したい
  • 宛名などの一部分だけ差し込みして送信したい
  • 添付ファイルを宛先ごとに変えたい

これらを解決する、一斉送信・差し込み送信ツールを作ってみましたので、公開します。

*このツールを使用したことにより、ご利用者様、または第三者に損害・トラブル等が発生した場合でも、一切の責任を負いません。自己責任の上でのご利用をお願いいたします。

ツールの概要

Googleスプレッドシートで作成したツールです。スプレッドシート上に作成したリストを使って、テキストや添付ファイルを差し込みし、一斉送信することができます。

ツールのメインシート
メインシートでは、メールのひな型入力や、送信の設定を行う
ツールのデータシート
データシートでは、宛先や差し込みテキスト、個別添付ファイルの設定を行う

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

送信されたメール(サンプル)
ピンク色部分が、差し込まれたテキストや添付ファイル

* Gmailは1日に送信可能な件数などに制限があります。
  大量に送信する予定の場合は、Googleのヘルプをご確認ください。

使い方

ツールを自分用にコピーする

私が公開しているスプレッドシートを開き、コピーを作成します。

ファイルメニューからコピーを作成を選択
ファイル → コピーを作成
コピー先を指定する
この例では、マイドライブにコピーを作成しました

メールのテンプレート(ひな型)を作る

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

メールテンプレート入力箇所
この部分に入力していく
発信者Emailあなたのメールアドレス
(エイリアスを設定している人は、そのアドレスでもOK)
発信者名あなたの名前(好きな名前にできます)
メールタイトルメールのタイトル
差し込みテキストを入れることも可能(後述します)
本文メールの本文
差し込みテキストを入れることも可能(後述します)
共通添付ファイル1~3全あて先に送付する添付ファイルのファイル名

メールタイトルと本文には、テキストの差し込みをすることができます。

例えば、「こんにちは、鈴木 太郎様」のように、あて先によって内容を変えたい場合に活用できます。

テキストを差し込む場所に、$0 ~ $9 のいずれかを入力してください。
イメージがつかみにくい場合は、下図をみていただければわかるかと思います。

テキストが差し込まれるイメージ
メール本文(またはタイトル)の $ 部分に、Dataシートの該当のテキストが差し込みされる

送り先データを作る

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

送り先データの入力箇所
この部分に入力する
グループメール一斉送信の際は、送信対象にグループを指定することができます。
その場合は、この欄にグループ名を入力します。(必須ではありません)
宛先メールアドレス送信先のメールアドレス。
半角カンマで区切って複数入力することができます。
CCアドレスccに設定するメールアドレス。
半角カンマで区切って複数入力することができます。
BCCアドレスbccに設定するメールアドレス。
半角カンマで区切って複数入力することができます。
差込 $0~$9メールタイトルまたは本文に差し込むテキストを入力。
個別添付ファイル名1~3共通添付ファイルを以外のファイルを追加で添付したい場合は、ファイル名を入入力。
処理結果入力不要。

添付ファイルをGoogleドライブにアップロードする

メールにファイルを添付する場合は、添付ファイルをGoogleドライブにアップロードしておく必要があります。

このツールの仕様上、添付ファイルは全て同じフォルダに格納してください。

また、添付ファイルを格納したフォルダのIDを控えておいてください。(後で使用します)

フォルダ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() : "テスト送信";

  // * 実行確認メッセージ
  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 ){

      // 差込処理
      const recipient = ( sendMode !== "テスト送信" ) ? data[i][1] : senderEmail;
      const processedTitle = insertionText(title, data[i].slice(4,14));
      const processedLetterBody = insertionText(letterBody, data[i].slice(4,14));

      // 個別添付ファイルの取得
      const additionalAttachments = [];
      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 {
            wsData.getRange(i + 1, 18).setValue(response.errMsg);
            continue;
          }
        }
      }

      // テストモードの場合、処理継続するか確認
      if ( sendMode === "テスト送信" ){
        const select = Browser.msgBox(
          `<テストモード>Dataシート${i + 1}行目:${recipient}に送信予定のメールを${senderEmail}にテスト送信します。よろしいですか?`,
          Browser.Buttons.YES_NO
        );
        if (select == "no") {
            Browser.msgBox("テスト送信を中断しました。");
            break;
        }
      }

      // メール送信処理
      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;
}

コメント

タイトルとURLをコピーしました