Vue+LIFF(LINE Front-end Framework)+GASでフォームを使ったBOTを作ってみた（その３：GAS編）

LIFFを使用したアプリケーションを何か作ってみたかったので、勤怠連絡のBOTを作ってみました。
ちょっと長くなりそうなので、全3回でまとめます。

- [Vue+LIFF(LINE Front-end Framework)+GASでフォームを使ったBOTを作ってみた（その１：Vue編）](https://qiita.com/korsmic/items/0009a020cc18e20c7406)
- [Vue+LIFF(LINE Front-end Framework)+GASでフォームを使ったBOTを作ってみた（その２：LIFF編）](https://qiita.com/korsmic/items/5e9c5e65f3023fe806f1)
- [Vue+LIFF(LINE Front-end Framework)+GASでフォームを使ったBOTを作ってみた（その３：GAS編）](https://qiita.com/korsmic/items/3615e3a59cb87c6e620d)

[githubはこちら](https://github.com/korsmic/vue-liff-bot)

## GASの設定

### 参考
GASの設定は以下の記事が参考になります。

- [Google Apps ScriptでLINE BOTつくったら30分で動かせた件](https://qiita.com/flyhigh/items/55c2584cf82718f47464)

- [Webhookイベントオブジェクト](https://developers.line.me/ja/reference/messaging-api/)

### 設定手順

以下の手順でGASを設定します。

1. Googleアカウントにログイン
2. Googleドライブを開く
3. `マイドライブ`をクリック
4. `その他`→`アプリを追加`→`Google Apps Script`
5. コードを記述→保存
6. `公開`→`ウェブアプリケーションとして導入`
7. `アプリケーションにアクセスできるユーザー`を`全員（匿名ユーザーを含む）に変更`
8. `公開`をクリックし、出てきた`現在のウェブ アプリケーションの URL`をコピーする
9. LINE Developersの対象BOTの`Webhook URL`に先ほどコピーしたGASのURLを張り付ける

以上でGASを利用したWebhookの設定が完了です。


## コード

スクリプトは、以下になります。

```javascript
//LINE Developersで取得したアクセストークンを入れる
var CHANNEL_ACCESS_TOKEN = '<LINE BOT アクセストークン>';
// 送信先のグループID
var GROUP_ID = '<グループへ参加させて set を送ると送られる>';
// グループIDを取得するためのキーワード
var SETTING_MESSAGE = 'set';

var line_reply = 'https://api.line.me/v2/bot/message/reply';
var line_push = 'https://api.line.me/v2/bot/message/push';

//ポストで送られてくるので、送られてきたJSONをパース
function doPost(e) {
  var webhook = JSON.parse(e.postData.contents).events[0];

  //返信するためのトークン取得
  var reply_token = webhook.replyToken;
  if (typeof reply_token === 'undefined') {
    return;
  }

  //送られたメッセージ内容を取得
  var message = webhook.message.text;
  var gid = webhook.source.groupId;

  // ユーザーの会話（グループIDが存在しない）
  if (typeof gid === 'undefined') {
    // 確認用メッセージの返信
    UrlFetchApp.fetch(line_reply, {
      headers: {
        'Content-Type': 'application/json; charset=UTF-8',
        Authorization: 'Bearer ' + CHANNEL_ACCESS_TOKEN
      },
      method: 'post',
      payload: JSON.stringify({
        replyToken: reply_token,
        messages: [
          {
            type: 'text',
            text:
              'ご利用ありがとうございます。以下のメッセージをグループへ送信しました。'
          },
          {
            type: 'text',
            text: message
          }
        ]
      })
    });
    // グループへメッセージをpush
    UrlFetchApp.fetch(line_push, {
      headers: {
        'Content-Type': 'application/json; charset=UTF-8',
        Authorization: 'Bearer ' + CHANNEL_ACCESS_TOKEN
      },
      method: 'post',
      payload: JSON.stringify({
        to: GROUP_ID,
        messages: [
          {
            type: 'text',
            text: message
          }
        ]
      })
    });
  // グループIDを取得する
  } else if (message == SETTING_MESSAGE) {
    // キーワードが等しい場合にグループID返信する
    UrlFetchApp.fetch(line_reply, {
      headers: {
        'Content-Type': 'application/json; charset=UTF-8',
        Authorization: 'Bearer ' + CHANNEL_ACCESS_TOKEN
      },
      method: 'post',
      payload: JSON.stringify({
        replyToken: reply_token,
        messages: [
          {
            type: 'text',
            text: 'グループIDは以下の通りです。'
          },
          {
            type: 'text',
            text: gid
          }
        ]
      })
    });
  }

  return ContentService.createTextOutput(
    JSON.stringify({ content: 'post ok' })
  ).setMimeType(ContentService.MimeType.JSON);
}

```

### 解説

メッセージに`groupId`が含まれるかで条件を分岐させています。

- 対ユーザーには送信メッセージのリピート（確認メッセージ）
- 対グループにユーザーから送信されたメッセージを送信


また、`groupId`を取得するためには、

1. BOTをグループに参加させる
2. `set`を発言する
3. BOTが`groupId`を発信します

以上で取得できます。

取得した`groupId`はGAS上のコードの`GROUP_ID`の箇所へ入れてください。
入れると、指定したグループへ発信できます。

![6.jpg](https://qiita-image-store.s3.amazonaws.com/0/83008/043d85fa-ea33-699f-c67b-85d8cc266065.jpeg)


## まとめ

`groupId`の取得やグループへの発信、対個人への発信などがやや面倒だと感じました。

また、グループに参加したときのイベント`join`を利用すればよかったのですが、うまくイベントを発生させることができず、`set`というキーワードを今回は利用しています。

そのほかにも、GASを利用すれば、

- メールの送信
- スプレッドシートへのログの記載

などなど、色々と派生させることができると思いますので、色々カスタマイズできると思います。