5
5

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 5 years have passed since last update.

【LineBot】地域、都道府県の選択を対話形式で行う

Last updated at Posted at 2019-04-06

はじめに

LineBotの作成の際に
「都道府県の選択を簡単に行えればいいな〜」
「対話形式で都道府県選択を行いたいな〜」
と思ったので自作してみました。

まだまだプログラミング初心者なので、DRYになっていない部分多々ありますが興味あればご覧ください。

基本的なLineBot作成方法は下記の記事などを参考にしてください。(すごく分かりやすいです。)
今更ながらRails5+line-bot-sdk-ruby+HerokuでLineBot作成してみたら、色々詰まったのでまとめました。

環境

  • Ruby on rails
  • heroku

作ったもの

下記の手順で都道府県を選択できるようにしました。
①地域の選択肢を、クイックリプライで表示させる。
②ユーザーが地域を選択する。
②選択した地域に含まれる各都道府県を、クイックリプライで表示させる。
④ユーザーが都道府県を選択する。
⑤LineBot側で選択された都道府県を認識してメッセージが来る。

以下がイメージ画像です。
※今回作成する部分は「どこの地域で遊ぶ?」〜「東京都で遊ぶ!」までの部分です。
IMG_4121.jpg → IMG_4120.jpg → IMG_4122.jpg
灰色の部分がクイックリプライと呼ばれる機能で、タッチするとMessageType::Textとして送信されます。

作成方法

概要

①都道府県モデル(Prefectureモデル)とseedデータ作成。
②地域と都道府県選択のためのmessageを用意。
③linebot_controllerのcallbackアクションに、分岐を作成。
といった流れで作成していきます。

①都道府県モデルとseedデータ作成。

まずは都道府県モデル(Prefectureモデル)を作成していきます。
$bundle exec rails g model Prefecture name:string
$bundle exec rails db:migrate

その後、都道府県データを作るためにseedをいじっていきます。

db/seeds.rb
# 47都道府県の配列を作る。
prefectures = [ "北海道", "青森県", ・・・・・・ "沖縄県" ]  

# prefecturesの配列を元にデータ作成する。
prefectures.each do |prefecture|
  Prefecture.create!(
    name: prefecture
  )
end

作成できたら
$bundle exec rails db:seed

これで下記のようなデータが出来るはずです。

id name
1 北海道
2 青森県
・・・ ・・・
47 沖縄県

②地域と都道府県選択のためのmessageを用意。

LineBotからリプライされるメッセージを作っていきます。
非常に量が多いため、app/controllers/linebot_controller.rbには記載せず、
今回はapp/models/line_clinet.rbに記載しました。

