前面已經完成預約的功能,並也能將用戶的預約給記錄下。
那可能有用戶想要更改或取消怎麼辦呢,那接下來就接續設定讓客戶取消。
我會用到這個功能【Buttons template】
到【line-bot-sdk-python:ButtonsTemplate】複製程式碼。
程式碼:
buttons_template_message = TemplateSendMessage(
alt_text='Buttons template',
template=ButtonsTemplate(
thumbnail_image_url='https://example.com/image.jpg',
title='Menu',
text='Please select',
actions=[
PostbackAction(
label='postback',
display_text='postback text',
data='action=buy&itemid=1'
),
MessageAction(
label='message',
text='message text'
),
URIAction(
label='uri',
uri='http://example.com/'
)
]
)
)
接下來,再回去Pycharm的service.py,在前面建立的service_select_event的function上方新增一個function叫做booked。
定義這個function是要判斷用戶是否已經預約過,所以需要帶入event與user的物件。
首先會先搜尋預約資料,搜尋條件(user_id、is_canceled為False(表示尚未被取消)、預約時間(需要大於當下時間)),並透過first回傳第一筆資料為reservation。
接下來就是判斷預約資料,如果有資料就會用到buttons_template_message。
設定完成後,再用reply_message回傳給用戶。
且,如果有預約時,會回傳true反之則回傳false。
在這也又看到ButtonsTemplate出現紅底波浪紋,所以一樣要去line_bot_api.py匯入ButtonsTemplate。
def booked(event, user):
reservation = Reservation.query.filter(Reservation.user_id == user.id,
Reservation.is_canceled.is_(False),
Reservation.booking_datetime > datetime.datetime.now()).first()
if reservation:
buttons_template_message = TemplateSendMessage(
alt_text='Buttons template',
template=ButtonsTemplate(
title='Menu',
text=f'{reservation.booking_service}\nbook time: {reservation.booking_datetime}',
actions=[
PostbackAction(
label='postback',
display_text='postback text',
data='action=canceled'
)
]
)
)
line_bot_api.reply_message(
event.reply_token,
[buttons_template_message])
return True
else:
return False
定義好booked後,再到service_select_event這個function,添加方程式,先去取得資料User的物件,然後再透過booked判斷是否有預約,如果有預約就會回傳給用戶取消的button template的訊息,然後return ture這判斷式成立,就會return,所以就不會在往下執行;如果return false判斷式就會不成立,就不會成立,所以就會繼續往下執行程式。
def service_select_event(event):
user = User.query.filter(User.line_id == event.source.user_id).first()
if booked(event, user):
return
完畢後,就重新啟動SERVER進行測試,若沒問題,這功能也就完成。
重新啟動SEVER進行測試流程:
重啟ngrok,在terminal輸入服務時指令,程式碼:
ngrok http 5000 --region ap
複製Forwarding的網址,到line developers修改Webhook URL,網址貼上後面加上/callback
然後運行APP,
接下來就能操作linebot了。
前面這些只是判斷用戶在未來是否有預約,那接下來就是設置資料取消預約的功能。
在service.py,後面新增一個function叫做service_canceled_event。
搜尋條件(user_id、is_canceled為False(表示尚未被取消)、預約時間(需要大於當下時間)),並透過first回傳第一筆資料為reservation。
判斷預約是否有預約資料,有的話就將is_canceled 改成 True,並存回資料庫,然後用reply_message告知用戶已經完成取消;反之,若無資料就會回傳,尚未預約。
def service_canceled_event(event):
user = User.query.filter(User.line_id == event.source.user_id).first()
reservation = Reservation.query.filter(Reservation.user_id == user.id,
Reservation.is_canceled.is_(False),
Reservation.booking_datetime > datetime.datetime.now()).first()
if reservation:
reservation.is_canceled = True
db.session.add(reservation)
db.session.commit()
line_bot_api.reply_message(
event.reply_token,
[TextSendMessage(text='already canceled')]
)
else:
line_bot_api.reply_message(
event.reply_token,
[TextSendMessage(text='no booked yet')]
)
然後再到,app主程式添加這段方程式,判斷action如果回傳cancel就會呼叫判斷式
elif data.get('action') == 'canceled':
service_canceled_event(event)
再來測試看看資料庫有沒有變化
為了防止用戶反覆預約,我會在service_confirmed_event這個function內在添加個判斷,看是否有預約。
方程式:
if booked(event, user):
return
這樣機器人的取消預約功能都大致上設定完成了。
下一篇,設置機器人管理者查閱權限