應該不少人都有玩過 IFTTT 的服務,可以建立起非常強大且方便的自動化工作流

它的主要原理跟工作流程是「如果 OOO 變成 YYY 以後,就進行 XXX 的動作」

舉例來說可以是「如果明天天氣預報會下雨,就發簡訊或者郵件通知我」、「如果收到某人訊息,就加到重要代辦事項」等等

IFTTT 目前可以免費試用,最多開三個 Applets,且每個 Applets 檢查更新頻率在一小時

如果你想要解除限制的話,就需要訂閱他們的 IFTTT Pro 服務,可以享有無限 Applets 且每五分鐘就能更新一次的服務

不過今天要介紹的是另外一款有類似功能的工具 n8n,支援的服務也相當多

而且是免費開源,也能自己架設在自己伺服器上,甚至可以跑自己寫的腳本,所以可自定義性更強,相當的不錯

n8n 介紹影片:

前段時間我自己也架了一套出來玩玩,觀察幾天運作相當穩定,所以寫一篇記錄一下

不過因為 n8n 自定義功能強大,玩法相當多,無法靠三言兩語講完,所以這篇只會有 RSS to Telegram 的例子

其他部分留待自己開發出更適合你自身的玩法 😚

大概流程分為以下兩部分:

  • 使用 Docker 快速建立一套開箱即用 n8n
  • 監測某 RSS Feed 出現關鍵字時,用 Telegram 私訊通知你,或者發送到某 Telegram 群組 or 頻道裡面

Docker 安裝 n8n

Docker 的執行環境請參考其他文章,或者有些人喜歡安裝在 NAS 裡面也可以

而 n8n 的 Docker 版本也相當簡單,沒有太多什麼需要額外設定的選項,我們只要先建立一個資料夾給 n8n 放資料庫即可

以後只要備份這個資料夾即可

mkdir ~/n8n-data

之後下面指令全部複製起來貼上執行,就能建立起一個 n8n 容器

docker run -d \
--name n8n --restart unless-stopped \
-p 5678:5678 \
-v ~/n8n-data:/home/node/.n8n \
n8nio/n8n

稍等幾秒系統自動部署完成以後,打開瀏覽器輸入伺服器的 IP 加上 5678 連接埠即可進入到 n8n 首頁了,超簡單 😗

RSS to Telegram

這部分我已經準備好模板了,你可以監測所有新 RSS 內容通通給你發通知,也可以只有出現某些關鍵字時候才發通知

請拷貝以下所有內容,直接在瀏覽器的 n8n 新的 workflow 中貼上即可

{
  "name": "RSS to Telegram",
  "nodes": [
	{
	  "parameters": {},
	  "name": "Start",
	  "type": "n8n-nodes-base.start",
	  "typeVersion": 1,
	  "position": [
		-560,
		390
	  ]
	},
	{
	  "parameters": {
		"chatId": "",
		"text": "=💹 #日幣匯率 {{$json[\"title\"]}}\n\n{{$json[\"link\"]}}",
		"additionalFields": {}
	  },
	  "name": "Telegram",
	  "type": "n8n-nodes-base.telegram",
	  "typeVersion": 1,
	  "position": [
		440,
		30
	  ],
	  "credentials": {
		"telegramApi": ""
	  }
	},
	{
	  "parameters": {
		"url": ""
	  },
	  "name": "RSS Feed Read",
	  "type": "n8n-nodes-base.rssFeedRead",
	  "typeVersion": 1,
	  "position": [
		-359.5,
		130
	  ]
	},
	{
	  "parameters": {
		"functionCode": "const staticData = this.getWorkflowStaticData('global');\n\nlatestRead = staticData.latestRead;\n\nfor (let item of items) {\n  item.json.latestRead = latestRead || '2021-06-01';\n}\n\nreturn items;"
	  },
	  "name": "Latest Read",
	  "type": "n8n-nodes-base.function",
	  "typeVersion": 1,
	  "position": [
		-160,
		130
	  ]
	},
	{
	  "parameters": {
		"conditions": {
		  "number": [
			{
			  "value1": "={{new Date($node[\"Latest Read\"].data[\"latestRead\"]).getTime()}}",
			  "value2": "={{new Date($node[\"RSS Feed Read\"].data[\"isoDate\"]).getTime()}}"
			}
		  ],
		  "boolean": [],
		  "string": [
			{
			  "value1": "={{$json[\"title\"]}}",
			  "operation": "contains",
			  "value2": ""
			}
		  ]
		}
	  },
	  "name": "IF",
	  "type": "n8n-nodes-base.if",
	  "typeVersion": 1,
	  "position": [
		40,
		130
	  ]
	},
	{
	  "parameters": {
		"functionCode": "const staticData = this.getWorkflowStaticData('global');\n\nif (items.length > 0) {\n  staticData.latestRead = items[0].json.isoDate || staticData.latestRead;\n}\n\n\nreturn items;"
	  },
	  "name": "Write Latest Read",
	  "type": "n8n-nodes-base.function",
	  "typeVersion": 1,
	  "position": [
		240,
		30
	  ]
	},
	{
	  "parameters": {},
	  "name": "NoOp",
	  "type": "n8n-nodes-base.noOp",
	  "typeVersion": 1,
	  "position": [
		230,
		270
	  ]
	},
	{
	  "parameters": {
		"triggerTimes": {
		  "item": [
			{
			  "mode": "everyX",
			  "value": 1
			}
		  ]
		}
	  },
	  "name": "Cron",
	  "type": "n8n-nodes-base.cron",
	  "typeVersion": 1,
	  "position": [
		-560,
		130
	  ]
	}
  ],
  "connections": {
	"RSS Feed Read": {
	  "main": [
		[
		  {
			"node": "Latest Read",
			"type": "main",
			"index": 0
		  }
		]
	  ]
	},
	"Latest Read": {
	  "main": [
		[
		  {
			"node": "IF",
			"type": "main",
			"index": 0
		  }
		]
	  ]
	},
	"IF": {
	  "main": [
		[
		  {
			"node": "Write Latest Read",
			"type": "main",
			"index": 0
		  }
		],
		[
		  {
			"node": "NoOp",
			"type": "main",
			"index": 0
		  }
		]
	  ]
	},
	"Write Latest Read": {
	  "main": [
		[
		  {
			"node": "Telegram",
			"type": "main",
			"index": 0
		  }
		]
	  ]
	},
	"Cron": {
	  "main": [
		[
		  {
			"node": "RSS Feed Read",
			"type": "main",
			"index": 0
		  }
		]
	  ]
	}
  },
  "active": true,
  "settings": {
	"timezone": "Asia/Taipei",
	"saveExecutionProgress": "DEFAULT",
	"errorWorkflow": "3"
  },
  "id": 2
}

