Telegram 簡介
Telegram 是一款集成眾多優點(e.g., 快速, 自由, 輕量 etc.)的通訊軟體
不管是親友間閒聊,或是社群間討論,用 Telegram 都較 LINE 適合
Telegram API 類型
- Client API
- 使用電話號碼登入,等同於一般使用者帳號
- 無 inline button 等 bot 特色功能
- 大多應用可由 telegram-cli 達成
- Bot API(本文重點)
- 限制較多,如無法主動私訊使用者
- 每個使用者都可以向 @BotFather 申請至多 20 隻
如何產生 bot
想要一隻 bot 需要先有一個 Telegram 帳號(電話號碼驗證)
私訊 @BotFather 輸入 /newbot
他將會請您依序輸入 bot 顯示的名稱、 bot 的 username(必須為 bot 結尾),且長度需介於 5-32 字元
完成後, BotFather 會顯示您的 Token(格式:12345:AAJqs_w-4),您可利用此 Token 透過 HTTPS 發送請求
發起 API 請求
所有 Bot API 請求必須是 https://api.telegram.org/bot<Token>/<Method Name>
的格式,例如 https://api.telegram.org/bot12345:AAJqs_w-4/getMe
如果有 Android 手機,強烈建議用這個 app 測試 Methods,比較不會遇到 URL encode 等奇怪的坑
支援使用 HTTPS GET
及 POST
,可由以下四種方式挑喜歡的用
- URL query string
最通用的格式
e.g.,https://api.telegram.org/bot12345:AAJqs_w-4/sendMessage?chat_id=109780439&text=Hello+World
- application/json
作者個人最推薦,送出的資料比較好看 - application/x-www-form-urlencoded
長得跟 HTML<form>
的資料一樣 - multipart/form-data
上傳檔案只能用這種,類似application/x-www-form-urlencoded
回傳會是 JSON 內容,包含一個 ok
欄位,如果 ok
等於 true
代表請求成功,會包含 result
欄位,裡面是執行結果
反之則會有給人類看的 descript
錯誤描述,以及不一定會出現的 error_code
及 retry_after
所有 method 都是無視大小寫的,例如 getMe
跟 GeTmE
是相同的
所有請求必須使用 UTF-8
編碼
可參考官方文件相同章節
取得訊息
目前 Telegram 支援兩種取得更新的方法,分別為
- 設定 Webhook
- 在有人傳送訊息給您的 bot(或加入群組、點擊按鍵等)時, Telegram 將會使用 JSON 格式 POST 到您的伺服器
- 需使用 setWebhook 預先設定
- 可用 getWebhookInfo 自行 debug
- 可參考官方完整教學(英文)
- 每次主動詢問
- 以 getUpdates 請求,將會回傳一個 JSON 陣列
- 如語言支援,也可用 Long polling 取得,詳見 WiKi
接收所有訊息
預設隱私模式(Privacy Mode)是開啟的,開啟時只會收到:
- 由
/
開頭的指令 - 對機器人 Reply 的訊息
- 系統訊息(e.g., 新成員加入)
- 自己是管理員的頻道
通常會希望關閉,才收得到全部訊息
- 私訊 @BotFather
- 輸入
/setprivacy
指令 - 選擇 Bot
- 點擊
Disable
Webook 除錯
官方提供了獨立說明頁
- 需要 HTTPS(TLS 1.0)伺服器,並且將埠開在 443, 8443, 80, 8080 其一(就算 port 80 也要求 TLS)
- 伺服器要擁有 TLS 憑證,可以自簽並提供根憑證,但更推薦免費的 Let’s Encrypt,可參考此中文教學
看 Telegram 端有無錯誤
使用 getWebhookInfo 可以看目前狀態,如有錯誤還能從 last_error_message
找到點資訊
對自己的 Webhook 測試
如果上個步驟沒問題的話,這裡有幾個 payload 提供測試,能用 curl 模擬 Telegram 伺服器,測試自己程式有沒有什麼奇怪錯誤
傳送訊息
Telegram 是藉由 sendMessage 傳送訊息給使用者,下面列出幾個主要參數
- chat_id(必要選項)
- 私訊(Private)為正數(例如
109780439
) - 頻道(Channel)為負數(例如
-1001068773197
),也可以用@頻道名
(例如@HiNetNotify
) - 群組(Group)為負數(例如
-248855446
) - 超級群組(Supergroup)跟 Channel 完全相同(聽說是從 channel 改來的功能)
- 私訊(Private)為正數(例如
- text(必要選項)
送訊息內容 - parse_mode
未設定則為純文字,皆不支援複合使用(像是<b><i>重要</i></b>
)- Markdown
可以用[連結](url)
、*粗體*
、_斜體_
、`等寬字`
、```程式碼(等寬區塊)```
在有使用者輸入資料得環境不建議使用,如果解析錯誤 Telegram Server 會出現錯誤,無法發送訊息 - HTML
同一般 HTML 用法,支援b
、strong
、i
、em
、a
、code
、pre
非標籤的<
、>
、&
、"
需要 HTML entity encode(&
)後使用
- Markdown
標記使用者
直接於訊息文字內使用 @username
的格式就能 tag 到使用者
如果不想打擾到對方,可用 [@username](https://t.me/username){:target="_blank"}
方式,讓連結可點擊,但不會出現通知
對於沒有 @username
的使用者,能使用 User ID 以 [Name](tg://user?id=109780439)
的格式標注
Inline Keyboard
在大部分 method 都可以使用
Inline Button 可以用 text
搭配下列其一
- url
- callback_data
最長限 64 位元組 - switch_inline_query_current_chat
在該聊天室打開 inline query 介面 - switch_inline_query
同上,但會打開聊天室列表,供選擇要發在哪群
需特別注意 inline_keyboard
是放在 reply_markup
底下,且為兩層 Array 包按鈕 Object,如下所示
sendMessage {
"text": "Hello",
"chat_id": 109780439
"reply_markup": {
"inline_keyboard": [ // 第一層(row)
[ // 第二層(col)
{ // 第三層(button 本體)
"text": "OwO",
"callback_data": "test_data"
}
],
],
[
[
{ // 第二排 第一個
"text": "Open",
"url": "https://blog.sean.taipei/2017/05/telegram-bot"
}
]
]
},
}
如果點了 callback_data
的按鈕,會觸發 callback_query
事件,需用 answerCallbackQuery 回應
此請求需含
- callback_query_id(必要參數)
同update.callback_query.id
- text
要顯示的文字,為空則不顯示通知 - show_alert
如為true
則跳出對話匡,反之只會在聊天視窗上出現橫條 - url
限用 Telegram 內部連結
就算沒有東西要通知使用者,也該在處理完後發一個僅有 callback_query_id
的空請求,否則使用者會持續看到處理中的標示
可參考官方的介紹
Inline Bot
除了使用 /command
外,使用者亦可經由 inline query 與 bot 互動
如果啟用了 inline query ,使用者可以經由在對話框輸入 bot username 呼叫此功能
此功能可以在任何群組、私訊、頻道使用
如果要啟用此功能,須於 @BotFather 使用 /setinline
指令設定
收到 inline_query
後,需用 answerInlineQuery 回應
請求的 result
欄位必須為 Array of InlineQueryResult,格式如下所示
answerInlineQuery {
"inline_query_id": 471503396014238996,
"results": [
{
"type": "article",
"id": "unique",
"title": "Hello World",
"description": "Testing",
"input_message_content": {
"parse_mode": "Markdown",
"message_text": "*Hello World*!"
}
}
]
}
請參見 API 文件 或 Inline Bot 介紹
Inline Feedback
通常會提供不只一筆結果提供選擇,且預設對同關鍵字會快取五分鐘,不是每次輸入都會收到
預設當然是 Disable ,想分析用戶都點了什麼的話可以用 /setinlinefeedback 設為 Enable
如果您的 bot 很多人使用,怕被回傳訊息塞滿,可以調整成折衷的 1/10
, 1/100
, 甚至是 1/1000
,如此就只會收到特定比例的通知
HTML5 Games
機器人可以利用 HTML5 網頁讓使用者在群組、私訊發起挑戰,透過內建排行榜一較高下
如要申請,需向 @BotFather 使用 /newgame
,同意使用條款後依序設定標題、描述、預覽圖、GIF、ID
如果使用者用 https://t.me/Sean_Bot?game=starPusher
格式開啟,會直接發送預設內容與 Play <Name>
按鈕
也可以在回覆 inline query 時使用 InlineQueryResultGame 或用 sendGame
每個使用者點 Play 後,都會發送含有 game_short_name
的 callback_query
,需要用 answerCallbackQuery ,並將遊戲網址置於 url
參數
客戶端收到後會利用 In-App Browser 開啟遊戲網頁
排行榜需要由伺服器呼叫 setGameScore ,並須自行防堵作弊
Example: Foxmosa 推星星
調整 Bot 的五官
幾乎所有設定都要讓 @BotFather 處理,這裡也不例外,下面列出建議設定的資訊,讓 Bot 看起來完整點
/setname
改名字,應該不需多加解釋/setdescription
位於私訊 Bot,還沒開始對話時,顯示於空白聊天室的文字/setabouttext
顯示於 Profile 頁面,會出現在 username 上方/setuserpic
上傳新頭貼,要是方形的,否則被裁切會顯得奇怪/setcommands
更改在聊天室輸入/
時出現的列表,要注意指令只能由小寫字母、數字和底線([a-z0-9_]
)組成,例如show_info - 說明文字(可以空白)
格式
下載檔案
bot 收到的每個檔案都只會看到 file_id
,需經由 getFile 取得檔案路徑後,
到 https://api.telegram.org/file/bot<token>/<file_path>
下載
目前限制 bot 透過官方 API 不能下載大於 20MB 的檔案
PWRTelegram
非官方 API Proxy ,具有許多特色功能,但須自行承擔風險
支援用普通 user 帳號及 bot Token 登入
可參考專案網站上的 API Document 或 Awesome Telegram Bot app
聽起來很棒 但我該用什麼語言起手
通常會直接用熟悉的語言,各大語言皆有 Telegram Bot 的 Library
- PHP
- Node.JS
- Python
- Java
- Ruby
- bash(Linux Shell)
- 可以解析 JSON(jq)
- 具有發送 HTTPS 請求的能力(cURL)
可參考 Bot Code Examples,其中收錄十餘種語言的 lib repo
後記
Telegram Bot 功能繁多,無法一一列舉、介紹,僅就主要功能介紹,payload 範例也只附加於較複雜的 method
如有任何疑問歡迎隨時到 群組 討論
相關連結
官方 API 文件
FAQ(for bots)
Android 版 Bot 發送器 可用來體驗 Methods 用法
Telegram 傳奇
Stack Overflow 英文程度可以的話,可以直接上去發問
Telegram 群組
Telegram 機器人應用交流 測試、討論 Bot 相關問題
Telegram 推廣特區 中文化、各式應用交流
Telegram 頻道
Bot News 官方 Bot 新聞
Bots Channel
Telegram Geeks Telegram 新功能搶鮮報
Telegram 機器人
Bot Father 管理員
Bot Support Bot 專用客服中心
Telegram Bot Raw 可以藉此簡單查看 Bot API 收到的訊息長什麼樣子
Telegram Store Bot 列表及評分