【GAS】資料を簡単にまとめてくれていろいろ教えてくれるLINEBOTで業務効率化してみた！


GASとLINE Messaging APIでサークルの業務効率化を図ってみました。GASあんまり使ったことなかったので自分用メモも兼ねて

# 作りたいもの
サークルの業務効率化のためのLINEBOT

## 現状の問題点
* LINEグループの連絡って流れがちだけど､かと言って複数グループは管理が面倒
* サークルのGoogleドライブ内の資料に書き込んだりそれらを閲覧したりする場合は大学アカウントでのログインが必要で正直めんどくさい(とはいえ公開範囲を誰でもにするのはセキュリティ的に問題がある)
* ↑情報探すにしても資料追加するにしても､そもそも工程が多いとめんどくさくてモチベーション下がりがち🥲

## 要件
* URLやメモ書きを投げたら､自動でサークルのGoogleドライブ内のスプレッドシートに保存してくれる
* 練習日程や用語の意味などを聞いたら､自動返信でアンサーをくれる
(↑ここに関してはMessagingAPIの機能である応答メッセージを使用してもよかったが､今回は語句の追加などの権限を自分以外にも付与したかったためスプレッドシートを使用)

# 作成手順
1. Messaging APIを利用しボット作成（GASを書いた後でもいいとは思うが､GASの中でアクセストークン等使用するため今回は先に作成）
    1. LINE Developersにログインする
    2. チャンネルタイプ「Messaging API」でチャンネルを作成
2. スプレッドシートの準備
3. GASを書く→デプロイ
4. 連携情報をLINEBOT用のアカウントに登録
5. 完成

