6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

LINE bot × GASで動作が遅いときに試してみること

Last updated at Posted at 2022-05-01

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をスプレッドシートに記載するコードです。
下記のような感じでスプレッドシートに記載されます。

image.png

この時に動作の平均時間ですが、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は多用しない。
・応答メッセージはコードが完全に動くのであれば先にユーザーにメッセージを返す

他にも配列を使うなどいろいろありますが、
まずは動作が遅いと感じた場合、こちらの内容を確認してみてください。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?