GASでLINEbotを作成したのに遅い、、、
GASでLINEbotを作成するときに
応答メッセージが返ってくることが遅いときがありませんか?
そんな時にちょっとお役に立てればと。
わかりやすいように、全部コード載せます。
長いのですみません。。。
const CHANNEL_ACCESS_TOKEN = '********************';
var SS = SpreadsheetApp.getActiveSpreadsheet();; //SpreadsheetのURL
var sheet = SS.getSheetByName("シート1"); //Spreadsheetのシート名(タブ名)
function doPost(request) {
const lastRow = sheet.getLastRow();
//POSTリクエストをJSONデータにパース
const receiveJSON = JSON.parse(request.postData.contents);
const event = receiveJSON.events[0];
//友だち追加されたときに、実施するイベント
if(event.type=="follow"){
return // returnで、処理を終了させる。
}
//テキスト以外が送られてきたときは何もしない。
if (event.message.type != "text"){
return
}
const timestamp = Utilities.formatDate(new Date(event.timestamp), 'JST', 'yyyy/MM/dd HH:mm:ss')
sheet.getRange(lastRow+1, 1).setValue(timestamp);
sheet.getRange(lastRow+1, 2).setValue(event.mode);
sheet.getRange(lastRow+1, 3).setValue(event.type);
sheet.getRange(lastRow+1, 4).setValue(event.deliveryContext.isRedelivery);
sheet.getRange(lastRow+1, 5).setValue(event.source.type);
sheet.getRange(lastRow+1, 6).setValue(event.source.userId);
sheet.getRange(lastRow+1, 7).setValue(event.webhookEventId);
sheet.getRange(lastRow+1, 8).setValue(event.message.type);
sheet.getRange(lastRow+1, 9).setValue(event.message.text);
sheet.getRange(lastRow+1, 10).setValue(event.message.id);
sheet.getRange(lastRow+1, 11).setValue(event.replyToken);
LINE_send(event.replyToken,"登録しました。")
}
function LINE_send(replyToken,text) {
reply_text ={
"replyToken": replyToken,
"messages": [{
"type": "text",
"text": text,
}]
}
options = {
"method": "post",
"headers":
{
"Content-Type": "application/json",
"Authorization": "Bearer " + CHANNEL_ACCESS_TOKEN,
},
"payload": JSON.stringify(reply_text)
};
UrlFetchApp.fetch("https://api.line.me/v2/bot/message/reply", options);
}
上のコードは、LINEから送られてきた、eventをスプレッドシートに記載するコードです。
下記のような感じでスプレッドシートに記載されます。
この時に動作の平均時間ですが、1.44秒となりました。
では、ちょっとコードを変えてみます。動作自体は同じです。
const CHANNEL_ACCESS_TOKEN = '********************';
var SS = SpreadsheetApp.getActiveSpreadsheet();; //SpreadsheetのURL
var sheet = SS.getSheetByName("シート1"); //Spreadsheetのシート名(タブ名)
function doPost(request) {
//POSTリクエストをJSONデータにパース
const receiveJSON = JSON.parse(request.postData.contents);
const event = receiveJSON.events[0];
//友だち追加されたときに、実施するイベント
if(event.type=="follow"){
return // returnで、処理を終了させる。
}
//テキスト以外が送られてきたときは何もしない。
if (event.message.type != "text"){
return
}
const timestamp = Utilities.formatDate(new Date(event.timestamp), 'JST', 'yyyy/MM/dd HH:mm:ss')
LINE_send(event.replyToken,"登録しました。")
sheet.appendRow([timestamp,event.mode,event.type,event.deliveryContext.isRedelivery,event.source.type,event.source.userId,event.webhookEventId,event.message.type,event.message.text,event.message.id,event.replyToken]);
}
function LINE_send(replyToken,text) {
reply_text ={
"replyToken": replyToken,
"messages": [{
"type": "text",
"text": text,
}]
}
options = {
"method": "post",
"headers":
{
"Content-Type": "application/json",
"Authorization": "Bearer " + CHANNEL_ACCESS_TOKEN,
},
"payload": JSON.stringify(reply_text)
};
UrlFetchApp.fetch("https://api.line.me/v2/bot/message/reply", options);
}
動作平均時間0.96秒
1.5倍ほど早くなりました。
LINEのメッセージ返答速度も速くなりました。
改良点
setValue、getValueを多用しない。
データを書き込んだり、読み込んだりしているsetValue、getValueですが
スプレッドシートAPIと呼ばれるAPIをたたいております。
その回数が多い分、GASの実行時間が長くなります。
ですので、極力回数を減らすと早くなります。
ここでは、
sheet.getRange(lastRow+1, 1).setValue(timestamp);
sheet.getRange(lastRow+1, 2).setValue(event.mode);
sheet.getRange(lastRow+1, 3).setValue(event.type);
sheet.getRange(lastRow+1, 4).setValue(event.deliveryContext.isRedelivery);
sheet.getRange(lastRow+1, 5).setValue(event.source.type);
sheet.getRange(lastRow+1, 6).setValue(event.source.userId);
sheet.getRange(lastRow+1, 7).setValue(event.webhookEventId);
sheet.getRange(lastRow+1, 8).setValue(event.message.type);
sheet.getRange(lastRow+1, 9).setValue(event.message.text);
sheet.getRange(lastRow+1, 10).setValue(event.message.id);
sheet.getRange(lastRow+1, 11).setValue(event.replyToken);
と、1つ1つのセルにデータを入力して、11回 setValueをつかっているものを
sheet.appendRow([timestamp,event.mode,event.type,event.deliveryContext.isRedelivery,event.source.type,event.source.userId,event.webhookEventId,event.message.type,event.message.text,event.message.id,event.replyToken]);
と、1回で、行を追加するようにしました。
これだけで、ずいぶんを早くなります。
応答メッセージを返すタイミングを見直す
そして次にLINEの応答速度を早くしたところです。
LINE_send(event.replyToken,"登録しました。")
というものが、LINEのメッセージを返送するコードです。これはコードの下のほうにある
function LINE_send(replyToken,text) {
reply_text ={
"replyToken": replyToken,
"messages": [{
"type": "text",
"text": text,
}]
}
options = {
"method": "post",
"headers":
{
"Content-Type": "application/json",
"Authorization": "Bearer " + CHANNEL_ACCESS_TOKEN,
},
"payload": JSON.stringify(reply_text)
};
UrlFetchApp.fetch("https://api.line.me/v2/bot/message/reply", options);
}
のfunctionを呼び出しています。
ここの
・【replyToken】に【event.replyToken】
・【text】に【"登録しました。"】
を入力して、実行してくれてます。
そして次にLINEの応答速度を早くしたところです。
LINE_send(event.replyToken,"登録しました。")
の位置をみてください。
上のコードでは、データを入力してからメッセージを返していますが
下のコードでは、データを入力する前にメッセージを返しています。
実際にユーザーには、データを記載する前にメッセージを返しても
データを記載した後にメッセージを返しても、影響はありません。
それであれば、先にメッセージを返してあげたほうが、ユーザーはストレスが軽減されます。
ただし、きちんと動作することが前提ですので、当初作成するときは、
順番通り、実行内容を先にして最後にメッセージを返すようにしないと
どこでバグが出ているかわからないので注意してください。
まとめ
・setValue,getValueは多用しない。
・応答メッセージはコードが完全に動くのであれば先にユーザーにメッセージを返す
他にも配列を使うなどいろいろありますが、
まずは動作が遅いと感じた場合、こちらの内容を確認してみてください。