#はじめに
PFでジャニーズの私物を特定して、すぐに購入できるサービスを作成したのでまとめます。
あまりにも長くなりそうなので、今回はLINE Messaging API
を使用した部分についてまとめます。
#サービスの概要
ジャニーズファンは推しと同じものを日常生活やライブで身につけたいという心理があります。
twitte上にファンの人が私物を特定してツイートをするので、そのツイートをキャッチして、LINEで通知・購入できるサービスになっています。
#なぜこのサービスを作成したか
私物の特定のツイートがされるとすぐファンが購入し、売り切れてしまうことがよくあります。
私自身、私物特定のツイートを発見し、サイトを検索してももう売り切れてしまっていたということが何回もあります。
他のファンよりも早く購入できるサービスがあればいいなと思い、このサービスを作成しました。
##完成したサービス
Webサイトは以下になります↓
LINEのQRコードになります。
ぜひ動かしてみてください!!
サービスのイメージがしづらいと思いますがこんな流れになります
1.Twitterで私服特定ツイートがされます。
LINE友達登録後できること
1.最新の情報を確認できます。
リッチメニュー右上の最新の情報ボタン
を押す→情報を確認したいメンバーを選択
する→最新の情報
が表示される
2.情報を受け取るメンバーを選択できます。
リッチメニュー左上のメンバー設定を変更する
を選択する→設定したいメンバーを選択
する→通知を受け取る
か、受け取らない
かを選択する
もちろん、現在の通知設定についてもリッチメニュー左下のメンバー設定を確認する
から確認可能です。
##使用した機能
Twitter API
LINE Messaging API
dotenv-rails'
config gem
ransack gem
sorcery gem
kaminari gem
enum_help gem
rails-i18n gem
AWS
heroku
##画面遷移図
##LINE Messaging API
「LINE BOT」とは、メッセージアプリのLINEを使用して、ユーザーの質問に自動で返答できたり、メッセージを送信できたりするプログラムのことです。
仕組みについてはこちら↓
Messaging APIを使って、ボットサーバーとLINEプラットフォームの間でデータを交換できます。リクエストは、JSON形式でHTTPSを使って送信されます。
1.ユーザーが、LINE公式アカウントにメッセージを送信します。
2.LINEプラットフォームからボットサーバーのWebhook URLに、Webhookイベントが送信されます。
3.Webhookイベントに応じて、ボットサーバーからユーザーにLINEプラットフォームを介して応答します
###今回の目標
・LINEbotは一つで6人分の情報を送信したい
・友達登録してくれたユーザーが自分で受け取るメンバーを選択できるようにしたい
・メンバー設定等はLINE画面で、全てこなせるようにしたい
###考えなければならなかったこと
#####情報が欲しいユーザーだけに送信しなければならない
今回はmulticast
メソッドを使用して送信します。
このような形で、user_idsに情報が欲しいユーザーのLINEのuser_idを挿入して送信する形です。
user_ids = [user_id1, user_id2, ...]
client.multicast(user_ids, <message>)
このuser_idをどうやって取得するか...
まず最初に想定したのは、自分が作成したサービスにLINEアカウントでログインしてもらい、user_idを取得する方法です。
ですが、ログインすることに抵抗がある方や、めんどくささを感じてしまう方がいらっしゃると思ったので、今回はリッチメニューを2種類作成
し、友達登録してもらった後の最初のトーク画面で、リッチメニューをタッチしてもらい、その時にサーバーに送られてくるレスポンスボディからuser_idを取得することにしました。
###1.gemを追加する
# LINE API用
gem 'line-bot-api'
LINE Messaging API SDK for Rubyを使用すると、LINE Messaging APIを使用してボットを簡単に開発でき、数分以内にサンプルボットを作成できます。
###2.リッチメニューを作成する
[デフォルトのリッチメニューをタッチしてもらい、user_idを取得した後、リッチメニューを切り替える]
####前提として
#####Webhookとは
Webhookとは、Webアプリケーションに対して、特定のイベントが発生したら別のWebアプリケーションに通知を発行するよう利用者が指定する仕組み。HTTPのPOSTリクエストを利用する。
###流れ
(前提として、LINEのアカウントは作成済みとします。)
1.リッチメニュー画像を2つ作成する
2.Postmanを使用して、リッチメニューを登録する
3.Rails側でタッチされた際に、リッチメニューが切り替わるように設定する
####1.リッチメニュー画像を2つ作成する
今回はこの2枚を準備しました。
使用できるサイズ等に決まりがあるので注意します。
リッチメニューの画像は以下の要件を満たす必要があります。
画像フォーマット:JPEGまたはPNG
画像の幅サイズ(ピクセル):800以上、2500以下
画像の高さサイズ(ピクセル):250以上
画像のアスペクト比(幅/高さ):1.45以上
最大ファイルサイズ:1MB
####2.Postmanを使用して、リッチメニューを登録する
参考にさせていただきました。もうこのサイトを見れば全てわかります。
リッチメニューを登録する流れは、
#####1.リッチメニューを作成する
#####2.リッチメニューで表示する画像を設定する
#####3.一つをデフォルトのリッチメニューとして設定する
今回は、リッチメニューを2つ登録する必要があります。
なので、言葉で言うと、1.と2.を2回行いリッチメニューを2パターン作成します。そのうち、一つをデフォルトのリッチメニューとして設定し、もう一つを、リッチメニューをタッチしていただいた方に表示するという流れです。
#####1.リッチメニューを2個登録します
Postmanを使用します。
1.新しいタブを開く
2.送信方法をPOSTに設定
3.エンドポイントに**https://api.line.me/v2/bot/richmenu**を設定
4.Authorizationタブを開き、TypeからBearer Tokenを選択する。
5.右側のToken欄に自分のチャネルのアクセストークンを設定
6.Headersタブを開いてKeyはContent-TypeとValueはapplication/jsonに設定する
7.Bodyタブを開いてオプションからrawを選択する。
テキストボックスに自分のリッチメニューの設定を入力する。
公式はこちらから↓
私の場合は
{
"size": {
"width": 1200,
"height": 810
},
"chatBarText": "Tap to open",
"name": "Nice richmenu",
"selected": true,
"areas": [
{
"bounds": {
"x": 0,
"y": 0,
"width": 1200,
"height": 810
},
"action": {
"type": "postback",
"data": "start"
}
}
]
}
8.sendボタンを押す
9.status:200 OKと表示され、richMenuId(リッチメニューのID)が表示される。
このrichMenuIdはまた使います。
richMenuIdがわからなくなったら、以下で探せます
<リッチメニューの配列を取得する>
送信方法 → GET
エンドポイント → https://api.line.me/v2/bot/richmenu/list
Authorization:Bearer {channel access token}
#####2.リッチメニューの画像をアップロードする
1.送信方法をPOSTに設定
2.エンドポイントにhttps://api-data.line.me/v2/bot/richmenu/{richMenuId}/content を設定。
{richMenuId}は送られてきたレスポンスのrichMenuIdを入れる。
3.Content-Typeはimage/jpeg、image/pngのように自分の画像の拡張子で設定
4.Bodyタブからbinaryを選択し、ファイルから自分の画像を選択
5.sendボタンを押す
6.status:200 OKと表示されればOK
この流れでリッチメニューを2パターン作成します。
#####3.作成したリッチメニューの一つをデフォルトに設定する
まず、最初の「まずはこちらをタッチ」の方のリッチメニューをデフォルトに設定します。
デフォルトに設定したことにより、友達登録をしていただいたときには全員にこのリッチメニューが表示されます。
<デフォルトのリッチメニューを設定する>
送信方法 → POST
エンドポイント → https://api.line.me/v2/bot/user/all/richmenu/{richMenuId}
Authorization:Bearer {channel access token}
もう一つの方のリッチメニューはRailsの方で設定します。
###リッチメニューのボタンをタッチした際に、切り替えされるよう設定する
まず上で設定したデフォルトの方のリッチメニューのbodyの中身は以下のようになっています。これを参考にまとめていきます。
{
"size": {
"width": 1200,
"height": 810
},
"chatBarText": "Tap to open",
"name": "Nice richmenu",
"selected": true,
"areas": [
{
"bounds": {
"x": 0,
"y": 0,
"width": 1200,
"height": 810
},
"action": {
"type": "postback",
"data": "start"
}
}
]
}
###方法・流れ
リッチメニューを押した際に、サーバーに送られてくるリッチメニューレスポンスオブジェクトの内容を判断し、反応を組み込んでいく。
まず、リッチメニューオブジェクトについて。
リッチメニューは以下のどちらかのオブジェクトで表されます。
リッチメニューIDを含まないリッチメニューオブジェクト。リッチメニューの作成時にこのオブジェクトを使用します。
リッチメニューIDを含むリッチメニューレスポンスオブジェクト。リッチメニューの取得時またはリッチメニューの配列の取得時にこのオブジェクトが返されます。
これらのオブジェクトは領域オブジェクトとアクションオブジェクトから構成されます。
流れ
1.リッチメニューを作成するときにリッチメニューレスポンスオブジェクトに含ませたい内容を組み込む
2.Railsでリクエストボディを取得した時の対応を組み込む
####1.リッチメニューを作成するときにリッチメニューレスポンスオブジェクトに含ませたい内容を組み込む
リッチメニューオブジェクトは
これらのオブジェクトは領域オブジェクトとアクションオブジェクトから構成されます。
ということなので、領域オブジェクト
とアクションオブジェクト
について理解したいです。。
領域オブジェクト
boundsとactionが必須です。
bounds : 領域の境界をピクセルで表すオブジェクト。= タッチして反応する領域を決めます。
ここの部分で領域を指定しています。
"bounds": {
"x": 0,
"y": 0,
"width": 1200,
"height": 810
}
action : 領域がタップされたときに実行されるアクション。↓でまとめている(アクションオブジェクト)のこと。
アクションオブジェクト
ユーザーがメッセージ内のボタンまたは画像をタップしたときに、ボットが実行できるアクションのタイプです。
私が使用したのは、ポストバックアクションです。
このアクションが関連づけられたコントロールがタップされると、dataプロパティに指定された文字列を含むポストバックイベントが、Webhookを介して返されます。
以下の部分です。上記のように、リッチメニューがタッチされると、dataプロパティに指定された"start"
を含むポストバックイベントが返されます。
"action": {
"type": "postback",
"data": "start"
}
####2.Railsでリクエストボディを取得した時の対応を組み込む
Rails側で対応を設定します。
def line_responce
#LINE Messaging API認証
line_client ||= Line::Bot::Client.new { |config|
config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
}
body = request.body.read
signature = request.env['HTTP_X_LINE_SIGNATURE']
unless line_client.validate_signature(body, signature)
error 400 do 'Bad Request' end
end
#request.bodyを解析する
events = line_client.parse_events_from(body)
events.each do |event|
#dataの中身が"start"だったら処理を実行させる
data = event['postback']['data']
if data == "start"
#user_id取得
userId = event['source']['userId']
LineUser.start(userId)
end
end
head :ok
end
LineUserモデル
にline_user_idカラム
を作成済みです。
レスポンスボディに含まれるLINEのuseridが、存在していなければ保存し、リッチメニューを切り替えます。
def self.set_user_richmenue(user_id)
if LineUser.find_by(line_user_id: user_id)
@lineuser = LineUser.find_by(line_user_id: user_id)
else
@lineuser = LineUser.new(line_user_id: user_id)
@lineuser.save!
end
client.link_user_rich_menu("#{user_id}", "#{もう一つのリッチメニューID}")
end
post '/line_responce', to: 'line_users#line_responce'
####試しに動かしてみる
開発環境で動かすときは
ngrok
を使用します。ここではngrokの説明は省きます
1.rails s
を実行する
2.ngrok http 3000
を実行する
3.ngrok
に表示されるhttps://~.ngrok.io
までをコピーする
4.LINE developersのページのWebhook設定
のとことに設定する
今回はroutes.rbに書いた通り使用したいので、こんな感じで入力し、更新ボタンを押す
5.検証ボタンが表示されるので、押してみて200が表示されればOK
6.自分のLINEページで、デフォルトのリッチメニューをタッチしてみると
ターミナルでこのように確認することができる。
Processing by LineUsersController#line_responce as HTML
Parameters: {"destination"=>"***", "events"=>[{"type"=>"postback", "postback"=>{"data"=>"start"}, "timestamp"=>**, "source"=>{"type"=>"user", "userId"=>"**"}, "replyToken"=>"**", "mode"=>"active"}], "line_user"=>{}}
Paramsの中を確認すると、events"=>[{"type"=>"postback", "postback"=>{"data"=>"start"}
このような感じで指定したstart
が取得できている。
これを、line_users_controller.rb
でif data == "start"
の形で判断させ処理を実行させている。
7.LINEの画面を確認すると、デフォルトのリッチメニューからもう一つのリッチメニューに変更されている
以上の流れでリッチメニューの切り替えを行いました。