貼上以後就會完整匯入所有 node,應該會看見下面這樣

我們先編輯 Cron 的 node,這個是用來設定整個 workflow 隔多少時間執行一次

Trigger Times 自己根據自己需求來設定,因為是架在自己伺服器上,所以更新頻率請隨意

你可以設定一個小時跑一次,也可以設定一分鐘跑一次都可以,但不建議太頻繁,不然你 IP 有可能會被該服務加黑名單

設定好之後,點右上角的 X 即可

接著來到第二個 RSS Feed Read 的 node,一樣點兩下之後即可進入編輯

如上圖裡面只有一個 URL 的欄位,請把你要監測的 RSS Feed 貼上即可

我這邊示例的是 PTT 日旅版 RSS Feed( https://www.ptt.cc/atom/Japan_Travel.xml

設定完同樣右上角 X 退出

再來到 IF node 判斷,點兩下進入編輯

如上圖,大部分欄位都已經有預設值,你也可以根據自己需求修改,如果沒有修改的話,就是會監測 RSS Feed title 的欄位

在 String 的 Value 2 欄位,填上你想要監測的「關鍵字」,也就是說在這個 RSS Feed title 出現「匯率」的關鍵字時

就會觸發這個 IF node

再繼續下一個 Telegram 以前,我們要先去做幾個準備動作

首先先去 Telegram Bot Father 那邊註冊一個新機器人,在 Telegram 搜尋「@BotFather」,或者點 https://t.me/BotFather

之後按下 Start,在輸入 /newbot 給它

BotFather 就會開始詢問你幾個問題,依照提示回答即可

如上圖,輸入完 /newbot 以後它會問你,你的機器人要叫什麼名字?這裡可以隨意取

第二個是幫機器人取一個 ID,機器人 ID 取名限制是末三位需要 bot 結尾

所以你可以取 TetrisBot 或者是 tetris_bot 都可以,只要注意末三位是 bot 即可

回覆 ID 以後,機器人就開好了,並且它會把機器人的訪問 API 發給你,這段代碼請自己保存好

必須當密碼一樣保存,因為任何人只要有這段代碼都可以控制你的機器人

建立好機器人以後,請自己先主動私聊 /start 一次自己的機器人,只有主動私聊 /start 過,機器人才能給你發訊息

再來我們要獲取你的 Telegram ID,請在 Telegram 搜尋「@my_id_bot」,或者點 https://t.me/my_id_bot

跟這個機器人私聊 /start 以後,它會馬上把你的 Telegram ID 發給你

如上圖,這個 Telegram ID 我們就可以拿去填到 n8n 的 Telegram node Chat ID 裡面即可

那如果你是想要 Telegram 在群組或者頻道裡面主動發訊息的話,也可以透過這個 My ID 機器人查詢群組或頻道 ID

群組的話,你只要把這個 My ID 機器人邀請進去即可,他一進群之後馬上就會吐出該群的 ID

頻道的話,請你轉發該頻道任何一條訊息給它即可

另外要注意的是,想要機器人主動在群組或者頻道講話,都是需要邀請你新建的機器人到裡面才可以的喔!

新建好機器人,並順利拿到 Telegram ID or Chat ID 以後,我們就又可以回到 n8n 繼續設定下去

同樣左鍵點兩次 Telegram node,進入到 Telegram node 設定頁

Chat ID 可以先填上面步驟拿到的 Chat ID

Telegram API 我們點進去新增一個機器人「Create New」

依照上圖操作即可,最後按右下角的「Create」即可新增好你的 Telegram 機器人到 n8n 裡面

如上圖,設定完畢後,右上角的 Save 保存一次,然後直接把 Active 開關打開,如此就能啟動這個 n8n workflow 囉!

收到的 Telegram 效果如上圖,再也不會錯過任何你有興趣的話題了

如果你有在經營某個遊戲社群的話,就能使用這玩意監測 PTT Stream 版的「限免」關鍵字

即時轉發到你的頻道或者群組喔!PTT Steam 的 RSS 地址如下:

https://www.ptt.cc/atom/Steam.xml

n8n 官網上面也有許多人寫好的 workflow 可以參考,拷貝回來後自己加以修改即可為己所用

https://n8n.io/workflows

n8n 支援的平台也相當多,常見的像是 Mailgun、Github、Google Sheets、HTTP request、Notion、Slack、Trello 等等都有

有興趣可以搭一套這個酷東西出來摸索玩玩,真的相當不錯喔! 🖖