- 自動通知
- 一眼看到
多支財務腳本共用一份函式庫,壞了會出聲
把設定、錯誤通知與執行紀錄整理成共用 Apps Script 函式庫,讓新腳本沿用相同做法。
背景與使用技術(4 項)
腳本壞掉的時候通常沒有人會收到通知,第一個徵兆是某張報表的數字對不起來。財務的 Apps Script 自動化原本各自複製一份錯誤處理,貼過去之後各自老化,趕時間時還會整段省略。把這些共通的雜事收斂成一個共用函式庫,包一層 tryRun() 就有 Slack 警示與稽核軌跡,目前 8 個專案共用,全部釘住明確版本。
誰在用
維護多支 Apps Script 自動化的財務團隊
原本怎麼做
財務團隊有一批跑在 Apps Script 上的小程式,各自負責不同的事,卻都得處理同樣幾件雜事:出錯要通知誰、這次到底成功沒有、跑了多久。同一段錯誤處理複製到六個地方,每個地方都因當下需要改一點,半年後六份長得都不一樣。趕時間時第一個被刪掉的就是錯誤處理,而沒有錯誤處理的腳本壞掉時不會出聲,報表少了一批資料,下游沒有人知道。
前後對比
量測:實測=有計時或有紀錄;估計=喜特先生推估;客戶自述=客戶回報;規格=設計上的固定條件;待補=尚未取得數字。
流程一眼看懂
每支腳本各自寫錯誤處理
半年後六份長得都不同
壞了不出聲
引用共用函式庫
setup() 填設定
tryRun() 包住進入點
失敗發 Slack、寫稽核紀錄
流程示意:依本案既有做法整理,非客戶實際畫面。
做了什麼
- 做成函式庫而不是範本:程式碼只留一份,修一次大家一起好。
- 讓正確做法比錯誤做法更省力:三步接上,錯誤通知免費附帶。
- 設定留在各專案自己手上,彼此隔離。
- 只加不改:既有函式的簽名與行為維持向後相容。
程式碼與實作細節收在頁面下方,需要時再展開。
你的情況像這樣嗎?
- 你有好幾支腳本,各自複製了一份錯誤處理。
- 腳本壞了你才從別人口中知道,報表早就少了一批資料。
- 你想知道「這支腳本上週到底有沒有跑」。
更多成果與運作條件
約每週 1 次(實測)
自動攔截並回報真實執行錯誤,上線三個月持續運作
8 個專案
共用同一份函式庫,全部明確釘住版本
7 欄稽核軌跡
可回答「這支腳本上週到底有沒有跑」,打開試算表就能查
以上為本案既有成果與運作條件;估計值依原始資料標示,其他專案需另行評估,並非通用成效保證。
挑戰:原本遇到的困難
財務團隊有一批跑在 Google Apps Script 上的小程式,各自負責不同的事:同步員工名單、整理退信名單、通知請款進度、提醒帳務異動、產生報表。它們要做的事不同,卻都得處理同樣幾件雜事:出錯要通知誰、這次到底成功沒有、跑了多久。
- 各自老化:同一段錯誤處理複製到六個地方,每個地方都因當下需要改一點,半年後六份長得都不一樣,修好一份不代表其他五份跟著好
- 錯誤處理最先被省略:趕時間時第一個被刪掉的就是錯誤處理,而沒有錯誤處理的腳本壞掉時不會出聲,報表少了一批資料,下游沒有人知道
- 沒有套件管理:Apps Script 沒有 npm 那種機制,預設每多一個專案就多一份要獨立維護的副本
這件事不能靠一份「請記得處理錯誤」的規範文件解決,得讓正確做法本身比錯誤做法更省力。
完整解決方案與設計取捨
把共用部分做成函式庫,不做範本。一個 script 專案可以發布成函式庫,其他專案用 script ID 引用它、呼叫它匯出的函式。程式碼只留一份,修一次,所有引用的地方一起好。
核心設計
- 三步接上:在專案依賴中加入函式庫、呼叫一次 setup() 填好共用設定、用 tryRun() 包住進入點
- 錯誤與通知免費附帶:tryRun() 失敗時自動發 Slack 警示,每支新腳本從第一天就有,不必有人記得加
- 可選的稽核軌跡:每次執行可寫入試算表,記錄時間、腳本名稱、函式名稱、狀態、耗時、錯誤訊息與環境,共 7 欄
- 設定留在使用端(引用函式庫的專案):token 與設定存在各專案自己的 Script Properties,彼此隔離
- 範圍凍住:只加不改,既有函式的簽名與行為維持向後相容
技術與實作細節
展開完整實作說明
版本鎖定比程式碼本身更需要紀律
Apps Script 函式庫的版本是每個使用端自己設定的。早期引用它的專案裡,大多數的版本欄位停在預設值 "0",也就是 HEAD 模式:每次執行都抓函式庫目前最新的程式碼。這代表一次不向後相容的改動,會在下一次排程執行時直接生效,沒有測試、也沒有預警。
後來所有使用端都已明確指定版本。但維護規則仍是「只加不改」:新功能以新增函式的方式加入,既有函式的簽名與行為不動。要升級,是每個使用端自己決定、自己改一次設定。
函式庫的版本號寫在每個使用端的設定檔裡,不是集中管理的。要知道某個專案現在用哪一版,得去看它的設定,這也是交接時必須告訴下一個人的事。
只留有人用的:砍掉沒人用的框架
函式庫早期帶著一套可插拔的模組框架,外加一個模組。2026 年 6 月全部砍掉,因為沒有任何使用端用到,框架等於只為單一模組而存在。砍掉之後,要加新功能就是直接加一個檔案,不必先理解並重建框架那一層。
同一時期,另一個專案選擇刻意重複一段邏輯,而不接這個函式庫,理由是要維持零跨專案依賴。這個判斷也是合理的。共用函式庫該收什麼、不該收什麼,是從這些取捨中慢慢看清楚的。
到了 2026 年 7 月,函式庫加入一對收據辨識函式,API 從 4 個增加到 6 個。這次擴充同樣是只加不改的新增,沒有動到既有行為。
錯誤回報不能反過來影響正常流程
tryRun() 成功路徑上的稽核紀錄寫入,外面再包一層 try-catch。原因是試算表寫入失敗(例如執行者沒有該試算表的存取權)不應該把一次正常的執行變成錯誤。
這種失敗本身也是無聲的,所以它只記在 Apps Script 的執行紀錄裡,不發到 Slack。若每次都對著財務頻道回報一個與業務無關的問題,大家很快就會學會忽略警示。
設定與憑證留在使用端
setup() 與 getConfig() 用 Script Properties(Apps Script 存放設定值的地方)存放 token 與設定,所有 key 加上統一前綴,避免和使用端自己的設定撞名。setup() 強制要求呼叫端明確傳入 Slack 機器人的存取憑證(bot token),讓 token 永遠不出現在函式庫的程式碼裡。