初心者がRubyで自作したLINE botを公開するまで

#目標
自作LINE bot公開
環境構築からゼロからやります
基本的な用語の説明も簡単に把握しよう

# 手段
Ruby on rails
LINE developers
heroku：クラウドプラットフォーム
ngrok：ローカルのwebサーバを外部公開できる
Mac

# 作った人のステータス
Ruby? Rails? なにそれ，おいしいの?

# 作成
## 0. まず開発環境を作る
ほぼこちらを参考にしました．感謝． 
[Ruby初学者のRuby On Rails 環境構築【Mac】](https://qiita.com/TAByasu/items/47c6cfbeeafad39eda07)

### マシンスペック

- MacBook Air(mid-2013)
- macOS Catalina 10.15.4

#### Install Homebrew

Homebrewとは（Wikipediaより） 

 >Homebrewは、macOSオペレーティングシステム上のパッケージ管理システムのひとつである。  

Homebrewがインストールされてるか確認

```console
$ brew -v
```
インストールされてたらこんなのが出ます．  

```console
Homebrew 2.2.12
Homebrew/homebrew-core (git revision ca9b2; last commit 2020-04-10)
Homebrew/homebrew-cask (git revision 66f2e; last commit 2020-04-10)
```
インストールされてなかったら[公式HP](https://brew.sh/index_ja.html)からインストール（丸投げ）
<br>

### Install rbenv

rbenvとは（[こちら](https://techacademy.jp/magazine/21534)より）  

 >rbenvとは、Rubyのバージョン管理を切り替えるツールです。使っている環境全体のバージョンだけでなく、ディレクトリごとにバージョンを設定することもできます。  

rbenvがインストールされてるか確認

```console
$ rbenv -v
```
インストールされてたらこんなのが出ます  

```console
rbenv 1.1.2
```
インストールされてなかったら以下コマンドでインストール

```console:Install_rbenv
$ brew install rbenv ruby-build
```

PATHを通す（鋭意執筆中）

<br>

### Install Ruby

rubyがインストールされてるか確認

```console
$ ruby -v
```
インストールされてたらこんなのが出ます  

```console
ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin19]
```

インストールされてなかったら・・・ 
インストールできるRubyを確認する

```console
$ rbenv install --list
```
バージョンを選んでインストール（以下の例では2.6.3）
ちょびっと時間かかります 
今回は環境全体に対してバージョンを切り替えておきます

```console:Install_Ruby2.6.3
$ rbenv install 2.6.3
$ rbenv global 2.6.3
$ rbenv rehash
```
ここで念のためRubyのバージョンを確認して確かめてもいいかも
<br>

### Install Bundler

Bundlerとは（[こちら](https://qiita.com/YUKchannel/items/319b291c0dc76d538e00)より）  
>bundlerは、gemの依存関係とバージョンを管理する為のツールになります。

gemとは簡単にいうとRuby版ライブラリです．

インストールの流れはもはやテンプレですね． 
bundlerがインストールされてるか確認

```console
$ bundler -v
```
インストールされてたらこんなのが出ます  

```console
Bundler version 2.1.4
```
インストールされてなかったら以下コマンドでインストール

```console:Install_bundler
$ gem install bundler
```
<br>

### Install PostgreSQL
わりと他の記事だとMySQLをインストールしているところが多いんですが
のちのち使うherokuはPostgreSQL対応らしいのでそちらをインストールします

```console:Install_PostgreSQL
$ gem install postgresql
```

### PostgreSQL起動
```console:PostgreSQL起動
$ brew services start postgresql
```

<br>

### Install Rails

```console:適当なワークスペースの作成
$ mkdir ~/workspace
$ cd ~/workspace
```

念のためローカルのRubyバージョンを指定しておく

```console:ローカルのRubyバージョン指定
$ rbenv local 2.6.3
```

Gemfile作成

```console:Gemfile作成
$ bundle init
```

作成したGemfileを編集して，`# gem "rails"`のコメントアウトを解除する
Railsのインストールとバージョン確認

```console:Install_Rails
$ bundle install --path=vendor/bundle
$ bundle exec rails -v
```
（nokogiriのインストールに時間がかかるのはあるあるだと思う）

<br>

### Railsアプリケーション作成
今回はLine botを作りたいので名前は`linebot`にしました

データベースをPostgreSQLに指定します．**大事．**
何もしないとsqlite3になって後々困ります．（経験談）
なぜならherokuはsqlite3に対応していないから．

```console:Railsアプリケーション作成
$ rails new linebot -d postgresql
```

<br>

### PostgreSQLのデータベースをつくる
たった今作った`linebot`ディレクトリに移動してデータベースを作ります

```console
$ cd linebot
$ rails db:create
```

作れたら同じディレクトリ内でアプリケーションを起動してみましょう

### Railsアプリケーション起動してみる

```console:Railsアプリケーション起動
$ rails s
```

```console
（以上略）
=> Booting Puma
=> Rails 6.0.2.2 application starting in development 
=> Run `rails server --help` for more startup options
Puma starting in single mode...
* Version 4.3.3 (ruby 2.6.3-p62), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:3000
* Listening on tcp://[::1]:3000
Use Ctrl-C to stop
```

よさげ．．．
てことで[http://localhost:3000/](http://localhost:3000/)にアクセスしてみます

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616261/51f14c9f-bd55-b950-6918-97a767bba1b7.png" alt="Yay! You're on Rails!" width="800px">

できた！！

<br>

## 1. Herokuに初デプロイ
作成したアプリを公開するためにHerokuというクラウドプラットフォームにデプロイします
LINE bot本体を作る前にまずデプロイがうまくできるかチャレンジ（さいしょうまくいかなかった）

herokuとは（元気があれば追記する）

[Heroku](https://jp.heroku.com/home)

### インストール
```console
$ brew tap heroku/brew && brew install heroku
```

### ログイン
```console
$ heroku login
```

### アプリ作成
```console
$ heroku create
```

こうするといい感じに自動的にURL作ってくれてgitのremote先に指定してくれているので楽
試しに`$ git remote -v`で確認するとちゃんと指定されていることがわかる

**大事**
**このときに生成されたURLはあとでLINE Developersでの設定に使うのでどこかにメモしておきましょう**

というわけでデプロイ

```console
$ git push heroku master
```

うまくいきました

<br>

## 2. LINE Developersコンソールでチャネルを作成
いよいよLINE botを作って行きますよ！
具体的にはLINE developersコンソールのMessaging APIを使います
で，このMessaging APIを使うためにはLINE Developersでチャネルを作る必要があります

[Messaging APIを利用するには | LINE Developers](https://developers.line.biz/ja/docs/messaging-api/getting-started/)の流れに沿って作りましょう！（説明丸投げ）


### Webhook URL設定
LINE Developersで作成したチャネルのMessaging API設定を開き，
ページの中程にあるWebhook URLに`{さっきコピーしたHerokuのURL}/callback`を設定します

**忘れずにやること**
そのすぐ下にある`Webhookを有効にする`をオン
そのもう少し下にある`応答メッセージ`を無効にする

### herokuに環境変数を設定する
**LINE_CHANNEL_SECRET**：チャネル基本設定ページの下のほうにあるチャネルシークレット
**LINE_CHANNEL_TOKEN**：Messaging API設定ページの一番下あたりにあるチャネルアクセストークン（ロングターム）．表示されてなかったら発行ボタンを押す．

```console
$ heroku config:set LINE_CHANNEL_SECRET={your LINE_CHANNEL_SECRET}
$ heroku config:set LINE_CHANNEL_TOKEN={your LINE_CHANNEL_TOKEN}
```

### 接続確認はあとで
Webhook URLのところにある検証ボタンをクリック
この時点ではLINE botの本体がないので正常に動作するはずがないのであとでやりましょう

<br>

## 3. LINE botの骨組みをつくる
[LINE Messaging API SDK for Ruby](https://github.com/line/line-bot-sdk-ruby)の`Installation`に則って進めて行きます

### line-bot-apiのインストール
前編で作成した`linebot`ディレクトリ内にある`Gemfile`を編集します．

```
gem 'line-bot-api'
```
この1行を`Gemfile`内のどこかに書きます．僕は一番下に書きました．
そして，実行．**←これ大事**

```
bundle
```

<br>

### routes.rb編集
```ruby:config/routes.rb
Rails.application.routes.draw do  
    post '/callback' => 'webhook#callback'    <--新規追加した行
end  
```
`post~`の行を追加します

<br>

### controller作成
とりあえずはLINE Messaging API SDK for Rubyに[おうむ返しbotのサンプル](https://github.com/line/line-bot-sdk-ruby/blob/master/examples/echobot/app.rb)があったのでそれを使って作ります．

その前にまずcontrollerを作成します

```console
$ rails g controller webhook  
```

そうすると`app/controllers/webhook_controller.rb`ができているはずなのでこれを編集します

```ruby:app/controllers/webhook_controller.rb
class WebhookController < ApplicationController
    require 'line/bot'  # gem 'line-bot-api'

    protect_from_forgery except: [:callback] # CSRF対策無効化

    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
      body = request.body.read
    
      signature = request.env['HTTP_X_LINE_SIGNATURE']
      unless client.validate_signature(body, signature)
        halt 400, {'Content-Type' => 'text/plain'}, 'Bad Request'
      end
    
      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
    
      "OK"
    end
end
```

<br>

## 4. Herokuにデプロイ
```console
$ git push heroku master
```


### 接続確認
Webhook URLのところにある検証ボタンをクリック

### 動作確認
自分のLINEに作成したLINE botを友達追加して何か入力してみましょう
入力した文字がそのまま返ってきたら成功！！

<br>

## 5. ngrokを使ってローカルテスト環境構築
いきなりデプロイする前にやっぱりローカルでテストしたい！ってことで
ngrokを使って実現しましょう

### 環境変数を設定
Herokuでやったときのようにこっちでも環境変数を設定しないといけません
毎回設定するのが面倒くさいのでバッシュファイルに書き込みましょう

```console:console
$ export LINE_CHANNEL_SECRET={your LINE_CHANNEL_SECRET}
$ export LINE_CHANNEL_TOKEN={your LINE_CHANNEL_TOKEN}
```


### ngrok
ngrokとは（元気があれば追記する）

[ngrok](https://ngrok.com/)
上のサイトの`Setup & Installation`の通りに進めます

### ngrokをダウンロード
上のサイトに行くと，`Download for ***`みたいなボタンがあると思うのでそれを押してダウンロード
もしくはお好みのバージョンを選んでも良し
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616261/689fb095-dea8-509f-89de-4c437e1ae743.png" alt="Download ngrok" width="800px">


### Unzip
```console
$ unzip /path/to/ngrok.zip
```
なんだけど，ダウンロードしたら勝手に解凍されてしまった．まあいっか．
ダウンロードディレクトリに入れとくのもあれなので良きところに場所を移しました．

### Connect your account
移動した先で以下のコマンドを実行

```console
$ ./ngrok authtoken ************
```
******にはトークンが入ります．

### 起動
`rails s`するターミナルとは別のターミナルでngrokを起動します

```console
$ ./ngrok http 3000
```
公式の例だとポート80になってるけど，おそらくRailsを起動した時にポート3000が立ち上がってるはずなのでそれに合わせます．

出てきた`https://`から始まるURLをwebhookURLとして設定すればOK！



<br>

# 参考
[Ruby初学者のRuby On Rails 環境構築【Mac】](https://qiita.com/TAByasu/items/47c6cfbeeafad39eda07)