有些咖啡廳,我離開時明明覺得「下次還會再來」,過一陣子卻只記得大概在哪一區、桌子似乎滿好坐,店名完全想不起來。
更尷尬的是,這些店可能就是我的 LINE Cafe Bot 推薦的。
前幾次更新,我讓 Bot 記住偏好、安排時間,也用 Rich Menu 把常用功能放到聊天室底部。從找店到真的出發,流程已經愈來愈完整。但人去過咖啡廳、喝完咖啡之後,Bot 和這次經驗就斷線了。
它知道我曾經說過喜歡安靜、有插座,卻不知道哪間店我真的去過,也不知道實際坐下來之後,我到底喜不喜歡。
所以這次我先補上「去過之後」的第一段流程:咖啡足跡、1~5 分評分,以及可以複選的體驗標籤。
上一篇 Rich Menu 的開發記錄在這裡:Bot 功能都做好了,我卻忘了怎麼用:用 Codex App 和 Sol 替 LINE Cafe Bot 補上 Rich Menu。上一篇解決「功能找不找得到」,這次則繼續往後問:用完之後,留下了什麼?
我不想把記錄咖啡廳變成寫心得作業,所以最後的操作很短:
標籤可以複選。如果一間店既安靜又有插座,我可以連續點兩次,再按完成。
之後只要輸入:
我的咖啡足跡
Bot 就會用 Flex Message 顯示最近的紀錄,包括店名、星等、體驗標籤、日期和 Google Maps 連結。
這套流程沒有要求使用者寫一段自然語言評論。不是因為文字沒有價值,而是我現在真正想留下的資料很明確:喜不喜歡、安不安靜、有沒有插座、適不適合工作,以及想不想再訪。
先把最容易留下、之後也真的用得到的回饋做好,比做一個最後沒人想填的完整表單更實際。

推薦卡片上的按鈕沒有直接放完整店名和 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}
這個結構讓查詢「我的咖啡足跡」很直接,也不需要先在所有人的紀錄中篩選使用者。
LINE Quick Reply 有一個行為需要特別處理:使用者點下一個按鈕後,原本那排按鈕就會消失。
如果第一次點「安靜」後只回覆一句「已加入」,使用者就沒辦法繼續選「有插座」。
所以每次新增標籤後,Bot 都會重新回覆目前狀態和同一組按鈕:
已評為 ★★★★★
體驗標籤:安靜、有插座
可以加入多個標籤;選好後按「完成紀錄」。
後端則用 Firestore transaction 更新標籤,並用 Set 去除重複內容。即使同一個標籤點兩次,也不會存成兩份;同時快速操作時,也比較不容易互相覆蓋。
畫面上像是一個簡單的複選介面,背後其實是每次 Postback 都重新讀取、更新,再產生下一組 Quick Reply。

雖然這個 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