在前面幾篇我們有透過BotFather為機器人建立Command了,但是我們僅僅是做好一個方便輸入的選單,點選Command後並沒有任何功能,現在就讓我們為他們加上功能吧!
我們在實作之前必須要有一個對於訊息傳送的觀念。
當我們從GAS操作機器人傳送訊息到使用者上,使用者就可以針對訊息做接收或回覆。
而現在我們要做的是在接收到訊息後再根據訊息內容做出回覆。
我們先來寫當我們接收到Command後該如何做回覆。
在這邊我的想法是新增一個gs檔,裡面寫一個sendtext()
方法,這個方法用來做所有的command,只要判斷收到的command內容相符合就針對command來定義回傳內容是訊息或是方法等等。
function sendtext(estringa){
var chatid = estringa.message.chat.id.toFixed();
var payload;
if (estringa.message.text){
if(estringa.message.text === "/shark") {
payload = {
"method": "sendMessage",
'chat_id': chatid,
'text': 'shark!!!'
}
return payload;
}
}
}
第2行:取得用戶ID,我在後面特別加上了一個toFixed()
,這樣可以避免回傳的使用者id出現科學記號無法辨識的情況。
第6行:如果收到的message是””
內的字串,則將payload
設為我們要傳送的訊息,這邊也可以執行方法,直接將payload
整段改為function名稱就可以了,例如:keyboards()
。
第7-11行:這邊可以根據自己需求來調整內容,例如收到訊息回傳訊息、圖片或聲音等等。
第12行:payload
的內容設置完後則返回最一開始的payload
,在收到下個訊息後即可繼續執行判斷式。
如果是callback_query則要另外寫一個方法,因為就如同上一篇所說到的,callback_query和一般的message.text回傳回來的內容是不同的,所以要分兩個方法來寫。callback_query的設定可以參考上一篇文章。
function callbackQuery(estringa){
var callback_chatid = estringa.callback_query.message.chat.id.toFixed();
var payload;
if(estringa.callback_query){
payload = {
"method": "sendMessage",
'chat_id': callback_chatid,
'text': '測試callback',
};
if(estringa.callback_query.data.indexOf("chinese") === 0){
payload.text = "感謝";
}
if(estringa.callback_query.data.indexOf("english") === 0){
payload.text = estringa.callback_query.data + "Thank you";
}
if(estringa.callback_query.data.indexOf("japanese") === 0){
payload.text = estringa.callback_query.data + "ありがとうございました";
}
if(estringa.callback_query.data.indexOf("korean") === 0){
payload.text = estringa.callback_query.data + "감사합니다";
}
return payload;
}
}
第4行:這邊變成是判斷是否為callback_query
第6-10行:這裡是我用來測試前面第四行的東西,假設我確實有得到回傳回來的callback_data
值,不管那個值是什麼,就會傳送我設定的文字。
第11-23行:再來這段程式碼就是用來判斷callback_query的內容是否會等於一開始設定callback_data
的值,如果是的話就將payload的內容改掉。
我在這邊後面還多寫了estringa.callback_query.data
這個參數,假設我們想要保留callback_data
的值就可以用上這個,使用的效果如下圖。
上圖點下中文因為沒有設置estringa.callback_query.data
所以只有傳出payload
的訊息,而點下英文則因為有加所以前面多了callback_data
的值。
而我們寫好接收到訊息後該怎麼設定回傳的內容後,我們還要做一件事情,也就是把訊息傳出去!
接收到訊息之後如果沒做回覆,這就不是我們當初的設計了,也就是說我們現在要在接受訊息的程式碼後面加上傳送訊息的方法。
改寫一下doPost
方法
function doPost(e){
var estringa = JSON.parse(e.postData.contents);
var d = new Date();
var SpreadSheet = SpreadsheetApp.openById("1h9kJrX7bIdrGqiwUP6Bf45JQ5iMlWdYLXWFRpcq6gOQ");
var Sheet = SpreadSheet.getSheetByName("收到的訊息");
var LastRow = Sheet.getLastRow();
Sheet.getRange(LastRow+1, 1).setValue(d);
Sheet.getRange(LastRow+1, 2).setValue(estringa);
if(estringa.message){
var payload = sendtext(estringa);
}
if(estringa.callback_query){
var payload = callbackQuery(estringa);
}
start(payload);
}
可以看到我在中間還有特別加入一個if判斷式,用來判斷接收到的值是message還是callback_query,判斷完再依序去執行不同方法,如果只有寫一個方法的話可以不用寫if判斷式,直接加上
var payload = 方法;
start(payload);
if(estringa.message)
這行特別提一下,原先我是寫if(estringa.message.text)
,但是在執行的時候出錯了,我發現在同時執行兩個方法時只有接收到message會有反應,callback_query卻沒有。
而我完全找不到問題出在哪,後來詢問了朋友才獲得解答,因為如果執行callback_query時,會沒有message回傳,而message.text
不能是空字串,也因此在執行到if(estringa.message.text)
這行時會出錯,程式到此就停止運作了,所以才要改成if(estringa.message)
,在使用上要特別注意。
寫好之後部屬,就可以看到傳送特定的command後,機器人就會做相應的回覆。
綜合回應message方法和callback_query方法就會像下圖這樣的情況,這邊我用到了上面提到的,把判斷為message後回傳訊息的payload
改成執行方法,將輸入/thank_you的回應設為keyboards()
方法。
這樣一來就可以在我輸入文字時透過message來回傳Inline keyboard,再接著透過callback_query來回傳message,如此一來就可以做很多的設計,這個就看各位的創意囉~