app/models/line_clinet.rbのサンプルコード
app/models/line_clinet.rb
class LineClient
  # 1回目の質問(地域選択部分)
  def self.first_reply
    { "type": "text",
                    "text": "どこの地域で遊ぶ?",
                    "quickReply": {
                      "items":
                      [
                        {
                          "type": "action",
                          "action": {
                          "type": "message",
                          "label": "北海道,東北",
                          "text": "北海道,東北"
                          }
                        },
                        {
                          "type": "action",
                          "action": {
                          "type": "message",
                          "label": "関東",
                          "text": "関東"
                          }
                        },
                        {
                          "type": "action",
                          "action": {
                          "type": "message",
                          "label": "甲信越,東海",
                          "text": "甲信越,東海"
                          }
                        },
                        {
                          "type": "action",
                          "action": {
                          "type": "message",
                          "label": "関西,北陸",
                          "text": "関西,北陸"
                          }
                        },
                        {
                          "type": "action",
                          "action": {
                          "type": "message",
                          "label": "中国,四国",
                          "text": "中国,四国"
                          }
                        },
                        {
                          "type": "action",
                          "action": {
                            "type": "message",
                            "label": "九州",
                            "text": "九州"
                            }
                        }
                      ]
                    }
                  }
  end

  # 2回目の質問(都道府県の選択部分)
  def self.second_reply_hokkaido_tohoku
    { "type": "text",
                    "text": "どの県で遊ぶの?",
                    "quickReply": {
                      "items":
                      [
                        {
                          "type": "action",
                          "action": {
                          "type": "message",
                          "label": "北海道",
                          "text": "北海道"
                          }
                        },
                        {
                          "type": "action",
                          "action": {
                          "type": "message",
                          "label": "宮城県",
                          "text": "宮城県"
                          }
                        },
                        {
                          "type": "action",
                          "action": {
                            "type": "message",
                            "label": "青森県",
                            "text": "青森県"
                          }
                        },
                        {
                          "type": "action",
                          "action": {
                          "type": "message",
                          "label": "岩手県",
                          "text": "岩手県"
                          }
                        },
                        {
                          "type": "action",
                          "action": {
                          "type": "message",
                          "label": "秋田県",
                          "text": "秋田県"
                          }
                        },
                        {
                          "type": "action",
                          "action": {
                          "type": "message",
                          "label": "山形県",
                          "text": "山形県"
                          }
                        },
                        {
                          "type": "action",
                          "action": {
                          "type": "message",
                          "label": "福島県",
                          "text": "福島県"
                          }
                        },
                        {
                          "type": "action",
                          "action": {
                          "type": "message",
                          "label": "地域を選び直す",
                          "text": "地域を選び直す"
                          }
                        }
                      ]
                    }
                  }
  end

  def self.second_reply_kanto
     { "type": "text",
                  "text": "どの県で遊ぶの?",
                  "quickReply": {
                    "items":
                    [
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "東京都",
                        "text": "東京都"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                          "type": "message",
                          "label": "神奈川県",
                          "text": "神奈川県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "千葉県",
                        "text": "千葉県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "埼玉県",
                        "text": "埼玉県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "群馬県",
                        "text": "群馬県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "栃木県",
                        "text": "栃木県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "茨城県",
                        "text": "茨城県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "地域を選び直す",
                        "text": "地域を選び直す"
                        }
                      }
                    ]
                  }
                }
  end

  def self.second_reply_kousinnetu_tokai
     { "type": "text",
                  "text": "どの県で遊ぶの?",
                  "quickReply": {
                    "items":
                    [
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "山梨県",
                        "text": "山梨県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                          "type": "message",
                          "label": "長野県",
                          "text": "長野県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "新潟県",
                        "text": "新潟県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "愛知県",
                        "text": "愛知県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                          "type": "message",
                          "label": "岐阜県",
                          "text": "岐阜県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "三重県",
                        "text": "三重県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "静岡県",
                        "text": "静岡県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "地域を選び直す",
                        "text": "地域を選び直す"
                        }
                      }
                    ]
                  }
                }
  end

  def self.second_reply_kansai_hokuriku
     { "type": "text",
                  "text": "どの県で遊ぶの?",
                  "quickReply": {
                    "items":
                    [
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "大阪府",
                        "text": "大阪府"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                          "type": "message",
                          "label": "京都府",
                          "text": "京都府"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "兵庫県",
                        "text": "兵庫県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "奈良県",
                        "text": "奈良県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "和歌山県",
                        "text": "和歌山県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "滋賀県",
                        "text": "滋賀県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "石川県",
                        "text": "石川県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                          "type": "message",
                          "label": "富山県",
                          "text": "富山県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "福井県",
                        "text": "福井県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "地域を選び直す",
                        "text": "地域を選び直す"
                        }
                      }
                    ]
                  }
                }
  end

  def self.second_reply_chugoku_shikoku
     { "type": "text",
                  "text": "どの県で遊ぶの?",
                  "quickReply": {
                    "items":
                    [
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "広島県",
                        "text": "広島県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                          "type": "message",
                          "label": "岡山県",
                          "text": "岡山県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "山口県",
                        "text": "山口県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "鳥取県",
                        "text": "鳥取県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "島根県",
                        "text": "島根県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "香川県",
                        "text": "香川県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                          "type": "message",
                          "label": "愛媛県",
                          "text": "愛媛県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "徳島県",
                        "text": "徳島県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "高知県",
                        "text": "高知県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "地域を選び直す",
                        "text": "地域を選び直す"
                        }
                      }
                    ]
                  }
                }
  end

  def self.second_reply_kyusyu
     { "type": "text",
                  "text": "どの県で遊ぶの?",
                  "quickReply": {
                    "items":
                    [
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "福岡県",
                        "text": "福岡県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                          "type": "message",
                          "label": "佐賀県",
                          "text": "佐賀県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "長崎県",
                        "text": "長崎県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "熊本県",
                        "text": "熊本県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "大分県",
                        "text": "大分県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "宮崎県",
                        "text": "宮崎県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "鹿児島県",
                        "text": "鹿児島県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "沖縄県",
                        "text": "沖縄県"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "地域を選び直す",
                        "text": "地域を選び直す"
                        }
                      }
                    ]
                  }
                }
  end

  # 3回目の質問
  def self.third_reply(prefecture)
     { "type": "text",
                  "text": "#{prefecture}で遊ぶでいい?",
                  "quickReply": {
                    "items":
                    [
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "#{prefecture}で遊ぶ!",
                        "text": "#{prefecture}で遊ぶ!"
                        }
                      },
                      {
                        "type": "action",
                        "action": {
                        "type": "message",
                        "label": "地域を選び直す",
                        "text": "地域を選び直す"
                        }
                      }
                    ]
                  }
                }
  end

