第14話 予約を削除する
こんにちは。Kenです!
すっかり銀杏香る秋になり、肌寒くなりました。今日もお酒を飲みながら執筆していきます。
前回は次回予約確認のプログラムを書きました。
今回は予約を削除するコードを書いていきたいと思います。なお、予約変更したい場合は、あえて変更モードを作るのではなく、予約削除→再度予約としたいと思います。こうしても利用者にそこまで負担がないと思ったからです。
データベースの予約を削除する
さて、前回の終わりに予約データを削除するSQLクエリを実行しましたが、その復習です。
$ heroku pg:psql
でpostgresを立ち上げて
DATABASE=> select * from reservations;
で全予約データを表示させ、
DATABASE=> delete from reservations where id = x;
消したいid番号をxに入れ、実行するとそのデータが消えます。
削除処理の大まかな流れ
今回も処理の起点はお客様が削除したい意思をメッセージで送った場合です。「予約キャンセル」というメッセージを受け取ったら処理をスタートさせたいと思います。
処理の大まかな流れは次のようなものです。
1.「予約キャンセル」というメッセージを受け取る
2.次回予約があるかどうかを確認する
→ある場合は、4へ
→ない場合は、3へ
3.「次回予約はありません」といったメッセージをリプライする
4.「??月??日 ??時〜 "メニュー" の予約をキャンセルしますか?」といった確認メッセージをリプライする
5.「はい」で返ってきたpostbackイベントを処理する。処理としては、データベースからの対象予約データの削除。
handleMessageEventの処理追加実装
handleMessageEventの中身を追加実装です。
else if(text === '予約キャンセル'){
const nextReservation = await checkNextReservation(ev);
if(nextReservation.length){
console.log('次回予約があります');
}else{
console.log('次回予約なし');
}
}
ひとまずこんなコードを作っておきます。checkNextReservationは前回作った未来の予約があるかどうかを確認する関数でした。このように共通で使うコードは関数として外出ししておくと使い回しができるのです。
もし予約があれば、nextReservationに予約オブジェクトが入った配列が返ってきて、予約がなければ何も返ってこない、それを判別してターミナルにメッセージをconsole.logする簡単なプログラムです。
しかし、前回のcheckNextReservationでは未来の予約の有無での処理になっていませんので、checkNextReservationを次のように書き換えます。
const checkNextReservation = (ev) => {
return new Promise((resolve,reject)=>{
const id = ev.source.userId;
const nowTime = new Date().getTime();
const selectQuery = {
text: 'SELECT * FROM reservations WHERE line_uid = $1 ORDER BY starttime ASC;',
values: [`${id}`]
};
connection.query(selectQuery)
.then(res=>{
if(res.rows.length){
const nextReservation = res.rows.filter(object=>{
return parseInt(object.starttime) >= nowTime;
});
console.log('nextReservation:',nextReservation);
resolve(nextReservation);
}else{
resolve();
}
})
.catch(e=>console.log(e));
});
}
connection.query.then(res=>{ })の中に、
if(res.rows.length){
・・・・
}else{
・・・・
}
を追加しました。これは、データベースからデータを抜き出す命令に対し、予約データが返ってきたか、返ってこないかの判別をするためです。
プログラムのチェック
ここまで出来たらプログラムのチェックです。herokuへデプロイし、heroku logs --tailでログを立ち上げましょう。
スマホのLINEにて「予約キャンセル」をメッセージで送ります。
コンソールで「次回予約があります」や「次回予約なし」が表示されましたでしょうか。
heroku pg:psqlでデータベースを立ち上げ、DELETE文でデータ削除をしたりしながら色々試してみてください。
削除確認リプライの実装
ではhandleMessageEvent関数の中身を実装していきます。
こんなメッセージをリプライしたいです。Flex Message Simulatorでこんな確認メッセージを作成しましょう。
else if(text === '予約キャンセル'){
const nextReservation = await checkNextReservation(ev);
if(nextReservation.length){
const startTimestamp = parseInt(nextReservation[0].starttime);
const menu = MENU[parseInt(nextReservation[0].menu)];
const date = dateConversion(startTimestamp);
const id = parseInt(nextReservation[0].id);
return client.replyMessage(ev.replyToken,{
"type":"flex",
"altText": "cancel message",
"contents":
{
"type": "bubble",
"body": {
"type": "box",
"layout": "vertical",
"contents": [
{
"type": "text",
"text": `次回の予約は${date}から、${menu}でおとりしてます。この予約をキャンセルしますか?`,
"size": "lg",
"wrap": true
}
]
},
"footer": {
"type": "box",
"layout": "horizontal",
"contents": [
{
"type": "button",
"action": {
"type": "postback",
"label": "予約をキャンセルする",
"data": `delete&${id}`
}
}
]
}
}
});
}else{
return client.replyMessage(ev.replyToken,{
"type":"text",
"text":"次回予約は入っておりません。"
});
}
}
まず初めに、checkNextReservation関数で次回の予約データを取得してます。「予約確認」イベントで使った関数をそのまま使い回し出来ますよね。
ボタンのイベント種別はpostbackです。そして、postbackのdataには`delete&${id}`としています。これは「予約をキャンセルする」ボタンがタップされた時に、deleteでイベントの振り分けをします。また、idは予約データをテーブルへインサートする際に、自動で割り振られたもので、データごとに唯一の値となっています。なので、予約データのidを渡してあげればどのデータを削除するのかを特定することが出来ます。
handlePostbackEvent関数内の実装
else if(splitData[0] === 'delete'){
const id = parseInt(splitData[1]);
const deleteQuery = {
text:'DELETE FROM reservations WHERE id = $1;',
values:[`${id}`]
};
connection.query(deleteQuery)
.then(res=>{
console.log('予約キャンセル成功');
client.replyMessage(ev.replyToken,{
"type":"text",
"text":"予約をキャンセルしました。"
});
})
.catch(e=>console.log(e));
}
postback.dataは`delete&${id}`としましたので、split('&')で分割し、splitData[0]で処理の場合分け、そしてsplitData[1]に予約データのidが入っているので、それを整数型へパースします。
クエリ文はDELETE文で、テーブルからidが一致するものをテーブルから削除します。
削除したら予約キャンセルのメッセージをリプライします。
ここまで実装したら、デプロイし、確認してみましょう。
念の為、データテーブルから予約データが削除出来ているか確認してみましょう。
heroku pg:psql
でheroku postgresqlへ接続し、
DATABASE=> select * from reservations;
予約データが削除されているはずです。
さて、今回はここまでにしましょう。
次回はリッチメニューを作成してみたいと思います。
少しでも参考になりましたら、「スキ」をいただけると幸いです。
最後までお読みいただき、ありがとうございます。
MENTA でLINEBOT開発サポートをしております。お気軽にご相談ください。
この記事が気に入ったらサポートをしてみませんか?