這是「給不會寫程式的人的惠惠機器人開發攻略」的第五篇。
開發一個聊天機器人可能會遇到需要針對不同的使用者儲存資料的狀況,這個時候就會需要一個資料庫了。我們將會使用 Firebase 的 Realtime Database 作為資料庫。
Firebase 設置
Firebase 的設置可以直接看這篇文章。
Google Apps Script 連接 Firebase - 哈哈姆特不EY聊天機器人(作者:Jia)
大概的流程是這樣:
進入 Google Apps Script >【資源】>【程式庫】>【輸入MYeP8ZEEt1ylVDxS7uyg9plDOcoke7-2l】>【選擇 Public Release】
GAS 設置完成之後,到 Firebase 新增一個專案。
取得 FIREBASE_URL:
左邊選單點【Database】>【Realtime Database】
取得 FIREBASE_SECRET:
左上角點齒輪圖示 >【專案設定】>【服務帳戶】>【資料庫密鑰】
然後把 FIREBASE_URL 和 FIREBASE_SECRET 跟這段程式碼丟進 GAS 裡面。
var FIREBASE_URL = "你的 Firebase URL";
var FIREBASE_SECRET = "你的 Firebase Secret";
var db = FirebaseApp.getDatabaseByUrl(FIREBASE_URL, FIREBASE_SECRET);
這樣就完成了。
我們可以使用db.setData(path, value)
來寫入資料。
使用db.getData(path)
來取得資料。當找不到資料時它會回傳null
。
註冊功能
firebase 是 NoSQL 資料庫,資料是一層一層的 JSON。
我們可以在 user/巴哈ID/state 這個路徑儲存玩家的狀態。
接下來我們稍微修改一下doPost(e)
裡面的東西。
類似這樣:
function register(id){
db.setData("user/"+id,"menu");
botReply("初次見面,我是惠惠。");
}
function doPost(e) {
var postContents = JSON.parse(e.postData.contents); // "e.postData.contents" 這裡使用了 Dot Notation
var msg = postContents.messaging[0].message.text; // msg 是使用者輸入的訊息
senderId = postContents.messaging[0].sender_id; // senderId 是使用者的巴哈ID
var userState = db.getData("user/"+senderId+"/state");
if (userState == null) {
register(senderId);
// 使用者在傳送第一個訊息給機器人時,就只會進行註冊的動作,不會觸發下面的 else 。
} else {
botReply("你好");
}
}
有了資料庫之後,就可以儲存各種東西。例如在 user/巴哈ID/exp 儲存經驗值,在 user/巴哈ID/status 儲存好感度之類的。
教惠惠說話
一句一句設計對話太累怎麼辦?可以做一個讓使用者教聊天機器人說話的功能,還可以讓使用者盡情發揮創意。
我們可以設計一個像這樣指令教惠惠說話:
/l 你是誰;我是惠惠
/l 你會什麼;爆裂魔法
在中間放一個分號來分輸入句和輸出句。
然後在 GAS 用slice()
來切割訊息字串。像下面這個樣子就可以依照分號的位置切成兩邊。
if(msg[0] == "/"){
if(msg[1] == "l" && msg.length >= 6 && msg.indexOf(";") >- 1){
var msgInput = msg.slice(3,msg.indexOf(";"));
var msgOutput = msg.slice(msg.indexOf(";")+1,msg.length);
db.setData("reply/" + msgInput, msgOutput);
db.setData("replySetter/" + msgOutput,senderId); // 用來記錄誰記了什麼,免得有人搗亂
botReply("好的,現在惠惠看到「" + msgInput + "」\n就會回答「" + msgOutput + "」");
}
}
資料庫裡面會長這個樣子:
接下來也要讓惠惠可以回覆學會的句子。
var replyMessage = db.getData("reply/" + msg);
if(replyMessage != null){
botReply(replyMessage);
}else{
botReply("惠惠看不懂這句話");
}
接著我們再改良一下 else 的部份,讓惠惠碰到沒看過的句子也能學習如何回答。
else{
botReply("惠惠看不懂這句話,請問我看到這句話要怎麼回覆呢?");
db.setData("user/" + senderId + "/msgInput", msg);
db.setData("user/" + senderId + "/state", "setReply");
}
在惠惠遇到沒看過的句子時,會把使用者的狀態設為"setReply",同時記下使用者的巴哈ID和訊息,並詢問使用者該如何回覆。
然後當使用者的狀態是"setReply"時,就要把使用者的訊息記錄為回覆的句子,最後把使用者的狀態改回"menu"。
if (userState == null) {
register(senderId);
} else if (userState == "setReply") {
var msgInput = db.getData("user/" + senderId + "/msgInput");
db.setData("reply/" + msgInput, msg);
db.setData("replySetter/" + msg,senderId);
botReply("好的,現在惠惠看到「" + msgInput + "」\n就會回答「" + msg + "」");
db.setData("user/"+senderId+"/state","menu");
}
然後就可以玩接龍了。
結語
下一篇會介紹如何串接 Tenor API 並傳送隨機 gif。