大家好,小弟第一次發文沒有程式背景,看了幾位前輩的文章,使用Google Apps Script想要做一個有查詢跟記錄功能的機器人,目前先做了查詢的部分,if((userData.events[0].message.text) == "查詢熱量"
接著呼叫
search(e)
但是這個查詢的參數要怎麼樣再傳進去我在LINE上輸入的字呢?
//程式碼開始
var CHANNEL_ACCESS_TOKEN = "";
var spreadSheetId = ""; //試算表 ID
var sheetName = "工作表1"; //工作表名稱
var searchColumn = 2; //搜尋第幾欄的資料
var spreadSheet = SpreadsheetApp.openById(spreadSheetId);
var sheet = spreadSheet.getSheetByName(sheetName);
var lastRow = sheet.getLastRow();
var lastColumn = sheet.getLastColumn();
var sheetData = sheet.getSheetValues(1, 1, lastRow, lastColumn);
function doPost(e) {
var userData = JSON.parse(e.postData.contents);
console.log(userData);
var replyMessage = [];
var replyContent;
var replyToken = userData.events[0].replyToken;
if((userData.events[0].message.text) == "查詢熱量"){replyMessage.push({type:"text", text:"開始查詢熱量~"});
sendReplyMessage(CHANNEL_ACCESS_TOKEN, replyToken, replyMessage);}
search(e);//這一段要怎樣再讀取LINEBOT傳進來的內容,然後去做查詢得動作呢?``
}
function search(e){
var userData = JSON.parse(e.postData.contents);
var searchResult = [];
var replyMessage = [];
var replyContent;
var replyToken = userData.events[0].replyToken;
var searchContent = userData.events[0].message.text;
if (userData.events[0].type != "message") {return;}
if (userData.events[0].message.type != "text") {return;}
searchResult = sheetData.filter(function(item, index, array){
return item[searchColumn - 1].toString() === searchContent;
});
for (var i = 0; i < searchResult.length; i++) {
replyContent = sheetData[0][0] + ":" + searchResult[i][0];
for (var j = 1; j < lastColumn; j++) {
replyContent += "\n\n" + sheetData[0][j] + ":" + searchResult[i][j];
}
replyMessage.push({type:"text", text:replyContent});
if (replyMessage.length == 5) {break;}
}
if (replyMessage.length == 0) {replyMessage.push({type:"text", text:"查詢不到「" + searchContent + "」的資料"});}
sendReplyMessage(CHANNEL_ACCESS_TOKEN, replyToken, replyMessage);
}
function sendReplyMessage(CHANNEL_ACCESS_TOKEN, replyToken, replyMessage) {
var url = "https://api.line.me/v2/bot/message/reply";
UrlFetchApp.fetch(url, {
"headers": {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": "Bearer " + CHANNEL_ACCESS_TOKEN,
},
"method": "post",
"payload": JSON.stringify({
"replyToken": replyToken,
"messages": replyMessage,
}),
});
}
//程式碼結束
這樣寫就確實會把事件往 function search(e)
傳了哦
只是要注意的是,一次的Line event
只能回覆一次訊息
所以或許是因為這樣,你以為search
的程式都沒跑到,但實際上是有執行的
只是第二次要發送你程式中的 查詢不到....的資料 的時候,就無法發送囉
所以應該修正的方式是,先把要回的訊息存起來,最後再一次發送!
雖然說這樣就無法達到你想要的效果,你應該是想
但因為你最下面 sendReplyMessage
是使用回覆的api,所以該token
只能使用一次就失效了
如果想要達到這種效果,應該要配合 push
的api才有辦法達到!
該api可參考:https://developers.line.biz/en/reference/messaging-api/#send-push-message
備註:因為push的api需要收費,雖然說每個月有500封扣打,但這種回饋式訊息,應該很少人直接用push來做,這部分就看你實際上到底需不需要這個效果了!
您好,想問如果要用push實作出來該怎麼做呢?
function sendPushMessage(CHANNEL_ACCESS_TOKEN, targetUserId, replyMessage) {
var url = "https://api.line.me/v2/bot/message/push";
UrlFetchApp.fetch(url, {
"headers": {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": "Bearer " + CHANNEL_ACCESS_TOKEN,
},
"method": "post",
"payload": JSON.stringify({
"to": targetUserId,
"messages": replyMessage,
}),
});
}
基本上就是把你的 sendReplyMessage
的url最後面換成push
還有 replyToken
換成目標 userId
您好,如果我這邊想要的是"查詢熱量後" 輸入"雞蛋"在進到Search function裡面查詢該怎麼改呢?這個e有其他的能替代嗎?我這邊輸入查詢熱量後他會把"查詢熱量"進入到Search function裡面
情境
使用者:查詢熱量
機器人:開始查詢熱量
使用者:雞蛋
機器人:雞蛋的熱量是 ....
你要的這個效果嗎? 這樣的話你必須記錄使用者的狀態
因為對程式來說,每一個訊息對他來說都是不同人
你程式必須去紀錄某位使用者,上一句有沒有講什麼話
才有辦法在他輸入查詢熱量後,知道他下一個打的訊息,是想查詢該訊息的熱量
我想這樣撰寫對於你剛接觸來說會有點複雜,建議尋找替代方案
像是,例:查詢熱量 雞蛋
就可以在一次訊息內了解使用者是要查詢雞蛋的熱量了
因為我這邊想要的功能可能有三四個,加上想說利用LINE OFFICIAL ACCOUNT的RICH MENUS點取對應的功能後,Action Text - 對應功能。然後再讓使用者輸入字串。紀錄使用者的狀態可以寫入GOOGLE SHEET嗎?寫入之後判斷對應的功能以後要BREAK DO POST FUNCTION嗎? 還是要怎樣讓他再去讀取新的e,因為真的很想完成這個東西,所以再麻煩撥冗回答了,感謝
那提供你實作方向
收到 Rich Menus
點擊的事件,針對該使用者進行狀態紀錄
Google App Script
的 Sheet api
可當資料庫紀錄狀態使用,可參考此網站
在完成1. 的情況下,每次收到訊息都檢查 Google Sheet
是否有紀錄該使用者的狀態
以上兩點是如果要記錄狀態的話該如何實作
寫入之後判斷對應的功能以後要BREAK DO POST FUNCTION嗎? 還是要怎樣讓他再去讀取新的e
要有一個觀念,每次事件都是重新執行一次doPost
所以你要當作每次都不知道是誰發訊息過來,實際情況也是一樣
你有很多使用者,你不能預設認為使用者都會等上一個人使用完,才換人使用
要每次都當作是不同人來看待