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


# GASでLINEbotを作成したのに遅い、、、

GASでLINEbotを作成するときに

応答メッセージが返ってくることが遅いときがありませんか？

そんな時にちょっとお役に立てればと。

わかりやすいように、全部コード載せます。
長いのですみません。。。

```javascript:
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624933/ec8343bd-d566-cb8f-e57c-38a4fed6cd0c.png)

この時に動作の平均時間ですが、**1.44秒**となりました。

では、ちょっとコードを変えてみます。動作自体は同じです。
```javascript:
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のメッセージを返送するコードです。これはコードの下のほうにある
```javascript:
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は多用しない。**
**・応答メッセージはコードが完全に動くのであれば先にユーザーにメッセージを返す**


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