- 自動通知
- 減錯
請款簽核的六種通知,條件到了才寄、只寄一次
依請款狀態寄出對應通知,利用追蹤表記錄避免重複寄送,附件另外定時歸檔。
背景與使用技術(4 項)
請款追蹤試算表背後是一條多節點的核准鏈,每個交接點過去都得靠人記得去通知。改成綁在試算表上的 Apps Script:定時掃描每一列的狀態,判斷該寄哪一種通知、寄給誰,並把申請人上傳的附件依辦公室自動歸檔。六種通知中有三種刻意共用同一個記錄欄,讓同一筆請款最多只收到其中一封。
誰在用
處理請款的申請人、核准人與財務
原本怎麼做
請款全部走同一張追蹤試算表:申請人送出一列,核准人核准或退回,財務可以帶著備註退件,急件還得更高層簽核,結案前申請人要補收據。每個交接點都要有人記得去通知。真正的失效模式是根本沒被注意到:一列資料紙面上看起來都對,卻靜靜等著一個不知道該去看它的人。
前後對比
量測:實測=有計時或有紀錄;估計=喜特先生推估;客戶自述=客戶回報;規格=設計上的固定條件;待補=尚未取得數字。
流程一眼看懂
申請人送出一列
核准人、財務、高層各自處理
靠人記得去發通知
追蹤表一列
定時掃描
條件成立且尚未寄過
寄信並寫記錄欄
附件另排程歸檔
流程示意:依本案既有做法整理,非客戶實際畫面。
做了什麼
- 狀態即記憶:不另建帳本,「這件事發過了沒」就記在那一列旁邊的記錄欄(試算表裡專門記「寄過了」的欄位)。
- 條件式掃描:每輪對每列每種通知只問兩件事——條件成立了嗎?寄過了嗎?
- 刻意收斂記錄欄:財務退件與兩種緊急通知共用一欄,同一筆請款最多只收到其中一封。
- 附件依單號歸檔,不管用哪個編號搜尋都找得到。
- 失敗可見:歸檔失敗的檔案與執行例外回報到 Slack,不會靜靜失敗。
程式碼與實作細節收在頁面下方,需要時再展開。
你的情況像這樣嗎?
- 你的流程靠一張追蹤表推進,每個交接點都要有人記得通知下一個人。
- 漏通知會卡住事情,重複通知又讓大家開始忽略訊息。
- 附件散在各處,要靠人手動歸檔與改名。
更多成果與運作條件
6 種通知,一輪掃描判斷
每列依條件與記錄欄決定寄或不寄,不再靠人記得
30 分鐘附件歸檔
每輪最多處理約 100 個檔案,單一檔案失敗不會卡住整批
1 個記錄欄共用 3 種通知
同一筆請款最多只收到其中一封,不會重複轟炸
- 財務退件按下就寄:不等下一輪排程,財務在選單按下就寄出
以上為本案既有成果與運作條件;估計值依原始資料標示,其他專案需另行評估,並非通用成效保證。
挑戰:原本遇到的困難
請款流程全部走同一張追蹤試算表:申請人送出一列,核准人核准或退回,財務可以帶著備註做退件,急件還得有更高層的人簽核,結案前申請人還要補上收據證明。每一個交接點過去都要有人記得去發通知,真正的失效模式是根本沒被注意到,一列資料紙面上完全正確,卻靜靜地等著一個不知道該去看它的人。
- 六種通知,條件各不相同:新案通知核准人、結果回覆申請人、財務退件、急件呈報高層(高層核准人若就是原核准人,內容不同,另算一種)、收據未補的持續提醒
- 漏發與重發都有代價:漏發退件,申請人不知道請款卡住;重複發送,高層很快就會開始忽略這個頻道;已經處理完還反覆通知,比沒通知更快磨掉人對自動化的信任
- 沒有後端:只有試算表與 Apps Script,「這件事發過了沒」的記錄只能以資料的形式留在那一列上
- 附件要人工歸檔:申請人上傳的收據與發票要手動拖進各辦公室資料夾,還要改名才好搜尋
所以設計的重點不是「能寄信」,而是每種通知只在該寄的時候寄一次。
完整解決方案與設計取捨
一支綁在請款追蹤試算表上的腳本,由時間驅動的 trigger 逐列掃描,對六種通知型態各自檢查「條件成立、且該種通知尚未寄出」,兩者都成立才寄。財務退件例外,由財務在選單中按下後立刻觸發。每種通知佔用一個記錄欄(試算表裡專門記「這封寄過了」的欄位),寄出後寫上已發送標記,之後每輪都會跳過。另有一支 30 分鐘週期的排程,負責把附件搬進辦公室資料夾並統一命名。
核心設計
- 狀態即記憶:不另建帳本或佇列,防重複的依據就是觸發它的那一列資料旁邊的記錄欄
- 條件式掃描:每輪對每列每種通知各問兩個問題,條件是否成立、記錄欄是否已寫入
- 刻意收斂的記錄欄:財務退件與兩種緊急通知共用一欄,同一筆請款最多發出其中一封
- 附件依單號歸檔:檔名加上單號與收款人前綴,不管用哪個編號搜尋都找得到
- 失敗可見:歸檔失敗的檔案與執行例外回報到 Slack,不會靜靜失敗
技術與實作細節
展開完整實作說明
六種通知,各自的條件與收件人
| 通知 | 觸發條件 | 收件人 |
|---|---|---|
| 新請款通知 | 已填核准人 email,且尚未通知 | 核准人(副本申請人) |
| 核准/退回回覆 | 核准人已回覆,回覆旗標已設,且尚未回覆過 | 申請人(副本核准人與財務) |
| 財務退件 | 撥款標為退件,且有備註 | 申請人 |
| 緊急通知 | 付款期限為緊急、付款方式非自動豁免項目,且已核准 | 指定的高層核准人(副本申請人與財務) |
| 緊急通知(高層自審) | 條件同上,且指定的高層核准人就是這一列原本的核准人 | 指定的高層核准人(副本申請人與財務) |
| 收據提醒 | 已核准、撥款非退件或免收據、收據尚未上傳 | 申請人,未解決前會反覆提醒 |
信件外觀統一:同一套卡片版型,包含 logo、從該列資料組出的明細表格、狀態標籤與回到試算表的按鈕,並附上純文字版,給不支援 HTML 的信箱使用。
一個記錄欄,三種通知
財務退件與兩種緊急通知共用同一個記錄欄,不各自開欄位。同一列上,三個條件不管哪一個先在某一輪成立,就會佔掉這一欄、寄出那一封,另外兩種從此不再對這一列觸發。
這是刻意的簡化。這三種情況在同一列上很少同時成立,用三個欄位各自追蹤幾乎互斥的結果,只是多出一份要保持同步、卻沒有實質好處的狀態。一個欄位寫著「這三種裡已經有一種發過了」,在試算表上更容易看懂,對實際會發生的情況來說也同樣正確。
這個取捨值得明講:如果將來三種情況同時成立的機率變高,就應該拆成三個欄位,不能靠這個共用欄位繼續掩蓋重疊。
防重複就是資料本身
整套系統沒有獨立的已發送清單。每種通知對應一個記錄欄,就放在觸發它的資料旁邊。腳本每輪只問兩件事:條件成立了嗎?這一格是不是已經寫上「已寄」?兩者分別為「是」與「否」,才會寄出。好處是狀態與資料不會分離,壞處是任何人手動改動那一格,都會直接改變系統的行為。
收據提醒會持續到什麼時候
收據提醒只要觸發條件仍成立,就會每週重複寄出。它會不會停,取決於另一個記錄欄是否被填上,而這個欄位由這支腳本自己從不寫入,是流程中另一個環節,由人確認收據真的收到後才填。如果那個確認步驟被漏掉,申請人即使已經上傳收據,也會一直被提醒下去。
這是刻意的設計。腳本沒有辦法可靠地判斷「這張收據正確、已經入帳」,所以把這個判斷交給流程中本來就負責的環節,而不是讓程式去猜。代價是,如果那個環節失效,提醒會持續得比它原本該存在的理由更久。
附件歸檔
另一支獨立的 30 分鐘週期排程,處理申請人上傳到列上的附件:把每個檔案搬到對應辦公室的資料夾,檔名前面加上單號與收款人。每輪最多處理約 100 個檔案,量大時自然延到下一輪,不會硬把整批塞進同一次執行。搬不動的檔案會回報到 Slack 的錯誤頻道,然後繼續處理下一個,不會因單一失敗而卡住整批。
已知限制:通知從維護者的個人帳號寄出
通知目前從維護者的個人帳號寄出,收件人的回信會直接回到個人信箱,寄件身分也綁在誰恰好維護這支腳本上。原本規劃改從財務共用信箱寄出,但這需要在共用信箱上開立代發權限,要有 Google Workspace 管理員權限才能設定,目前沒有,因此暫緩。寫在這裡,是因為它是已知的限制,不是沒注意到的疏漏。