iT邦幫忙

1

💳 用 n8n 將信用卡消費資料寫入 Google Sheets:過程與踩雷記錄

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20251111/20155103qBFSueMBM0.png

在前一階段,我已完成 開啟加密PDF、帳單轉文字、GPT 解析內容與 LINE 通知流程。這篇文章主要記錄下一步──如何用 n8n 把解析後的帳單資料自動寫入 Google Sheets,並分享建立 Google 憑證、節點設定、以及踩雷與排錯的經驗。

https://ithelp.ithome.com.tw/upload/images/20251111/20155103f5mmL1ed3K.png

https://ithelp.ithome.com.tw/upload/images/20251111/201551034yR7sblo8g.png


🧠 一、建立 Google OAuth 憑證:從雲端 Console 到 n8n Credential

為了讓 n8n 能動態建立工作表、寫入資料,第一步就是設定 Google OAuth。

建立流程概述

  1. 進入 Google Cloud Console
    建立一個新專案,啟用 Google Sheets APIGoogle Drive API

  2. 建立 OAuth Client

    • 類型:Web application
    • 在 Authorized redirect URIs 欄位,貼上 n8n 給的網址,例如:
      https://n8n.yourdomain.com/rest/oauth2-credential/callback
      
  3. 設定 Scopes
    建議至少加入以下兩個:

    • https://www.googleapis.com/auth/spreadsheets
    • https://www.googleapis.com/auth/drive.file
  4. 下載 client ID / secret
    接著回到 n8n → Credentials → 新增 Google OAuth2。
    貼上 client_idclient_secret,點擊 Connect OAuth2 Account 完成授權。

✅ 小提醒:若授權後遇到「invalid redirect URI」錯誤,代表 Google Cloud 的 URI 未更新。重新貼上 n8n 提供的完整網址即可。


🧩 二、n8n workflow 架構:從 JSON 到 Sheets

這個流程承接前一階段的 GPT 輸出,主要步驟如下:

  1. Function 節點:解析 JSON

    • 將 GPT 輸出的字串透過 JSON.parse() 轉成物件。
    • 移除 ```json 或多餘空白。
    return [{
      ...JSON.parse($json["output"].replace(/```json|```/g, "").trim())
    }]
    
  2. HTTP Request 節點:建立 Sheet

    • 呼叫 Google Sheets API 的 batchUpdate
    • 傳入 JSON 內容如下:
    {
      "requests": [
        {
          "addSheet": {
            "properties": {
              "title": "2024-09_Richart"
            }
          }
        }
      ]
    }
    
  3. Merge 節點:確保建立完成再寫入

    • 因為建立 sheet 需要時間,若馬上執行 append 可能會報錯。
    • 我使用 Merge 節點(Wait for Both Inputs),確保「建立表單」與「準備資料」都完成後,才進入下一步。
  4. Split In Batches

    • all_transactions 陣列展開為多筆 item。
  5. Google Sheets 節點:Append Row

    • 以「Map Each Column Manually」設定欄位。
    • 例如:
欄位名稱 Expression
date {{$json["date"]}}
description {{$json["description"]}}
amount_twd {{$json["amount_twd"]}}
currency {{$json["currency"]}}
statement_month {{$json["statement_month"]}}

⚠️ 三、踩雷實錄與排錯心得

1. JSON parameter needs to be valid JSON

常見原因是「半 JSON 半 Expression」的混用。
建議二選一:

模式 範例
Full Expression ={{ { "title": $json["sheet_name"] } }}
JSON + Expression { "title": "{{$json["sheet_name"]}}" }

2. [object Object] 出現在預覽值

代表某欄位被當成字串輸出物件。
在 Expression 裡可用:

{{ JSON.stringify($json["sheetInfo"], null, 2) }}

3. "Invalid value at 'requests[0].add_sheet.properties' (title)"

我原本把整個物件塞進 title 欄位,例如:

"title": { "month": "2024-09" }

但 API 預期的是純字串。
修正方式:

={{ $json["statement_month"] + "_" + $json["bank"] }}

4. OAuth scope 不足或過期

當授權時忘記勾選 Sheets / Drive 權限,API 會回傳 403。
重新授權並檢查 scope 是最有效的解法。


🔄 四、使用 Merge 節點確保順序執行

這是我後來才意識到的重要環節。
若 workflow 同時建立 Sheet 與插入資料,n8n 可能並行處理,導致:

“The specified sheet does not exist.”

解法:
在建立 sheet 的節點與資料輸出節點之間,插入 Merge 節點,選擇:

Mode: Wait → Combine Inputs

💬 五、實用的 GPT Prompt

  1. 檢查 n8n Expression 是否為有效 JSON

    「這是我在 n8n 用於 Google Sheets API 的 Expression:={{ ... }}。請幫我確認是否是有效 JSON,並指出可能造成 JSON parameter needs to be valid JSON 的原因。」

  2. 幫我設計欄位 mapping

    「我有一份信用卡交易 JSON,要寫入 Google Sheets。請幫我列出適合分析的欄位英文名稱、說明與建議資料型態。」


📊 六、成果與延伸應用

目前每份信用卡帳單被解析後,n8n 都會:

  • 自動建立對應月份的 Google Sheet
  • 插入所有交易明細
  • 以月份命名工作表(例如 2024-09_Richart

🎬 同場加映:自動統計所有工作表總額

當每月帳單自動生成後,我想做一個「總覽頁」,輸入月份即可抓取該月份表的加總。

https://ithelp.ithome.com.tw/upload/images/20251111/20155103eZjcTV97Xk.png

🧩 公式起點

=SUM("A2"!B2:B999)

這樣寫不會動,因為 "A2" 被視為文字。

✅ 正確解法

=SUM(INDIRECT("'" & A2 & "'!B2:B999"))

說明

元件 功能
A2 工作表名稱儲存格
& 串接字串
"'!B2:B999" 範圍引用
INDIRECT() 轉成實際引用
' 保護表名含空白

🚫 問題:表不存在時報錯

=IFERROR(SUM(INDIRECT("'" & A2 & "'!B2:B999")), "")

功能解釋

函數 功能
IFERROR() 出錯顯示空白
SUM(INDIRECT(...)) 動態加總
"" 錯誤時顯示空白

🗓 延伸:日期轉文字格式

=TEXT(A2, "yyyy-mm")

若要含引號輸出:

="\"\"\"\"\" & TEXT(A2, "yyyy-mm") & "\"\"\"\"\"

🧮 最終版本

=IFERROR(SUM(INDIRECT("'" & TEXT(A2,"yyyy-mm") & "'!B2:B999")), "")

這樣即使表單名稱依月份命名,也能自動抓取正確範圍,表不存在時不報錯。


🏁 小結

這段「同場加映」的總額統計公式,讓我能在試算表首頁快速查看每月總支出。
整體流程:
📩 帳單 → GPT 解析 → n8n 寫表 → 總額自動統計,完全自動化。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言