【LINE×Rails】Rails初学者も作れるLINE Botアプリケーション

# 概要
この記事では、先日リリースした[ReLINE【"猫さん"】](https://www.cat-reline.com/)で得た LINE Messaging API の知見を使って、`投稿に応じて返信するテキストを変化させるLINE Botアプリケーション`を作成します。

記事の内容に沿って実際に手を動かして取り組んでもらうと、今回私が作成したものと同じものができるので、お時間のある方はチャレンジしてもらえると嬉しいです！

【注意点】
この記事では上記のLINE Botアプリケーションを作成する流れを記載していきます。そのため技術的な話はほとんど出てきませんが、身近なLINEアプリを使ってプログラミングへの楽しさや作成する面白さなどを感じてもらえたら幸いです。

【今回挑戦する４ケース】
１."おまじない"（`アブラカタブラ`、`チチンプイプイ`、`ヒラケゴマ` のいずれかテキスト）が投稿された場合
　  　=> `It is Omajinai`と返す
２．`ruby`というテキストが投稿された場合
　　  => `Is it Programming language? Ore?`と返す
３．`スタンプ`が投稿された場合
　　  => `Thanks!!`と返す
４．上記以外のイベントが発生した場合
　　  => `.......`と返す

尚、今回はngrokを使用して、Railsは開発環境のままでも楽しめるようにします。
（以下の画像は完成イメージです）

![Screenshot_2021-11-30-16-44-36-17.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587204/78cbd740-9129-aef2-e71a-35dc561219dd.jpeg)

# 本記事の全体の流れ
　１．LINE側の設定
　２．Rails側の設定
　３．ngrokの立ち上げ
　４．その他諸々の設定


# １．LINE側の設定
【大まかな流れ】

- LINEアカウントを使用してLINE Developersにログイン
- プロバイダーの作成
- Messaging APIを選択から作成まで
- チェンネルIDとチェンネルシークレットの値を控える
- チャンネルアクセストークンを発行して値を控える

## ■ LINEアカウントを使用してLINE Developersにログイン
[LINE Developers](https://developers.line.biz/ja/)にアクセスして、右上にある「ログイン」からLINEアカウントを使用してログインします。
![スクリーンショット 2021-11-30 13.48.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587204/23c3ba22-9186-33bf-ee86-459a7c8b4fc8.png)

## ■ プロバイダーの作成
新規プロバイダーを作成します。「作成」ボタンをクリックします。`新規プロバイダー作成`がポップアップで表示されるので、プロバイダー名を入力して「作成」をクリックしてください。

![スクリーンショット 2021-11-30 16.54.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587204/f883fceb-87d3-c6dd-4f07-3937b56d6f44.png)


## ■ Messaging APIを選択から作成まで
新規プロバイダーを作成できたら、Messaging APIを選択してください。
![スクリーンショット 2021-11-30 17.45.00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587204/1573ada7-855a-e468-dd79-4c2ffa6f4358.jpeg)

入力画面に遷移したら必須項目を埋めて、「作成」ボタンをクリックしてください。
![スクリーンショット 2021-11-30 17.47.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587204/b5370636-6436-45dd-1ecf-0388fe4f2628.png)

【必須項目に関しての補足】

- チャンネルの種類：Messaging API
- プロバイダー：先程作成したプロバイダー名
- チャンネル名：（好きなチャンネル名を入力）
- チェンネル説明：（適宜入力）
- 大業種：（分類の中から選択）
- 小業種：（分類の中から選択）
- メールアドレス：自分のメールアドレス
- LINE公式アカウント利用規約の内容に同意します：チェックを入れる
- LINE公式アカウントAPI利用規約の内容に同意します：チェックを入れる

`以下の内容でMessaging APIチャンネルを作成しますか？`というポップアップが表示されたら「OK」をクリックし、続いて表示される`情報利用に関する同意について`は「同意する」をクリックしてください。

## ■ チェンネルIDとチェンネルシークレットの値を控える
下記画像の緑色で隠している２箇所をコピーして控えておいてください（後程Railsの設定のところで使用します）。

- チャンネルID
- チャンネルシークレット

![スクリーンショット 2021-11-30 13.59.21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587204/6ff5592e-1b72-f309-7d0c-c7a3cd8d9d48.jpeg)


## ■ チャンネルアクセストークンを発行して値を控える
タグを「Messaging API設定」に切り替えて、チャンネルアクセストークン（長期）を発行し、こちらもコピーして控えておきます（後程Railsの設定のところで使用します）。
![スクリーンショット 2021-11-30 14.03.31.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587204/e3a78a68-02d1-3ef9-88ce-b0b564978f61.jpeg)

以上で一旦LINE側の設定は終了になります。



# 2.Rails側の設定
【大まかな流れ】

- 開発環境
- rails new からサーバー起動確認まで
- Gem(`line-bot-api`)を加える
- ルーティングの設定
- credentials.yml.encの編集
- コントローラーの設定
- development.rbに`ngrok`を使用する設定を追加

## ■ 開発環境
● Ruby：3.0.2
● Ruby on Rails：6.1.4.1
＊ credentials.yml を使用するのでRailsのバージョンが5.2以上であれば大丈夫です。Rubyに関してもRailsが動けば問題ないかと思われます。

## ■ rails new からサーバー起動確認まで
では、早速rails new でアプリケーションを立ち上げて、ちゃんとサーバーが起動するかを確認しましょう。

```bash
$ rails new hello_hogefuga
$ cd hello_hogefuga
$ bin/rails s
```
Yay! You're on Rails! が表示されたらOKです。
![スクリーンショット 2021-11-30 14.49.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587204/44a91584-59f2-49d9-4151-3e124249bfc7.png)


## ■ Gem(`line-bot-api`)を加える
この開発で必要なgem [`line-bot-api`](https://github.com/line/line-bot-sdk-ruby)をGemfileに加えて、bundle installを実行します。

```rb
# Gemfile
gem 'line-bot-api'
```
```bash
$ bundle install
```

## ■ ルーティングの設定
次にルーティングを設定します。

```rb
# config/routes.rb
Rails.application.routes.draw do
  post '/callback', to: 'hoges#callback'
end
```

## ■ credentials.yml.encの編集
今回は開発環境で動かすだけなので必要ではないかもしれませんが、万が一情報が漏れてしまうとマズイので、チャンネルID・チャンネルシークレット・チャンネルアクセストークン（長期）の値をcredentials.ymlに加えましょう。

＊vimの使い方は各自で調べてください。

```bash
$ EDITOR='vim' bin/rails credentials:edit
```
```yml
channel_id: 11111 # 先程控えたチャンネルID
channel_secret: 'hogehogehoge' # 先程控えたチャンネルシークレット
channel_token： 'fugafugafugafugafugafuga' # 先程控えたチャンネルトークン（長期）
```

## ■ コントローラーの設定
次にコントローラーを作成し、config/routes.rbで設定したアクションの中身を記述しましょう。

＊今回は体験重視のため、ロジック部分もコントローラーに記載しております。

```bash
$ bin/rails g controller hoges
```

（以下のコントローラーの記述は[公式GitHUb](https://github.com/line/line-bot-sdk-ruby)を参考に少し手を加えております）

```rb
# app/controllers/hoges_controller.rb
class HogesController < ApplicationController
  protect_from_forgery except: :callback

  OMAJINAI = /アブラカタブラ|チチンプイプイ|ヒラケゴマ/

  def callback
    client = Line::Bot::Client.new do |config|
      config.channel_id = Rails.application.credentials.channel_id
      config.channel_secret = Rails.application.credentials.channel_secret
      config.channel_token = Rails.application.credentials.channel_token
    end

    body = request.body.read
    signature = request.env['HTTP_X_LINE_SIGNATURE']
    return head :bad_request unless client.validate_signature(body, signature)

    events = client.parse_events_from(body)
    events.each do |event|
      message = case event
                when Line::Bot::Event::Message
                  { type: 'text', text: parse_message_type(event) }
                else
                  { type: 'text', text: '........' }
                end
      client.reply_message(event['replyToken'], message)
    end
    head :ok
  end

  private

  def parse_message_type(event)
    case event.type
    when Line::Bot::Event::MessageType::Text
      reaction_text(event)   # ユーザーが投稿したものがテキストメッセージだった場合に返す値
    else
      'Thanks!!'             # ユーザーが投稿したものがテキストメッセージ以外だった場合に返す値
    end
  end

  def reaction_text(event)
    if event.message['text'].match?(OMAJINAI)
      'It is Omajinai'                          # 定数OMAJINAIに含まれる文字列の内、いずれかに一致した投稿がされた場合に返す値
    elsif event.message['text'].match?('ruby')
      'Is it Programming language? Ore?'        # `ruby`という文字列が投稿された場合に返す値
    else
      event.message['text']                     # 上記２つに合致しない投稿だった場合、投稿と同じ文字列を返す
    end
  end
end
```

＊Line::Bot::Clientに用意されているメソッドに関しては、[公式ドキュメント](https://developers.line.biz/ja/docs/messaging-api/)や[公式GitHub](https://github.com/line/line-bot-sdk-ruby)などを参照してください。

## ■ development.rbに`ngrok`を使用する設定を追加
次にngrokを使用できるように、development.rbに以下の記述を加えます。

```rb
# config/environments/development.rb
require 'active_support/core_ext/integer/time'
Rails.application.configure do
  # ===== 省略 =====
  config.hosts << '.ngrok.io'
end
```
以上でRails側の設定は完了です。

# 3.ngrokの立ち上げ
【大まかな流れ】

- ngrokのインストール
- ngrokの起動とURL(https)を控える
- Railsサーバーを立ち上げ直す

## ■ ngrokのインストール
HomebrewがインストールされているMacでしたら、以下のコマンドでngrokをインストールできます。

（Homebrewが入っていない方は[こちら](https://brew.sh/index_ja)のページからインストールを行ってください）

```bash
$ brew install ngrok
```

## ■ ngrokの起動とURL(https)を控える
インストールが完了したら以下のコマンドを実行してngrokを立ち上げます。

```bash
$ ngrok http 3000
```

立ち上がると下記画像のようになるので、緑色の枠の部分(https.....)をコピーして控えておいてください（後程その他諸々の設定のところで使用します）。
![スクリーンショット 2021-11-30 16.13.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587204/be14f485-c430-28ae-ec0b-d8cc10e34e39.png)

## ■ Railsサーバーを立ち上げ直す
`2.Rails側の設定`の最後でconfig/environments/development.rbを編集しているので、Railsサーバーを立ち上げ直します。

```bash
# 別にターミナルを開いてサーバーを立ち上げ直す
$ bin/rails s
```

＊ngrokは立ち上げる度に付与されるURLが異なりますので、都度控えて後述のWebhook URLの編集部分を変更してください。

以上でngrokの立ち上げは完了です。

# 4.その他諸々の設定
【大まかな流れ】

- Webhookの設定
  - Webhookの利用を有効にする
  - Webhook URLを編集
  - `検証`を行う
- 応答設定
  - グループ・複数人チャットへの参加を許可する：無効
  - 応答メッセージ：無効
  - あいさつメッセージ：無効

## ■ Webhookの設定
LINE Developersに戻り、残りの設定を行いましょう。
まずは`Messaging API設定`のタグをクリックし、`Webhookの利用`をアクティブにします。

次に、`Webhook URL`横にある「編集」ボタンをクリックし、表示された入力画面にngrokで控えた「https://.....ngrok.io」の値を貼り付け、その後ろにRails側で設定したルーティングのURLを加えます。

`https://.....ngrok.io/callback`

入力が整ったら「更新」ボタンをクリックしてください。

ここまでの設定で問題が無ければ「検証」ボタンを押すと`成功`のポップアップが表示されるので確認してみましょう。

![スクリーンショット 2021-11-30 16.20.37.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587204/45dba7fe-1d25-95c5-d885-2cdf1a331b1b.jpeg)

もし`成功`以外が表示されてしまった際は、rails c を使ってcredentials.ymlで設定した値がちゃんと呼び出せるか、入力している値に差異がないか、その他設定で打ち間違いがないかなどなど、一度確認してみてください。

```bash
# credentials.ymlがちゃんと呼び出せるかの確認方法
$ rails c

$ Rails.application.credentials.channel_id       # チャンネルID
$ Rails.application.credentials.channel_secret　　　　　　# チャンネルシークレット
$ Rails.application.credentials.channel_token    # チャンネルトークン（長期）
```

## ■ 応答設定
「検証」で成功が表示されたら、`応答メッセージ`が表示されている行の右側にある「編集」ボタンをクリックしてください。

`応答設定`のページに遷移したら、`基本設定`、`詳細設定`の中身を以下の画像のように修正してください。

![スクリーンショット 2021-11-30 16.29.33.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587204/1bc65b0a-ef44-8bfd-a3cc-894eec71ad4f.jpeg)

【基本設定・詳細設定の補足】

- 応答モード：Bot
- あいさつメッセージ：オフ
- 応答メッセージ：オフ
- Webhook：オン

修正を終えたら完了です。

LINE Developersの`Messaging API設定`のところで表示されているQRコードを、スマートフォンのLINEアプリで読み込んで友だち追加を行ったら、LINE Botと１対１のトークルーム内で`アブラカタブラ`・`ruby`・`スタンプ`を投稿してみましょう。

![スクリーンショット 2021-12-01 19.39.20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587204/303f5da9-a843-cec0-91d9-1f69b4ac8943.jpeg)

（この記事の始めに掲載した画像と同じようなものが表示されたのではないでしょうか？）

# 最後に
作成は以上になります。お疲れ様でした！

ちょっとだけ今回の機能部分の話をすると、受け取ったeventsの中身、特にmessage['text']の値をRubyの`match?`メソッドと正規表現を使って、`match?`メソッドの返り値がtrueであるか否かで条件分岐させています。（割りと単純ですよね！？）

今回は全てテキストメッセージを返す仕様になっていますが、別の値、例えば外部APIを叩いてその結果を返したりすることもできるかと思いますので、意欲のある方はチャレンジしてもらえればと思います👍✨

最後まで読んでいただき、ありがとうございました！🐾

***
### 参考URL

・LINE Developers Messaging API
　　　https://developers.line.biz/ja/docs/messaging-api/

・GitHub line/line-bot-sdk-ruby
　　　https://github.com/line/line-bot-sdk-ruby