Telegram bot學習筆記-1:用GCP + node.js接收/推播訊息

Augustus
Augustus
Jul 3, 2019 · 11 min read
node.js建立Telegram機器人:接收訊息、推播

本篇同步發表於:Let’s Write - Telegram bot學習筆記-1:用GCP + node.js接收/推播訊息

本篇大綱:

  • 為什麼從line bot轉到telegram bot
  • 建立Telegram機器人
  • 接收訊息
    getUpdates
    webhook
  • 推播訊息
    replay_markup
    parse_mode

為什麼從line bot轉到telegram bot

在「用line push messaging api推播每日氣象預報」這篇中提到,LINE@自從升成2.0後,原本開發用的方案沒了,而用SDK去發訊息的動作,也一律算進訊息數裡。免費的輕量級方案,一個月訊息量限500次,比方一則訊息要推播給10人,就算10次。不到一周訊息數就要超量,自動推播被擋。

在這種制度下,讓我開始找別的替代方案,就想到保密性很強的Telegram。

維基百科介紹:

Telegram是一個跨平台的即時通訊軟體,它的用戶端是自由及開放原始碼軟體,但是它的伺服器是專有軟體。使用者可以相互交換加密與自毀訊息,傳送相片、影片等所有類型檔案。官方提供手機版、電腦版和網頁版等多種平台用戶端;同時官方開放應用程式介面,因此擁有許多第三方的用戶端可供選擇,其中多款內建中文。

總之,它不像line@一樣拿訊息數來收費,而且也支援Node.js,就決定把所有推播功能轉到Telegram上。

目前建立的機器人在這,完成了Google Trend功能、新聞功能:


建立Telegram機器人

要新增一個Telegram的機器人很特別,不用寫什麼程式碼或是進到哪個後台新增,而是直接向他們的機器人申請,用機器人去新增機器人,很有機器人的感覺。

這個機器人叫「BotFather」,眾機器人之父啊~

安裝完Telegram,點了上面BotFather後,就會出現跟機器人的對話視窗:

BotFather的對話窗

按下「Start」,或在對話中輸入「/start」 ,就會出現所有功能的列表:

BotFather的所有功能

直接點選要執行的功能就行了,其實在輸入「/」時,也會看見所有項目:

輸入 / 會出現項目

跟建立機器人有關的是這幾個:

/newbot 新增機器人
/mybots 列出所有創建的機器人
/setname 修改機器人的名稱
/setdescription 修改機器人的描述,這個會出現在對話框的顯示訊息上
/setabouttext 修改機器人的資訊
/setuserpic 修改機器人大頭照
/setcommands 修改機器人command選單
/deletebot 刪除機器人

setcommands很好用,設定完會就會有像機器人這個 / 開頭的功能列表一樣,預設是一個「/start」。

要新增機器人,就是按 /newbot,接著會是問答式的填寫資料:設定機器人名字、ID。

ID的最後一定要是「bot」結尾。

名字跟ID設定完後,機器人就建好了,這時BotFather會傳一段訊息如下:

拿到機器人的token

紅色字的就是這個新機器人的token,這token很重要,所有的API都需要,有了token就可以用機器人發訊息,所以也不要亂傳出去,當別人有這個token,同樣也可以用你這隻機器人去發訊息,認token不認人的。

*截圖上的token,在這篇筆記文發佈後就會刪掉。


接收訊息

有了機器人後,機器人最基本的功能有2個:

  • 接受訊息
  • 發送訊息

接受訊息部份,Telegram提供2種方式,這2種方式只能選擇1種使用,不能都用:

  • getUpdates
  • webhook

getUpdates

這方式最簡單,只要輸入網址就可以看到訊息的json,網址如下:

https://api.telegram.org/bot{YOUR_BOT_TOKEN}/getUpdates

把 {YOUR_BOT_TOKEN} 替換成你的token,像本篇範例就是:

https://api.telegram.org/bot878308903:AAGvPIY5hThgh-0aIlunKYJKK1MN3TGCowQ/getUpdates

輸入網址後就可以看到結果,這邊傳一個測試訊息給機器人,會看到如下:

用getUpdates方式接受訊息

text就是傳的訊息,from就是傳訊息的人,from.id要記下來,用API發訊息時會用到,每一個傳訊息的人,機器人給的id都不同,是唯一碼。

用getUpdates的方法,好處是使用方便,直接GET網址就行。壞處是要一直GET,才能知道有人傳了訊息來。

