プログラミング初学者がLINE-botを作ってみた


## 概要
私事ですが、全く天気予報を見ないです。
そのため朝に雨が降っていなければ傘を持っていかず、毎回コンビニで傘を買ったり、雨に打たれながら帰宅することが多々あります。
そこで！傘代の節約、これ以上家に傘を増やさないためにも、自分用に朝7時に傘が必要か通知してくれて、こちらが「明日・明後日・今日・などなど」と入力すればその日に雨が降るかを返してくれるLINE　Botを実装してみました。

![IMB_wjbsdm.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/773411/e7313ff0-05c0-4f21-04ed-521ebd7a741d.gif)


## 手順
・事前にRailsの環境を整える
新規Railsアプリケーションの作成「rails new」コマンドを実行

```
＄　rails new アプリケーション名
```
作成されたディレクトリ（フォルダ）に移動

```
＄　cd　作成されたディレクトリ名
```
Gemfileの一番下に以下のコードを追加

```rb

gem ' dotenv-rails ' 
gem 'line-bot-api'　#dotenv-railsは環境変数を扱うために使用するgem
```

以下のコマンドでGemをインストール

```
＄bundle install
```

Userモデルを作成

```
$ rails generate model モデル名 カラム名:データ型
```
上記のコマンドで新しくマイグレーションファイルも作成される。このマイグレーションファイルを以下のように編集

```rb
class CreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      t.string :line_id, null: false # この行を修正

      t.timestamps
    end
  end
end
```
以下のコマンドでデータベース・テーブルを作成

```
$ bundle exec rails db:create
$ bundle exec rails db:migrate
```
新規作成されたファイルを編集

```rb:lib/tasks/scheduler.rake
task :update_feed => :environment do
  require 'line/bot'  # gem 'line-bot-api'
  require 'open-uri'
  require 'kconv'
  require 'rexml/document'
#line-bot側の設定
  client ||= Line::Bot::Client.new { |config|
    config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
    config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
  }
  # 使用したいxmlデータURLを入力
  # xmlデータをパース
  # パスの共通部分を変数化
  # 6時〜12時の降水確率
  # メッセージを発信する降水確率の下限値の設定
  min_per = 20
  if per06to12.to_i >= min_per || per12to18.to_i >= min_per || per18to24.to_i >= min_per
    word1 =
      ["テキスト入力",].sample
    word2 =
      ["テキスト入力"].sample
    # 降水確率によってメッセージを変更する閾値の設定。
#ifの条件式の中で降水確率によって送信されるメッセージを変更
    mid_per = 50
    if per06to12.to_i >= mid_per || per12to18.to_i >= mid_per || per18to24.to_i >= mid_per
      word3 = "テキスト入力"
    else
      word3 = "テキスト入力！"
    end
    # 発信するメッセージの設定
    push =
      "#{word1}\n#{word3}\n降水確率\n　  6〜12時　#{per06to12}％\n　12〜18時　 #{per12to18}％\n　18〜24時　#{per18to24}％\n#{word2}"
    # メッセージの発信先idを配列で渡す必要があるため、userテーブルよりpluck関数を使ってidを配列で取得。
#multicastsメソッドは、今回利用しているgem「line-bot-api」で定義されており、このメソッドを呼び出している
    user_ids = User.all.pluck(:line_id)
    message = {
      type: 'text',
      text: push
    }
    response = client.multicast(user_ids, message)
  end
  "OK"
end
```

以下のコマンドでコントローラの作成

```
$ bundle exec rails g controller linebot
```
作成されたコントローラーの編集

```rb:app/controller/linebot_controller.rb
class LinebotController < ApplicationController
  require 'line/bot'  # gem 'line-bot-api'
  require 'open-uri'
  require 'kconv'
  require 'rexml/document'

  def callback
    body = request.body.read
    signature = request.env['HTTP_X_LINE_SIGNATURE']
    unless client.validate_signature(body, signature)
      return head :bad_request
    end
    events = client.parse_events_from(body)
    events.each { |event|
      case event
        # メッセージが送信された場合の対応を入力

        # ユーザーからテキスト形式のメッセージが送られて来た場合の対応を入力

          when /.*(明日|あした).*/
            # info[2]：明日の天気
            per06to12 = doc.elements[xpath + 'info[2]/rainfallchance/period[2]'].text
            per12to18 = doc.elements[xpath + 'info[2]/rainfallchance/period[3]'].text
            per18to24 = doc.elements[xpath + 'info[2]/rainfallchance/period[4]'].text
            if per06to12.to_i >= min_per || per12to18.to_i >= min_per || per18to24.to_i >= min_per
              push =
                "テキスト\nテキスト\n降水確率\n　  6〜12時　#{per06to12}％\n　12〜18時　 #{per12to18}％\n　18〜24時　#{per18to24}％\nテキスト"
            else
              push =
                "テキスト"            end
          # テキスト以外（画像等）のメッセージが送られた場合
        else
          push = "テキスト"
        end
        message = {
          type: 'text',
          text: push
        }
        client.reply_message(event['replyToken'], message)
        # LINEお友達追された場合
      when Line::Bot::Event::Follow
        # 登録したユーザーのidをユーザーテーブルに格納
        line_id = event['source']['userId']
        User.create(line_id: line_id)
        # LINEお友達解除された場合
      when Line::Bot::Event::Unfollow
        # お友達解除したユーザーのデータをユーザーテーブルから削除
        line_id = event['source']['userId']
        User.find_by(line_id: line_id).destroy
      end
    }
    head :ok
  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



```

記号の意味
・「.」：何か1文字（「あ」や「a」など1文字なら何でもヒットします）
・「*」：直前の文字が０回以上繰り返す場合にマッチ
***
ルーティングの設定
メッセージが来た時、友達追加された時、解除がされた時に、linebotコントローラのcallbackアクションが呼ばれるようにしています。

```config/routes.rb

Rails.application.routes.draw do
  post '/callback' => 'linebot#callback'
end
```

この後、お好きなレンタルサーバー、共有サーバーでデプロイ
（私はHerokuでデプロイしました）

***
こちらの
[LINE　Botアカウント作成・設定](https://developers.line.biz/ja/
)
をして完成！！