26
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2021-03-14

概要

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

IMB_wjbsdm.gif

手順

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

$ rails new アプリケーション名

作成されたディレクトリ(フォルダ)に移動

$ cd 作成されたディレクトリ名

Gemfileの一番下に以下のコードを追加


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

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

$bundle install

Userモデルを作成

$ rails generate model モデル名 カラム名:データ型

上記のコマンドで新しくマイグレーションファイルも作成される。このマイグレーションファイルを以下のように編集

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

新規作成されたファイルを編集

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

作成されたコントローラーの編集

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文字なら何でもヒットします)
・「*」:直前の文字が0回以上繰り返す場合にマッチ


ルーティングの設定
メッセージが来た時、友達追加された時、解除がされた時に、linebotコントローラのcallbackアクションが呼ばれるようにしています。

config/routes.rb

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

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


こちらの
LINE Botアカウント作成・設定
をして完成!!

26
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?