【第2回】LINE×Ruby on Railsで作ろう！シゴトに生かすLINE Bot！

# はじめに

以下の2つを利用します。  まだ準備できていない方は準備をおねがいします。

* Ruby 2.7.1
* ngrok
* 準備がまだの方はこちらから準備ください：https://bit.ly/36ctimN

---

前回参加されていない方はこちらから`clone` & 環境変数の設定をしてLINE Botがメッセージを返すところまで進めてください

```bash
$ git clone https://github.com/4geru/rails-line-bot-lecture.git
$ cd rails-line-bot-lecture
$ cp .env.sample .env
$ bundle install
```

環境変数はこちらから： https://developers.line.biz/console/
前回の資料: [【第1回】LINE×Ruby on Railsで作ろう！シゴトに生かすLINE Bot！ - Speaker Deck](https://speakerdeck.com/4geru/di-1hui-linexruby-on-railsdezuo-rou-sigotonisheng-kasuline-bot?slide=8)

---
# 今回のやること

- おみくじbotを作る
    - 前回の復習で新しいメッセージを追加する
- じゃんけんbotを作る
    - Flex Messageでボタンを押すことができる
- リッチメニューからじゃんけんを始める

---
# 今回のゴール

- LINEからのイベント/LINEに送れるメッセージを学ぶ
- FlexMessageの実装ができるようになる
- リッチメニューの実装ができるようになる

---
# 次回予告
## レシピお問い合わせBot

LINE Botと外部APIをつなげるだけで、活用できる幅が非常に広がります

コロナも終息になりつつありますが、コロナの影響で自炊する機会も増えたのではないでしょうか?

ということで次回は楽天レシピAPIと連携をしてみます

---
# 前回学んだことの応用

## Railsのサーバーを起動する

前回から今回用に新たにデータの追加したので、最新のプロジェクトをローカルに持ってきます

```bash
$ cd rails-line-bot-lecture/
$ git pull origin
$ git checkout 352248ed154087913a99c5a2a95a6f0af00f3bcf
```

---

Railsのサーバーを起動させます

```bash
$ bundle exec rails s -p 3000
```

---

## ngrokの起動

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/4b175c8f-77ad-d9ce-a778-f985040335bb.png)

※ ngrokとは一時的に外部にportを解放するものです。

---

## webhookの登録

以下にアクセスします。

LINE Developers：https://developers.line.biz/console/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/9b7d04a4-6f8f-afa7-5f29-1e69e0836e19.png)

* 「Messaging API」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/04a4095a-50e9-ca51-4b3b-ea589b34fe10.png)

* 前項でコピーしたngrokが生成したURLの末尾に`/linebots`を加えたものをWebhook URLの欄に入力します。

---
# 前回の復習

## おみくじメッセージの実装

`app/controller/linebots_controller.rb`に下記を記述します

```ruby:app/controller/linebots_controller.rb
... 
if event['message']['text'] =~ /カテゴリ/
 LineBot::Messages::LargeCategoriesMessage.new.send
# ==== ここから新しく追加 ====
elsif event['message']['text'] =~ /おみくじ/
  {
    type: 'text',
    text: '今日の運勢は' + ['大吉', '中吉', '小吉', '凶'].sample + 'です'
  }
# ==== ここまで新しく追加 ====
else
...
```

---

# じゃんけんBotの作成

## 関係するファイル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/e07d11d9-d5da-407d-e5ad-5643906b4f34.png)

---

## Flex Messageの概要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/2f6137d5-633c-4a95-ceb9-1bc20a821985.png)

Flex MessageはNativeでいうAlertやDialogのようなリッチなインターフェースをLINE Bot上で実現することが出来る機能です。

バブルメッセージとカルーセルメッセージが存在があります。

* バブルメッセージ：1つのメッセージを表示
* カルーセルメッセージ：複数のバブルメッセージを表示

---

## Flex Messageの構築ツール

