4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

公式LINE(Messaging API)を友達追加したときにLINEIDをDBに保存する方法 Rails sorcery

Posted at

はじめに

プログラミングスクール「RUNTEQ」を卒業し、
未経験にてエンジニア転職を目標に活動しています。
未経験であり、内容が間違っている可能性があります。気になる点がありましたら連絡ください。
また、記事で紹介しているやり方は私自身で考えた方法であるため、他に良いやり方があると思いますので、あくまで参考までにいただけたらと思います。

今回、個人開発ポートフォリオとして「ぶさかわフォト」を開発しました。
ぶさかわフォトについては下記記事を見て頂けたらうれしいです!
https://busakawa.com

ぶさかわフォトではユーザーをフォローし、フォローしたユーザーが投稿したときにLINE通知が来るように設定しました。
開発の中で、公式LINEを友達追加したときにLINEIDをDBへ保存する方法に苦戦したため、記事を書きたいと思います。

使用技術

カテゴリ 技術
フレームワーク Rails7.1.3
バックエンド Ruby3.2.3

DB

・Usersテーブルの"line_user_id"カラムに保存する
・LineBotTokensテーブルには"line_user_id"と"line_user_id_token"のカラムを準備し、一時的に保存する

前提として

1.sorceryにてアカウント作成後、ログインしている状態である。

※LINEにてログインしている場合は、sorceryの設定にてDB上にLINEIDを保存することは容易である。今回はsorceryでアカウントを作成後、公式LINEを友だち追加し、LINEIDをDBに保存する方法です。

手順

1.公式LINEのアカウント登録ボタンを作成
2.公式LINEを追加することで発生するwebhookイベントオブジェクトの処理
3.webhookイベント後の処理

1.公式LINEのアカウント登録ボタンを作成

先にコードを貼り付けます。

<%= link_to "https://lin.ee/ldrvLk4" do %>
  <img src="https://scdn.line-apps.com/n/line_add_friends/btn/ja.png" alt="友だち追加" height="36" border="0">
<% end %>

リンクにつきましては、LINE Official Accountの友達追加ガイドを参照してください。

Image from Gyazo
リンクを開くとこのようになり、
[Image from Gyazo]
公式LINEを表示できます。
(今回はテストの為友だちに登録済みです。となっています)

(2).公式LINEを追加することで発生するwebhookイベントオブジェクトの処理

ここからが今回の記事のキーポイントとなります。

前知識

・そもそもwebhookイベントとは?となると思いますので、下記URLを共有いたします。
https://developers.line.biz/ja/docs/messaging-api/receiving-messages/
 一言で言えば、LINE公式アカウントを友だち追加したときに発生するHTTP POSTリクエストということです。

・webhookイベントオブジェクトはJSON形式で送られてきます。
https://developers.line.biz/ja/docs/messaging-api/receiving-messages/#webhook-event-in-one-on-one-talk-or-group-chat

では、説明してきます。
先にコードを共有いたします。

def webhook
    body = request.body.read
    events = client.parse_events_from(body)
    events.each do |event|
      case event
      when Line::Bot::Event::Follow
        user_id = event['source']['userId']
        token = SecureRandom.alphanumeric(15)
        LineBotToken.create(line_user_id: user_id, line_user_id_token: token)
        message = [
          {type: "text", text: "下記URLよりLINE認証を行ってください"},
          {type: "text", text: "https://busakawa.com/line_bots/new?state=#{token}&openExternalBrowser=1"}
        ]
        client.push_message(user_id,message)
      end
    end

webhookイベントが発生すると、ルーティングにて、webhookアクションを発生させるようにしています。(routes設定は省略いたします)
webhookイベントでは、
1.Followイベントの場合、userIDを取得し、変数へ。
2.SecureRandomnにて安全なランダム値を作成。
SecureRandomnについての詳細は下記参照
https://docs.ruby-lang.org/ja/latest/class/SecureRandom.html
3.messageの設定を行い公式LINE追加時にトークを送信する。
といった流れになっています。
・&openExternalBrowser=1を付けることで、LINEトークでのURLをブラウザで開くようにしています。 PC(Windows)の場合不要ですが、スマホ(IPhone)の場合はLINE内でURLを開いてしまいます。(Macbook Androidは分かりません)

なぜこのような処理にしたか

実施したこと

  1. webhookアクションにてcurrent_userを使う
    最初はcurrent_userを使いました。
    ログインしている状態で、公式LINEを追加することでUsersテーブルのline_user_idに保存するようにしましたが、ログにてcurrent_userが引っかかりエラーとなりました。
    2.QRコード作成 (rqrcode)
    Usersテーブルに新たに、"ine_user_id_token"カラムを追加し、User作成時にSecureRandomnにてランダムな値を保存しました。
    そのline_user_id_tokenの値をQRコードに埋め込もうとしましたが、LINEそのものが送られてきたデーターを取得し、webhookにて返すということは出来ませんでした。

    そこで、webhookイベントにてSecureRandomnにてランダムな値とLINEIDを別のテーブルに保存し、トーク画面のURLからLINEIDを取得する処理にすることにしました。

(3)webhookイベント後の処理

URL先はLineBotsのnewアクションとしていますので、

  def new
    if current_user.line_user_id.present?
      flash[:notice] = "LINE連携が完了しました"
      redirect_to posts_path
    else
      @line_user_id_token = params[:state]
    end
  end

このように書きました。params[:state]にてSecureRandomnのランダムな値を取得します。

line_bots/new.html.erb

<div class="container">
  <div class="row">
    <div class="text-center p-3 m-3">
      <%= link_to "LINE連携する", line_bots_path(line_user_id_token:  @line_user_id_token), data: { turbo_method: :post }, class: "btn btn-outline-success" %>
    </div>
  </div>
</div>

line_bots/new.html.erbにてボタンを作成し、

def create
    @line_bot_token = LineBotToken.find_by(line_user_id_token: params[:line_user_id_token])
    current_user.update(line_user_id: @line_bot_token.line_user_id)
    @line_bot_token.destroy
    flash[:notice] = "LINE連携が完了しました"
    redirect_to posts_path
  end

createアクションにてUsersテーブルのline_user_idへ保存し、LineBotTokenのデータは不要の為削除します。

以上になります。

4
3
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
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?