Learning Objectives
- 用 QuickReply 與各種動作物件,讓使用者不用打字就能操作
- 設計 postback 的 data,並用 parse_qs 解析,處理 PostbackEvent
- 用 TemplateMessage 傳送 Buttons、Confirm、Carousel 範本
- 依正確的順序建立圖文選單:建立、上傳圖片、設為預設
讓使用者用按的,不用打字
要使用者打出剛好符合的文字,機器人才聽得懂,這很容易出錯,手機上打字也慢。LINE 提供三種放按鈕的地方:
| 功能 | 出現在哪裡 | 適合 |
|---|---|---|
| 快速回覆(Quick Reply) | 輸入框上方,跟著一則訊息出現,用過就消失 | 當下的幾個選項 |
| 範本訊息(Template) | 聊天室裡的一張卡片,一直留在對話中 | 需要說明內容的選擇,例如列出場次 |
| 圖文選單(Rich Menu) | 聊天室下方固定的選單 | 機器人的常用功能 |
三種按鈕都由動作物件決定按下後發生什麼事:
| 動作 | 按下後 | 機器人收到 |
|---|---|---|
MessageAction |
使用者傳出一段文字 | 一般的文字訊息事件 |
PostbackAction |
送出 data,使用者看不到 |
PostbackEvent |
DatetimePickerAction |
跳出時間選擇畫面 | PostbackEvent,時間在 postback.params |
LocationAction |
打開位置畫面(只能用在快速回覆) | 位置訊息事件 |
URIAction |
打開網址 | 沒有事件 |
模擬手機不會真的開網址,也不會打開地圖;位置動作直接送出一個固定的位置。
逐步看:快速回覆與 postback
使用者傳一句話,機器人回一則帶五個按鈕的訊息。接著模擬使用者按下兩個會送出 postback 的按鈕,注意 data 字串怎麼變成可以使用的資料。
設計 postback 的 data
data 是一段由你決定格式的字串,上限 300 字元。常見的寫法是查詢字串:action=book&id=3,用 urllib.parse.parse_qs 就能解析。
寫 on_postback 時要注意:
- 每個值都是串列,而且都是字串。
parse_qs('action=book&id=3')得到{'action': ['book'], 'id': ['3']}。 data只放識別用的資料。 場次名稱、價格這些內容用id從資料庫查,避免data裡的內容和資料庫不一致。- 按鈕可能被按很多次。 範本訊息留在聊天室裡,使用者隔天還是能再按一次,而且那時活動可能已經額滿或結束。處理時要依目前的狀態判斷,不能假設按下去一定是第一次。
快速回覆按鈕在使用者按下後,或聊天室出現新訊息時就會消失(時間選擇與位置按鈕例外,官方寫明這兩種會留到資料送出為止;模擬手機一律收起來)。同一則訊息最多 13 個按鈕。
逐步看:三種範本訊息
三種範本都包在 TemplateMessage 裡,差別只在 template。輸出區第三欄是 alt_text。
圖文選單由三個步驟組成
圖文選單是一張圖片加上「哪個區域對應哪個動作」,圖片裡的按鈕文字是圖片的一部分。建立的順序是固定的:
| 步驟 | SDK 呼叫 | 說明 |
|---|---|---|
| 1. 建立 | MessagingApi.create_rich_menu(RichMenuRequest(...)) |
定義大小與 areas,回傳 rich_menu_id |
| 2. 上傳圖片 | MessagingApiBlob.set_rich_menu_image(...) |
這支 API 在另一個網域(api-data.line.me),所以 SDK 另外有 MessagingApiBlob |
| 3. 設為預設 | MessagingApi.set_default_rich_menu(rich_menu_id) |
所有使用者都會看到;要給個別使用者不同的選單時,個別設定的優先 |
沒有上傳圖片就不能套用,API 會回 400。
圖片格式是 JPEG 或 PNG,寬 800 到 2500 像素、高至少 250 像素、寬除以高至少 1.45、最大 1 MB,以官方規格為準。已上傳的圖片不能替換,要改圖片就得建立新的選單。
圖文選單只需要設定一次,通常寫成一支單獨的設定腳本,不需要 webhook。下面的範例就是這樣;互動練習為了方便才放在程式啟動時,每次重新啟動都會多建立一個選單,真實環境不要這樣做。
動手做:解析 postback 的 data
完成 answer(data),依 data 傳回要回覆的文字:
| data | 回覆 |
|---|---|
action=book&id=3 |
已預約 3 號座位 |
action=cancel&id=7 |
已取消 7 號座位 |
| 其他,包含沒有 action 的字串 | 看不懂這個按鈕 |
hello 這種字串解析後沒有 action,這時直接用 params['action'] 會丟出 KeyError,webhook 就變成 500。
想一想
下面的程式會印出什麼?
from urllib.parse import parse_qs
print(parse_qs('action=book&id=3')['id'])
想讓使用者按下「報名」後,機器人知道是哪一個場次,但聊天室不要出現 action=join&id=2 這段文字。該用哪個動作?
一次回覆三則訊息,每一則都設了 quick_reply。使用者會看到哪些按鈕?
TemplateMessage 的 alt_text 是做什麼用的?
呼叫 set_default_rich_menu 時,LINE 回 400:must upload richmenu image before applying it to user。該怎麼修?
重點整理
- 快速回覆跟著訊息出現,範本是留在聊天室裡的卡片,圖文選單固定在下方
- 三種都用動作物件;
MessageAction產生文字訊息,PostbackAction產生PostbackEvent,data使用者看不到 parse_qs的值是字串組成的串列;按鈕可能重複按,要依目前的狀態判斷- 範本的
alt_text必填,是通知與聊天列表顯示的文字 - 圖文選單的順序:建立、上傳圖片(
MessagingApiBlob)、設為預設
範本訊息的版面是固定的。下一課學 Flex Message,用 JSON 自己排版,做出更符合內容的卡片。