RailsでLINEBotつくる（メッセージを受信したユーザーへ、メッセージを返す処理）

##はじめに
素人が独学でググりながらつくり、多分こういうことだろうということで書いているところが多々あるので、ところどころ理解が間違ってるところがありそうです。その際は教えていただけると大変助かります。

##主旨
LineBotをrubyで書いた時の自分の中で整理できた情報を、勉強の意味で残そうと思います。
いろいろ書くとごちゃごちゃするのでここでは「メッセージを受信したユーザーへ、メッセージを返す処理」に限定しています。

##環境設定
環境設定にあたり、以下Qiitaを参考にしました。とてもわかりやすく大変お世話になりました。
こちら全て終わっている前提で話を進めます。
https://qiita.com/y428_b/items/d2b1a376f5900aea30dc

##全体像
そもそも、botとプログラムコードの関係ですが、多分以下です。

1.ユーザー→bot
  LINE上で、ユーザーがbotへ何らかのアクション
2.bot→プログラムコード
  webhookとやらでやってるっぽい
3.プログラムコード→bot
  rails上で挙動を書いてやればbotが動く

なので、プログラムコードにはbotからこうあったらbotにこうする、みたいなことをつらつらと書く必要があります。
（詳細はあまりわからないのですがとりあえず）linebotapiのメソッドを使えば、いい感じにbotが動いてくれます。

##実際のコードをrailsで書く
まず、あれやこれやの事前の環境設定をできた前提で
ユーザーがbotに何かをメッセージ送信等のアクションをするとします。
それはrails上では、（きちんと事前準備をしていると）「/callbackにメッセージをpostする」ということになりますので、routesにcallbackにpostされた時のアクション（linebotコントローラーのcallbackアクション）を指定します。

```ruby:routes.rb
Rails.application.routes.draw do
  post'/callback',to:'linebot#callback'
end
```
この後、linebotコントローラーのcallbackアクションにつらつらとpostされた後の挙動を書いていきます。
とりあえずいい感じのメソッドが使えるようになるlinebotapiを使えるようにし（事前にgemに追加しておく）
あとは詳細不明ですが、公式等に書いてある以下コードをコピペしました。
ここまでは下準備です。

```ruby:linebot_controller.rb
# gem 'line-bot-api'
require 'line/bot' 
# callbackアクションのCSRFトークン認証を無効
protect_from_forgery :except => [:callback]
# 公式かなんかに書いてあった
def client
        @@client ||= Line::Bot::Client.new { |config|
          config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
            config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
        }
end
```
いよいよ、callbackアクションの中身を書きます。
最初は確か公式からのコピペですが、とりあえずユーザーから受信したデータを変数eventsに格納します

```ruby:linebot_controller.rb
def callback
# なんやかんやで、ユーザーからのデータを変数eventsに格納している
    body = request.body.read
    signature = request.env['HTTP_X_LINE_SIGNATURE']
    unless client.validate_signature(body, signature)
       head :bad_request
    end
    events = client.parse_events_from(body)
# 以下、いろんなコードを書く
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
end
```

あとはapiのメソッドを使いながら適当にやる感じです。
今回はユーザーにメッセージを返す処理なので以下メソッドとなります。（このclientは事前に定義したやつっぽい）

#####client.push_message(宛先userid, メッセージ内容)

なので、以下でokです。eventsは複数あり得るので、each処理してます。

```ruby:linebot_controller.rb
# ユーザーへメッセージを送付する
events.each {|event|
             message = { 
　　　　　　              type: 'text',
                        text: 'ここに文章いれる'
                       }                          
             client.push_message(event['source']['userId'], message)
             }
```
event['source']['userId']とすると、受信したユーザーからのデータeventsの中のuseridのデータを参照してくれます。
メッセージの内容は、ユーザーの特定の内容に反応させたいのであれば、if分でなんやかんややればいいし
オウム返しbotであれば、このメッセージのところに、ユーザーから受信したデータのテキストをいれていると思われます。

最後に全体を記載しておきます。これで多分動くはず。

```ruby:linebot_controller.rb
class LinebotController < ApplicationController
# gem 'line-bot-api'
require 'line/bot' 
# callbackアクションのCSRFトークン認証を無効
protect_from_forgery :except => [:callback]
# 公式かなんかに書いてあった
def client
        @@client ||= Line::Bot::Client.new { |config|
          config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
            config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
        }
end
#〜〜〜〜〜〜〜ここまで下準備〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

def callback
# なんやかんやで、ユーザーからのデータを変数eventsに格納している
    body = request.body.read
    signature = request.env['HTTP_X_LINE_SIGNATURE']
    unless client.validate_signature(body, signature)
       head :bad_request
    end
    events = client.parse_events_from(body)
# ユーザーへメッセージを送付する
　　 events.each {|event|
                 message = { 
　　　　　　                  type: 'text',
                            text: 'ここに文章いれる'
                           }                          
                 client.push_message(event['source']['userId'], message)
                 }
　　　head :ok
end
end
```

##最終的につくったもの
最後に最終的に私がつくったbotを紹介します。くだらないです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366075/5faf8081-0368-3622-c3b3-19a68260198d.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366075/3f6e2714-0cb2-0057-8b67-4591b7e3f951.png)