# 早速作っていく！
## 1. Messaging APIを利用しボット作成
1.　[LINE Developers](https://developers.line.biz/ja/) にログイン
2.　MessagingAPI選択→StartNow選択で作成開始
    ![API作成2枚 のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553195/31c28b07-a817-5234-f7ca-709d7b0fed9e.png)
3.　諸々設定しBot作成 　気をつけることはChannelTypeをMessagingAPIから変えないことくらい
![ライン作成 のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553195/282e61ff-ab1d-0510-1f98-0a4ca92b5177.png)
4. その他の細かい設定＆トークン発行
Messaging APIのところ
![設定API.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553195/e2bf76d4-6251-344a-29b1-2233e68e35a3.png)
* webhookをオンに
* 必要に応じて､グループへの参加･Auto-reply･追加時のメッセージ の設定を行う
* チャンネルアクセストークンを発行する
![スクリーンショット 2022-03-27 14.29 のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553195/435e75d8-d3ee-442a-403e-a6d7b4a7db71.png)




## 2. スプレッドシートの準備
1.　普通にスプレッドシートを作成する
2.　資料保存用のシートと自動返信用のシートの2枚を作成し自動返信用には文言を追加する(下記画像参照↓)
![スクリーンショット 2022-03-27 15.59.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553195/f4507e49-e364-2e0a-45ec-d5b17d92816c.png)
3.　スプレッドシートのURL欄の「/d/」と「/edit」の間の乱数がスプレッドシートIDとなり､後ほど使用するのでメモっておくor使用時に取りに来る
4.　拡張機能からAppsScript作成
![F3C93972-9BBD-47A8-BAAC-93E7C03EEA17.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553195/695a3c88-1edc-12a9-b6f8-172402483e40.jpeg)

## 3. GASを書く
### 1. 資料の自動保存機能用のソースコード
後半の自動返信機能の実装で使用するコードが一部含まれていますので､不要な方は適宜削除してください
```javascript:autoSave.gs
// 1-4で取得したLINE Messaging APIのチャネルアクセストークン
var LINE_ACCESS_TOKEN ="*****************************";
// auto-replyに必要
var url = "https://api.line.me/v2/bot/message/reply";
// スプレッドシートのID(2-2でメモしたもの､スプレッドシートのURL欄の「/d/」と「/edit」の間の部分)
var spreadsheetId = "*****************************";

function doPost(e) {
  // 投稿されたメッセージとそのreplyTokenを取得
  var userMessage = JSON.parse(e.postData.contents).events[0].message.text;
  var replyToken = JSON.parse(e.postData.contents).events[0].replyToken;

  if (userMessage.match(/^http/)) {
    // httpから始まるメッセージの場合そのまま追加
    userMessage = userMessage.substr(0);
    autoSave = true;
  } else if (userMessage.match(/^[資料追加]/)) {
    // 資料追加から始まるメッセージの場合、資料追加を除いた文字列を代入
    userMessage = userMessage.substr(1);
    autoSave = true;
  } else if (typeof e !== "undefined") {
    // このelse ifの処理は自動返信用なので不要な場合削除してください
    //JSON文字列をパースして変数jsonに格納
    var json = JSON.parse(e.postData.contents);
    //変数jsonを関数replyFromSheetに渡し、replyFromSheetを実行
    replyFromSheet(json);
    autoSave = false;
  } else {
    return;
  }

  if (autoSave === true) {
    // -----スプレッドシートへ保存 ここから-----
    var sheetName = "保存用シート";
    var spreadsheet = SpreadsheetApp.openById(spreadsheetId);
    var sheet = spreadsheet.getSheetByName(sheetName);
    // 空白・タブ・改行で区切り配列に変換
    var arr = userMessage.split(/\s/);
    // 配列の先頭に日時を代入
    arr.unshift(new Date());
    // セルの最下部に配列を転記
    sheet.appendRow(arr);
    // -----ここまで-----
    resMessage = "記録しました！"; //記録成功時に送信するメッセージ
  } else {
    return;
  }

  // ↓記録成功時メッセージを送信しない場合不要
  UrlFetchApp.fetch(url, {
    headers: {
      "Content-Type": "application/json; charset=UTF-8",
      Authorization: "Bearer " + LINE_ACCESS_TOKEN,
    },
    method: "post",
    payload: JSON.stringify({
      replyToken: replyToken,
      messages: [
        {
          type: "text",
          text: resMessage,
        },
      ],
    }),
  });
  return ContentService.createTextOutput(JSON.stringify({ content: "post ok" })).setMimeType(
    ContentService.MimeType.JSON
  );
}
```

### 2. 練習日程や用語の意味などの自動返信機能用のソースコード(さっきのコードの下に挿入してください)
```javascript:autoReply.gs
//　返信用の関数replyFromSheet  dataには変数jsonが代入される
function replyFromSheet(data) {
  // Sheet
  var sheet2Name = "自動返信シート";
  var spreadsheet = SpreadsheetApp.openById(spreadsheetId);
  var autoReplySheet = spreadsheet.getSheetByName(sheet2Name); // 使用するシートの名称･デフォルトだとシート1とかの部分

  //　シートの最終行を取得する
  var lastRow = autoReplySheet.getLastRow();
  //　シートの全受信語句と返信語句を二次元配列で取得する
  var wordList = autoReplySheet.getRange(1, 1, lastRow, 2).getValues();
  //　受信したメッセージ情報を変数に格納する
  var reply_token = data.events[0].replyToken; //reply token
  var text = data.events[0].message.text; //ユーザーが送信した語句

  //　返信語句を格納するための空配列を宣言
  var replyTextList = [];
  //　LINEで受信した語句がシートの受信語句と同じ場合、返信語句をreplyTextにpushする
  for (var i = 1; i < wordList.length; i++) {
    if (wordList[i][0] == text) {
      replyTextList.push(wordList[i][1]);
    }
  }
  //　LINEで受信した語句がシートの受信語句と一致しない場合、処理終了
  if (replyTextList.length < 1) {
    return;
  } else {
    var messageLength = replyTextList.length;
  }

  //　"messages"に渡す配列を格納するための空配列を宣言
  var messageArray = [];
  //　replyTextListに格納されている返信語句をmessageArrayにpushする
  for (var i = 0; i < messageLength; i++) {
    messageArray.push({ type: "text", text: replyTextList[i] });
  }

  var headers = {
    "Content-Type": "application/json; charset=UTF-8",
    Authorization: "Bearer " + LINE_ACCESS_TOKEN,
  };
  var postData = {
    replyToken: reply_token,
    messages: messageArray,
  };
  var options = {
    method: "post",
    headers: headers,
    payload: JSON.stringify(postData),
  };

  //LINE Messaging APIにデータを送信する
  response = UrlFetchApp.fetch(replyUrl, options);
}

```

※LINEの仕様5つ以上のメッセージを返信できないようになっているようなので､同じ語句に５つ以上返信ワードを設定される方は参考文献欄の記事を参考になさってください。今回は基本的に1ワードにつき1返信ワード設定の予定で５つ以上になることはないと思われたためその部分の処理を省略しています。

## 4. デプロイ
1. 右上のアイコン横のデプロイから新しいデプロイを選択
2. 種類の選択からウェブアプリを選び、[実行者:自分 ･ アクセスできるユーザー：全員]でデプロイする
![でプロおい.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553195/be552b15-137b-e09b-8122-7afa56b1669b.png)
3. ウェブアプリのURLをコピー
![デプロイ後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553195/18b3699d-40b3-985f-2d6d-dd76a8113ae1.png)
:::note info
コピーできずに閉じた場合は､右上のデプロイから「デプロイの管理」を選択したら再度確認できます🙆‍♀️
:::

## 5. 連携情報をLINEBOT用のアカウントに登録
1. 1-4で詳細を設定した少し上にあるWebhookURLにコピーしてきたウェブアプリのURLをペースト
![繋ぎこみ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553195/4b2cd7ab-7574-5dae-6e44-65632e7e0ea0.png)
2. 出来上がったラインボットを使ってみる！！！ 特に何もなければ↓

## 完成〜〜〜🎉
![スクリーンショット 2022-03-28 1.28.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553195/e729c02d-0d51-39b3-de1c-34c2c4e5d980.png)

# 最後に
ここまで読んでくださりありがとうございます！！！
LINEBOTの作成は2回目ですが､前回は単にMessagingAPIの機能である応答メッセージを使用し､GASとの繋ぎ込みを行ったのは今回は初めてだったのですが､うまくいってよかったです。☺️
それでは良きエンジニアライフを！！！




## 参考文献
* [LINEで投稿されたメッセージをGoogleスプレッドシートへ保存しDB化する](https://chusotsu-program.com/line-gas/)
* [Lineチャットボットで受け取ったテキストをスプレッドシートへ記録する](https://gurishunin.com/line_gas_wirte_spreadsheet/)
* [【シリーズ第4話】コピペでOK！スプレッドシートの語句を返信するLINE BOTをGASで作成する方法(実践編)](https://www.yukibnb.com/entry/linemessagingapi_gas)