這個專案可讓你把收據照片傳給 LINE Bot,系統會自動:
- 下載 LINE 圖片訊息
- 用 OpenAI 視覺模型辨識收據 / 發票內容
- 抽出日期、店家、憑證編號、總計、品項等欄位
- 寫入 Google Sheets
- 自動維護
登錄者ID -> 登錄者對照表
目前的 prompt 已經擴充為優先支援:
- 韓國收據
- 台灣一般收據
- 台灣電子發票 / 發票
程式會自動建立或修正四個工作表:
expenses- 欄位:
登錄日期, 登錄者, 登錄者ID, 憑證編號, 日期, 店家, 品項, 交易類型, 數量, 單價, 複價, 複價(台幣), 總計, 幣別, 退稅狀態, 退稅金額, 退稅說明, LINE事件ID, LINE訊息ID
- 欄位:
user_mapping- 欄位:
登錄者ID, 登錄者
- 欄位:
processed_events- 欄位:
LINE事件ID, LINE訊息ID, 使用者ID, 狀態, 首次接收時間, 最後更新時間, 寫入列數, 錯誤訊息
- 欄位:
category_analysis- 主表欄位:
登錄者, 交易類型, 金額台幣, 圖表標籤 - 右側會另外產生總計表:
總計對象, 總金額台幣, 圖表標籤 - 會自動建立各登錄者與整體的交易類型金額圓餅圖,以及各登錄者總消費比較長條圖
- 主表欄位:
同一張收據若有多個品項,會寫入多列;總計 會重複出現在該張收據的每一列。
韓國收據的 店家 與 品項 會顯示為 中文翻譯(韓文原文)。
登錄日期 會依票據地區自動決定時區:
- 韓國收據:
Asia/Seoul - 台灣收據 / 台灣發票:
Asia/Taipei - 其他或無法判斷:使用
APP_TIMEZONE
可使用 .env 或 Render 的環境變數 / Secret File:
LINE_CHANNEL_SECRET=
LINE_CHANNEL_ACCESS_TOKEN=
OPENAI_API_KEY=
OPENAI_MODEL=gpt-4.1-mini
GOOGLE_SHEET_ID=
GOOGLE_SERVICE_ACCOUNT_JSON=/etc/secrets/google-service-account.json
GOOGLE_SERVICE_ACCOUNT_JSON_CONTENT=
APP_TIMEZONE=Asia/Taipei
FX_RATE_TWD_TO_TWD=1
FX_RATE_KRW_TO_TWD=0.024
FX_RATE_USD_TO_TWD=32GOOGLE_SERVICE_ACCOUNT_JSON 可填:
- 本機或 Render Secret File 的檔案路徑
- 直接貼完整 JSON 字串
GOOGLE_SERVICE_ACCOUNT_JSON_CONTENT 可直接放 JSON 內容,若同時設定,會優先使用它。
FX_RATE_* 用來把明細複價換算成台幣,並提供 category_analysis 工作表統計與圖表使用。
Windows PowerShell:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
Copy-Item .env.example .env
uvicorn app.main:app --host 0.0.0.0 --port 8000macOS / Linux:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
uvicorn app.main:app --host 0.0.0.0 --port 8000本機測試時可搭配 ngrok:
ngrok http 8000Webhook URL 設為:
https://<你的對外網址>/callback
- 在 LINE Developers 建立 Messaging API channel。
- 取得
LINE_CHANNEL_SECRET與LINE_CHANNEL_ACCESS_TOKEN。 - 在 LINE Official Account Manager 關閉會干擾測試的自動回覆功能。
- 在 LINE Developers 設定 Webhook URL 為
/callback。 - 先用 Verify 測試 webhook 是否成功。
- 建立 Google Cloud Service Account。
- 啟用 Google Sheets API。
- 下載 Service Account JSON 金鑰。
- 將目標 Google Sheet 分享給 service account email,權限設為可編輯。
- 記下 Google Sheet URL 中的 Sheet ID,填入
GOOGLE_SHEET_ID。 - 本機可把 JSON 放在本機檔案並設定路徑;Render 可改用 Secret File。
這個 repo 已附上 render.yaml 與 .python-version,建議用 Render Web Service 部署。
Render 建議設定:
- Runtime:
Python - Build Command:
pip install -r requirements.txt - Start Command:
uvicorn app.main:app --host 0.0.0.0 --port $PORT - Health Check Path:
/health
Render 上需要設定的值:
LINE_CHANNEL_SECRETLINE_CHANNEL_ACCESS_TOKENOPENAI_API_KEYOPENAI_MODELGOOGLE_SHEET_IDAPP_TIMEZONEFX_RATE_TWD_TO_TWDFX_RATE_KRW_TO_TWDFX_RATE_USD_TO_TWD
Google 憑證有兩種做法:
- Secret File
- 在 Render 的 Environment > Secret Files 上傳 JSON
- 檔名建議用
google-service-account.json GOOGLE_SERVICE_ACCOUNT_JSON設成/etc/secrets/google-service-account.json
- Environment Variable
- 將完整 JSON 內容貼到
GOOGLE_SERVICE_ACCOUNT_JSON_CONTENT
- 將完整 JSON 內容貼到
- 使用者把收據照片或發票照片傳給 LINE Bot。
- Webhook 先快速回應 LINE,避免逾時。
- 背景程序抓取圖片、呼叫 OpenAI 做辨識。
- 系統先用
webhookEventId與message.id做去重,避免 redelivery 重複入帳。 - 系統更新
user_mapping工作表中的使用者名稱。 - 系統把辨識結果逐列寫入
expenses,包含交易類型與複價(台幣)。 - 系統自動重算
category_analysis工作表與圓餅圖。 - Bot 再主動 push 一則摘要訊息給使用者。
手動維護使用者名稱:
POST /manual-register/{user_id}?name=王小明手動重算分析工作表:
POST /refresh-analysis健康檢查:
GET /health若環境變數未設好,/health 會回傳缺少哪些設定。
- 台灣發票若使用民國年,程式會要求模型轉成西元日期。
- 台灣發票號碼會優先抓像
AB12345678這類格式。 - 韓國收據若有 승인번호、거래번호、영수증번호,會盡量作為憑證編號。
- 登錄時間會依辨識出的
source_region或currency自動切換為韓國或台灣時區。 - 韓國收據會將店家與品項顯示為
中文翻譯(原文)。 - 每列明細會自動分類成
餐飲、服飾、交通、住宿、美妝保養、藥妝醫療、超市便利商店、家居雜貨、電子產品、伴手禮禮品、娛樂、服務、其他其中之一。 category_analysis圖表統計使用複價(台幣);若收據沒有逐項明細,會用整筆總計換算台幣後做分類統計。- 韓國退稅欄位為估計值,主要依收據內容、退稅標記與金額門檻判斷;旅客身分、停留時間與實際是否為退稅店,仍需人工確認。
- 已加入 LINE webhook redelivery 去重機制,會同時記錄
LINE事件ID、LINE訊息ID與processed_events工作表。 - 若收據上沒有逐項品項,
items可能為空,但仍會盡量保留總計。 - 模糊、反光、裁切不完整的照片,辨識成功率會明顯下降。