LINEで簡易予約システム-予約・キャンセルの通知を受け取る

予約システムは、お客様と予約ロボットとのLINEメッセ―ジのやり取りです。直接見ることはできません。スプレッドシートを確認するか、常に予約のチェックをするしかありません。これでは忙しいときは大変です。予約やキャンセルがあったときに、管理者宛にLINE通知があれば便利です。

そこで予約・キャンセル時、管理者宛メッセージ配信する機能を追加しました。通常LINEは受け取ったメッセージに対して返信します。今回はメッセージを受け取ってない相手(管理者)宛にメッセージを送る機能(PUSH配信)を追加します。

メッセージを送るには、管理者のID(宛先ID)が必要になります。今まではこれを取得してませんでしたので、これを取得しスプレッドシートのセルに格納しておきます。今回はセル”G2”にIDを格納することにします。

追加スクリプト(管理者IDの格納)

//管理者メニュー
  if(odrNum==pass||adminName==nickname){
      var mess1 = nickname + '様\n管理者でログインしています。\n';
      var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = spreadsheet.getActiveSheet();
       sheet.getRange(1, 7).setValue(nickname);
       sheet.getRange(2, 7).setValue(user_id);
      var range = sheet.getRange(1,1,number,3);
      var value = range.getValues();
      var cnt = 0;

太字の部分を追加記述します。これで管理者のIDが格納されます。予約・キャンセルのメッセージをこのID 宛に配信します。

追加スクリプト(配信用のメッセージを作成)予約・キャンセルとも作成します。

キャンセルメッセージ

 case '2':
      var reply = '予約をキャンセルします。\n';
      var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = spreadsheet.getActiveSheet();
      var range = sheet.getRange(1,1,number,2);
      var value = range.getValues();
      for(let i = 0; i <= (number-1); i++){
       if(value[i][1]==nickname){
        mess2 = mess2 + value[i][0] + ' ' + value[i][1] + '様の予約をキャンセルしました。\n';
        sheet.getRange(i+1,2).clear();
       var pushmsg = value[i][0] + value[i][1] + '様の予約をキャンセルしました。';
        pushMessage(pushmsg);
        }  
        }
           mess2 = mess2 + '\n 1ご予約 2キャンセル 3予約確認 \n 番号のみ返信してください。\n';
  break;

太字部分を追加します。これが配信されるキャンセルメッセージです。

予約メッセージ

 case '5':
      var reply = nickname + '様、予約処理の結果です。\n';
      var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = spreadsheet.getActiveSheet();
      var range = sheet.getRange(1,1,number,3);
      var value = range.getValues();
      var yoyaku = odrNum - 500;
      var same = value[yoyaku][2];
      var tttt = same - hournow - timelim;
      if(tttt>=0){
      mess2 = mess2 + value[yoyaku][0] + 'でご予約承りました。\nどうもありがとうございました。\n 3 を送信すると予約確認ができます。\n';
      sheet.getRange(yoyaku+1,2).setValue(nickname);
       var pushmsg = value[yoyaku][0] + nickname + '様の予約があります。';
        pushMessage(pushmsg);
	break;
      }

太字部分を追加します。これが配信される予約メッセージです。

メッセージ配信関数新規に記述します。名前はpushMessage()です。remessはメッセージ本文です。

function pushMessage(remess) {

//sheet指定済みの場合
// channelTokenはアクセストークンです。
   var range = sheet.getRange(2, 7);//アクティブsheetの"G2"
   var USER_ID = range.getValue();//ID取得
//  console.log(USER_ID); //デバック用IDログ出力
  var postData = {
    "to": USER_ID,
    "messages": [{
      "type": "text",
      "text": remess,
    }]
  };

  var url = "https://api.line.me/v2/bot/message/push";
  var headers = {
    "Content-Type": "application/json",
    'Authorization': 'Bearer ' + channelToken,
  };

  var options = {
    "method": "post",
    "headers": headers,
    "payload": JSON.stringify(postData)
  };
  var response = UrlFetchApp.fetch(url, options);
}

これで管理者が予約・キャンセルの通知を受け取ることができます。

Loading

LINEで簡易予約システム-リセット処理の自動化

管理メニューの終了処理と同じ機能を、スプレッドシートのトリガー機能を使用して自動化します。

手順といたしましては、

  • ①終了処理のGASスクリプト関数作成
  • ②1日1回実行するトリガーを設定

予約をすべて削除するスクリプトは以下になります。今までの関数では、関数内でスプレッドシートを変数に取り込んでいましたが、これですとすべての関数の中で記述する必要があります。今回は関数外でアクティブシートを定数で指定しすべての関数で使用できるようにしました。同様にアクセストークンも関数外で定数として記述すればすっきりしたスクリプトになります。関数名は、daily_task()としました。

const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
const sheet = spreadsheet.getActiveSheet();
function daily_task() {
// var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// var sheet = spreadsheet.getActiveSheet();
var range = sheet.getRange(“H1”);
var number = range.getValue();
var range = sheet.getRange(1,1,number,2);
var value = range.getValues();

  for(let i = 0; i <= (number-1); i++){
     sheet.getRange(i+1,2).clear();
    }

return;
}

スクリプトを保存後、[編集]⇒[現在のプロジェクトのトリガー]をクリックします。

[トリガーを追加]をクリックします。

以下のように設定し保存します。デブロイの選択では最新のものを選択します。

これで毎日午前0時から1時の間にこの関数が実行されて予約がリセットされます。

Loading

LINEで簡易予約システムを作成-動作確認

No3で作成したシートに以下の項目に入力したか確認します。

  • A列 ラインで表示される予約時間名を設定します。
  • B列 予約したお客様名が自動的に格納されます。(直接入力可)
  • C列 予約時刻を数字で表したもの(24時間)
  • D列 管理パスワード(D1)(5桁以上の数字推奨)
  • E列 同時に表示する予約数(E1)
  • F列 休日フラグ(休日0 それ以外1)
  • D列 管理者名(自動入力)
  • H列 1日の総予約スロット(H1)
  • I列 何時間前まで予約を受けるか(I1)

次にLINE Developersへ行って。Messaging API設定からボットのベーシックID とQRコードをコピーし、どちらからでもよいのでこの公式アカウントを友達に追加します。これでこのシステムを使う準備が出来ました。

まず管理パスワードをメッセージとして送ります。これで管理者モードになりました。

つぎに他の人が管理者パスワードを入力するか、ログアウトするまで管理者モードは維持されます。管理者になれるのは、一人だけの仕様です。

管理者からログアウトするには[9]を送ります。

ログアウトすると管理者メニューは使えません。予約モードになります。

予約モードで使えるキーは、[1] [2] [3] です。予約時には、予約番号をタイプします。

以上で動作確認は終了です。簡易システムのため使用できる機能は少ないですが、カスタマイズして様々な機能を追加することができます。

例:・自動的に予約リセット(毎日処理)。・予約があったら管理者宛メール(LINE)を送る。等

この記事が、少しでも皆様の参考になれば幸いです。

Loading

LINEで簡易予約システムを作成No4-LINEとスプレッドシートの連携

それではいよいよスプレッドシートにGASスクリプトを記述します。作成したスプレッドシートを開き。[ツール]⇒[スクリプトエディタ]とクリックするとスクリプトエディタが起動します。

以下が張り付けるコードです↓

function doPost(e) {
var replyToken= JSON.parse(e.postData.contents).events[0].replyToken;
if (typeof replyToken === ‘undefined’) {
return;
}

var url = ‘https://api.line.me/v2/bot/message/reply’;
var channelToken = ‘ここに取得したトークンを張り付けます‘;
var event = JSON.parse(e.postData.contents).events[0];
//日付け時刻の取得
var date = new Date();
var month = date.getMonth() + 1;
var day = date.getDate();
var dateMsg = month + ‘月’ + day +’日’;
var hournow = date.getHours();
// ユーザーのメッセージを取得
var mess2 =”;
var mess1 = ”;
var reply =”;
var userMessage = event.message.text;
var odrNum = userMessage;
var user_id = event.source.userId;
var nickname = getUserProfile(user_id);
//スプレッドシートから設定を取得
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var range = sheet.getRange(1,4,1,6);
var count = range.getValues();
var number = count[0][4];
var pass = count[0][0];
var limit = count[0][1];
var adminName = count[0][3];
var timelim = count[0][5];
var holiday = count[0][2];
if (holiday === 0){ var order = ‘4’;} else {
var order = odrNum.slice(0,1);;
}
//管理者メニュー
if(odrNum==pass||adminName==nickname){
var mess1 = nickname + ‘様\n管理者でログインしています。\n’;
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
  sheet.getRange(1, 7).setValue(nickname);
var range = sheet.getRange(1,1,number,3);
var value = range.getValues();
var cnt = 0;

switch (odrNum) {

 case ‘6’:
sheet.getRange(1, 6).setValue(0);
mess2 = mess2 + ‘予約不可に設定しました。\n’;
break;

case ‘7’:
sheet.getRange(1, 6).setValue(1);
mess2 = mess2 + ‘予約可能に設定しました。\n’;
break;
case ‘8’:
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var range = sheet.getRange(1,1,number,2);
var value = range.getValues();
for(let i = 0; i <= (number-1); i++){
sheet.getRange(i+1,2).clear();

     }
    mess2 = mess2 + '予約をすべて削除しました。\n';
break;

case ‘9’:
mess2 = mess2 + ‘ログアウトしました。\n’;
sheet.getRange(1, 7).setValue(”);
break;
 default:
mess2 = mess2 + ‘予約確認をします。\n’;

          for(let i = 0; i <= (number-1); i++){
    if(value[i][1]){
    mess2 = mess2 +value[i][0] + ' に' + value[i][1] + '様の予約があります。\n';
      cnt++;
    }  
    }


    break;
    }
    if (count[0][2] === 0){ var mess3 = '予約できない設定です\n';}else{ mess3 = '予約出来る設定です\n';}

mess2 = mess2 + '予約' + cnt + '件です。\n' + mess3 +'\n管理者メニューです\n 6 予約不可(休日処理)\n 7 予約可\n 8 すべての予約を削除(終了処理)\n 9 管理者からログアウト\n 予約確認のみは、その他のキー\n';

} else {

//お客様メニュー
switch (order) {
 case ‘1’:
var reply = dateMsg + ‘の予約を受け付けます\n’;
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var range = sheet.getRange(1,1,number,3);
var value = range.getValues();
var limCount = limit;
for(let i = 0; i <= (number-1) ; i++){ var same = value[i][2]; var tttt = same – hournow – timelim; if(!value[i][1]&&tttt>=0){
mess2 = mess2 + value[i][0] + ‘予約可 予約番号 ‘+ (500+i) +’\n’;
limCount–;
if(limCount==0){
break;
}
}
}
mess2 = mess2 + ‘\n予約はまだ完了していません。\n予約番号送信後、必ず返信をご確認ください\n’;
break;
 case ‘2’:
var reply = ‘予約をキャンセルします。\n’;
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var range = sheet.getRange(1,1,number,2);
var value = range.getValues();
for(let i = 0; i <= (number-1); i++){
if(value[i][1]==nickname){
mess2 = mess2 + value[i][0] + ‘ ‘ + value[i][1] + ‘様の予約をキャンセルしました。\n’;
sheet.getRange(i+1,2).clear();
}
}
mess2 = mess2 + ‘\n 1ご予約 2キャンセル 3予約確認 \n 番号のみ返信してください。\n’;
  break;
 case ‘3’:
var reply = ‘予約確認\n’;
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var range = sheet.getRange(1,1,number,2);
var value = range.getValues();
for(let i = 0; i <= (number-1); i++){
if(value[i][1]==nickname){
mess2 = mess2 +value[i][0] + ‘ に’ + value[i][1] + ‘様の予約があります。\n’;
}
}

 mess2 = mess2 + '\n 1ご予約 2キャンセル 3予約確認 \n 番号のみ返信してください。\n'; 
break;

case '4':

// var reply = ‘休日処理’;
mess2 = mess2 + ‘本日は定休日、または予約を停止しています。\n\n’;
break;
case ‘5’:
var reply = nickname + ‘様、予約処理の結果です。\n’;
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var range = sheet.getRange(1,1,number,3);
var value = range.getValues();
var yoyaku = odrNum – 500;
var same = value[yoyaku][2];
var tttt = same – hournow – timelim;
if(tttt>=0){
mess2 = mess2 + value[yoyaku][0] + ‘でご予約承りました。\nどうもありがとうございました。\n 3 を送信すると予約確認ができます。\n’;
sheet.getRange(yoyaku+1,2).setValue(nickname);
break;
}
else {
mess2 = mess2 + value[yoyaku][0] + ‘は予約出来ませんでした。\n\n 1ご予約 2キャンセル 3予約確認 \n 番号のみ返信してください。\n’;
break;
}

 default:
var reply = ‘番号が認識できませんでした。番号を確認し、もう一度お試しください。\n\n 1ご予約 2キャンセル 3予約確認 \n 番号のみ返信してください。\n’ ;
// if(odrNum==pass||adminName==nickname){reply=”;}
  break;
}

var mess1 = mess1 + reply ;
}

var messages = [{
‘type’: ‘text’,
‘text’: mess1 + mess2 ,
// ‘text’: ‘こんにちは’+ nickname +’さん\n プロトタイプ準備中の為、運用を一時停止しています。\n’ ,

}];

UrlFetchApp.fetch(url, {
‘headers’: {
‘Content-Type’: ‘application/json; charset=UTF-8’,
‘Authorization’: ‘Bearer ‘ + channelToken,
},
‘method’: ‘post’,
‘payload’: JSON.stringify({
‘replyToken’: replyToken,
‘messages’: messages,
}),
});
return ContentService.createTextOutput(JSON.stringify({‘content’: ‘post ok’})).setMimeType(ContentService.MimeType.JSON);
}

function doGet() {
return;
// HtmlService.createHtmlOutputFromFile(‘index’);
}

function getUserProfile(user_id){
var channelToken = ‘ここに取得したトークンを張り付けます‘;
var url_2 = ‘https://api.line.me/v2/bot/profile/’ + user_id;
var userProfile_2 = UrlFetchApp.fetch(url_2,{
‘headers’: {
‘Authorization’ : ‘Bearer ‘ + channelToken,
},
})
return JSON.parse(userProfile_2).displayName;
//return;
}

↑ここまで

貼り付けたら、[公開]⇒[ウェブアプリケーションとして導入]をクリックすると以下の窓が開きます。最初の選択肢は New 2番目は Me(****@gmail.com) 3番目は Anyone, even Anonymous を選択し Deploy ボタンをクリックします。

許可を確認をクリックします。するとアカウントの選択画面になりますから、自分のアカウントを選択します。
矢印部分をクリックします。
許可をクリックします。
https://script.google.comで始まるURLをコピーします。これをLINEにHOOKします。メモ帳に保存しておくとよいでしょう。OKをクリックします。

次にライン公式アカウントに戻ります。

[ライン公式アカウントログイン][アカウント][設定][Messaging API]へ行きます。

先ほどコピーしたアドレスを貼り付けて作業は終了です。

次回はいよいよ動作確認です。

Loading

LINEで簡易予約システムを作成No3-Googleスプレッドシートの作成

PCでスプレッドシートの操作をする際、Chromeブラウザが使いやすいのでお勧めします。右上の9つの丸のアイコンをクリックしてスプレッドシートを選択します。

新しいスプレッドシートをクリックします。これが予約システムのメインシートになります。

  • A列 ラインで表示される予約時間名を設定します。
  • B列 予約したお客様名が自動的に格納されます。(直接入力可)
  • C列 予約時刻を数字で表したもの(24時間)
  • D列 管理パスワード(D1)
  • E列 同時に表示する予約数(E1)
  • F列 休日フラグ(休日0 それ以外1)
  • D列 管理者名(自動入力)
  • H列 1日の総予約スロット(H1)
  • I列 何時間前まで予約を受けるか(I1)

太文字の部分が、サロン様に合わせて設定する部分です。次に[ツール]⇒[スクリプトエディタ]をクリックしスクリプトエディタ画面を表示します。GAS(Google APP Script)を1から作成するのは大変なので、今回は私が作成したものを、貼り付けます。もちろんカスタマイズすることも可能です。このシートは、無題のスプレッドシートとなってますのでわかりやすい名前を付けておきましょう。このままでも問題はありませんが。それでは、スクリプトエディタを設定する前にLINEに戻って”チャネルアクセストークン(長期)”を取得します。これがないとLINEと連携することはできません。難しくはないのですが手順が長いので画像を参照して取得してください。

LINEチャネルアクセストークン(長期)の取得

https://www.linebiz.com/jp/login/

上のリンクからライン公式アカウントにログインします。

作成したアカウントをクリックします。
プロフィールをクリックし赤矢印のLINE Official Account Managerへ移動します。
画像のように設定変更します。
  • Botを選択
  • 挨拶メッセージ オフ
  • 応答メッセージ オフ
  • Webhook オン

その後Messaging APIに移動します。

その画面にある、LINE Developers へのリンクをクリックして LINE Developers へ移動します。

コンソールへ移動します。
作成したチャンネルをクリックします。チャンネルがないときは新規チャンネル作成をします。
Messaging API設定をクリックして一番下のほうにチャンネルアクセストークンの発行ボタンがあるのでクリックしてトークンを発行します。

これでアクセストークンが発行されたので、いよいよGoogleスプレッドシートシートに戻りGASスクリプトの設定をします。

Loading

LINEで簡易予約システムを作成No2-ライン公式アカウントの作成

ラインアカウントとGoogleアカウントの取得はおすみでしょうか?今回はラインの公式アカウントの取得方法を紹介します。

参考:ライン公式アカウント開設ページ

ライン公式アカウントには、認証済みアカウントと未認証アカウントがあります。今回は未承認アカウントを作成します。上記ページの下の方にある”未承認アカウントを開設する”をクリックしアカウントを作成するページに移ります。その際”LINEアカウントでログイン”を選択します。続いて表示される下記画面にて、現在使用している個人のLINEアカウントもしくはメールアドレスを登録することでLINE公式アカウントを作成することができます。(LINE公式ページより引用)

以下のページを参考にして登録を完了してください。

LINE公式アカウントの作り方|開設の設定と運用方法

予約に利用するための基本設定

LINE公式アカウントでは、企業や店舗に関連するさまざまな情報を登録することができます。まずは最も基本的なアカウントのプロフィールページから設定を進めましょう。プロフィールページを設定するには、Web版管理画面は右上部にある「設定」をクリック、アプリ版管理画面では「設定→アカウント」の順にタップしてください。

https://www.linebiz.com/jp/column/technique/20190418-3/

ここで大事なのは、アカウント名です。分かりやすいものにしましょう。友だち一覧にも表示されるLINE公式アカウントの名前です。通常は企業名や店舗名を入力します。

ここで一旦ライン公式アカウントの設定は中断しGoogle スプレッドシートの設定に移ります。

Googleスプレッドシートの作成

予約システムのメインはGoogleスプレッドシートにあります。ここで予約システムの仕様を決定します。

お客様

  • 予約をする
  • 予約を確認する
  • 予約をキャンセルする

サロン

  • すべての予約の確認をする
  • 予約のリセット(閉店時)
  • 休日の場合の処理
  • 予約を何時間(何分)前まで受けるか

このような仕様で運用できるようにしたいと思います。

スプレッドシートは、表計算ソフトのような体裁です。

GAS(Google Apprication Script)はGoogleが開発・提供しているプログラミング言語です。JavaScriptというWebブラウザ上で動作するプログラミング言語をベースに作成されています。これを利用した予約システムをスプレッドシートに埋め込み動作させます。

次回は、予約用のスプレッドシートを作成します。

未完成ですが、テストバージョンのLINE簡易予約システムを公開しています。ID検索で @647kausy を検索し’310riyo’を友達に追加すると簡易予約システムを試すことができます。下のQRコードからも友達追加可能です。

動作テストを、再開しました。

Loading

LINEで簡易予約システムを作成No1

サロンでの3密を避けるためには、予約制は効果的な方法です。LINEとGoogleスプレッドシートを利用して。無料で構築できる簡易予約システムを紹介しようと思います。

必要なものは、LINE ID と Googleアカウントです。

◎LINE ID

LINEを利用するには、LINEアプリが使えるスマートフォンが必要です。ここでは、LINEを使用していることを前提でお話します。

参考:LINE登録方法(LINE公式)

◎Google アカウント

Googleアカウントとは、無料で取得できるGmailメールアドレスのIDです。これも取得していることが前提になります。

参考:Googleアカウントの作成(自分用)google公式ヘルプ

手順

  • ライン公式アカウントの作成・設定
  • Googleスプレッドシートの設定
  • ライン公式アカウントとGoogleスプレッドシートの連携

誰でも設置できるように説明していきたいと思います。不明な点はコメント欄にお願いいたします。次回はLINE公式アカウントの作成・設定法の予定です。

開発中の画像です、変更になることもあります。

Loading