webhook

webhook的優缺點跟getUpdates相反,建立方式比較複雜,還必須要是https,但當有人傳訊時可以立即觸發,不用一直GET。

因為在寫line bot時就是用webhook,所以本篇也採用webhook的方式。

要把機器人的接收訊息方式設成webhook很簡單,一樣是輸入一個網址,如下:

https://api.telegram.org/bot{YOUR_BOT_TOKEN}/setWebhook?url={YOUR_WEBHOOK_URL}

替換{YOUR_BOT_TOKEN}成你的token。
替換{YOUR_WEBHOOK_URL}為你的webhook網址。

Google一下telegram setWebhook,就會看見蠻多教學是講怎麼拿到webhook的網址。

這篇是直接用Google Cloud Platform放node.js,GCP產出的網址本身就是https,不會有憑證的問題。

如何在GCP上放一個node.js的app,可以參考這篇:

node.js如下:

node.js telegram bot webhook

用webhook的流程是這樣:

telegram bot接到訊息 → bot POST到webhook的網址。

這邊的webhook網址就直接用https://XXX.XXX.XXX/webhook。

所以在設定webhook網址時,本篇範例就是:

https://api.telegram.org/bot878308903:AAGvPIY5hThgh-0aIlunKYJKK1MN3TGCowQ/setWebhook?url={YOUR_GCP_URL}/webhook

{YOUR_GCP_URL}記得替換。

輸入完網址按下enter,設定成功就會看見回傳的json:

webhook 設定成功

以下示範的部份有另外將message存到firebase。

發送訊息後,/webhook被POST,訊息存到firebase:

webhook觸發存訊息到firebase

接受了訊息,就可以判斷訊息的關鍵字或是格式,讓機器人自動做出不同的回應,這部份會寫在下一篇。


推播訊息

機器人推播訊息,需要接telegram bot API。官方文件上有提供一些node.js的套件:Bot Code Examples

原本一開始是選用telegram-bot-api這套,後來發現直接用POST就可以使用telegram API,就放棄了套件,直接用POST。

Telegram Bot API的methods,說明文件在這:

使用methods很簡單,只需要POST的url後面加上要用的methods名稱就行。規則如下:

https://api.telegram.org/bot{YOUR_BOT_TOKEN}/{API_METHOD}

比方想傳送訊息,是用sendMessage這個method,那只要POST這個url就行:

https://api.telegram.org/bot878308903:AAGvPIY5hThgh-0aIlunKYJKK1MN3TGCowQ/sendMessage

data裡面帶入文件上列的parameter,範例code如下:

發出訊息的demo code

TARGET_ID就是接收訊息那一段的message.from.id。

接著打開網址,機器人就會發出訊息了:

成功發出訊息

message還有其他的參數可以用:

  • parse_mode:text裡要不要換成markdown或html格式。
  • disable_web_page_preview:如果訊息有網址,要不要顯示頁面預覽。
  • disable_notification:通知要不要轉成靜音。
  • reply_to_message_id:這個訊息是要回覆哪一則訊息。
  • reply_markup:叫出keyboard。

parse_mode、reply_markup,這2個參數讓訊息的方式變得很有趣。

replay_markup

主要是叫出鍵盤、訊息內選單、回覆格式,這三項功能用的,這部份比較複雜,看了好久才懂,實際的應用會寫在下一篇。

parse_mode

可以設成Markdown / HTML。自己比較常用的是html。

他們的html不是所有的都支援,目前支援的部份如下:

<b>bold</b>, <strong>bold</strong><i>italic</i>, <em>italic</em><a href="http://www.example.com/">inline URL</a><a href="tg://user?id=123456789">inline mention of a user</a><code>inline fixed-width code</code><pre>pre-formatted fixed-width code block</pre>

如果出現不是這上面的html,訊息就會發不出去。

這邊也試發一個:

發送html格式訊息的demo code

換行的部份用「\n」。

收到的訊息如下:

發出html格式訊息

關於Telegram Bot的接收訊息、推播訊息就寫到這。

本篇參考了2篇教學,如下:

Augustus Front-End study notes

Augustus,前端工程師的學習筆記

Augustus

Written by

Augustus

努力學習中的前端工程師。目前心得:前端是條不歸路啊孩子……https://letswrite.tw/

Augustus Front-End  study notes

Augustus,前端工程師的學習筆記

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade