予約内容をGmailで自動返信させよう【連載5/5】

予約システム

連載「予約システムを自作しよう 」の5回目(最終回)です。

前回までの作業で、予約受付フォームを入力すると予約が取れる場合のみ、予約状況カレンダーに予定が自動反映されるようになりました。

今回は、予約受付フォームでの回答内容に応じてお客様に予約内容の確認メールと予約が取れなかった時のエラーメールが自動送信するような機能について説明していきます。

いよいよラストスパートです。引き続き開発を進めていきましょう。

GASに自動送信機能を追記していく

自動返信機能の実装

エディタの「コード.gs」をクリックし、以下のコードをコピーして貼り付けてください。

前回のコードから追加されている部分は黄色になっています。

function reserveForm(e) {
  /*********************************
   * 定義
   *********************************/
  // 何ヵ月後まで予約可能にしますか。
    let agoMonth = 3;

  // 予約枠時間の固定時間
    let TimeZone =1;

  // 営業開始時間
    let BusinessStartHours = "10:00";

  // 営業終了時間
    let BusinessEndHours = "18:00";

  // 予約状況カレンダーID
  let CalendarId01 = "XXXXXXXXXXXXXXXXXXXX@group.calendar.google.com";

  // 予約状況カレンダー公開URL
  let CalendarUrl = "予約状況カレンダー公開URL";

  // 予約フォーム公開URL
  let FormUrl = "予約フォームURL";

  /*********************************
   * 新規用定義
   *********************************/
  // フォームの回答を取得
  let [timestamp ,Email, Day ,Start_time ,Name ,Mnum] = e.values;

  // 表示データの加工
  // Googleカレンダー表示用タイトル作成
  let CalTitle = Name + "様";

  //Googleカレンダー表示用説明作成
  let Explanation = 
    "会員番号:" + Mnum + "\n" +
    "メール :" + Email ;

  // タイプ
  let NomalOperation = "正常";
  let Error01 = "時間帯逆転しています";
  let Error02 = "開始時間が既に過ぎています";
  let Error03 = "予約可能の最大日時外です";
  let Error04 = "営業時間外です";
  let Error05 = "カレンダーに既に予定が入っています";


  // 自動返信メール件名
  let MailTitle01 = "予約時エラーのご連絡(" + Error01 +")";
  let MailTitle02 = "予約時エラーのご連絡(" + Error02 +")";
  let MailTitle03 = "予約時エラーのご連絡(" + Error03 +")";
  let MailTitle04 = "予約時エラーのご連絡(" + Error04 +")";
  let MailTitle05 = "予約時エラーのご連絡(" + Error05 +")";
  let MailTitleOK = "予約完了のご連絡";

  // 自動返信メール本文(部品)
  let MailBodyForm =
    "************************************************" + "\n" +
    "予約受付フォーム" + "\n" +
    "受付日時:" + timestamp + "\n" +
    "メール :" + Email + "\n" +
    "日 時 :" + Day + " " + Start_time + "~(" + TimeZone + "時間)" + "\n" +
    "氏 名 :" + Name + "\n" +
    "会員番号:" + Mnum + "\n" +
    "************************************************"+ "\n\n" + 
    "予約状況カレンダー"+ "\n" +
    CalendarUrl;
  
  let MailBodyCommon = Name + "様 ご連絡ありがとうございます。";
  
  let MailBodyNG1 = "ご希望いただいた新規予約依頼は完了できませんでした。";
  let MailBodyNG2 = 
  "お手数ですが、エラー内容をご確認の上、再度ご予約のほどお願いいたします。"+ "\n" +
  "予約受付フォーム:" + FormUrl;


  // 自動返信メール本文
  let MailBodyOK =
  MailBodyCommon+ "\n" +
  "ご希望いただいた新規予約依頼が完了しました"+ "\n" +
  MailBodyForm + "\n" +
  "正しく予約されているか予約状況カレンダーの確認を必ずお願いいたします。";

  let MailBody01 = 
  MailBodyCommon + "\n\n" +
  MailBodyNG1 + "\n" +
  "(" + Error01 +")" + "\n\n" +
  MailBodyForm + "\n\n" +
  MailBodyNG2;

  let MailBody02 = 
  MailBodyCommon + "\n\n" +
  MailBodyNG1 + "\n" +
  "(" + Error02 +")" + "\n\n" +
  MailBodyForm + "\n\n" +
  MailBodyNG2;

  let MailBody03 = 
  MailBodyCommon + "\n\n" +
  MailBodyNG1 + "\n" +
  "(" + Error03 +")" + "\n\n" +
  MailBodyForm + "\n\n" +
  MailBodyNG2;

  let MailBody04 = 
  MailBodyCommon + "\n\n" +
  MailBodyNG1 + "\n" +
  "(" + Error04 +")" + "\n\n" +
  MailBodyForm + "\n\n" +
  MailBodyNG2;

  let MailBody05 = 
  MailBodyCommon + "\n\n" +
  MailBodyNG1 + "\n" +
  "(" + Error05 +")" + "\n\n" +
  MailBodyForm + "\n\n" +
  MailBodyNG2;


  /*********************************
   * 日付データ加工
   *********************************/
  // 今日の日付取得
  const Today = new Date();
  const NowTime = new Date();

  // 予約可能の最大日時取得
  const TodayAgo = Today.setMonth(Today.getMonth() + agoMonth);

  // 日時の情報を加工・変換
  let DateDetailStart_time = Day + " " + Start_time;
  let DateDetailStart = new Date(DateDetailStart_time);

  let DateDetailEnd_time = Day + " " + Start_time;
  let DateDetailEnd0 = new Date(DateDetailEnd_time);
  let DateDetailEnd = new Date(DateDetailEnd0.setHours(DateDetailEnd0.getHours()+TimeZone));

  let DateDetalBusinessStartHours = Day + " " + BusinessStartHours;
  let DateDetalBusinessStart = new Date(DateDetalBusinessStartHours);

  let DateDetalBusinessEndHours = Day + " " + BusinessEndHours;
  let DateDetalBusinessEnd = new Date(DateDetalBusinessEndHours);

  /*********************************
   * 計算処理呼び出し
   *********************************/
  let CalResult01 = new Array();
  let CalResult02 = new Array();
  let CalResult03 = new Array();
  let CalResult04 = new Array();

  // 開始時間と終了時間の精査処理呼び出し
  CalResult01 = CheckTime(DateDetailStart, DateDetailEnd);

  // 開始時間が今より前の時間でないか精査呼び出し
  CalResult02 = CheckNowTime(NowTime,DateDetailStart);

  // 予約可能の最大日時内か精査呼び出し
  CalResult03 = CheckMaxHours(TodayAgo,DateDetailStart);

  // 営業時間内か精査呼び出し
  CalResult04 = CheckMaxHours(DateDetailStart,DateDetalBusinessStart,DateDetalBusinessEnd);

   if(CalResult01 == NomalOperation ){
    if(CalResult02 == NomalOperation ){
      if(CalResult03 == NomalOperation){
        if(CalResult04 == NomalOperation){
          // 新規予約処理呼び出し
          Logger.log("新規予約処理スタート");
          NewReservation(CalendarId01, DateDetailStart, DateDetailEnd,CalTitle, Explanation,Email, MailTitleOK,MailBodyOK,MailTitle05,MailBody05);

        } else {
          // メール送信(営業時間外です)
          MailApp.sendEmail(Email, CalResult04[1], CalResult04[2]);
          Logger.log("メール送信(営業時間外です)");
        }
      } else {
        // メール送信(予約可能の最大日時外です)
        MailApp.sendEmail(Email, CalResult03[1], CalResult03[2]);
        Logger.log("メール送信(予約可能の最大日時外です)");
      }
    } else {
      // メール送信(開始時間が既に過ぎています)
      MailApp.sendEmail(Email, CalResult02[1], CalResult02[2]);
      Logger.log("メール送信(開始時間が既に過ぎています)");
    }
  } else {
    // メール送信(時間帯逆転しています)
    MailApp.sendEmail(Email, CalResult01[1], CalResult01[2]);
    Logger.log("メール送信(時間帯逆転しています)");
  }

  /*********************************
   * 計算処理
   *********************************/
  /*********************************
     * 時間エラー処理
   *********************************/
  // 開始時間と終了時間の精査
  function CheckTime(StartTime, EndTime) {

    if (StartTime < EndTime) {

      Logger.log('開始時間と終了時間正常');
      CalResult01 = NomalOperation;
      return CalResult01;

    } else {

      Logger.log('開始時間と終了時間逆転');
      let Type = Error01;
      let MailTitle = MailTitle01;
      let MailBody = MailBody01;

      CalResult01[0] =Type;
      CalResult01[1] =MailTitle;
      CalResult01[2] =MailBody;

      return CalResult01;

    } 
  }

  // 開始時間が今より前の時間でないかの精査
  function CheckNowTime(NowTime ,StartTime) {

    if (NowTime < StartTime) {

      Logger.log('開始時間正常');
      CalResult02 = NomalOperation;
      return CalResult02;


    } else {

      Logger.log('開始時間が既に過ぎている');
      let Type = Error02;
      let MailTitle = MailTitle02;
      let MailBody = MailBody02;

      CalResult02[0] =Type;
      CalResult02[1] =MailTitle;
      CalResult02[2] =MailBody;

      return CalResult02;

    } 
  }


  // 予約可能の最大日時内か精査
  function CheckMaxHours(TodayAgo, StartTime) {

    if (StartTime <= TodayAgo) {

      Logger.log('予約可能日時');
      CalResult03 = NomalOperation;
      return CalResult03;

    } else {
      
      Logger.log('予約可能の最大日時外');

      let Type = Error03;
      let MailTitle = MailTitle03;
      let MailBody = MailBody03;

      CalResult03[0] =Type;
      CalResult03[1] =MailTitle;
      CalResult03[2] =MailBody;

      return CalResult03;

    } 
  }
  
  // 営業時間内か精査
  function CheckBusinessHours(StartTime, StartBusinessTime, EndBusinessTime) {

    if (StartBusinessTime <= StartTime) {
      if(StartTime <= EndBusinessTime){

        Logger.log('営業時間内');
        CalResult04 = NomalOperation;
        return CalResult04;

      }else{
        Logger.log('営業時間外(後)');

        let Type = Error04;
        let MailTitle = MailTitle04;
        let MailBody = MailBody04;

        CalResult04[0] =Type;
        CalResult04[1] =MailTitle;
        CalResult04[2] =MailBody;

        return CalResult04;

      }
    } else {
      
      Logger.log('営業時間外(前)');

      let Type = Error04;
      let MailTitle = MailTitle04;
      let MailBody = MailBody04;

      CalResult04[0] =Type;
      CalResult04[1] =MailTitle;
      CalResult04[2] =MailBody;

      return CalResult04;
    } 
  }

  /*********************************
     * 新規予約処理
  *********************************/
  function NewReservation(CalendarId, StartTime, EndTime,CalendarTitle, Explanation, Email ,MailTitleOK , MailBodyOK ,MailTitleNG , MailBodyNG) {

    // カレンダーオブジェクトを取得
    let Calendar = CalendarApp.getCalendarById(CalendarId);

    // イベントがなければ実行する関数
    // "!"を用いることでBoolen化する
    if (!Calendar.getEvents(StartTime, EndTime).length) {
      // カレンダーに日程を追加
      Calendar.createEvent(CalendarTitle, StartTime, EndTime, { description: Explanation });

      Logger.log('カレンダー処理正常完了');

      // ユーザーメール送信
      MailApp.sendEmail(Email, MailTitleOK , MailBodyOK);

    } else {
      Logger.log('カレンダーに既に予定が入っています');

      // ユーザーメール送信
      MailApp.sendEmail(Email, MailTitleNG , MailBodyNG);

    }
  }

}

カレンダーID等の設定

上記のコードは、以下の項目が設定されていませんので設定をお願いいたします。

メールが来るかテストしよう

一度、フォームURLから予約を送信してみて、以下のイメージのようなメールが来ていれば、GASの自動返信メールの実装がうまくできています。

予約完了のメール

予約不可のメール

まとめ

今回は、連載「予約システムを自作しよう 」の第5回目「予約内容をGmailで自動返信させよう」を説明してきました。

今回の予約システムでは、最初に想定した店舗の情報をもとに実装しました。これをベースとして、追加機能の作成もトライしてみてください。

これですべての工程が終了となります。お疲れ様でした。

連載目次: 予約システムを自作しよう

  1. 予約システムを自作しよう
  2. Googleカレンダーをサイトに載せよう
  3. Googleフォームで予約受付フォームを作ろう
  4. Googleフォームの内容をGoogleカレンダーに反映させよう
  5. 予約内容をGmailで自動返信させよう

コメント