かんたんLINE botをつくろう！【Rails 応用編】

# はじめに

前回記事で作成した、以下のコードを改造していきます！

https://qiita.com/kohki_takatama/items/278b1f47e355e08df43a

```ruby
class LinebotController < ApplicationController
  def callback
    body = request.body.read
    events = client.parse_events_from(body)
    
    events.each do |event|
      case event
      when Line::Bot::Event::Message
        case event.type
        when Line::Bot::Event::MessageType::Text
          message = {
            type: 'text',
            text: event.message['text']
          }
          client.reply_message(event['replyToken'], message)
        end
      end
    end
  end

  private
   
  def client
    @client ||= Line::Bot::Client.new { |config|
      config.channel_secret = ENV['LINE_CHANNEL_SECRET']
      config.channel_token = ENV['LINE_CHANNEL_TOKEN']
    }
  end
end
```

コピペして楽しむのもよし！
自分で実装してみるもよし！
コードは折りたたみで隠されているので、お好きにご活用ください。

公式を参考にしたい方は

https://developers.line.biz/ja/reference/messaging-api/#text-message

こちらをご覧ください！

# 語尾を変更

語尾を「にゃん！」に変更します。

<details><summary>差分</summary>

`+ 'にゃん！'`を追加するだけ！

```diff_ruby
class LinebotController < ApplicationController
  def callback
    body = request.body.read
    events = client.parse_events_from(body)
    
    events.each do |event|
      case event
      when Line::Bot::Event::Message
        case event.type
        when Line::Bot::Event::MessageType::Text
          message = {
            type: 'text',
-            text: event.message['text']
+            text: event.message['text'] + 'にゃん！'
          }
          client.reply_message(event['replyToken'], message)
        end
      end
    end
  end

  private
   
  def client
    @client ||= Line::Bot::Client.new { |config|
      config.channel_secret = ENV['LINE_CHANNEL_SECRET']
      config.channel_token = ENV['LINE_CHANNEL_TOKEN']
    }
  end
end
```
</details>

# 一定のメッセージを返す

機能としては退化しますが、コードの理解を深めるためにやってみましょう。
<details><summary>差分</summary>

```diff_ruby
class LinebotController < ApplicationController
  def callback
    body = request.body.read
    events = client.parse_events_from(body)
    
    events.each do |event|
      case event
      when Line::Bot::Event::Message
        case event.type
        when Line::Bot::Event::MessageType::Text
          message = {
            type: 'text',
-            text: event.message['text']
+            text: 'ニホンゴワカリマセーン🤷‍♂️'
          }
          client.reply_message(event['replyToken'], message)
        end
      end
    end
  end

  private
   
  def client
    @client ||= Line::Bot::Client.new { |config|
      config.channel_secret = ENV['LINE_CHANNEL_SECRET']
      config.channel_token = ENV['LINE_CHANNEL_TOKEN']
    }
  end
end
```

`message`の中の`text: `の後が返信される内容になってるんですね〜
</details>

# 分離してみる

メッセージ内容は別のアクションで定義してみましょう。
これで、`callback`関数の中は条件分岐して返信するだけになりました。
<details><summary>差分</summary>

（`parroting`は「オウム返し」の意味です。）

```diff_ruby
class LinebotController < ApplicationController
  def callback
    body = request.body.read
    events = client.parse_events_from(body)
    
    events.each do |event|
+      message = []
      case event
      when Line::Bot::Event::Message
        case event.type
        when Line::Bot::Event::MessageType::Text
-          message = {
-            type: 'text',
-            text: event.message['text']
-          }
+          message.push(parroting(event))
        end
      end
+     client.reply_message(event['replyToken'], message)
    end
  end

  private

+  def parroting(event)
+    {type: 'text', text: event.message['text']}
+  end

  def client
    @client ||= Line::Bot::Client.new { |config|
      config.channel_secret = ENV['LINE_CHANNEL_SECRET']
      config.channel_token = ENV['LINE_CHANNEL_TOKEN']
    }
  end
end
```
</details>

<details><summary>コードそのもの（コピペ用）</summary>

```ruby
class LinebotController < ApplicationController
  def callback
    body = request.body.read
    events = client.parse_events_from(body)
    
    events.each do |event|
      message = []
      case event
      when Line::Bot::Event::Message
        case event.type
        when Line::Bot::Event::MessageType::Text
          message.push(parroting(event))
        end
      end
      client.reply_message(event['replyToken'], message)
    end
  end

  private

  def parroting(event)
    {type: 'text', text: event.message['text']}
  end

  def client
    @client ||= Line::Bot::Client.new { |config|
      config.channel_secret = ENV['LINE_CHANNEL_SECRET']
      config.channel_token = ENV['LINE_CHANNEL_TOKEN']
    }
  end
end
```
</details>




# 画像（イメージ）を返信