Flex Messageは自由度が高い分デザインが大変なのですが、以下のようなツールを使うと手軽に構築することができます。

* FlexMessageSimulator：Webアプリ
* LINE Bot Designer：デスクトップアプリ

### Flex Mesage Simulator

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/a3368fbe-b521-0e45-02f1-38044ca6c6cb.png)
Flex Message Simulator：https://developers.line.biz/flex-simulator/

### LINE Bot Designer

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/2b62fa81-b50a-ef60-fd3f-dd03df6db813.png)
LINE Bot Designer：https://developers.line.biz/ja/services/bot-designer/

---
## Flex Messageを作る

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/0a34c044-cf57-a240-5e07-a51d8f53754f.png)
Flex Message Simulator：https://developers.line.biz/flex-simulator/

---
## データのコピー

<img width="1565" alt="Flex Message Simulator 2020-06-02 21-55-25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64677/bf9722dd-55d3-f225-3a01-d0de812f3c55.png">

- View as JSON > Copy からJSONデータを内容は編集せずそのままコピーします

---

## Messageファイルの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/dbfe763a-6407-bafe-307b-e0e3f6902978.png)

---
```ruby:app/service/linebots/messages/sample_message.rb
# class TemplateMessage 以下に変更
class SampleMessage
  include LineBot::Messages::Concern::Carouselable
  def send
     carousel('alter_text', [bubble])
  end

  def bubble
    # ここにペースト
  end
```

* class名をTemplateMessageから SampleMessageに変更します
* Flex Message SimulatorのJSONをコピーしてbubbleの中に貼り付けます

---
## LinebotsControllerに追加

`app/controller/linebots_controller.rb`を開きます

```ruby:app/controller/linebots_controller.rb
when Line::Bot::Event::Message
  if event['message']['text'] =~ /カテゴリ/
    LineBot::Messages::LargeCategoriesMessage.new.send
  elsif event['message']['text'] =~ /おみくじ/
    {
      type: 'text',
      text: '今日の運勢は' + ['大吉', '中吉', '小吉', '凶'].sample + 'です'
    }
  # ==== ここから新しく追加 ====
  elsif event['message']['text'] =~ /FlexMessage/
    LineBot::Messages::SampleMessage.new.send
  # ==== ここまで新しく追加 ====
  else
    {
      type: 'text',
      text: event['message']['text']
    }
  end
```

ユーザーが送ってきたメッセージに 「FlexMessage」が含まれていた場合、今回作成したSampleMessageに保存された、FlexMessageを返します。

---
### 確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/7fa42da4-ba1b-28d4-8c2d-c8bdbf8bac57.png)

* テキストで「FlexMessage」とメッセージを送ると Flex Messageが返って来くるはずです。

---
## じゃんけんメッセージを送る

`app/controller/linebots_controller.rb`を開きます
ユーザーが送ってきたメッセージに「じゃんけん」が含まれていた場合に、じゃんけんの選択肢を返すFlexMessageが記述されている`JankenMessage`クラスを返します

```ruby:app/controller/linebots_controller.rb
when Line::Bot::Event::Message
  if event['message']['text'] =~ /カテゴリ/
    LineBot::Messages::LargeCategoriesMessage.new.send
  elsif event['message']['text'] =~ /おみくじ/
    {
      type: 'text',
      text: '今日の運勢は' + ['大吉', '中吉', '小吉', '凶'].sample + 'です'
    }
  elsif event['message']['text'] =~ /FlexMessage/
    LineBot::Messages::SampleMessage.new.send
  # ==== ここから新しく追加 ====
  elsif event['message']['text'] =~ /じゃんけん/
    LineBot::Messages::JankenMessage.new.send
  # ==== ここまで新しく追加 ====
  else
    {
      type: 'text',
      text: event['message']['text']
    }
  end
``` 


---
## JankenMessage
LINE Botに「じゃんけん」とメッセージを送ると、下のようなメッセージが返ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/bdf75fcc-a144-2170-45f3-f33cdcd26596.png)

