有一次一位客人在確認信底下直接回問這句話,業務當下心裡一沉,以為是重複建了團——回頭查才發現,是同一封詢問信被兩套系統各處理了一次,各自寄出一封「已收到您的詢問」。
進單建檔這支程式後來做了雲端版本,方便不受限於某一台電腦,但舊的本機版沒關乾淨,兩邊同時盯著同一張表格裡「未處理」的那個欄位,各自搶著把同一列標成已處理、各自寄出confirmation。這種錯特別難靠程式邏輯避免,因為兩邊各自的執行紀錄互相看不到對方,誰先搶到那一列完全是運氣。解法很土:兩邊只能擇一啟用,而且關掉的那一邊要真的把觸發器關乾淨,不是「應該沒在跑吧」這種猜測——後來我固定會去 Apps Script 的觸發器清單裡親眼確認,不憑印象。
第一天我說過,這三十天我會寫失敗的那些。今天就是這篇——幾個做到一半收手、或是做出來但後來關掉的東西,還有我從中整理出來的停損判斷。
供應商追約清單一開始是手動跑的,後來加了一個以時間驅動的 Apps Script 排程。過一陣子我在另一支程式裡又加了一個「每天檢查效期」的功能,完全忘記前面那支已經在做同一件事,兩支各自掛在自己的觸發器清單裡,互相看不到對方。兩邊各自安靜地跑,直到同事問「怎麼一天收到七封一樣的清單」,才發現重疊。
這件事沒有什麼高深的教訓,就是自動化長到一定數量之後,你會忘記自己做過什麼。現在我固定會把每個專案裡「觸發器」面板都攤開來看一遍,列成一份清單——盤點不是做一次就結束的事。
有一條靠 API 在兩個雲端硬碟資料夾之間同步檔案的自動化,某天開始每天失敗——後來查出來是背後一組服務帳戶的存取權限被連動調整過,程式呼叫時直接被拒絕。因為它失敗的時候不會發出任何聲音,原本也沒包 try/except 去攔截例外,所以沒有人知道,直到我回頭檢查才發現它已經連續失敗了兩個多月。
這條後來直接刪掉不做了——因為真正需要的功能,已經被另一套架構取代。但它留下的教訓比功能本身有價值:**安靜地失敗,比大聲地壞掉危險得多。**現在每一支排程都一定要包一層例外處理,失敗就寄信通知,不能讓它自己吞掉錯誤。
收款平台 G 的後台,我想讓程式自動登進去抓每月的明細。第一關的滑塊驗證可以用模擬人類手速拖曳的方式繞過,但送出帳密之後,固定會跳出一個必須由真人完成的圖形驗證,程式解不了,每一次都是,換了幾種保留登入狀態的做法也沒用。
我在這件事上花了兩個禮拜,最後停手。停手的判斷是三個問題:對方是不是刻意在擋自動化(是)、繞過去有沒有違反服務條款的風險(有)、這件事一個月做幾次(一兩次)。三個答案湊起來,結論很清楚。
後來我想到第四個問題,也是最有用的那個:**有沒有別條路可以拿到同一份資料?**有——那個平台每個月會主動寄一封月結信到信箱。改用信件附件歸檔那一套,完全不用登入,問題就解決了。
有一個合作平台的訂單通知信,格式特別常變動,而且還要另外處理浮動的保費計算,用正規表示式硬刻的解析規則,格式一變就得跟著改。我評估過自己寫解析程式的維護成本,結論是不划算,就讓它留在原本的舊工具上繼續跑。
這不是失敗,是刻意不做。但我把它放在這篇,因為「決定不做」跟「做不到」在帳面上長得很像,差別只在於你有沒有想清楚為什麼。
這幾件事拼起來,我自己用的判準大概是這樣:對方是不是刻意在擋、繞過去有沒有風險、這件事多久做一次、有沒有替代路徑。四個問題裡只要有兩個答案不利,我就會停。
做自動化最貴的成本從來不是把它寫出來,是維護一個一直在跟你作對的對手。認賠停損是判斷,不是投降。
如果你手上有一個卡了兩個禮拜還沒通的自動化,先別急著再試一次,問那四個問題。有時候真正的答案不是「怎麼繞過去」,是「我其實可以從別的地方拿到同一份資料」。