本篇大綱
2020.08.09 更新:今天收到信,有人詢問回覆訊息的問題,補充 回覆訊息 的判斷部份。
機器人選單 / 鍵盤 = 網頁導覽列
一個網頁想讓使用者知道整個站的內容,最重要的是導覽列。對機器人來說,要讓使用者知道有哪些功能,也是靠導覽列,不過機器人上不叫導覽列,LINE Bot 叫選單,Telegram Bot 就叫鍵盤(Keyboard)。
因為是先學寫 LINE Bot,轉到 Telegram Bot 時疑惑了一下,找不到選單的 API,後來文件看了半天,才知道 Telegram Bot 上是叫 Keyboard。
Telegram Bot 跟 LINE Bot 的名稱不同,所以功能上也有一個很不同的地方。
LINE Bot 的選單可以在使用者一進入機器人對話視窗時,就直接顯示出來。
Telegram Bot 預設是無法的,除非使用者傳過訊息給機器人,機器人回覆訊息時帶上鍵盤,或是機器人有了使用者的 id,在主動傳訊息時帶上鍵盤,要以上兩種情況,而機器人及使用者又沒關掉鍵盤時,使用者在每次進入對話視窗才會看到鍵盤。
本篇最後的結果,實際上都有放進自己寫的 Telegram Bot 上,可以從這加入:
本篇 Telegram Bot 是用 Webhook 的方式,Webhook 的 code 寫在 Google Apps Script 上,一些基本使用,比方如何接上 Webhook、如何在 Google Apps Script 上讀寫 Firebase、如何用 Telegram 發送訊息給使用者……等,因為前幾篇寫過了,這邊就不再寫:
- Telegram Bot 學習筆記 – 1:用 GCP + Node.js 接收 / 推播訊息
- Telegram Bot 學習筆記 – 2:用 Google Apps Script 接收 / 推播訊息
- Google Apps Script 基本使用:跨網域 AJAX、接 Firebase
Telegram Bot 的鍵盤,文件上 type 寫有四種:
這是廣告,點擊一下可以幫本站多個一點點的廣告收入,謝謝
- InlineKeyboardMarkup
- ReplyKeyboardMarkup
- ReplyKeyboardRemove
- ForceReply
第 3 種是移除鍵盤。
第 4 種是回覆某則訊息,就像 LINE 對訊息的回覆一樣。
3、4 不算是鍵盤,1、2 才是。
另外如果跟 BotFather 對話過,會發現它的鍵盤可以點擊後進入到第二層鍵盤,那個是屬於 Updating Messages 的功能。
統整這一段,本篇關於鍵盤會寫這五個功能:
- ReplyKeyboard
- InlineKeyboard
- 第二層選單效果:editMessageReply
- 移除鍵盤:ReplyKeyboardRemove
- 回覆訊息:ForceReply
Telegram Bot Keyboard 格式
Telegram Bot Keyboard,不論是 reply 還是 inline,寫 code 的格式都是這樣:
ReplyKeyboard
ReplyKeyboard 是一般回覆用鍵盤,可以把它當成是選擇題來用,當使用者點了鍵盤上的按鈕,就會主動發一個按鈕上的文字出去,比方按鈕上寫了「哈哈哈」,當使用者點了,就會發一個「哈哈哈」的訊息出去。
ReplyKeyboard 有四個參數可以用:
- keyboard:鍵盤內容,格式可看上一段 Telegram Bot Keyboard 格式
- resize_keyboard:手機上有用,鍵盤高度是不是要隨按鈕文字多寡而伸縮
- one_time_keyboard:桌機上有用,鍵盤是不是要按了一下就自動隱藏起來
- selective:是不是要針對特定使用者被提及時才發送鍵盤
想讓使用者使用鍵盤,就在 sendMessage 時加上 reply_markup
就行,以下是範例:
這是廣告,點擊一下可以幫本站多個一點點的廣告收入,謝謝
user_id
記得要替換成發送對象的 id。發送後會看到這樣子:


功能上的操作可看這:

InlineKeyboard
replyKeyboard 只是單純的回覆訊息功能,所以在 button 上只會寫 text。而 inlineKeyboard 的功能就比較多,可以加上網址,可以加上支付功能,也可以加上 callback_data 去觸發其它功能。
replyKeyboard 跟 inlineKeyboard 還有一個很大的不同,就是樣式。
replyKeyboard 是固定在底部的,inlineKeyboard 則是加在訊息之下,像這樣:

目前自己比較常用的到的參數是以下幾個:
- text:按鈕顯示文字
- url:要連結的網址
- callback_data:觸發某項功能
完整的參數請見說明文件:inlineKeyboardButton
text, url
這個部份比較簡單,就是在寫 keyboard
的陣列時,加進去就行了,以下是範例:
執行後會看見收到的訊息樣子:

