- 減錯
- 自動通知
員工名冊與 Slack 帳號,每 12 小時自己對好
定時更新員工與 Slack 名單、配對帳號並同步表單選項;無法配對的保留人工處理。
背景與使用技術(4 項)
手工維護的員工與 Slack 帳號對照表,一有人到職或離職就過期,簽核通知因此還會送給已離職的人。改用 Apps Script 每 12 小時刷新人事名冊與 Slack 使用者清單、自動配對帳號,人事異動時直接發通知。人事系統提供 478 個以上欄位,只取其中 18 欄。
誰在用
維護員工名冊與各項通知的內部人員
原本怎麼做
員工與 Slack 帳號靠手工對照表。有人到職或離職,對照表當下就過期,不是有人記得更新,就是某個自動化把訊息送給已經不在的人。離職盤點時,對照表上還在的人不會被列進來。公司信箱分兩個網域,只比對 email 會漏掉用另一個網域的人。
前後對比
量測:實測=有計時或有紀錄;估計=喜特先生推估;客戶自述=客戶回報;規格=設計上的固定條件;待補=尚未取得數字。
流程一眼看懂
人事系統
手工對照表
各項通知與離職盤點
人事系統+Slack 使用者
每 12 小時同步
三層比對
對照表(可人工覆寫)
通知與表單下拉選單
流程示意:依本案既有做法整理,非客戶實際畫面。
做了什麼
- 只拉需要的欄位:用允許清單從源頭只取 18 欄,敏感資料根本不進來。
- 機器算對照、人只處理機器不該拍板的:三層比對配不到的人,留一欄給人工覆寫,不硬猜。
- 離職與停用的帳號留在名冊並標示狀態,人事異動時發 Slack 通知。
- 四個表單共用同一份名單,取代四支各自為政、沒有重試的腳本。
程式碼與實作細節收在頁面下方,需要時再展開。
你的情況像這樣嗎?
- 你有一份員工或客戶名單,靠人手維護,每次異動都要回頭改。
- 自動通知要私訊給對的人,但你不確定名單此刻還正不正確。
- 系統裡有不該擴散的敏感欄位,卻又得把名單給別的工具用。
更多成果與運作條件
只同步必要的人事欄位
人事系統提供的 478 個以上欄位中,明確只列入 18 欄,薪資、生日與證號都不進管線
超過九成的員工自動對上(實測)
三層比對自動配對,其餘大多是已離職且 Slack 帳號也移除的人,或人事系統裡本來就不是真人的紀錄,少數在職員工才需要人工補填
12 小時自動刷新
離職的人與停用帳號保留在名冊中並標示狀態,異動最多延遲一個同步週期就會通知
- 四個表單共用一份名單:姓名下拉選單改讀同一來源,每個表單各自具備重試與退避機制
以上為本案既有成果與運作條件;估計值依原始資料標示,其他專案需另行評估,並非通用成效保證。
挑戰:原本遇到的困難
很多自動化問的都是同一件事:這個人是誰、他的 Slack 帳號是哪一個。簽核通知要私訊給對的人,離職時要收回的權限要對到正確的帳號。這一切都靠一份對照表,而且這份表必須是此刻正確的。
- 手工對照必然過期:只要有人到職或離職,對照表在那一刻就已經是錯的,之後不是有人記得更新,就是某個自動化把訊息送給已經不在的人
- 離職盤點漏人:對照表沒更新時,已離職的人仍被標成在職,離職盤點就不會把他列進來
- 名冊欄位太敏感:人事系統裡薪資、福利、生日、證號、住址都在同一個物件上,名冊若被大量引用,就等於把這些資料散出去
- 同一人兩個網域:公司信箱分兩個網域在用,只比對 email 會漏掉 Slack 帳號用另一個網域的人
所以目標是讓兩份來源名單自己保持最新,對照由程式算出,並且在源頭就不抓取不需要的敏感欄位。
完整解決方案與設計取捨
分工先定下來:資料是否最新交給程式,人只處理程式不該自己拍板的判斷。實作是一個小型的 Apps Script 專案,包含五個同步功能與一個除錯工具:
- 人事名冊同步:從人事系統的自訂報表端點拉取每位員工(含已離職者),只取允許清單上的欄位,清空後整批重寫到名冊工作表。每次同步都與前一次結果比對,偵測到新進、離職、主管或部門異動就發 Slack 通知
- Slack 使用者同步:從 Slack 的使用者清單拉取真實使用者(含已停用帳號,排除機器人),整批重寫到使用者工作表
- 對照表產生:兩份名單剛刷新好之後,依序用三層比對配對員工與 Slack 帳號,比不到的留一欄給人工覆寫
- 職務異動史:逐員工呼叫人事系統的職務資料端點,把每次主管、部門、職稱、地點的變動各寫成一列,目前改為需要時手動執行
- 表單下拉選單同步:讀取人工維護的在職員工名冊,同步進四個既有表單的姓名下拉選單,取代四支各自為政、沒有重試機制的腳本
- 欄位檢查工具:列出這把金鑰能取得的全部欄位,日後要新增同步欄位時,依清單決定,不靠記憶
名冊同步、Slack 同步、對照表產生與表單下拉選單同步掛在同一個 12 小時排程上,後兩者接在前兩支之後執行,確保永遠比對最新名單;職務異動史則另外手動執行。
技術與實作細節
展開完整實作說明
為什麼不直接開放整份人事資料給自動化讀?
人事系統裡一位員工身上掛的資料遠不只姓名與部門,薪資、福利、生日、證號、住址都在裡面,API 能拿到的欄位超過 478 個。而這份名單會被很多自動化引用,是公司內部流通很廣的一張表。一旦薪資欄進了一份很多人打得開的試算表,「誰該看到」就控制不住了:試算表可以被複製、整份匯出、被另一個檔案引用,權限設定不會跟著資料走。
所以決定抓哪些欄位,等於是在決定這些資料最後會散到哪裡。與其先全部撈進來再設權限,不如讓不需要的欄位根本不被 API 回傳。沒進到表裡的東西,之後也沒有外洩的路徑。
允許清單,而不是事後設權限
人事名冊的拉取寫成一份明確的允許清單(只有列在清單上的欄位才會被取回),478 個以上的欄位只列入 18 欄,分三組:身分(姓名、工作信箱、員工編號)、組織(職稱、部門、事業群、地點、主管)、任職(到職與離職日期、在職狀態)。清單集中在設定區的一行陣列裡,要放寬或收緊範圍,永遠是一處看得懂、追得到的修改。
另一種做法是照樣全部撈進來,再在試算表層級設權限。權限會跟著檔案走,資料不會跟著權限走。允許清單是把問題往前推一步,讓這些欄位根本進不來。
從兩份名單到一個答案
過去的對照表是靠人一個一個判斷的。現在對照表產生功能(syncSlackMapping)讀的是剛刷新好的兩份名單,資料已經在試算表上,不需要再呼叫任何 API。三層比對依序進行:
- 工作信箱完全相同
- @ 前面的帳號名稱相同,且限於公司自己的信箱網域
- 姓名在兩份名單中都唯一
哪一層先對到,就用那一層寫入,不往下試。中間那層最有用,因為公司信箱分兩個網域,單純比對 email 會漏掉另一個網域的人。比不到的,大多是已離職且 Slack 帳號也移除的人,或人事系統裡本來就不是真人的紀錄(共用行事曆、測試帳號),這些直接標為「刻意不對應」,不會永遠掛在待辦清單上。
另外有一道自動檢查:同一個 Slack 帳號不能被兩個人認領。若兩筆紀錄在同一層比對出同一結果(實際發生過,是兩位不同員工名字相同),強度較高的那一筆保留,其餘清空並標記給人工複查。
一則通知,取代一張過期的表
名單變動時,過去沒有任何人會知道。現在同步時拿新抓回的名單與工作表原本的內容比對,偵測到新進、離職、主管或部門異動,就發一則彙整通知。新進員工若能自動配對,會直接附上 Slack 帳號;對不到的則直接點名,讓三層比對攔不住的人立刻被看見。
偵測刻意不另外存快照,只比對工作表現有內容與本次抓回的資料。代價是第一次執行,或同步欄位剛調整過的那次,沒有可信的基準,會跳過偵測,以免發出一堆假警報。通知最多延遲一個同步週期,也就是 12 小時。
職務異動史:誰在什麼時候回報給誰
現況快照回答的是「現在的主管是誰」,財務審查常問的卻是「去年那筆簽核當時是誰經手、當時他回報給誰」,只看快照答不出來。職務異動史逐員工抓取,每員工一次 API 呼叫,整輪約 2.5 至 4.5 分鐘,接近 Apps Script 單次執行六分鐘的上限,因此沒有排進 12 小時排程,改為需要新資料時手動執行。單一員工抓取失敗會被略過並記錄,不拖垮整批。
人事系統的歷史紀錄只存主管的名字,不存當時的員工 ID,所以回填 ID 時用顯示名稱比對目前名冊。大部分情況可靠,遇到簡稱或暱稱對不上就留空,不硬猜。
表單下拉選單讀的那份名冊仍是人工維護的。姓名打錯字或留白列,下一個同步週期就會直接反映到四個表單上。這是文件上寫明的已知風險,編輯這一欄的人需要知道這個連動關係。
技術細節
- 整批刷新,而不是附加。 來源工作表每次先清空再整批重寫,所以同步是「重複執行結果相同」的,跑幾次都一樣。讓「先清空再重寫」安全成立的,是一條明確的所有權規則:來源工作表歸程式所有,不做手動編輯,所有人工作業都只落在獨立的對照覆寫工作表上,而覆寫以員工 ID 為 key,整批重寫不會蓋掉。
- 離職與停用的人,紀錄留著。 直接刪列會讓歷史對照斷掉,日後查「去年這筆是誰核的」就查不到。所以紀錄保留,用在職狀態欄位標示。
- 「在職」看狀態欄位,不看離職日期。 人事系統在職員工的離職日期欄回傳的是預設佔位日期,不是空白,若用它判斷會把幾乎所有人誤判為離職。
- 重試與錯誤回報。 API 呼叫外層包了「失敗後等待時間逐次加倍再重試」的機制;遇到我方請求有誤的 4xx 錯誤(429 除外)則直接失敗,不做無謂的重試。任何失敗都透過共用的錯誤包裝函式自動回報到 Slack,而不是在排程中悄悄掛掉。
- 配額。 排程跑在公司的 Google Workspace 帳號下,Apps Script 對外呼叫 API 的每日配額寬裕,這裡的呼叫量不會逼近上限。