LoginSignup
0
0

More than 3 years have passed since last update.

【Rails】自作WebアプリからMastodonのプロフィール画像を変更

Last updated at Posted at 2019-02-18

個人開発のWebアプリまちかどルートv5.41への実装メモです。

プログラミングに入門して8ヶ月。
今回も SNS「Mastodon」のAPI に挑戦してみました。

profile.png

まえがき

・まちかどルートではMastodonのアカウントでログイン認証するようにしています。

・今回の実装をするまでは、まちかどルートのプロフィール画像を変えるためにわざわざMastodonで変更し、まちかどルートで再ログインする必要がありました。

・画像アップローダーとしてRails 5.2の新機能 Active Storage を使い、ファイルをAmazon S3に保管しているのですがgem 'mastodon-api'(v2.0)を通してアップロードするとき、その環境のせいでとても苦労しました。

model

user.rb
has_one_attached :image

Active Storageを使うのでマニュアルどおりの作法でmodelにこう書きます。バリデーションについては今回、割愛します。

view

edit.html.erb
<%= form_with model: @user, multipart: true, local: true do |f| %>
  <%= f.file_field :image %>
<%= button_tag :type => "submit" do %>変更を保存<% end %>

プロフィール画像のファイルを選択するためのフォームです。

controller

users_controller.rb
def update

   # 画像の選択の有無を確認
   if params[:image] != nil

    # 画像を uploaded_file に格納
    uploaded_file = params[:image]

    # 画像を /public にいったん配置するため output_path にパスを設定
    output_path = Rails.root.join('public', uploaded_file.original_filename)


    # Mastodonには2MB制限があるので画像を縮小

    ## MiniMagickを使います。まずは画像を入力
    img = MiniMagick::Image.read(uploaded_file)

    ## 縮小します
    img.resize "300x300"

    ## 縮小したら /public に書き出します
    img.write output_path


    # MastodonのAPIを通してアップロードします

    ## 配列を用意します。Mastodon指定のパラメーターは avatar です
    user_array = { "avatar": output_path }

    ## APIを叩くためのクライアントを生成します
    domain = '[対象のMastodonインスタンスのドメイン]'
    access_token = '[ユーザーのアクセストークン]'
    client = Mastodon::REST::Client.new(base_url: "https://#{domain}", bearer_token: access_token)

    ## MastodonのAPIを叩きます
    result = client.update_credentials(user_array)


    # 以上でMastodon側のプロフィール画像が変更されます
    # 続いて、まちかどルートにも同じ画像を反映させます
    @user.avatar = result.avatar
    @user.save


    # 最後に、不要となった/publicの画像を削除します
    File.delete(output_path)

   end

   flash[:notice] = "アイコンを変更しました" 
   redirect_to @user
end

controllerが一番苦労しました。
解説はコメントアウトにある通りです。

あとがき

Active Storageはとても簡単に導入できるアップローダーなのですが

user_array = { "avatar": @user.image }

と書ければ、わざわざ/publicに画像を配置する手間がなくて楽なのに url_for(@user.image)とやっても「そんな画像はありません」というエラーが返ってきてしまうんです。

というわけで、いろいろ試行錯誤して上記のようになりました。とくに/publicにいったん配置する方法がわかったので、これから他の画像系APIを使うのに役立ちそうです。今後も学んでいきたいと思います。

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