3
0

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を使った通知機能の作成のために、ユーザー登録と後から連携を実施したい

Last updated at Posted at 2024-12-08

なぜ実現したいのか。

  • LINEを使ったユーザー登録を実装済み
  • LINEを使った通知機能をユーザーに使ってもらいたい
  • 今の実装だと、LINEを使ったユーザー登録にしかできず、LINEだけの紐づけが出来ずに既存のユーザーがLINEとの連携が出来ない

という状況を改善するために本記事を記載して、自分の実装内容についてまとめていく。

今回の記事の内容について

まずは、LINEを使ったユーザー登録の記載とMessingAPIの導入についての流れを記載してから、その後LINEとの連携だけを実装する内容を記事にします。

技術構成

カテゴリ 技術内容
サーバーサイド Ruby 3.2.3
フレームワーク Rails 7.2.1
フロントエンド HTML, CSS, Bootstrap, Hotwire(JS)
開発環境 Docker

事前処理

LINEを使ったユーザー登録

sorceryを使ったサブモジュールでの登録
今回はsorceryを使った認証機能のため、sorceryのサブモジュールを使っての認証機能を作成しています。
https://github.com/Sorcery/sorcery/wiki/External
sorceryのGEMを参考に実装していく。以下に実装の内容をまとめる。

  1. LINEログインAPIの取得
  2. sorceryのサブモジュールのインストール
  3. 外部認証用のテーブルの作成(authenticationsテーブル
  4. モデルファイルで関係性の定義
  5. config/initializers/sorcery.rb で受け取るLINEの設定
  6. /oauths_controller.rb の作成をしてログインについての処理の記載
  7. ルーティングの記載
  8. ビューファイルで配置
  9. ngrokの導入でテスト環境をHTTPS通信に切り替えて実装

MessingAPIの導入

実装済みについて

  • 既に実装済みのnotificationsテーブルを生かして実装。
  • アプリケーション内では通知は受け取る前提に。
  • LINEの通知のONとOFFだけを切り替えられるように、usersテーブルにline_notification_enabledを作成する

以下に実装順序と実装をしたこと

  1. LINEのMessingAPIの導入
  2. ユーザーテーブルにline_notification_enabledの作成
  3. line-bot-api GEMの導入
  4. NotificationsControllerを使って、LINEのメッセージが届くように実施

メインの実装(※ここから本題です)

問題の確認

冒頭で述べた通りですが改めて実装内容としては以下の通りです。

  1. 「LINEでの通知を実施したい場合、ユーザーにはLINEのユーザーIDを保存する必要がある」
  2. 「現状がLINEでのユーザー登録及びログインしか出来ず、ログイン済みのユーザーは紐づける方法がない」

という2点が実装中でおきた問題です。

  1. 「LINEでの通知を実施したい場合、ユーザーにはLINEのユーザーIDを保存する必要がある」

    問題:sorceryでの認証として必要なことと、LINE固有のIDが紐づけできていないこと

    理由:保存先がusersテーブルの、emailで受け取るようにしている

    解決:LINEの固有のIDを受け取るためのカラムを追加してそれで保存すること

  2. 「現状がLINEでのユーザー登録及びログインしか出来ず、ログイン済みのユーザーは紐づける方法がない」

    問題:sorceryでの認証ではLINEとの連携が出来ない

    理由:Sorceryの外部認証は新規ユーザー作成を前提とした設計であること

    解決:omniauth-lineを導入して、かつ、別のLINEのログインAPIも導入してコールバック先も分けて実装

という実装をしていきます。

LINEのユーザーIDを保存するように変更

  1. users テーブルに line_user_id カラムを追加と、email カラムの null: false 制約を削除

  2. config/initializers/sorcery.rb内のマッピングの内容を変更
    email→line_user_idに変更

      # LINE認証に関すること
      config.line.key = ENV['LINE_Sorcery_ID']
      config.line.secret = ENV['LINE_Sorcery_SECRET']
      # 本番環境のURLに置き換える
      config.line.callback_url = '<https://smart-phone-choice.com/oauth/callback?provider=line>'
      #ユーザーを識別するためのOpenID Connect IDトークンとメールアドレス
      config.line.scope = "profile openid email"
      config.line.bot_prompt = 'aggressive'
      # 以下の内容にline_user_idを使う
      config.line.user_info_mapping = { name: 'displayName', line_user_id: 'userId' }
    
    
  3. app/controllers/oauths_controller.rb 内に、skip_before_action :require_loginを追記する

omniauth-lineを導入して連携の処理のみの記載

  1. Gemfile内にgem 'omniauth-line’の導入

    gem 'omniauth-line'
    gem 'omniauth-rails_csrf_protection' # CSRF対策
    
  2. config/initializers/omniauth.rbの作成と編集

    Rails.application.config.middleware.use OmniAuth::Builder do
     # LINEのプロバイダーとスコープの指定
     provider :line, ENV['LINE_OmniAuth_ID'], ENV['LINE_OmniAuth_SECRET'],
               scope: 'profile openid email',
               bot_prompt: 'aggressive',
               # 本番環境のコールバックURLに変更する
               callback_url: '<https://smart-phone-choice.com/auth/line/callback?provider=line>' # 認証後にリダイレクトされるURL
    end
    
  3. config/routes.rb の追加

      # 既存ユーザーのLINE連携用のLineConnectionsController用のルートを追加
      get '/auth/line/callback', to: 'line_connections#callback' # LINE連携ページへのルート
      post '/auth/line/callback', to: 'line_connections#callback' # LINE連携処理を行うルート
    
  4. app/controllers/line_connections_controller.rbでコールバックの記載

    class LineConnectionsController < ApplicationController
      before_action :require_login
    
      def callback
        auth = request.env['omniauth.auth']
    
        if current_user.update(line_user_id: auth.uid)
          redirect_to my_profile_path, success: t('defaults.flash_message.line_success')
        else
          redirect_to my_profile_path, danger: t('defaults.flash_message.line_failure')
        end
      end
    end  
    
  5. ビューファイルで条件先を埋め込む

      <% if current_user.line_registered? %>
        <p>LINEでの登録済み</p>
      <% else %>
        <!-- LINEの後から連携のユーザー用 -->
        <% if current_user.omniauth_user_linked_to_line? %>
          <p>LINEとの連携済み</p>
        <% else %>
          <%= button_to 'LINEと連携する', '/auth/line', method: :post, data: { turbo: false }, class: 'btn btn-success' %>
        <% end %>
      <% end %>
    

MessingAPIとの連携。公式アカウントのリンク先の追加。

LINEログインAPI内の「チャンネル基本設定」の「友達追加オプション」にりんくされたLINEの公式アカウントとして追加する

念のため、公式アカウントのリンク先を追加(MessingAPIの友達かた結局通知が届くので)

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

出来上がりのLINEのDevelopサイトと

!https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683921/829c4930-9eb8-b416-116e-76346deb1519.png

SMC_testで、sorceryのサブモジュールで使うLINEを使ったユーザー登録
SMC連携でomniauth使う既存のユーザーのLINEとの連携
すまちょい公式でMessingAPIを使った通知

という風に分けています。

まとめ

初学者の私にとっては、ログの内容を見ながら、どういう処理の中でどのようにしてデータが保存されているのかと確認しながらの実装で、テーブル設計の部分についてでしたので非常に勉強になった実装です。
また、データベースに保存する実施をしましたが、Webhookやトークンを使うことで、データベースに保存せずにMessingAPIを主体に通知機能も出来るのでは?
と思ったので、今後実装出来ればと思っています。
あくまで、LINEでのユーザー登録やMessingAPIの導入済みの方が、既存ユーザーにどう連携したらいいのか?と思った際に参考をしていただけると幸いです。

ありがとうございました。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?