前幾天的 SubWise 已經可以建立訂閱、查看所有訂閱、修改消費、刪除消費、分析消費、分析訂閱。但仔細想想,這些功能其實都有一個共同點:都是使用者主動問,系統才回答。
如果我知道自己有 Netflix、Spotify、ChatGPT Plus 等訂閱,真正實用的功能其實是:「最近有沒有什麼訂閱快要扣款?」因此今天 Day 25,我想讓 SubWise 多一點「管家」的感覺。今天要完成的功能就是:找出未來 7 天內即將扣款的 Active 訂閱,並透過 LINE 顯示提醒。
第一個重點是新增 get_upcoming_subscriptions(records, days=7),責任很單純:從既有訂閱資料中,找出指定天數內即將扣款的 Active 訂閱。一開始先讓它只負責資料處理,不碰 LINE——資料篩選 → 獨立測試 → 確認正確 → 再接 LINE,而不是一開始就把所有東西混在一起。
訂閱資料裡有 Status 欄位,因此特別加入 Active 篩選:
status = str(record.get("Status", "")).strip().lower()
if status != "active":
continue
這裡特別做了 .strip().lower(),是因為 Google Sheets 裡的資料可能出現「Active」「active」「 Active」等不同寫法,如果直接比較字串很容易造成不必要的漏判,先統一格式再判斷會比較穩定。
取得今天日期後計算結束日期:
today = date.today()
end_date = today + timedelta(days=days)
判斷條件是 today < billing_date <= end_date,這裡有一個細節值得注意:要的是「明天~未來第 7 天」,而不是「今天~未來第 7 天」,所以用 today < 而不是 today <=,避免把今天就要扣款的訂閱漏算或重複判斷。
找到符合條件的訂閱後,不只顯示日期,也直接在 Python 算出距離天數,並放回訂閱資料裡:
days_until = (billing_date - today).days
subscription = record.copy()
subscription["days_until"] = days_until
這樣後面的格式化函式就可以直接使用,不需要在顯示層重新計算一次。
在真正連 Google Sheets 之前,先用測試資料驗證:三筆訂閱中,一筆是 Inactive、兩筆是 Active,執行後成功只找出兩筆 Active 訂閱,Inactive 的那筆被正確排除,代表「只有 Active 訂閱會進入提醒清單」這個條件已經成立。
建立 format_upcoming_subscriptions(records),把資料轉成 LINE 訊息:days_until == 1 顯示「🔔 明天扣款」,days_until > 1 顯示「📅 X 天後扣款」,最後組合成完整的提醒訊息。這裡同樣把「資料處理」與「畫面呈現」分開。
Python 已經會找即將扣款的訂閱了,但使用者不會輸入 upcoming=true,只會自然地說「最近有哪些訂閱要扣款?」因此讓 Gemini 判斷出:
{
"type": "query",
"target": "subscription",
"period": "all",
"keyword": null,
"category": null,
"upcoming": true
}
這裡維持一貫的架構原則:**Gemini 負責理解使用者想做什麼,Python 負責真正操作資料。**其中最重要的是 upcoming: true 這個欄位,代表使用者不是單純想看訂閱,而是想找「即將扣款」的訂閱。
測試時也發現一個有意思的地方——period 回傳的是 all 而不是 week,因為目前的設計是讓 upcoming 成為明確的功能旗標:upcoming = false 時依 period 做一般查詢,upcoming = true 時直接走 get_upcoming_subscriptions(days=7) 的特殊流程,不需要強迫 Gemini 同時輸出 period = week。
讓 query_data(data) 知道 upcoming = True 時要走特殊流程:target == subscription 且 upcoming == True 就走「取得訂閱 → 找未來 7 天 → 格式化提醒」,否則走一般訂閱查詢。這樣「一般訂閱查詢」和「即將扣款提醒」就可以共存。
新增功能最怕的就是「新功能做好了,但舊功能壞掉」,因此又實際測試「我有哪些訂閱?」,確認 LINE 依然正常回傳全部 9 筆訂閱,代表新增 upcoming 並沒有破壞原本的 Query。
一開始 Google Sheets 中沒有未來 7 天內的扣款,輸入「最近有哪些訂閱要扣款?」,SubWise 正確回覆「🔔 最近 7 天沒有即將扣款的訂閱。」
為了確認提醒真的能被觸發,暫時把 Netflix 的下一次扣款日期改成 2026-08-28(今天是 2026-08-26,距離扣款 2 天),再次測試同樣的問句,這次成功得到:
⏰ 即將扣款提醒
📌 Netflix
💰 費用:NT$390
📅 扣款日:2026-08-28
📅 2 天後扣款

代表整條流程終於完整跑通。測試結束後,把測試日期恢復成原本的 2026-09-25,避免測試資料留在正式資料中。
今天再次體會到 Vibe Coding 很容易遇到的一件事:**程式看起來合理,不代表整個系統真的正常。**因此今天分成四層依序驗證:
days_until 計算是否正確upcoming: true
query_data() 能不能正確呼叫即將扣款流程這種分層測試方式,讓除錯變得容易很多——每一層出問題時,都能很快定位是哪一層的邏輯出錯,而不用每次都從頭排查整條鏈路。
upcoming 意圖判斷(自然語言 → upcoming: true 旗標)days_until)明天 Day 26 不是開發新的財務功能,而是把目前已經做好的能力整理給使用者。例如使用者輸入 help,SubWise 可以讓第一次使用的人直接看到完整的功能導覽,這一步不是增加功能的深度,而是降低第一次使用者的門檻——讓已經做好的十幾天成果,第一次被整理成一個「看得懂、敢開始用」的入口。我們明天見!