---
## JankenMessageの解説
実際に `LineBot::Messages::JankenMessage.new.send` を見ていきます。`app/services/line_bot/messages/janken_message.rb` に記述されています。

「グー」では、messegeのtypeは `button` です。
`button` には、 `action` を設定することができます。`action` でボタンを押した時の挙動を設定できます。

`action` には、　`postback`, `message`, `uri`, `datetimepicker` などがあります。
参考：[Home > ドキュメント > Messaging API > アクション](https://developers.line.biz/ja/docs/messaging-api/actions/)

今回は、 `postback` を利用します。 `postback` は `displayText` でボタンを押したメッセージを、
任意データを `data` をサーバーに返すことができます。

```ruby
{
  "type": "button",
  "style": "link",
  "height": "sm",
  "action": {
    "type": "postback",
    "label": "ぐー",
    "displayText": "ぐー",
    "data": "type=janken_result&result=gu"
  }
}
```


---
# リッチメニューの設定
次にリッチメニューを実装していきます

## リッチメニューとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/ca794af1-bcd9-6f54-f0ce-9cc9af2fe407.png)


---
## リッチメニューの設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/b5de5066-7552-b2b4-d65f-56caa5e9ca40.png)

- 以下のURLにアクセスし、対象のbotを選択します

こちらから： https://manager.line.biz/

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/105103b3-ef6a-f7ae-88e4-713569fdafbe.png)

- 「ホーム」→「リッチメニュー」→「作成」 を選択

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/01b069eb-7807-3fa9-7ea6-cb5ef5ec8ba1.png)


---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/48ea1b51-ec99-9fc5-f7a4-4cc4ebcb9ad1.png)

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/11270cb1-dbad-943b-2949-0caa8d59dd76.png)

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/f30a64cb-4414-4ce5-4731-ce5d3abe4b66.png)

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/4fd1dc06-d873-8aee-4f12-9455bba2f4a9.png)

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/9342eee5-27e1-7e9b-bafd-4125d7cba1d4.png)

---
### 確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/f1a36151-4b04-0bc1-4199-854fb139379b.png)

---
# これで今回は終了です！

#　トラブルシューティング

* プログラムのコードは`finished_part2`のブランチにまとまっています
* `git checkout finished_part2`でハンズオン終了時のコード を見が見れます
* ハンズオン開始時と終了時のコードを比べたい場合は、以下 のURLを参照してください
* https://github.com/4geru/rails-line-bot-lecture/compare/352248ed154087913a99c5a2a95a6f0af00f3bcf...finished_part2

---
# 時間が余った方へ

## コンピュータとユーザーのメッセージを変えてみよう
`app/services/line_bot/postback_event.rb` の中にコンピュータが出した手を返すメッセージが格納されています。ここを拡張して、ユーザーの出した手も返してみましょう

```ruby:app/services/line_bot/postback_event.rb
module LineBot
  class PostbackEvent
    def self.send(data)
      ...
      when 'janken_result'
        {
          type: 'text',
          text: 'コンピュータは' + ['ぐー', 'ちょき', 'ぱー'].sample + 'を出しました'
        }
      when 'middle_search'
```

## じゃんけんの結果を返すclassを追加してみよう

`app/services/line_bot/messages/template_message.rb` を元にして、じゃんけんの結果を返す
`app/services/line_bot/messages/janken_result_message.rb` を追記してみましょう。

## じゃんけんがあいこだった場合の処理を追加みよう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164153/732663f3-b6a4-9d4e-a6ce-5559987753cb.png)

回答は`finished_part2`ブランチの`app/services/line_bot/messages/janken_result_message.rb`の中にあります。
参照：hhttps://github.com/4geru/rails-line-bot-lecture/compare/352248ed154087913a99c5a2a95a6f0af00f3bcf...finished_part2#diff-b7aaf0c0f1afc44c5fab758532c3f936R6-R32