オンラインスクールRUNTEQのキャラクター「らんてくん」を表示してみましょう！
（RUNTEQ宣伝も兼ねて。怒られたら変えますw）

先程の`parroting`と同じく、privateの下に「１つのアクションとして」作成してみます。
`parroting`と`image`の２つのメッセージを返信するようにしてみましょう。

<details><summary>差分</summary>

`message.push`の形で、messageに追加をしていくと複数のメッセージを返信できます。

```diff_ruby
class LinebotController < ApplicationController
  def callback
    body = request.body.read
    events = client.parse_events_from(body)
    
    events.each do |event|
      message = []
      case event
      when Line::Bot::Event::Message
        case event.type
        when Line::Bot::Event::MessageType::Text
          message.push(parroting(event))
+          message.push(runtequn_image)
        end
      end
      client.reply_message(event['replyToken'], message)
    end
  end

  private

  def parroting(event)
    {type: 'text', text: event.message['text']}
  end

+  def runtequn_image
+    runtequn = 'https://stickershop.line-scdn.net/stickershop/v1/product/18201714/LINEStorePC/main.png?v=1'
+    {type: 'image', originalContentUrl: runtequn, previewImageUrl: runtequn}
+  end

  def client
    @client ||= Line::Bot::Client.new { |config|
      config.channel_secret = ENV['LINE_CHANNEL_SECRET']
      config.channel_token = ENV['LINE_CHANNEL_TOKEN']
    }
  end
end
```
</details>

# スタンプを返信

スタンプを返信してみましょう！

先ほどと同じく、`message.push`も忘れず！

<details><summary>追加アクション</summary>

```ruby
def sticker
  {
    "type": "sticker",
    "packageId": "11537",
    "stickerId": "52002734"
  }
end
```
</details>

# 小説家になろう！の小説情報を取得

なろう小説APIというものがあります。

https://dev.syosetu.com/man/api/

こちらを使って、特定の小説（`ncode: 'n8920ex'`）の最終更新日を取得してみましょう！

<details><summary>追加アクション</summary>

```rb
def narou_api
  uri = URI('https://api.syosetu.com/novelapi/api/')
  params = {
    out: 'json',
    ncode: 'n8920ex',
  }
  uri.query = URI.encode_www_form(params)

  res = Net::HTTP.get_response(uri)
  novel = JSON.parse(res.body)
  p novel
  {type: 'text', text: "#{novel[1]['title']}\n\n最終更新：#{novel[1]['general_lastup']}"}
end
```

`ncode: 'n8920ex'`は個人的に大好きな小説ですw

なろう小説APIは語句検索やトレンド作品一覧も取得できます！
また、なろう小説に限らず様々なAPIがあります。APIを活用し、趣味の情報を送ってくれるLINEbotを作ってみるのもおすすめです！
</details>

# 確認テンプレート

「確認テンプレート」を使用してみましょう！

https://developers.line.biz/ja/reference/messaging-api/#template-messages:~:text=%5D%0A%20%20%7D%0A%7D-,%23,-%E7%A2%BA%E8%AA%8D%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88

<details><summary>追加アクション</summary>

```rb
  def confirm_template
    {
      "type": "template",
      "altText": "これは確認テンプレートです",
      "template": {
        "type": "confirm",
        "text": "本当に？",
        "actions": [
          {
            "type": "message",
            "label": "はい",
            "text": "はい"
          },
          {
            "type": "message",
            "label": "いいえ",
            "text": "いいえ"
          }
        ]
      }
    }
  end
```

LINEっぽいメッセージ！
テンションが上がります。

</details>

# 条件分岐をしてみよう！

これで最後です！

<details><summary>差分</summary>

```diff_ruby
def callback
  body = request.body.read
  events = client.parse_events_from(body)
  
  events.each do |event|
    message = []
    case event
    when Line::Bot::Event::Message
      case event.type
      when Line::Bot::Event::MessageType::Text
+        case event.message['text']
+        when 'クラッカー' then
+          message.push(sticker)
+        when 'らんてくん' then
+          message.push(runtequn_image)
+        else
+          message.push(parroting(event))
+        end
      end
    end
    client.reply_message(event['replyToken'], message)
  end
end
```

これで、メッセージに応じて返信することができるようになりました！

先ほどの確認テンプレートを組み合わせてもいいですね！

</details>

# おわりに

おつかれさまでした！
できることはまだまだたくさんあります！
ぜひ以下の公式リンクも見てみてください〜

https://developers.line.biz/ja/reference/messaging-api/#text-message

さらにアドバンスな内容をやりたい方は、
「`postback`を利用したクイズを3問作ってみる」のが良いと思います！
~~もしかしたら記事を書くかも。~~記事書きました！

https://qiita.com/kohki_takatama/items/439c63611725298c04c1

ここまで全３本、お読みいただきありがとうございました！

次は何を書こうかしら・・・