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
第三種是移除鍵盤。
第四種是回覆某則訊息,就像line對訊息的回覆一樣。
這是廣告,點擊一下可以幫本站多個一點點的廣告收入,謝謝
三、四不算是鍵盤,一、二才是。
另外如果跟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去trigger其它功能。
replyKeyboard跟inlineKeyboard還有一個很大的不同,就是樣式。replyKeyboard是固定在底部的,inlineKeyboard則是加在訊息之下,像這樣:

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

callback_data
這個把它想像成trigger會比較好懂。
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,就可以把這個按鈕當成是trigger 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
」的物件,裡面會有的值就是誰針對哪一個訊息作回覆,這邊 Augustus 把收到回覆訊息後的 data 寫進 Firebase 裡截圖來看:

reply_to_message.text
可以知道使用者是針對哪一個訊息在回覆。
reply_to.from
可以知道是哪一位使用者在回覆。
message.text
可以知道使用者回覆了什麼訊息。
有了這三個值,就可以針對不同的回覆,讓機器人去處理並回應。
Telegram Bot學習筆記系列

