見出し画像

【Rails】Sorcery で Twitter 認証 [3] プロフィール画像を取得して ActiveStorage でアップロードしたい

去年の11月末 RUNTEQ の卒業制作で、黙々と勉強するいわゆる「もくもく会」を共有するアプリ「MOKUMOKU」をリリースしました。その制作過程で得られた情報を発信したいと思います。

前回の続き、今回は Sorcery を利用して Twitter のプロフィール画像を取得して、ActiveStorage でアップロードする実装について書きたいと思います。

<バージョン>
 Ruby:2.5.1
 Rails: 5.2.1

ActiveStorage へのアタッチの流れ

「ruby 画像 ダウンロード」でググると、open-uri の open メソッドを使うと Web 上の画像がダウンロード出来るようです。

そして ActiveStorage は直接 IO インスタンスをアタッチ出来るとあるため
https://api.rubyonrails.org/classes/ActiveStorage/Attached/One.html#method-i-attach)、URL さえ分かればそれらを組み合わせて実装出来そうです。

Twitter のプロフィール画像の URL の取得

Twitter 開発ページのこちらこちらを確認すると「profile_image_url_https」が画像の URL のようです。前回はアカウントの名前などを取得したので、同様に sorcery.rb でマッピングの設定を追加すればそのまま取得出来そうです。

また、そのままプロフィール画像を取得すると 48x48 のサイズで小さいため、「_normal」や「_bigger」などのバリアントを除外したオリジナルサイズのものを取得するようにパスを調整します。

大まかな実装

# sorcery.rb
  config.twitter.user_info_mapping = {
    # name などは割愛
    # ハッシュのキーは任意の名前
    profile_image_url: 'profile_image_url_https'
  }
# oauths_controller.rb
  def create
    @user = User.new(user_params)

    if @user.save
      @user.download_and_attach_avatar
      redirect_to root_url, success: 'ユーザーを作成しました'
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :screen_name, :email, :profile_image_url, :avatar)
  end
# user.rb
  require 'open-uri'

  has_one_attached :avatar

  def download_and_attach_avatar
    return unless avatar_image_url

    file = open(avatar_image_url)
    avatar.attach(io: file,
                  filename: "profile_image.#{file.content_type_parse.first.split("/").last}",
                  content_type: file.content_type_parse.first)
  end

  # Twitter のプロフィール画像のオリジナルサイズのパスを取得する
  def avatar_image_url
    profile_image_url&.gsub(/_normal/, '')
  end


参考記事:
Ruby 画像をダウンロードする方法
ActiveStorageでattachできるものについて調べてみた
How store an image from URL with Active Storage


この記事が気に入ったらサポートをしてみませんか?