GASでhtml形式にして、メール送信する方法

社内SE

index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" >
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.1/css/bootstrap-select.min.css">

  </head>
  <body>
    
    <div class="container">
      <i id="processing" class="fa fa-refresh fa-spin fa-3x fa-fw"></i>
      <form class="form-horizontal" id="myForm" onsubmit="return false;">

        <div class="form-group">
            <label class="control-label col-xs-3" for="input_sender">差出人</label>
            <div class="col-xs-9">
                <input type="text" name="text" class="form-control" id="input_sender" value="ヘルプ" required>
                <div class="help-block with-errors"></div>
            </div>
        </div>   

        <div class="form-group">
            <label class="control-label col-xs-3" for="input_meil">発信者Email</label>
            <div class="col-xs-9">
                <input type="email" name="email" class="form-control" id="input_meil" value="test@test.jp" required>
                <div class="help-block with-errors"></div>
            </div>
        </div>    

        <div class="form-group">
          <label class="control-label col-xs-3" for="input_meil">テンプレート文章</label>
          <div class="col-xs-9">
            <select class="form-control" id="select_body" required></select>
            <div class="help-block with-errors"></div>
          </div>
        </div>

        <div class="form-group">
          <div class="col-xs-offset-3 col-xs-9">
            <button id="send_button" type="submit" class="btn btn-primary btn-large">
                    <i class="fa fa-send fa-lg"></i>送信
            </button>
          </div>
        </div>
      </form>  
    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" ></script>
    <script src="https://use.fontawesome.com/7bcbed1321.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.1/js/bootstrap-select.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/1000hz-bootstrap-validator/0.11.8/validator.min.js"></script>


    <script>
      /**
       スプレッドシートのデータをもとに、セレクトボックスを構築する
      */
      function getSelectList() {
        try {
          google.script.run
            .withSuccessHandler(function(result) {

              console.log("result", result);

              var select = document.getElementById('select_body');
              var option = document.createElement('option');
              option.setAttribute('value', '');
              option.setAttribute('selected', true);
              // option.innerHTML = '未選択';
              select.appendChild(option);

              for (var i = 0; i < result.data.length; i++) {
                option = document.createElement('option');
                option.setAttribute('value', i + 1);
                option.innerHTML = result.data[i];
                select.appendChild(option);
              }
            })
            .withFailureHandler(function(result) {
              toastr.error('リストの取得に失敗しました。', result);
            })
            .getSelectListFromMasterSS();

        } catch (e) {
          toastr.error(e);
        }
      }

      /**
       コード.registerFormData()を呼んで、
      フォームの内容をスプレッドシートに引き渡し
      */
      function sendData() {

        try {

          processing(true);

          var data = [];
          data[0] = 'dummy';
          data[1] = document.getElementById('input_sender').value;
          data[2] = document.getElementById('input_meil').value;
          data[3] = document.getElementById('select_body').options[document.getElementById('select_body').selectedIndex].text; //フォームの内容をスプレッドシートに登録する

          console.log("data", data);

          google.script.run
            .withSuccessHandler(function(result) {
              processing(false);
              if (result.data) {
                toastr.info('送信完了');
              } else {
                toastr.error('送信失敗しました');
              }
            })
            .withFailureHandler(function(result) {
              processing(false);
              toastr.error('データ送信に失敗しました。', result);
            })
            .registerFormData(data);

        } catch (e) {
          processing(false);
          toastr.error(e);
        }

      }

      // 処理中アイコン表示・非表示
      function processing(processing) {
        if (processing) {
          document.getElementById('processing').style.visibility = "visible";
          document.getElementById('send_button').setAttribute("disabled", true);
        } else {
          document.getElementById('processing').style.visibility = "hidden";
          document.getElementById('send_button').removeAttribute("disabled");
        }
      }

      // ロード完了後の処理
      $(function() {
        // トースト通知の位置指定
        toastr.options.positionClass = "toast-bottom-left";
        // バリデーションチェック有効化
        $('#myForm').validator();

        // 処理中アイコン非表示
        processing(false);

        // セレクトボックスのリストを動的に取得
        getSelectList();

        // submit時のイベント登録
        $('#myForm').validator().on('submit', function(e) {
          if (document.getElementById('send_button').className.indexOf("disabled") != -1) {
            // submit用のボタンのスタイルにdisabledが設定されていればバリデーションエラー
          } else {
            // バリデーションエラーでなければ送信
            sendData();
          }
        })
      });
    </script>
  </body>
</html>

main.gs

/*****************************
* スプレッドシートの開始行や項目列の場所
*******************************/
var SHEET_LIST = (function () {
  
  return {

    COL_FamilyName : 2,  //姓
    COL_LastName   : 3,  //名
    COL_JukoStatus : 4,  //受講状況
    COL_Seiseki    : 5,  // 成績
    COL_Hiredate   : 6,  //入社日
    COL_EndDate    : 11, //修了日
    COL_EMAIL      : 12, //メールアドレス
    COL_CourseName : 13, //コース名

  };
}());


function onOpen() {
  SpreadsheetApp.getUi() 
    .createMenu("メール送信")
    .addItem("メール送信", "sendMail")
    .addToUi();
}

