Jaba LINE Bot 是呷爸 AI 午餐訂便當系統的 LINE 介面,讓使用者可以直接在 LINE 中與 AI 對話點餐。

這個專案是 jaba 核心系統 的延伸,透過 LINE Messaging API 將點餐功能帶入最常用的通訊軟體中。


為什麼做這個?

jaba 系統本身是一個網頁應用,但每次點餐都要打開瀏覽器略顯麻煩。既然大家每天都在用 LINE,何不讓點餐對話直接在 LINE 中進行?

使用情境

  • 個人聊天:設定個人偏好(「叫我小明」「我不吃辣」)
  • 群組聊天:說「開單」開始群組點餐,成員直接喊餐點名稱

系統架構

┌─────────────────┐     HTTPS      ┌─────────────────┐     HTTP      ┌─────────────────┐
│   LINE 使用者    │ ────────────> │  LINE Platform  │ ────────────> │   Render        │
│  (手機/電腦)     │ <──────────── │   (webhook)     │ <──────────── │  (jaba-line-bot)│
└─────────────────┘                └─────────────────┘               └────────┬────────┘
                                                                              │
                                                                              │ HTTPS
                                                                              │ (API Key)
                                                                              ▼
                                   ┌─────────────────┐               ┌─────────────────┐
                                   │   jaba 系統      │ <──────────── │   nginx         │
                                   │  (AI 點餐核心)   │               │  (API Gateway)  │
                                   └─────────────────┘               └─────────────────┘

核心元件

元件 說明 部署位置
LINE Bot 接收/回覆 LINE 訊息 Render (雲端)
jaba 系統 AI 點餐核心邏輯 本地伺服器
nginx API Gateway、流量分流 本地伺服器

功能特色

  • 1對1 聊天:設定個人偏好(名稱、飲食限制),在群組點餐時自動套用
  • 群組點餐 Session:群組專屬點餐流程,訂單獨立管理
  • 白名單機制:僅啟用的使用者/群組可使用
  • 自動清理:Bot 被踢出群組或使用者封鎖時,自動清除相關資料

群組點餐流程

這是最主要的功能,讓群組成員可以快速完成團體訂餐:

1. 說「開單」→ 開始群組點餐,顯示今日菜單
2. 成員直接說餐點(如「雞腿便當」「珍奶 微微 L」)
3. 支援跟單:「+1」「我也要」
4. 說「菜單」→ 查看今日菜單
5. 說「目前訂單」→ 查看點餐狀況
6. 說「收單」或「結單」→ 結束點餐,顯示訂單摘要

群組指令

指令 說明
開單 開始群組點餐,自動顯示今日菜單
收單 / 結單 結束點餐,顯示訂單摘要
菜單 查看今日可點的菜單
目前訂單 查看目前點餐狀況
+1 / 我也要 跟單(點和上一個人相同的餐點)
@jaba 呷爸 顯示狀態和可用指令說明

飲料縮寫

支援常見的飲料點法縮寫:

縮寫 意思
微微 微糖微冰
少少 少糖少冰
半半 半糖半冰
全全 全糖全冰

例如:「珍奶 微微 L」= 珍珠奶茶 微糖微冰 大杯

觸發方式

情境 觸發方式
1對1 聊天 偏好設定相關訊息(點餐請透過群組)
群組(未點餐) 開單菜單@jaba 呷爸、啟用密碼
群組(點餐中) 所有訊息都會處理(AI 過濾非訂餐訊息)

白名單 + 密碼啟用

