IF / Switch:條件分支
workflow 不會每次都做同一件事。「金額大於 1,000 才通知經理」「客戶是 VIP 才寄致謝信」「表單有勾同意才存資料」——這種「看資料再決定走哪條路」的能力,n8n 靠兩個節點做到:IF(二選一)跟 Switch(多選一)。這章把兩個節點的差別、設定方式、常見坑一次講清楚,讓你以後看到「有時候要 A、有時候要 B」的需求,腦袋自動浮出解法。
為什麼要學條件分支
到第 14 章為止,你會用 {{ $json.amount }} 把上一個節點的資料塞進下一個節點——不錯,但這只是「原封不動地往下傳」。真實的自動化幾乎每一條都會有「岔路」:
- 訂單來了:金額 大於 1,000 通知經理,其他丟到日常清單就好。
- 客戶名單進來:VIP 走「寄致謝信+建 Slack 頻道」,普通客戶只寄自動回覆。
- 表單提交:勾了同意條款才存資料庫,沒勾就寄「請重新填」的信。
- 系統告警:等級 critical 打電話、warning 發 Slack、info 只寫 log。
這些「看資料決定走哪條路」的邏輯就叫條件分支(conditional branching),寫程式的人會用 if / else 或 switch / case;在 n8n 裡,你不寫程式,直接放 IF 節點或 Switch 節點,用視覺化的方式拉線接下游——資料進來、節點判斷、走上面或下面(IF)或走哪一號 output(Switch)。
IF vs Switch:哪個時候用哪個
兩個節點都在做「判斷 → 分路」,選錯不會壞,但用對會讓 canvas 乾淨很多。一句話對照:
| 特徵 | IF 節點 | Switch 節點 |
|---|---|---|
| 幾個 output | 固定兩個:true(上)、false(下) | 可自訂多個(Rules 模式官方沒硬性上限,實務常見 3–10 條;Expression 模式由 Number of Outputs 決定) |
| 回答的問題 | 一個 yes/no(例:「金額 > 1000 嗎?」) | 一個資料對應多種可能(例:「tier 是 gold、silver 還是 bronze?」) |
| 心智模型 | 程式的 if / else |
程式的 switch / case;像大樓電梯,按幾樓去幾樓 |
| 條件寫法 | 可加多個條件,用 AND / OR 組合 | 每個 output 各自寫條件(Rules 模式)或直接用一個 Expression 決定去哪號(Expression 模式) |
| 該怎麼挑 | 只有「要 / 不要」兩條路走時 | 三條路以上、或明顯的分類(等級、狀態、來源) |
動手做:加第一個 IF 節點
我們拿一個具體情境:訂單金額大於 1,000 就往「通知經理」走,否則往「日常紀錄」走。假設你的上游節點(可能是 Webhook、Google Sheets、Airtable)已經把訂單以 { "amount": 1500, "customer": "台北文具行" } 這種 JSON 傳下來。
-
在 canvas 上加 IF 節點
在上游節點右邊的 + 圖示點一下(或空白處按 Tab)叫出節點抽屜 → 搜尋框輸入
if→ 點 If(在 Flow 分類底下)。節點會落到 canvas 上,自動連好上游。 -
設第一個 Condition
雙擊 IF 節點打開右邊面板。你會看到一個 Conditions 區塊,預設有一列空的比較。三個欄位由左到右填:
- Value 1(左值):點欄位進入 Expression 模式,寫
{{ $json.amount }}——這是從上游拿amount欄位。 - Operator(中間):先在下拉左邊選型別
Number,右邊再選is greater than(官方 v2 IF 節點的正式名稱,不是larger)。 - Value 2(右值):填
1000(純數字,不用引號)。
- Value 1(左值):點欄位進入 Expression 模式,寫
-
看節點右邊多了兩條 output 線
設好 condition 後,IF 節點右側會分出兩條 output:上面標 true(綠色)、下面標 false(紅色)。這就是你可以拉線的兩條路。
-
分別接不同下游節點
從 true 那個圓點拖一條線出去,接你的「通知經理」節點(例:Slack 傳訊息到 #manager 頻道)。再從 false 拖一條線出去,接「日常紀錄」節點(例:Google Sheets Append Row)。canvas 現在會分岔成兩條路。
-
存檔+按 Execute Workflow 測
Ctrl+S 存檔。canvas 右上按 Execute Workflow。IF 節點跑完會用綠框標示它走的是哪條 output——你看訂單金額 1500 > 1000,理應走 true,實際看到 Slack 節點也跟著亮起來就對了。
-
再測一次「應該走 false」的資料
把上游 mock 資料改成
amount: 800再跑一次,這次應該只有 Google Sheets Append 那條亮,Slack 那條沒動。兩條都測過,這個 IF 才算真的驗證完。
IF 節點的四種資料型別 Condition
IF 節點的 Operator 下拉分兩層:左邊先挑資料型別,右邊才會顯示對應的比較運算子。挑對型別很重要——挑錯的話「看起來對,跑起來永遠是 false」,是新手第一名踩雷。
| 型別 | 常見 Operator | Value 2 要填什麼 | 例子 |
|---|---|---|---|
| String(字串) | exists / does not exist / is empty / is not empty / is equal to / is not equal to / contains / does not contain / starts with / does not start with / ends with / does not end with / matches regex / does not match regex | 字串(可含 Expression) | Value 1 {{ $json.status }}、Operator is equal to、Value 2 paid |
| Number(數字) | exists / does not exist / is empty / is not empty / is equal to / is not equal to / is greater than / is less than / is greater than or equal to / is less than or equal to | 純數字(不加引號) | Value 1 {{ $json.amount }}、Operator is greater than、Value 2 1000 |
| Boolean(布林) | exists / does not exist / is empty / is not empty / is true / is false / is equal to / is not equal to | 對 is true / is false 不用填;is equal to 填 true 或 false |
Value 1 {{ $json.consent }}、Operator is true |
| Date & Time(日期) | exists / does not exist / is empty / is not empty / is equal to / is not equal to / is after / is before / is after or equal to / is before or equal to | ISO 日期字串或 Expression(例:{{ $now }}) |
Value 1 {{ $json.createdAt }}、Operator is after、Value 2 2026-01-01 |
另外還有 Array(陣列,例 contains、length equal to、length greater than)跟 Object(物件,僅 exists / does not exist / is empty / is not empty),比較少用,這裡先跳過。注意 Date & Time 沒有 is between 這個 operator——要判「在兩個時間之間」得寫兩個 condition(is after A 且 is before B)再用 AND 組合。
"1500",你選了 Number → is greater than → 1000——結果永遠是 false。因為字串 1500 不是數字 1500,n8n 不會幫你自動轉。修法:Value 1 改成 {{ Number($json.amount) }} 強制轉型,或者上游用 Expression / Set 節點先轉好。看到「條件應該對卻走 false」,八成就是這個坑。多條件組合:AND / OR
一個 IF 節點裡可以放好幾個 condition,然後決定它們的組合方式。當你加第二列 condition 後,兩列之間會出現一個 AND / OR 下拉(官方 UI 就直接叫 AND / OR,沒有 Combinator 這個 label),兩個選項:
| Combinator | 意思 | 什麼時候用 |
|---|---|---|
| AND(且) | 官方說法:「Keep data when it meets all conditions」——所有 condition 都要為 true 才算 true | 「金額大 而且 付款狀態是 paid 才通知」 |
| OR(或) | 官方說法:「Keep data when it meets any of the conditions」——任一 condition 為 true 就算 true | 「客戶是 VIP 或 訂單超過 5,000 都要通知經理」 |
範例:訂單金額大於 1,000 AND 付款狀態是 paid
需求是「不只要金額大,還得真的收到錢才通知經理」。開 IF 節點,加兩個 condition:
- Condition 1:Value 1
{{ $json.amount }}、OperatorNumber is greater than、Value 21000 - Condition 2:Value 1
{{ $json.status }}、OperatorString equals、Value 2paid - Combine:
AND
兩個都滿足才走 true。如果 status 是 pending,即使金額 5,000 也會走 false。
範例:VIP 客戶 OR 高額訂單
需求是「特別關照」——只要滿足其一就走 true:
- Condition 1:Value 1
{{ $json.tier }}、OperatorString equals、Value 2vip - Condition 2:Value 1
{{ $json.amount }}、OperatorNumber is greater than、Value 25000 - Combine:
OR
{{ $json.a && ($json.b || $json.c) }},Operator 選 Boolean is true。第二招比較優雅,但要會寫一點 JS。Switch 節點詳解:兩種模式
Switch 節點打開來會先問你 Mode:Rules 還是 Expression。這是 Switch 跟 IF 最大的差別,兩種模式的思維完全不一樣。
Mode 1:Rules(規則模式,最常用)
像很多個 IF 疊起來——每個 Rule 都有自己的 condition(跟 IF 節點一樣的 Operator 系統),滿足哪個 Rule 就走對應那個 output。加 Rule 的方法:面板上按 Add Routing Rule,就多出一個 output(節點右邊會多一個圓點)。
例子:客戶等級分三種,不同下游處理。上游丟下來的 item 是 { "tier": "gold", ... }。設 Switch 節點:
- Rule 0:Value 1
{{ $json.tier }}、OperatorString equals、Value 2gold→ output 0 接「寄致謝信+通知業務」 - Rule 1:Value 1
{{ $json.tier }}、OperatorString equals、Value 2silver→ output 1 接「寄折扣券」 - Rule 2:Value 1
{{ $json.tier }}、OperatorString equals、Value 2bronze→ output 2 接「寄一般歡迎信」
Rules 底下有一個 Fallback Output 下拉,官方三個選項:None(預設,未對到就直接丟掉)、Extra Output(多開一條 output 專收未對到的 item,最常用)、Output 0(未對到就走跟第一條 Rule 一樣的 output)。想要有「未分類」下游,選 Extra Output。
另外還有一個 Send data to all matching outputs 開關(預設關):關的時候一筆 item 只會走第一條對到的 Rule;打開的話同時對到兩條 Rule 就會兩條都送——選這個要小心 items 被複製走多條分支的效果。
Mode 2:Expression(表達式模式,進階)
直接寫一個 Expression 回傳要走 output 幾號(從 0 開始數)。這比 Rules 模式簡潔,但需要你會用 Expression。
同上例用 Expression 模式:
{{ { "gold": 0, "silver": 1, "bronze": 2 }[$json.tier] }}
意思是「查表:tier 是 gold 走 output 0、silver 走 output 1、bronze 走 output 2」。回傳的數字對應 canvas 右側從上到下第幾條輸出線。Number of Outputs 欄位要先設好(例:3),節點才會有那麼多條線可以接。
常見實例對照表
把 IF / Switch 常見用法整成一張表,看你的需求對到哪一列,直接抄就好:
| 情境 | 用哪個節點 | 條件設定 | 下游怎麼接 |
|---|---|---|---|
| 新表單來 → 有勾同意才存 Sheet,沒勾就寄「請重新填」 | IF | Value 1 {{ $json.consent }}、Operator Boolean is true |
true → Google Sheets Append;false → Gmail Send Message |
| 訂單金額分級通知:<1000 助理、1000-5000 組長、>5000 經理 | Switch(Rules) | Rule 0 amount < 1000、Rule 1 兩個 condition AND:amount >= 1000 且 amount <= 5000、Rule 2 amount > 5000(Number operator 沒有 is between,得拆成兩條) |
各接一個 Slack 節點,target 頻道不同 |
| Gmail Trigger 收信 → 依寄件人 domain 分流到不同資料夾 | Switch(Rules) | Value 1 {{ $json.from.split('@')[1] }}、每個 Rule String equals 一個 domain |
各接 Gmail Add Label 或 Move Message |
| 系統告警:等級 critical 打電話、warning 發 Slack、info 只寫 log | Switch(Expression) | Expression:{{ { critical: 0, warning: 1, info: 2 }[$json.level] }} |
output 0 → HTTP Request 打電話 API;output 1 → Slack;output 2 → HTTP Request 寫 log |
| 訂單狀態 = paid 且金額 > 1000 才通知經理 | IF(多條件 AND) | 兩個 condition:status equals paid、amount > 1000;Combine AND | true → Slack 通知經理;false → 不接任何節點(沒動作) |
Webhook 收 payload → 依 event_type 走不同流程 |
Switch(Rules) | 每個 Rule 一個 event_type 字串 | 各自接對應的處理節點鏈;記得打開 Fallback 接一個「未知事件」告警 |
IF 後面又接 IF:巢狀分支可以,但要克制
n8n 沒有規定分支不能再分支——IF 的 true 那條下游接一個 Switch,Switch 的某個 output 又接一個 IF,都合法。但視覺上會變成很多岔路,過幾個月你自己回來看都會頭大。
什麼時候可以放心巢狀
- 兩層以內、每層都很單純(例:先 IF 判 VIP,VIP 那條再 Switch 依國家分區)——canvas 還讀得懂。
- 下游動作只有兩三步就結束,不是又拉一大串。
什麼時候該抽 Sub-workflow
- 三層以上的巢狀分支——canvas 變成樹狀圖,肉眼難以追。
- 同一個判斷邏輯在好幾條 workflow 都出現(例:「這個客戶是不是 VIP」)——抽成 sub-workflow,一改全改,第 19 章會講。
- 某個分支下游超過 5 個節點——這條分支自成一個小工作流,抽出來單獨測比較好。
IF / Switch 常見卡關
條件分支不動、走錯邊、分不出來——把下面對照一次,八成能自己救。
| 症狀 | 可能原因 | 怎麼救 |
|---|---|---|
| 「兩條分支都走了」 | 不會發生。IF 是 XOR,每一筆 item 只會走 true 或 false 其中一條。你看到兩邊都亮綠,是因為上游有多筆 items,其中一部分走 true、一部分走 false,兩條下游各拿到自己那份。 | 點 IF 節點看每條 output 的 items 數,加起來應該等於上游 items 總數 |
| 「條件應該對,卻永遠走 false」 | 資料型別跟 Operator 型別不符(例:資料是字串 "1500",你選 Number is greater than) |
Value 1 加轉型:{{ Number($json.amount) }}、{{ String($json.status) }};或上游用 Set 節點先轉好 |
| 「Switch 有些 item 消失了」 | 那些 item 沒對到任何 Rule,且你沒開 Fallback Output——n8n 就把它們丟掉了 | 面板 Fallback Output 下拉從 None 改成 Extra Output,節點會多長一條 output,接一個「未分類」節點(例:Slack 通知你、Sheet 記一筆) |
| 「分支之後想合起來,讓下游只寫一遍」 | 這是正常需求,但需要 Merge 節點 | 兩條分支的末端拉去接同一個 Merge 節點(第 16 章整章講合流) |
| 「Expression 模式的 Switch 顯示 output 編號無效」 | Expression 回傳的數字超出 Number of Outputs 範圍(例設 3 個 output 卻回 5) | Expression 用查表或 clamp 保底:{{ ({a:0,b:1,c:2}[$json.type]) ?? 0 }},找不到走 0 |
| 「IF 節點打開沒有 Conditions 區塊,只有一個空白面板」 | 版本差異或節點沒 load 完 | 把節點刪了重新加一次;或關掉 canvas 分頁重開 workflow |
| 「用 String contains 沒對到,明明看得到字串裡有」 | 大小寫敏感(contains 是 case-sensitive);或欄位前後有空白 |
Value 1 加 {{ $json.text.toLowerCase().trim() }},Value 2 也用小寫 |
| 「Date is before/after 判斷永遠走 false」 | Value 1 拿到的是字串日期,不是 Date 物件;n8n 有時候能自動轉、有時不能 | Value 1 改成 {{ DateTime.fromISO($json.createdAt) }} 明確轉成 Luxon DateTime |
常見問題
IF 之後我想「兩條都繼續走原本的流程」,怎麼寫?
tag = "vip" 或 "normal"),下游再依這個欄位處理。這樣資料流不分岔,也保留了分類資訊。一個 workflow 太多 IF 會不會拖慢速度?
條件太複雜、UI 拉不出來,怎麼辦?
Boolean is true。例子:{{ $json.amount > 1000 && ($json.tier === "vip" || $json.paid) && !$json.blocked }}——這種 A AND (B OR C) AND NOT D 混合邏輯,用 Expression 一行搞定。當然,能寫成清楚可讀的更好;真的很複雜就抽到 Code node 裡處理,回傳 { shouldNotify: true },IF 再判 {{ $json.shouldNotify }}。IF 節點跑一次算一個 execution 嗎?會吃我的額度嗎?
Switch 最多能有幾個 output?IF 能有三個 output 嗎?
可以在 IF / Switch 之後再合流嗎?
Append 或 Combine 模式明確控制怎麼合,比較保險。Switch 的 Rules 從上到下順序有影響嗎?
但 Switch 節點有一個 Send data to all matching outputs 開關(Options 底下,預設關):打開後同一筆 item 只要對到就送,多條 Rule 都會拿到——這時順序就不影響「有沒有走到」,但仍影響 output 編號的視覺。若要徹底不用管順序,把每條 Rule 寫成互斥(例:
amount >= 100 AND amount < 1000、amount >= 1000 AND amount < 5000、amount >= 5000,用兩個 condition + AND 拼出區間;Number 沒有 is between operator)。IF 節點的條件可以取上上一個節點的資料嗎?
{{ $node['節點名稱'].json.欄位 }}——這是 第 14 章教過的跨節點取值語法。例:{{ $node['Webhook'].json.body.customer_id }}。條件裡跨節點取值很常見(例:現在的節點是「查詢客戶」的結果,但你想用「Webhook 觸發時的原始 payload」做判斷)。注意節點名稱區分大小寫、中間有空白要保留。