callback_data
這個把它想像成「觸發」會比較好懂。
callback_data 後面是加一段字串,就像在填入 function 的名稱。
一般機器人收到訊息,訊息的 JSON 是這樣子:

而當 inlineKeyboard 的按鈕設了 callback_data,使用者按下了以後,雖然不像 replyKeyboard 一樣會發一個訊息出去,但機器人一樣會收到一段訊息,假設 callback_data 設成以下:
var inlineKeyboardCallback = [ [ { text: '這是一個測試callback_data的按鈕', callback_data: '/trigger-function' } ] ]
使用者按下後,機器人會收到的訊息 JSON 會是這樣子:

跟一般訊息的 JSON 對比,會看見 message 一樣存在,但是被包在 callback_query 底下,而 callback_query.data 就是我們寫在 callback_data 的值。
因此,只需要寫一個 if else
去判斷使用者按的按鈕,它的 callback_data 是什麼?然後執行不同的 function,就可以把這個按鈕當成是觸發 function 的功能按鈕了。
補充說明一下,這邊範例寫的 callback_data 是 /trigger-function
,之所以在開頭先加一個 /
,是一個習慣。主要是 Telegram Bot 在輸入 /
時,就會出現 Commands 選單,像這樣:

在 callback_data 開頭也用 /
,可以提醒那是一個觸發功能的值。
發送 inlineKeyboard 的範例 code 如下:
user_id
記得要替換成發送對象的 id。
製作第二層選單 Updating messages:editMessageReply
第二層 Keyboard 就是把第一層 Keyboard 給更新掉
一開始在 BotFather 上看到它的 Keyboard 可以點了以後,又進到下一層,還以為是在寫 Keyboard 的陣列時就要寫好的,實測後發現不是。
直到文件看到 Updating messages 這邊,才想到所謂的第二層 Keyboard,或是說第二層選單,其實就是把原本第一層的 Keyboard 給整個 update 成第二層的樣子,這樣在操作時就會有進到第二層的感覺。
要更新 Keyboard,用的是 editMessageReplyMarkup 這個方法,需要的參數有三樣:
- chat_id:要替換的 inlineKeyboard,它的使用者 id
- message_id:要替換的 inlineKeyboard,那則訊息的 id
- inlineKeyboard:要替換的新 Keyboard
對機器人來說,每一個使用者會有一個 id,而每一個訊息也會有一個 id,會用到第二層 Keyboard 的,要用 callbacl_data,這邊再看一次收到 callback_data 時,機器人接收到的 JSON:

沒錯,可以看見 from.id、message_id。
inlineKeyboard 才能 update
更新選單,只能更新 inlineKeyboard,傳新的選單時也只能給 inlineKeyboard。
結合上一段 inlineKeyboard 的 callback_data 功能,要加入第二層選單的範例 code 如下:
這段 code 實際的使用可以看這:

移除鍵盤 ReplyKeyboardRemove
Keyborad 在不用的時候,會縮成一個小按鈕,按了又會再出現。而實際操作上,會有要移除鍵盤,丟新鍵盤的狀況。
移除鍵盤跟給鍵盤的 code 很像:
回覆訊息:ForceReply
回覆訊息很簡單,只要在 sendMessage 時,force_reply 設為 true,如下:
user_id
記得要替換成發送對象的 id。
訊息發送後,看到的結果如下:

當使用者是回覆「回覆訊息」時,機器人一樣會收到「message」,但會多了一個「reply_to_message
」的物件,裡面會有的值就是誰針對哪一個訊息作回覆,這邊 August 把收到回覆訊息後的 data
寫進 Firebase 裡截圖來看:

reply_to_message.text
可以知道使用者是針對哪一個訊息在回覆。
reply_to.from
可以知道是哪一位使用者在回覆。
message.text
可以知道使用者回覆了什麼訊息。
有了這三個值,就可以針對不同的回覆,讓機器人去處理並回應。
Telegram Bot 學習筆記系列
- 用 GCP + Node.js 接收 / 推播訊息
- 用 Google Apps Script 接收 / 推播訊息
- 鍵盤 Keyboard
- 命令列 Commands
- 取得使用者大頭照
- Google 表單提交時收到通知


以下是留言,但關於留言的部份必需先讓你們知道:
本站的文章都是 August 因為覺得有趣,才會實作並整理成筆記文而後進行發表。
如果留言是希望把 Demo 改成「你想要」的樣子,或是把功能改成「符合你需求」的樣子,
Sorry~ 除非那修改是 August 也有興趣的,不然不會幫你們寫程式去面對工作或是交作業。
未來這類的留言不會再主動回覆。😎
另外,公開信箱是為了讓金流驗證用,
因為之前遇過幾次回信協助解決問題後,對方卻一聲謝謝也沒有,就這樣拿去幫工作交差。
因此決定不再回覆信件,有疑問就利用留言功能囉。