iT邦幫忙

2025 iThome 鐵人賽

DAY 29
0

參加 iTHome 鐵人賽最怕的是什麼?除了沒靈感、或是寫不完,甚至到最後忘記在午夜前按下「送出」按鈕,導致前功盡棄 QQ

今天,就讓我們一起動手,用自動化工具 n8n 打造一個忠實的發文提醒小助理。它會在每天晚上檢查你是否已發文,如果還沒,就立刻發送 Discord 通知,確保你不會因為一時疏忽而斷賽

核心設計思路

這個流程的邏輯是: 「每天在指定時間觸發 -> 抓取你的鐵人賽 RSS -> 檢查最新一篇文章的發布日期 -> 如果最新文章不是今天發的 -> 就發送通知提醒自己」

這樣可以確保在午夜 12 點前,如果還沒發文,就會收到警告,避免斷賽的悲劇發生

流程圖

在開始動手前,我們先用一張流程圖來理解整個自動化腳本的樣貌

graph TD
    A[開始] --> B[1. Schedule 排程觸發];
    B --> C[2. RSS Feed Read 讀取 RSS];
    C --> D[3. Aggregate 合併資料];
    D --> E{4. IF 判斷是否已發文};
    E -- 否/False --> F[5a. Discord 發送提醒];
    E -- 是/True --> G[5b. NoOp 結束流程];

workflow

1. 建立排程觸發

  • 來到儀表板,新增一個流程「Create Workflow」

    image 0.png

  • 初始節點選擇排程「On a schedule」

    image 1.png

  • 時間設定為晚上的 9pm

    image 2.png

  • 接著到設定的地方

    image 3.png

  • 設定為台灣時區

    image 4.png

2. 讀取鐵人賽 RSS

  • 下個節點選擇「RSS Read」

    image 5.png

  • URL 填入你鐵人賽的 RSS 網址

    image 6.png

  • 接著切換到「Settings」的分頁,把「Always Output Data」打開,避免第一天沒有資料就不會進行下去

    image 7.png

3. 合併資料

為了方便後續的判斷,我們需要將 RSS 抓回來的多篇文章資料合併成一個陣列

  • 下個節點選擇「Aggregate」來合併資料

    image 8.png

  • 選擇「All Item Data」會把列表的資料都放進「data」的變數裡面

    image 9.png

4. 條件判斷

  • 下個節點選擇「IF」,用來判斷「最新文章的日期」是否等於「今天的日期」

    image 10.png

  • 判斷式內容填以下的內容,格式選擇「Boolean」的「is true」

    {
      {
        $json.data.some(
          (item) =>
            new Date(item.isoDate).toISOString().split("T")[0] ===
            $now.toFormat("yyyy-MM-dd")
        );
      }
    }
    

    image 11.png

5. 設定分支流程

  • IF 節點判斷為 false 時,就傳送 Discord 通知,這邊的下個節點可以選擇「Discord」的「Send a message」來傳送訊息

    image 12.png

  • 「Connection Type」選擇「Webhook」,憑證的串接在之前的文章有撰寫過,這邊就不重複惹

    image 13.png

  • Message 可以設定為

    **🚨 iTHome 鐵人賽警告 🚨**
    
    @everyone 今天還沒有發文喔!再不寫就要斷賽啦!
    
  • 而當 IF 節點判斷為 true 時,我們什麼事都不用做,可以連接一個 NoOp (No Operation) 節點,讓流程圖看起來更完整、語意更清晰

    image 14.png

