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


為了讓 n8n 能動態建立工作表、寫入資料,第一步就是設定 Google OAuth。
進入 Google Cloud Console
建立一個新專案,啟用 Google Sheets API 與 Google Drive API。
建立 OAuth Client
https://n8n.yourdomain.com/rest/oauth2-credential/callback
設定 Scopes
建議至少加入以下兩個:
https://www.googleapis.com/auth/spreadsheets
https://www.googleapis.com/auth/drive.file
下載 client ID / secret
接著回到 n8n → Credentials → 新增 Google OAuth2。
貼上 client_id 與 client_secret,點擊 Connect OAuth2 Account 完成授權。
✅ 小提醒:若授權後遇到「invalid redirect URI」錯誤,代表 Google Cloud 的 URI 未更新。重新貼上 n8n 提供的完整網址即可。
這個流程承接前一階段的 GPT 輸出,主要步驟如下:
Function 節點:解析 JSON
JSON.parse() 轉成物件。return [{
...JSON.parse($json["output"].replace(/```json|```/g, "").trim())
}]
HTTP Request 節點:建立 Sheet
batchUpdate。{
"requests": [
{
"addSheet": {
"properties": {
"title": "2024-09_Richart"
}
}
}
]
}
Merge 節點:確保建立完成再寫入
Split In Batches
all_transactions 陣列展開為多筆 item。Google Sheets 節點:Append Row
| 欄位名稱 | Expression |
|---|---|
| date | {{$json["date"]}} |
| description | {{$json["description"]}} |
| amount_twd | {{$json["amount_twd"]}} |
| currency | {{$json["currency"]}} |
| statement_month | {{$json["statement_month"]}} |
JSON parameter needs to be valid JSON常見原因是「半 JSON 半 Expression」的混用。
建議二選一:
| 模式 | 範例 |
|---|---|
| Full Expression | ={{ { "title": $json["sheet_name"] } }} |
| JSON + Expression | { "title": "{{$json["sheet_name"]}}" } |
[object Object] 出現在預覽值代表某欄位被當成字串輸出物件。
在 Expression 裡可用:
{{ JSON.stringify($json["sheetInfo"], null, 2) }}
"Invalid value at 'requests[0].add_sheet.properties' (title)"我原本把整個物件塞進 title 欄位,例如:
"title": { "month": "2024-09" }
但 API 預期的是純字串。
修正方式:
={{ $json["statement_month"] + "_" + $json["bank"] }}
當授權時忘記勾選 Sheets / Drive 權限,API 會回傳 403。
重新授權並檢查 scope 是最有效的解法。
這是我後來才意識到的重要環節。
若 workflow 同時建立 Sheet 與插入資料,n8n 可能並行處理,導致:
“The specified sheet does not exist.”
解法:
在建立 sheet 的節點與資料輸出節點之間,插入 Merge 節點,選擇:
Mode: Wait → Combine Inputs
檢查 n8n Expression 是否為有效 JSON
「這是我在 n8n 用於 Google Sheets API 的 Expression:
={{ ... }}。請幫我確認是否是有效 JSON,並指出可能造成JSON parameter needs to be valid JSON的原因。」
幫我設計欄位 mapping
「我有一份信用卡交易 JSON,要寫入 Google Sheets。請幫我列出適合分析的欄位英文名稱、說明與建議資料型態。」
目前每份信用卡帳單被解析後,n8n 都會:
2024-09_Richart)當每月帳單自動生成後,我想做一個「總覽頁」,輸入月份即可抓取該月份表的加總。

=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 寫表 → 總額自動統計,完全自動化。