小弟JS新手,在網路上看到有開源資料開始學習。
以下程式碼掛在google app script給line bot使用,想要讓使用者可以輸入"YYYYMMDD"就能查詢當日活動,其他訊息則略過。
有嘗試在「//開始查詢資訊」前加入if判斷式做break,但是沒有成功,想請各位大神提點,謝謝!
var CHANNEL_ACCESS_TOKEN = " ";
var spreadSheetId = " "; //試算表 ID
var sheetName = ["藝文","優惠"]; //工作表名稱
var searchColumn = [1]; //搜尋第幾欄的資料
var whiteList = [""]; //白名單(允許取得資料的使用者ID
var whiteListMode = 0; //白名單模式,1 表示需要設定白名單才能進行查詢,0 表示任何人加了好友都可以查詢。
var fuzzySearch = 1; //模糊搜尋模式,1 表示表格內部分字串相同即取出資料,0 表示儲存格內容完全相同才取出資料。
var spreadSheet = SpreadsheetApp.openById(spreadSheetId);
function doPost(e) {
var userData = JSON.parse(e.postData.contents);
var allowed = whiteListMode;
var clientID = userData.events[0].source.userId;
var replyToken = userData.events[0].replyToken;
if ((userData.events[0].type == "follow" || userData.events[0].message.text.toLowerCase() == "findmyid") && whiteListMode === 1) {
var replyMessage = [{type:"text", text:"您的使用者 ID 是「" + clientID + "」,請將此 ID 告知此官方帳號的擁有者加入白名單後才能開始查詢資料。"}];
sendReplyMessage(CHANNEL_ACCESS_TOKEN, replyToken, replyMessage);
return;
}
if (userData.events[0].type != "message") {return;}
if (userData.events[0].message.type != "text") {return;}
// 檢查是否是允許的用者提出搜尋需求
for (var i = 0; i < whiteList.length; i++) {
if (whiteList[i] == clientID) {
allowed = 0;
break;
}
}
if (allowed === 1) {
var replyMessage = [{type:"text", text:"您的使用者 ID 是「" + clientID + "」,請將此 ID 告知此官方帳號的擁有者加入白名單後才能開始查詢資料。"}];
sendReplyMessage(CHANNEL_ACCESS_TOKEN, replyToken, replyMessage);
return;
}
//開始查詢資訊
var replyMessage = [];
var replyToken = userData.events[0].replyToken;
var searchContent = userData.events[0].message.text;
for (var i = 0; i < sheetName.length; i++) {
var searchResult = [];
var sheet = spreadSheet.getSheetByName(sheetName[i]);
var lastRow = sheet.getLastRow();
var lastColumn = sheet.getLastColumn();
var sheetData = sheet.getSheetValues(1, 1, lastRow, lastColumn);
for (var j = 0; j < searchColumn.length; j++){
var searchTemp = sheetData.filter(function(item, index, array){
if (fuzzySearch == 0) {return item[searchColumn[j] - 1].toString().toLowerCase() === searchContent.toLowerCase();}
else {return item[searchColumn[j] - 1].toString().toLowerCase().indexOf(searchContent.toLowerCase()) != -1 ;}
});
searchResult = searchResult.concat(searchTemp);
}
if (searchResult.length > 0) {
var replyContent = "";
searchResult = uniqueArrayElement(searchResult);
replyContent = "在「" + sheetName[i] + "」中搜尋到 " + searchResult.length + " 筆資料";
for (var k = 0; k < searchResult.length; k++) {
replyContent += "\n\n" + sheetData[0][0] + ":" + searchResult[k][0];
for (var l = 1; l < lastColumn; l++) {
replyContent += "\n" + sheetData[0][l] + ":" + searchResult[k][l];
}
}
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 uniqueArrayElement(arrayData) {
var result = arrayData.filter(function(element, index, arr){
return arr.indexOf(element) === index;
});
return result;
}
//回送 Line Bot 訊息給使用者
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,
}),
});
}
樓主應該也是看 Boris 資訊小站的影片吧 XD 我當初也是看同個影片,用同一個程式碼練手。不過對我來說這份程式碼有點小複雜,有點難抓出是什麼問題,但我以你的需求寫了一個新的:
var CHANNEL_ACCESS_TOKEN = " ";
var spreadSheetId = " "; //試算表 ID
var sheetName_1 = "藝文";
var sheetName_2 = "優惠"; //工作表名稱
var search_Column = 1; //搜尋第幾欄的資料
var spreadSheet = SpreadsheetApp.openById(spreadSheetId);
var sheet_1 = SpreadSheet.getSheetByName(sheetName_1); // 第一張資料表的資料
var sheet_2 = SpreadSheet.getSheetByName(sheetName_2); // 第二張資料表的資料
var max_row = sheet_1.getLastRow(); // 取得第一張資料表最後的行數,用於迴圈檢索次數
var max_row_2 = sheet_2.getLastRow(); // 取得第一張資料表最後的行數,用於迴圈次數
function doPost(e) {
var userData = JSON.parse(e.postData.contents);
var replyToken = userData.events[0].replyToken;
if (userData.events[0].type != "message") { return; }
if (userData.events[0].message.type != "text") { return; }
//開始查詢資訊
var replyMessage = []; // 要為JSON 格式~
var replyToken = userData.events[0].replyToken;
var search_keyword = userData.events[0].message.text; // 使用者要找的關鍵字 YYYYMMDD
if (search_keyword != "") {
// 先看看第一張資料表內有沒有關既字的內容
for (x = 1; x <= max_row; x++) {
var sheet_block = sheet_1.getRange(search_Column, x).getValue();
// 如果有相符內容
if (search_keyword == sheet_block) {
reply_block = sheet_1.getRange(2, x).getValue(); // 取得隔壁欄、同一行的資料,若要回傳的資料不在第二欄,更改 getRange 的 2
replyMessage = [
{
"type": "text",
"text": "找到了!當天的活動:" + reply_block // 回傳活動
}
]
break;
}
else {
// 如果沒在第一個工作表找到,會到這個回圈搜尋第二個資料表
for (x = 1; x <= max_row_2; x++) {
var sheet_block = sheet_2.getRange(search_Column, x).getValue();
if (search_keyword == sheet_block) {
reply_block = sheet_1.getRange(2, x).getValue(); // 若要回傳的資料不在第二欄,更改 getRange 的 2
replyMessage = [
{
"type": "text",
"text": "找到了!當天的優惠:" + reply_block // 回傳優惠
}
]
break;
}
// 關鍵字都不在兩張資料表裡,則回傳沒找到訊息
else {
replyMessage = [{
"type": "text",
"text": "抱歉,未找到相關資料,請試看看其他日期"
}]
}
}
}
}
}
//回送 Line Bot 訊息給使用者
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,
}),
});
}
}
我沒有實際跑一次測試,但他的流程會是這樣:
趕時間所以我是用巢狀 if 寫,如果有多張資料表要找還是用回圈會更有效率。
我沒看到你的 Google Sheet,但如果你希望使用者傳 YYYYMMDD 就能同時顯示「藝文」、「優惠」兩張資料表的內容,可以濃縮在一個工作表就好:
YYYYMMDD | 藝文 | 優惠 |
---|---|---|
20210521 | 我愛你 | 單身者半價 |
20210814 | 情人節 | 情侶打到骨折! |
這樣關鍵字在第一欄,而藝文、優惠分別在二、三欄,只需跑一次回圈就好,並將 reply_message 改成:
var sheet_block = sheet_1.getRange(2,x).getValue(); // 這裡是藝文欄位的資料
var sheet_block_2 = sheet_1.getRange(3,x).getValue(); // 這是優惠的
reply_message = [{
"type":"text",
"text":"找到了!當天活動:"+sheet_block
},
{
"type":"text",
"text":"當天優惠則為:"+sheet_block_2
}]
reply_message 是個陣列,可以塞好幾個 JSON 內容( 不要加到五個以上 )這樣機器人會傳兩個文字訊息,分別是藝文和活動的資料。
不知道過這麼久你還需不需要 XD 如果有問題歡迎回覆~