6. 測試與啟用

  • 可以點選最下方的「Execute workflow」來試跑看看,而完整的流程會長這樣,這邊也要記得到上方把流程切換為「Active」啟用

    image 15.png

  • Discord 會收到這樣的訊息

    image 16.png

  • 最後也附上完整的流程 JSON 內容

    {
      "nodes": [
        {
          "parameters": {
            "rule": {
              "interval": [
                {
                  "triggerAtHour": 21
                }
              ]
            }
          },
          "type": "n8n-nodes-base.scheduleTrigger",
          "typeVersion": 1.2,
          "position": [0, 0],
          "id": "4e275616-c21c-411e-b510-bc2510aef7ca",
          "name": "Schedule Trigger"
        },
        {
          "parameters": {
            "url": "https://ithelp.ithome.com.tw/rss/series/8496",
            "options": {}
          },
          "type": "n8n-nodes-base.rssFeedRead",
          "typeVersion": 1.1,
          "position": [220, 0],
          "id": "9f72e3cb-8f20-4e5f-8732-79667a2cecbd",
          "name": "RSS Read",
          "alwaysOutputData": true
        },
        {
          "parameters": {
            "conditions": {
              "options": {
                "caseSensitive": true,
                "leftValue": "",
                "typeValidation": "strict",
                "version": 2
              },
              "conditions": [
                {
                  "id": "b59baac4-6a94-434d-a9cb-ccbe13ab557b",
                  "leftValue": "={{ $json.data.some(item => new Date(item.isoDate).toISOString().split('T')[0] === $now.toFormat('yyyy-MM-dd')) }}",
                  "rightValue": "={{ $now.toFormat('yyyy-MM-dd') }}",
                  "operator": {
                    "type": "boolean",
                    "operation": "true",
                    "singleValue": true
                  }
                }
              ],
              "combinator": "and"
            },
            "options": {}
          },
          "type": "n8n-nodes-base.if",
          "typeVersion": 2.2,
          "position": [660, 0],
          "id": "fdf179a3-e78f-4d53-9cb4-069871445fed",
          "name": "If"
        },
        {
          "parameters": {
            "authentication": "webhook",
            "content": "**🚨 iTHome 鐵人賽警告 🚨**\n@everyone \n<@YOUR_DISCORD_USER_ID>\n今天還沒有發文喔!再不寫就要斷賽啦!",
            "options": {}
          },
          "type": "n8n-nodes-base.discord",
          "typeVersion": 2,
          "position": [880, 100],
          "id": "80fdff87-081c-4fe4-8f23-c7387985eb54",
          "name": "Discord",
          "webhookId": "<REDACTED_WEBHOOK_ID>",
          "credentials": {}
        },
        {
          "parameters": {},
          "type": "n8n-nodes-base.noOp",
          "typeVersion": 1,
          "position": [880, -100],
          "id": "2e8a21ad-34db-4bd8-8391-3685b3f0e054",
          "name": "No Operation, do nothing"
        },
        {
          "parameters": {
            "aggregate": "aggregateAllItemData",
            "options": {}
          },
          "type": "n8n-nodes-base.aggregate",
          "typeVersion": 1,
          "position": [440, 0],
          "id": "2e31e8b0-7b45-463d-b117-7f5f4934a48c",
          "name": "Aggregate"
        }
      ],
      "connections": {
        "Schedule Trigger": {
          "main": [
            [
              {
                "node": "RSS Read",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "RSS Read": {
          "main": [
            [
              {
                "node": "Aggregate",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "If": {
          "main": [
            [
              {
                "node": "No Operation, do nothing",
                "type": "main",
                "index": 0
              }
            ],
            [
              {
                "node": "Discord",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Aggregate": {
          "main": [
            [
              {
                "node": "If",
                "type": "main",
                "index": 0
              }
            ]
          ]
        }
      },
      "pinData": {},
      "meta": {
        "templateCredsSetupCompleted": true,
        "instanceId": "<REDACTED_INSTANCE_ID>"
      }
    }
    

這樣就完成了一個可靠的鐵人賽發文通知小助理,再也不用擔心忘記發文而斷賽惹。也祝大家順利完賽!


上一篇
[Day28]_Threads 貼文備份-#5.END
系列文
告別重複瑣事: n8n workflow 自動化工作實踐29
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言