iT邦幫忙

2026 iThome 鐵人賽

DAY 15
0
ChatGPT & Codex

這隻 LINE Bot 不是我寫的:30 天讓 Codex 從零幫我做到上線系列 第 15

Day 15 - 推薦完就忘了?我替 LINE Cafe Bot 加上咖啡足跡,記住真正去過的店

  • 分享至 

  • xImage
  •  

有些咖啡廳,我離開時明明覺得「下次還會再來」,過一陣子卻只記得大概在哪一區、桌子似乎滿好坐,店名完全想不起來。

更尷尬的是,這些店可能就是我的 LINE Cafe Bot 推薦的。

前幾次更新,我讓 Bot 記住偏好、安排時間,也用 Rich Menu 把常用功能放到聊天室底部。從找店到真的出發,流程已經愈來愈完整。但人去過咖啡廳、喝完咖啡之後,Bot 和這次經驗就斷線了。

它知道我曾經說過喜歡安靜、有插座,卻不知道哪間店我真的去過,也不知道實際坐下來之後,我到底喜不喜歡。

所以這次我先補上「去過之後」的第一段流程:咖啡足跡、1~5 分評分,以及可以複選的體驗標籤。

上一篇 Rich Menu 的開發記錄在這裡:Bot 功能都做好了,我卻忘了怎麼用:用 Codex App 和 Sol 替 LINE Cafe Bot 補上 Rich Menu。上一篇解決「功能找不找得到」,這次則繼續往後問:用完之後,留下了什麼?

一次造訪,只需要幾個按鈕

我不想把記錄咖啡廳變成寫心得作業,所以最後的操作很短:

  1. 分享位置,取得附近咖啡廳推薦。
  2. 在店家卡片上點「記錄這次造訪」。
  3. 選擇 1~5 分。
  4. 加入「安靜」、「有插座」、「適合工作」或「想再訪」標籤。
  5. 點「完成紀錄」。

標籤可以複選。如果一間店既安靜又有插座,我可以連續點兩次,再按完成。

之後只要輸入:

我的咖啡足跡

Bot 就會用 Flex Message 顯示最近的紀錄,包括店名、星等、體驗標籤、日期和 Google Maps 連結。

這套流程沒有要求使用者寫一段自然語言評論。不是因為文字沒有價值,而是我現在真正想留下的資料很明確:喜不喜歡、安不安靜、有沒有插座、適不適合工作,以及想不想再訪。

先把最容易留下、之後也真的用得到的回饋做好,比做一個最後沒人想填的完整表單更實際。

https://ithelp.ithome.com.tw/upload/images/20260826/20183556WfhxWLOqMN.png

推薦卡片怎麼知道我記錄的是哪間店?

推薦卡片上的按鈕沒有直接放完整店名和 Google Maps URL,而是沿用前一版 Datetime Picker 的短期搜尋 session。

按下「記錄這次造訪」時,LINE 傳回的 Postback data 類似:

v=1&a=visit&s=searchSessionId&c=2
  • a=visit 代表建立造訪紀錄。
  • s 是這次搜尋的 session ID。
  • c=2 代表本次推薦中的第二間店。

後端收到後,先到 Firestore 找回當時的搜尋資料,再確認 session 是否仍有效、是不是原本的使用者、是不是同一個聊天室,以及第二間店是否真的存在。

驗證通過後,才會建立一筆 30 分鐘有效的足跡草稿,接著請使用者評分。

這樣做比把完整資料塞進按鈕安全,也讓同一個搜尋 session 可以同時支援「安排時間」和「記錄造訪」兩種操作。

為什麼要先建立草稿,再完成紀錄?

評分和標籤不是一次回傳,而是好幾次 LINE Postback。如果每按一下就直接當成永久紀錄,使用者點到一半離開,資料庫裡就會留下很多不知道算不算完成的內容。

所以我把狀態分成兩種:

draft → completed

草稿會保存店家、使用者、聊天室、評分和目前選到的標籤,並帶有 30 分鐘期限。只有按下「完成紀錄」後,狀態才會改成 completed,同時移除草稿期限。

資料放在每個 LINE 使用者自己的 Firestore 子集合:

cafe-user-journeys/{lineUserId}/visits/{journeyId}

這個結構讓查詢「我的咖啡足跡」很直接,也不需要先在所有人的紀錄中篩選使用者。

Quick Reply 原本不是複選,我讓它看起來像複選

LINE Quick Reply 有一個行為需要特別處理:使用者點下一個按鈕後,原本那排按鈕就會消失。

如果第一次點「安靜」後只回覆一句「已加入」,使用者就沒辦法繼續選「有插座」。

所以每次新增標籤後,Bot 都會重新回覆目前狀態和同一組按鈕:

已評為 ★★★★★
體驗標籤:安靜、有插座

可以加入多個標籤;選好後按「完成紀錄」。

後端則用 Firestore transaction 更新標籤,並用 Set 去除重複內容。即使同一個標籤點兩次,也不會存成兩份;同時快速操作時,也比較不容易互相覆蓋。

畫面上像是一個簡單的複選介面,背後其實是每次 Postback 都重新讀取、更新,再產生下一組 Quick Reply。

https://ithelp.ithome.com.tw/upload/images/20260826/20183556ln8YqVOTGE.png

群組裡的按鈕,不能誰看到都能完成

雖然這個 Bot 目前主要是我自己使用,我仍保留了群組情境的驗證。

每一個評分、標籤和完成按鈕,都會重新檢查 Journey ID、操作者、聊天室、草稿期限與完成狀態。Postback 的 action、評分範圍和標籤也全部採白名單,像是 0 分、6 分或不存在的標籤,不會直接寫進資料庫。

即使只是個人專案,我還是希望資料邊界在一開始就清楚。因為等資料真的累積起來,再回頭補「這筆到底是誰按的」,通常會更麻煩。

先讓真實體驗留下來

偏好記憶保存的是使用者主動說出的需求;咖啡足跡保存的,則是實際去過之後留下的感受。

現在輸入「我的咖啡足跡」,我看到的不再是一份想去清單,而是自己真的坐過、喝過,甚至願意再回去的地方。

不過,把評分存進 Firestore 還不是終點。如果 Bot 已經知道哪些店我喜歡、哪些體驗對我重要,這些資料應該回到下一次搜尋裡,而不是只躺在歷史列表中。

下一篇,我會接著寫這套足跡如何形成推薦回路:低分店家怎麼被排除、高分標籤怎麼成為柔性線索,以及新版服務如何安全部署到 Cloud Run。

專案開源與完整程式碼

👉 GitHub
https://github.com/zonawang/line-cafe-journey
👉 更多 LINE Bot 與 AI 實作紀錄: https://github.com/zonawang/zona-ai-learning-lab


上一篇
Day 14 - Bot 功能都做好了,我卻忘了怎麼用:用 Codex App 和 Sol 替 LINE Cafe Bot 補上 Rich Menu
下一篇
Day 16 - 記錄不是終點:我讓咖啡足跡回頭影響 LINE Bot 的下一次推薦
系列文
這隻 LINE Bot 不是我寫的:30 天讓 Codex 從零幫我做到上線16
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言