function sendMail() {

  const template = HtmlService.createTemplateFromFile("Index");
  const html = template
  .evaluate()
  .setSandboxMode(HtmlService.SandboxMode.IFRAME)
  .addMetaTag('viewport', 'width=device-width, initial-scale=1')
  .setWidth(400).setHeight(300);
  SpreadsheetApp.getUi() 
    .showModalDialog(html, "送信メールツール");

}

/**
  セレクトボックスのリストを動的に取得する
*/
function getSelectListFromMasterSS() {
  var selectList = [];
  activeSheet  = SpreadsheetApp.getActiveSpreadsheet().getSheets();

  for(var i=0; i < activeSheet.length; i++ ){
    var get_SheetName = activeSheet[i].getSheetName();
    if ( get_SheetName.match(/メール/)) {
      selectList.push(get_SheetName);
    }
  }
  Logger.log("selectList = %s", selectList); 
  return {data: selectList};
}

/**
  メイン処理
*/
function registerFormData(data) {
Logger.log("data = %s", data);

  const todayDt = Utilities.formatDate( new Date(), 'JST', 'yyyy/MM/dd');

  var strSender     = data[1];  // 差出人
  var strFrom       = data[2]; // 差出メールアドレス
  var strSheetName  = data[3]; // テンプレートの「メール」シート名

  var mymailAddress = Session.getActiveUser().getUserLoginId();

  if(mymailAddress.indexOf(strFrom) === -1) {
    // Browser.msgBox("差出人メールアドレスでログインしてから送信を行ってください。");
    var msg = ("差出人メールアドレスでログインしてから送信を行うか、メールエイリアスを取得・設定して再度送信してください。");
    SpreadsheetApp.getActiveSpreadsheet().toast(msg, '要確認',10);
    return;

  }

  // メール用テンプレート取得
  var get_SheetName = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(strSheetName);
  // メール件名
  var get_subject = get_SheetName.getRange(2, 3).getValue();
  // メール本文
  var get_body = get_SheetName.getRange(4, 3).getValue();

  var errList = {};
  var resultdata = [];

  /* スプレッドシートの情報を取得 (対象者絞り)*/
  const mySheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('送信者リスト');
  var sheetData = mySheet.getDataRange().getValues()
    .filter(function(e){
      return ((e[SHEET_LIST.COL_Seiseki -1 ] == ''))
      // return ((e[SHEET_LIST.COL_JukoStatus -1 ] == "受講中") && (e[SHEET_LIST.COL_Seiseki -1 ] == ''))
    })
    .map(function(e,index){
      const row = [];

      var Hiredate = Utilities.formatDate(e[SHEET_LIST.COL_Hiredate - 1], 'Asia/Tokyo', 'yyyy/MM/dd'); //入社日
      var to_Name = e[SHEET_LIST.COL_FamilyName - 1] + ' ' + e[SHEET_LIST.COL_LastName - 1]; //氏名
      var to_email = e[SHEET_LIST.COL_EMAIL - 1];  //メールアドレス

      // メール本文を差し込みデータを対応
      strBody = get_body.replace("{{氏名}}", to_Name, "g");

      try {
        GmailApp.sendEmail(
          to_email,           //toアドレス
          get_subject,        //表題
          strBody,            //本文
          {
            // cc:cc,
            // bcc:bcc,
            from: strFrom,   //fromアドレス
            name: strSender  //差出人
          }
        )

        resultdata.push([Hiredate, to_Name,todayDt ])
        return row;           
      }
      catch(e){
        // errList[index] = "エラーの内容:" + e + "\\n" + to_Name + to_email;
         errList[index] = [to_Name , to_email , e ];
      }

    });

    var strErr =[];
    for (cd in errList) {
      strErr.push(errList[cd]);
    }

    const rSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('送信結果');
    //シートのすべてをクリアする
    rSheet.clear();

    // Browser.msgBox("strErr.length : " + strErr.length); 
    if (sheetData.length > 0 && strErr.length > 0) {
      var msg = "対象者 " + sheetData.length + " 件中、下記対象者への送信ができませんでした。"; 
        rSheet.getRange(1,1).setValue(msg);
        rSheet.getRange(2,1,1,3).setValues([[ '対象者', 'メールアドレス', 'エラー内容' ]]);
        rSheet.getRange(2,1,1,3).setBackground('#74cc74');
        rSheet.getRange(3,1,strErr.length, 3).setValues(strErr);

      SpreadsheetApp.getActiveSpreadsheet().toast(msg);
      Logger.log("送信エラーデータ = %s", msg);     

    }else if (sheetData.length > 0 && strErr.length == 0){
      var msg = sheetData.length + "名対象者に対して送信しました。" 
      rSheet.getRange(1,1).setValue(msg);
      // rSheet.getRange(2,1,1,3).setValues([[ '入社日', '対象者', '配信日' ]]);
      // rSheet.getRange(2,1,1,3).setBackground('#74cc74');
      // rSheet.getRange(3,1,resultdata.length, 3).setValues(resultdata);
      SpreadsheetApp.getActiveSpreadsheet().toast(msg);
      Logger.log("送信件数 = %s", msg);
    }else{
      var msg = "対象者リストシートにデータはありません。"
      rSheet.getRange(1,1).setValue(msg);
      SpreadsheetApp.getActiveSpreadsheet().toast(msg);
    }

    result = true;
    return {data: true};

}

コメント