【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