每日定時檢查未交作業並發送提醒信 | (EP.5) n8n 自動化講師應用教學
哈囉,歡迎來到自動化工作流的實戰教學。在接續上一集建立作業提交表單後,今天要進入更關鍵的一環:每天自動比對誰還沒交作業,並寄出精準的提醒 Email。
身為講師,你應該把時間花在教學上,而不是每天手動逐一核對學生的繳交進度。這套工作流讓系統在每天早上 9 點幫你做完這件事,而且內建多重防呆機制,保證不會重複騷擾已繳交或當天已提醒過的學生。
工作流整體架構
這套工作流圍繞著四份 Google Sheets 試算表運作,透過「資料比對」找出需要提醒的學生,再執行寄信與紀錄。整體分為以下五個階段:
| 階段 | 說明 |
|---|---|
| 1. 定時觸發 | 每天早上 9 點自動啟動 |
| 2. 讀取資料 | 同步抓取四份試算表資料 |
| 3. 交叉比對 | 找出未交且今日未提醒的學生 |
| 4. 寄送提醒 | 發送個人化提醒 Email |
| 5. 寫入日誌 | 成功、失敗分別記錄於不同表格 |
Google Sheets 資料表設計
在建立工作流前,需先在同一份試算表中建立四個工作表(Sheet),各自負責不同功能:
assignments(作業清單)
| 欄位 | 說明 |
|---|---|
assignment_id |
作業代號(唯一識別碼) |
assignment_name |
作業名稱(顯示於信件中) |
due_at |
截止時間 |
is_active |
是否啟用(填入 1 代表啟用,0 代表停用) |
students(學生名單)
| 欄位 | 說明 |
|---|---|
student_id |
學生代號 |
student_name |
學生姓名 |
email |
學生 Email |
submissions(繳交紀錄)
| 欄位 | 說明 |
|---|---|
student_id |
繳交學生的代號 |
assignment_id |
對應的作業代號 |
reminder_logs(提醒日誌)
| 欄位 | 說明 |
|---|---|
student_id |
被提醒的學生代號 |
assignment_id |
對應的作業代號 |
reminded_at |
提醒時間(台灣時區) |
設計原則: 工作流只讀取
is_active = 1的作業,因此新增或停用作業只需修改試算表中的欄位值,完全不需要改動 n8n 流程。
核心比對邏輯:誰需要收到提醒信?
工作流的核心是一段 JavaScript Code 節點,邏輯如下:
篩選條件:同時符合以下三點,才會被列入寄信名單
- 尚未繳交該份作業:比對
submissions表,以student_id + assignment_id作為組合鍵判斷。 - 今天尚未被提醒過:比對
reminder_logs表,確認今日(台灣時間)尚無對應紀錄。 - 有有效的 Email:缺少 Email 的學生資料直接略過,不中斷流程。
時區處理細節: 系統使用 UTC+8 台灣時間進行日期判斷,確保在台灣時間 9 點執行時,「今日」的判定是正確的。
1 | 台灣時間 = UTC 時間 + 8 小時 |
這個設計讓流程即使被手動觸發多次,同一位學生在同一天內也只會收到一封提醒信。
寄信節點設定與防錯機制
信件內容動態化
提醒信的主旨與內文都使用動態變數,讓每封信看起來更有針對性:
- 主旨:
作業提醒:[作業名稱] 尚未提交 - 內文: 包含學生姓名、作業代號、作業名稱、截止時間
自動重試機制
寄信節點設定了「失敗自動重試」:
- 重試次數:3 次
- 每次間隔:5 秒
- 允許失敗繼續執行(
continueOnFail: true)——確保單一學生的寄信失敗不會中斷整批發送
結果分流
寄信完成後,系統透過判斷 Gmail 是否回傳 id 欄位,來決定寫入哪份日誌:
- 有
id(成功) → 寫入reminder_logs,作為下次「今日已提醒」的比對依據 - 無
id(失敗) → 寫入failed_reminder_logs,記錄錯誤訊息供人工追蹤
工作流測試清單
正式上線前,建議準備以下測試情境逐一驗證:
- 學生已繳交: 確認不出現在寄信名單中
- 學生未繳交: 確認收到提醒信,且
reminder_logs有新增紀錄 - 重複手動執行: 確認同一位學生當天只收到一封
- 學生無 Email: 確認流程不中斷,直接略過該筆資料
- 作業
is_active = 0: 確認該作業不在本次提醒範圍內
全數通過後,Cron 排程即可正式上線,系統從此每天早上自動幫你追蹤進度。
常見問答 (FAQ)
Q:如何新增一份新作業,讓系統開始追蹤?
A:直接在 Google Sheets 的 assignments 工作表中新增一列,填入 assignment_id、assignment_name、due_at,並將 is_active 設為 1 即可。工作流每天執行時會自動讀取最新資料,完全不需要修改 n8n 流程。
Q:如果某份作業的提醒期限已過,該如何停止寄送?
A:將該作業在 assignments 表中的 is_active 欄位改為 0(或任何非 1 的值),工作流便不會再讀取這份作業,自然也不會繼續發送提醒。
Q:如何避免同一天對同一位學生重複寄送提醒信?
A:工作流在執行比對時,會讀取 reminder_logs 中當日的紀錄,建立「今日已提醒組合鍵集合」(以 student_id + assignment_id 為鍵)。若該組合鍵已存在,這位學生就會從本次寄信名單中被剔除。這個機制確保即使工作流被手動觸發多次,同一學生每天最多只收到一封提醒。
Q:如果學生名單中某位學生沒有填寫 Email,會發生什麼事?
A:Code 節點在組建寄信名單時,會直接跳過沒有 Email 的學生資料,不會將其加入輸出清單。即使有漏網之魚進入後續節點,發信前還設有一道「If Has Email」條件判斷,確保沒有 Email 的資料不會觸發寄信動作,也不會造成流程中斷。
Q:寄信失敗時,系統會怎麼處理?
A:寄信節點設有「失敗自動重試 3 次,每次間隔 5 秒」的機制。若三次重試後仍失敗,系統會將該筆資料(含學生代號、作業代號、錯誤訊息、失敗時間)寫入 failed_reminder_logs 工作表,供管理員後續追查或手動補寄。此外,寄信節點設定了 continueOnFail: true,單一筆失敗不會中斷整批發送,其他學生仍會正常收到提醒。
Q:系統如何判斷學生是否已繳交?提交記錄需要手動維護嗎?
A:submissions 工作表記錄所有已繳交的學生與作業組合,比對鍵為 student_id + assignment_id。這份資料通常由上一集介紹的表單提交流程(EP.4)自動寫入,不需要手動維護。只要整個自動化系列串接完整,從學生提交表單到更新繳交紀錄,再到本集的每日提醒,整條鏈路都會自動運作。
Q:這套流程可以同時追蹤多份作業嗎?
A:可以。Code 節點的邏輯是「學生名單 × 啟用中作業」的全量組合比對,因此無論 assignments 表中有幾份啟用中的作業,都會在同一次執行中被一併處理。每位學生可能在同一天收到多份不同作業的提醒信(各自獨立寄出)。
Q:Cron 排程的時區設定需要注意什麼?
A:n8n 的 Cron 表達式 0 9 * * * 依據的是 n8n 伺服器的系統時區。若伺服器使用 UTC,設定「早上 9 點台灣時間」應改為 0 1 * * *(UTC 1:00 = 台灣 9:00)。Code 節點內部已額外加入 UTC+8 偏移換算,確保「今日」的日期判斷以台灣時間為準,避免跨日比對錯誤。