用 VPS 建 Webhook Server 小筆記
在以前,我可能會用爬蟲的方式去拿一些資訊,但沒串接到一些通訊軟體上面
這次簡單紀錄一下在串接第三方服務的一些指令與流程
背景
使用情境的話,大概會是 :
- 某個 Application 偵測到特定條件,通知 Webhook Server
- 例如我寫了爬蟲,發現 あみた 出了新影片
- Webhook Server 收到通知,然後進行相關訊息轉送
- 例如我有一支程式,在收到通知後他會寄一封信到我的 Mail,同時在 Line 通知我。
- 也有可能這個 Webhook Server 是通訊軟體商提供,你直接送過去,他就會有訊息通知。
你可能會說,那為何不要我寫爬蟲時同時 run 一些 bot 然後直接做多方面通知 ?
其實是可以,但是發通知的可能是多種程式 (例如你今天有爬 あみた 影片的、可能也有商品開賣的)
而且今天也許並不需要你自己寫程式,而是某個 SaaS 會做特定工作,然後提供一個功能 :
" 你可以給我們一個 webhook url,如果我工作完成了就告訴你 ! "
那你還是得自己弄 webhook Server 來做接收,或是直接找一些提供 webhook url 的通訊軟體。
在市面上有一些已經整合的不錯的服務,例如 IFTTT
他就可以達成上面的 "Webhook Server" 的工作,只要你寫的程式去觸發 webhook,
IFTTT 可以幫你用 Line、Telegram、Mail 等等方式通知你。
但最主要的缺點就是會有時間週期的限制,一點也不即時。
準備工作
- 你需要有一支程式負責做某項工作,然後讓他來發通知。
- 你需要一個 VPS 或是能夠建立實體 IP / 或 DNS 網址的 Server 來當作 Webhook 的觸發平台
- 你需要有 "你想接收通知" 的通訊軟體的 bot 或廠商提供的 webhook url。
我這邊只舉例我用到的,但既然是工程師的話,我想您一定能夠推敲出更改的方案 XD
如果不知道怎麼做,想了很久仍然找不出合適方式,也可以在下方提出討論。
建立發通知的程式
這邊舉三個例子。
其實,不必想太多,Webhook 的觸發基本上 只是發送一個 POST
幾乎就只是在實作 post 這件事而已,用 js 甚至都能寫。
Python
1 | import requests |
透過現有服務方
像是這個服務方,他提供讓我們輸入 webhook url 來讓他們去做 request 動作
我們在後面的過程建好 Webhook Server 後,就可以將網址填到欄位裡面。
透過 cURL
如果有當過網管、或是因為某些需求需要測試網路,應該對這個不陌生。
(我沒當過,所以我很陌生其實)
但總之呢,Linux 內通常都會內建這樣的工具,讓你去做一些基本的 GET/POST 或測試操作。
這邊提供一個工具,可以讓你直接模擬 POST 的動作
REQBIN: How do I POST JSON with Curl?
填好對應欄位,再按 Run,就能直接做測試。
也就是說,想要確認你的 Webhook Server 有沒有問題,可以直接用這個來當作測試
(用 Postman 也可以,不過很多 Webhook 服務方會用 cURL 做舉例,剛好搭配這個工具)
1 | curl -X POST http://your_server/webhook |
建立能夠串接的通訊軟體 Bot
這邊要做的是,我們在中介層中,接到通知後,要去啟動相對應的 bot 然後在通訊軟體裡面告訴你。
(中介層 : 負責接收服務方打過來的 POST 的程式,也就是 webhook server,下一個段落會細說)
常見的通訊軟體 :
- Line (之後會有一篇文章記錄,也非本次會提及)
- Telegram
- Discord (但這個建議直接用頻道內建的 url,所以這邊不提及。)
這次我是使用 Telegram 來申請相關服務,所以主要是記錄這部分的。
流程 :
- 搜尋好友
@BotFather
和@getidsbot
,將他們加入好友。 - 對 @BotFather 輸入指令 :
/newbot
,然後輸入你的bot想取的名稱
,再輸入他的專有id且一定要bot三個字結尾
,然後你就會得到一組 token 像是123456789:ABCd_qgergrgjeigroXgrG_cGEGge_GEGeeAY
之類的。 - 打開 Telegram -> 建立頻道(Channel) -> 邀請你剛剛建立的 bot
- 在頻道隨便打一則訊息,然後按出現在訊息旁邊的 "分享",分享給
GetIDs Bot
- 然後上面那個 Bot 會告訴你
Origin chat
的 id 是多少,記錄下來。
再來就是 Bot 怎麼發送訊息到 Channel 內
有兩種方式 : 一種是直接用基礎的 GET/POST 來發送,用 request 就能做了,且各種程式語言都能。
另一種則是使用相關 Library,例如 Python 的。
下面會給一個範例,但根據版本也許不一定能正確執行,僅供參考。
當然,下面這樣的程式,是在 Webhook Server 收到通知後,要去執行的
這個段落僅僅是為了講解 Telegram Bot 相關使用的流程,所以提及下面的程式碼。
1 | from telegram import Bot |
建立 Webhook Server
這邊則是要講解要建一個 Webhook Server 需要哪些要素。
- 要有獨立 IP 或是能夠被其他 Client 觸及的域名之類的。
最好的方法是用 VPS,VPS 可以申請一個靜態域名。
我自己是有 VPS,所以寫完之後,再改 Port 就完事了。
雖然我沒有試過,但是像是宿舍沒有個人 IP 的電腦也許可以用 Ngrok 解決。 - 要寫一支可以監聽 POST 的程式。
我自己是使用 Python Flask。 - 該程式在聽到 POST 動作後,可以做一些判斷,然後去執行上面提供的 Telegram 程式碼。
Flask 的監聽範例
1 | import json |
上面這支程式會監聽您的 VPS 的 80 port,且只會對 POST 的動作有反應。
假設您的 IP 是 100.100.100.100
,那您的 webhook url 就是 100.100.100.100/webhook
(在 @app.route
有定義,只監聽 /webhook
route。)
但如果您的 VPS 有使用到 Apache 之類的來做 HTML Server 之類的用途,
那可能會因為 80 Port 被占用而相衝。
解決 80 Port 被佔用問題
這邊有兩個解法 :
在程式內把 port=80 改成 port=8888 之類的。
但缺點是,有些服務商在送 Webhook 時拒絕送 80 port 以外的。
這種時候就需要下面的解法,
把占用 80 port 的程式給改掉設定,例如 Apache 預設是聽 80 port。如何去改掉 Apache 的預設監聽值 ?
可以參考這篇文章 : How to Change Apache HTTP Port in Linux
1 | # 1. 編輯 ports.conf |
如何讓程式常駐
如果是透過 ssh 連到 VPS,那在關閉連線後可能會關閉程式。
您可以透過 pm2 或是內建的 tmux 來達成在背景執行。
原本我想嘗試 PM2,但是他的 deb 安裝方式 ... 官方的 Lib 有問題
後來忙於其他事就先用 tmux 用用。
Tmux 部分,可以參考我的文章 我終於會用 tmux 啦 !
這邊也簡單的複習一下使用方式 :
1 | # 進入 tmux |
測試
統整一下上面的資訊 :
訊息傳遞流 :
- 從觸發端(自己寫的程式、服務商) 發送 POST
- Webhook Server 收到 POST,然後做相對應處理,可以是寄 Mail 或是 Bot 傳訊息
- Bot 會在你的頻道內輸出訊息。
觸發端,可以用 cURL 測試最簡單,或是自己用 Python、Javascript 去發送 Request。
Webhook Server,可以自己建或是使用網路上既有的服務如 IFTTT。
在 Webhook Server 接收到 POST 之後,可以再串通訊軟體提供的 API 這樣。
結語
這邊先道歉一下,並沒有將整個完整的程式碼提供出來
主要是有些 local 設定,上面那樣的貼法將各個功能簡單化我覺得不錯
如果對流程的概念熟悉,其實上面的資訊很夠了;
作為參考,希望能給您帶來一些靈感。
(而且其實幾乎可以直接用上面的程式碼去串,要改一些參數傳遞 config 就是)
Telegram 拿來當作 Bot 的接收其實挺不錯的
因為 Line 和 Discord 比較常拿來聯繫朋友,
每次有通知看到橘色的 icon 亮在那邊就會有強迫症要點掉
而且 Bot 通知太多的話聲音很煩。
Reference
How to Change Apache HTTP Port in Linux
Telegram Bot機器人申請與Webhook指令全紀錄
用 Python 打造自己的 Telegram Bot!
Github 也有很多已經做好的 Repo,建議直接找找看您使用的服務有沒有可以串的 !
![](https://i.imgur.com/888jFLr.gif)