end

変数を渡したりしたいので、基本的にはmethodとして定義しています。

③linebot_controllerのcallbackアクションに、分岐を作成。

送信されるメッセージに応じて、LineBotの返信メッセージを変えていきます。
想定通りのフローでユーザーが動くと
first_reply
second_reply_〇〇
third_reply
の順に表示されて、反応していくことになります。

app/controllers/linebot_controller.rbのサンプルコード
app/controllers/linebot_controller.rb
class LinebotController < ApplicationController
  require 'line/bot'

  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
    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)

    # 作った都道府県データを再度変数に保存しておく。
    prefectures = Prefecture.all

    events.each { |event|
      #ここでLINEで送った文章を取得。スペースなどの空白は削除
      @message = event.message['text'].gsub(" ", "") 
      # eventの種類による場合分け(MesageやBeaconなどがあります)
      case event
      when Line::Bot::Event::Message # Event::Messageの場合の処理
        case event.type
        when Line::Bot::Event::MessageType::Text # MessageType::Textの場合の処理
          case @message # 送信されたメッセージに応じて分岐させる。

          # 地域選択された際に、該当地域の各都道府県を表示する部分。←2枚目の画像の部分
          when "北海道,東北"
            message = ::LineClient.second_reply_hokkaido_tohoku
            client.reply_message(event['replyToken'], message)
          when "関東"
            message = ::LineClient.second_reply_kanto
            client.reply_message(event['replyToken'], message)
          when "甲信越,東海"
            message = ::LineClient.second_reply_kousinnetu_tokai
            client.reply_message(event['replyToken'], message)
          when "関西,北陸"
            message = ::LineClient.second_reply_kansai_hokuriku
            client.reply_message(event['replyToken'], message)
          when "中国,四国"
            message = ::LineClient.second_reply_chugoku_shikoku
            client.reply_message(event['replyToken'], message)
          when "九州"
            message = ::LineClient.second_reply_kyusyu
            client.reply_message(event['replyToken'], message)

          # Prefectureモデルに該当するメッセージの場合に反応する。←3枚目の画像の部分
          when *prefectures.pluck(:name) #prefecturesのnameカラムに値があるものに反応するように記載。
            prefecture = Prefecture.find_by(name: @message)
            message = ::LineClient.third_reply(prefecture.name)
            client.reply_message(event['replyToken'], message)

          # 最初の質問部分(設定以外のテキストが送られてきた場合に表示) ←1枚目の画像の部分
          else
            message = ::LineClient.first_reply
            client.reply_message(event['replyToken'], message)
          end
        end
      end
    }


    head :ok
  end

end

まとめ

コードを見ていただくと分かる通り、実はメッセージによって分岐させているだけなので、一番初めに「北海道」などと送信すると、LineBotは対話形式を無視していきなり反応してしまいます。欠陥品です。(笑)

「(笑)じゃねーよ、もっといい方法あるだろがボケ」と思われている方いらっしゃると思いますので、もし思われている方いればいい方法教えて欲しいです。(gemとかどっかにありそう)

おまけ

もしよければ「ずぼらデート」というLineBotを作ったので、友達登録してみてください。

↓QRコード
yemHjR88WA.png

5
5
3

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
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?