Overview

寫 Telegram bot 其實很簡單,只是處理幾個 http request 而已。反而是 set up 還比較麻煩。

要建立 bot 大約要做以下步驟:

  1. 跟 BotFather 說要起機......械人
  2. 從 Telegram 收取 message
  3. 處理 message

Bot Father

建立一個 bot,當然要透過另一個 bot 去做。在 Telegram 找 BotFather,然後跟他對話即可。

設立簡介、名稱、command list 都要透過 BotFather 去做。完成後會得到一個 bot token ,等於是你的 bot password,請保存在安全的地方。

這時你已經可以在 Telegram 搜尋自己的 bot,也可以發訊息給它,當然它還不會回覆。

收取 message

要在你的 server 收到 message,有兩種方法:getUpdatessetWebhook

getUpdates

只要 GET https://api.telegram.org/my-bot-token/getUpdates,便可以得到 message array 回來,

此方法是我方主動跟 Telegram 拿取 message,乃最簡單獲得 messages 的方法。缺點是需自行使用 long polling 並定時執行才能獲取最新 messages。

setWebhook

另一方法則是使用 web hook。

POST 你的 web server address 到 https://api.telegram.org/my-bot-token/setWebhook 即完成。有新 message 時 Telegram 會主動通知我方。資料會以 POST 的形式發過來。

不過使用此方法需:

  1. 有一 public web server
  2. Web server 需支援 https

SSL 方面,若不想付費的話,用 self sign cert 也可以。

使用 self sign cert

可以用 openssl 來 generate certificate:

openssl req -newkey rsa:2048 -sha256 -nodes -keyout my-bot-cert.key -x509 -days 365 -out my-public-cert.pem -subj "/C=HK/ST=Hong Kong/L=My-NAME/O=My-ORG/CN=my-domain.com"

再用 setWehook 上載你的 public cert 上 Telegram:

curl -i -X POST -H "Content-Type: multipart/form-data" -F "certificate=@my-public-cert.pem" -F "url=https://my-web-server/my-bot.php" https://api.telegram.org/my-bot-token/setWebhook

PS: 其實不一定使用 curl,不過 setWebhook 需要使用 POST,並 upload certificate,最簡單的方法是使用 curl

應該使用哪個?

單從兩者可看出,一個是 pull, 一個是 push。要算即時性的話一定是用 setWebhook。但其實你的 bot 不是一秒有十個 message 的話,使用 getUpdates 已足夠迅速。另外 setWebhook 是 Telegram 跟你的 server 自動溝通,要 debug 的話較困難,所以在 debug 時可以選擇用 getUpdates,production 時才用 setWebhook

而每論使用那一個方法,最後都可以得到一個 message 的 json 。

處理 message

Message 大約是這個樣子:

{
    "update_id": 57743038,
    "message": {
        "message_id": 7,
        "from": {
            "id": 0000001,
            "first_name": "Goofyz",
            "username": "goofyz"
        },
        "chat": {
            "id": 0000001,
            "first_name": "Goofyz",
            "username": "goofyz",
            "type": "private"
        },
        "date": 1459783985,
        "text": "\/start"
    }
}

每個 message 都有發送者的 user_id, first_name 等,還有日期時間和最重要的訊息內容 text。若是圖片訊息便會有其他 fields,詳情可參閱官方文件。

之後便是你的 business logic 的領域。你可以回覆文字、儲存進 database,又或者干脆不理他們 (!)。

Something extra: Deep linking

如果想為 bot 做 authorization,或不想任何人都可以用你的 bot ,可以在 bot link 上加上 ?start=some-random-specific-text,如 https://telegram.me/goofyzbot?start=goofyz-secretly-love-whatsapp 。以此連結為開始的話,bot 便會得到 /start goofyz-secretly-love-whatsapp 作為 text,你便可透過處理此 argument 去做 authorization (或其他初始化動作)。

結語

老實說,Telegram Bot 很簡單,就只是收發 message 而已。但處理 setWebhook 比起寫 bot 更麻煩。我最初 setWebhook 後只得到 result: ok,但 server 就是收不到 message,根本不知問題出在那裏。最後才發現 self-sign cert 的 CN 要等於你的 server domain,BOOM。

最後,Telegram 實在比 WhatsApps 快很多,功能多很多,bot 令 Telegram Group 比 WhatsApps 更多玩法,實在值得轉用。可惜在任何 IM 上我也是單機

相關連結