為了控制使用權限,採用密碼啟用機制:

  1. 管理員設定啟用密碼(環境變數 REGISTER_SECRET
  2. 使用者在 LINE 中輸入密碼
  3. 系統自動將使用者/群組加入白名單
  4. 之後即可正常使用點餐功能

自動移除機制

  • Bot 被踢出群組 → 自動移除該群組白名單
  • 使用者封鎖 Bot → 自動移除該使用者白名單
使用者:(輸入密碼)
Bot:🎉 啟用成功!現在你可以使用點餐功能了。

技術棧

技術 用途
Flask Web 框架,處理 Webhook
line-bot-sdk v3 LINE Messaging API SDK
Render 雲端部署平台(免費 HTTPS)
requests HTTP 客戶端,呼叫 jaba API

開發重點

1. Webhook 驗證

LINE Platform 會在每個請求加上 X-Line-Signature,需驗證以防偽造:

@app.route("/callback", methods=["POST"])
def callback():
    signature = request.headers.get("X-Line-Signature", "")
    body = request.get_data(as_text=True)

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return "OK"

2. 群組 Session 機制

群組使用 Session 機制控制回應:

def should_respond(event, user_text):
    # 1對1 聊天:永遠回應
    if event.source.type == "user":
        return True, user_text

    # 群組:使用 Session 機制
    group_id = event.source.group_id
    text_stripped = user_text.strip()

    # 檢查群組是否在點餐中
    is_ordering = check_group_session(group_id)

    if is_ordering:
        # 點餐中:所有訊息都轉發給 jaba(AI 會過濾非訂餐訊息)
        return True, user_text
    else:
        # 非點餐中:只回應特定指令
        if text_stripped in ["開單", "菜單"]:
            return True, user_text
        # 還會檢查:啟用密碼、@呷爸/@jaba 等(簡化省略)
        return False, user_text

這樣的好處:

  • 點餐中不用每則訊息都加關鍵字
  • AI 會自動過濾閒聊,只回應訂餐相關訊息
  • 非點餐時不會被無關訊息打擾

3. API Key 保護

外部請求 jaba API 需攜帶 API Key,nginx 負責驗證:

def get_jaba_headers():
    headers = {"Content-Type": "application/json"}
    if jaba_api_key:
        headers["X-API-Key"] = jaba_api_key
    return headers

環境變數

變數 必要 說明
LINE_CHANNEL_SECRET LINE Channel Secret
LINE_CHANNEL_ACCESS_TOKEN LINE Channel Access Token
JABA_API_URL jaba API 網址(未設定則為 Echo 模式)
JABA_API_KEY API 驗證金鑰
REGISTER_SECRET 啟用密碼

部署到 Render

專案包含 render.yaml,可一鍵部署:

  1. Fork 專案到自己的 GitHub
  2. 在 Render 建立新 Web Service,連結 GitHub repo
  3. 設定環境變數
  4. 部署完成後取得 URL(如 https://jaba-line-bot.onrender.com
  5. 到 LINE Developers Console 設定 Webhook URL

專案結構

jaba-line-bot/
├── app.py                      # 主程式
├── requirements.txt            # Python 依賴
├── render.yaml                 # Render 部署設定
├── .env.example                # 環境變數範本
├── nginx-config-for-server.conf # nginx 設定參考
├── docs/                       # 詳細文件
│   ├── architecture.md         # 系統架構
│   ├── line-setup.md           # LINE 設定
│   ├── deployment.md           # 部署指南
│   ├── jaba-integration.md     # jaba 整合
│   └── configuration.md        # 環境變數
└── openspec/                   # OpenSpec 規格文件
    ├── specs/                  # 功能規格
    └── changes/                # 變更歷史

學到的事

LINE Bot SDK v3 的變化

v3 版本改用 linebot.v3 模組,與舊版差異不小:

# v3 寫法
from linebot.v3 import WebhookHandler
from linebot.v3.messaging import Configuration, ApiClient, MessagingApi

# 需要用 Context Manager
with ApiClient(configuration) as api_client:
    messaging_api = MessagingApi(api_client)
    messaging_api.reply_message(...)

群組中取得使用者名稱

1對1 聊天用 get_profile(user_id) 就好,但群組中要用 get_group_member_profile(group_id, user_id)

if event.source.type == "group":
    profile = messaging_api.get_group_member_profile(
        event.source.group_id, user_id
    )
else:
    profile = messaging_api.get_profile(user_id)

Render 免費方案的限制

  • 閒置 15 分鐘後會休眠
  • 喚醒需要 30-60 秒
  • 第一次訊息可能會因 timeout 失敗,使用者需再發一次

相關連結