vkontakte_api:VK API用のrubyアダプター

今年の初めに、私はRailsアプリケーションからVK APIを使用する必要がありました。 残念ながら、私に合った宝石は見つかりませんでした:どこかでキャメルケース(rubyコードでは不自然に見える)でメソッドの名前を書くことを余儀なくされました(どこかでomn​​iauthを使用したという事実にもかかわらず)そして一般的に、APIにアクセスするために、ハードコードNet::HTTP



、イベントマシンリアクターをブロックしました。 また、ドキュメントに関しては、何らかの理由ですべてが非常に悲しかったので、ソースコードを常に読む必要がありました。



それでvkontakte_apiが生まれました。 このライブラリを書くための口実として役立った鉄道プロジェクトはすでに休んでいます-しかし、gemは7月にバージョン1.0に達し、重要な変更の口実として機能し、開発を続けています。 faradayを使用すると、ライブラリは、APIメソッドの呼び出し、VKontakteサーバーへのファイルのアップロード、およびオプションの許可をサポートします。前の段落で述べたプログラマーの決定は必要ありません。



vkontakte_api



を使用してAPIをvkontakte_api



する方法を見てみましょう。 例として、OAuth2承認に合格したユーザーのニュースフィード(APIメソッドnewsfeed.get )、 友人のリスト( friends.get )、およびグループ( groups.get )を表示する単純なWebアプリケーションが役立ちます。 そして、次のようになります。







カスタマイズ



認可では、VKontakteのアプリケーション編集ページで取得できるアプリケーションIDとセキュアキーを使用します。 また、redirect_uriも後で説明します。 これらのパラメーターはVkontakteApi.configure



ブロックで指定されます。このブロックはconfig/initializers/vkontakte_api.rb



ます。 Railsアプリケーションでは、組み込みのジェネレーターを使用して、デフォルト設定でこのファイルを生成できます。



 $ rails generate vkontakte_api:install
      
      





設定は次のように表示されます。



 # config/initializers/vkontakte_api.rb VkontakteApi.configure do |config| config.app_id = '123' # ID  config.app_secret = 'AbCdE654' #   config.redirect_uri = 'http://vkontakte-on-rails.herokuapp.com/callback' end
      
      





(実際、 もっと多くのオプションが利用可能ですが、残りはここでは必要ありません)



ログイン



VKontakteを介してサイトにomniauth



するだけでよいため、 omniauth



使用は実用的ではありませんomniauth



の機能を使用します。



VKontakteでのアプリケーションの承認でOAuth2プロトコルを使用します。 これは、承認の結果としてアクセストークンが取得されることを意味し、APIメソッドを呼び出すときに転送する必要があります。



それを取得するためのスキームは次のとおりです:ユーザーはVKontakteの認証ページへのリンクをたどり、「許可」ボタンをクリックしてアプリケーションに自分の(ユーザー)データへのアクセスを許可することに同意し、VKontakteはそれをアプリケーションにリダイレクトし、 code



パラメーターをURLに渡します。 さらに、アプリケーションはこのコードを使用してuser_id



ユーザーのトークンとuser_id



別のリクエストで受け取り、セッションに保存します。



CSRF攻撃から保護するために、OAuth2プロトコルは、安全な場所に保存した後、承認のためにユーザーを送信するときに、未定義の値でstate



パラメーターを渡すこと推奨します。 ユーザーが戻ったときに、パラメーターで受信したstate



と保存された値を確認します。



そのため、ログインページで、VKontakteのアプリケーション認証ページへのリンクを表示する必要があります。 vkontakte_api



は、このページのURLを生成するVkontakteApi.authorization_url



ヘルパーを提供します。 scope



を渡す必要があるパラメーターでは-これらは文字(またはコンマで区切られた名前の文字列)の形式でアプリケーションが受け取る権利です-および上記のstate







 # app/controllers/sessions_controller.rb class SessionsController < ApplicationController def new #   state srand session[:state] ||= Digest::MD5.hexdigest(rand.to_s) #  URL   @vk_url = VkontakteApi.authorization_url(scope: [:friends, :groups, :offline, :notify], state: session[:state]) end end
      
      







 <!-- app/views/sessions/new.html.erb --> <%= link_to @vk_url, class: 'btn btn-primary' do %> <i class="icon-home icon-white"></i>    <% end %>
      
      





ここでnotify



scope



指定されないならVKontakteがstate



無視する何らかの未知の理由に注意されるべきです。



ユーザーがアプリケーションの権限を確認すると、設定で以前に指定されたredirect_uri( SessionsController#callback



へのパスを含む)にリダイレクトされ、 state



code



パラメーターがURLに渡されます。 直前に述べたように、 state



は既に保存されているstate



と照合する必要があります。 さらにcode



を詳しく見ていきcode







コードを使用して、アクセストークンを取得できます。そのためには、VKontakteへのリクエストを完了する必要があります。 ユーザーはこのリクエストに一切参加しません。リクエストはサーバーからvk.comに直接送信されます。 このため、 vkontakte_api



はヘルパーvkontakte_api



も提供しcode



。唯一のパラメーターは悪名高いcode



です。



 # encoding: utf-8 class SessionsController < ApplicationController def callback #  state if session[:state].present? && session[:state] != params[:state] redirect_to root_url, alert: ' ,    .' and return end #   @vk = VkontakteApi.authorize(code: params[:code]) #      session[:token] = @vk.token #   id    -    session[:vk_id] = @vk.user_id redirect_to root_url end end
      
      





ユーザーがアプリケーションを終了すると、単にセッションを消去します。



 class SessionsController < ApplicationController def destroy session[:token] = nil session[:vk_id] = nil redirect_to root_url end end
      
      





トークンを受信すると、API自体を操作できます。



APIメソッド呼び出し



APIメソッドを呼び出すには、 VkontakteApi::Client



オブジェクトが必要です。 コンストラクタにトークンを渡すだけです。



次に、クライアント自体でメソッドを呼び出すことができます。 複合名を持つメソッドは、チェーンで呼び出されます: vk.users.get(params)



。 rubyコミュニティで採用されている規則に従って、メソッド名はsnake_case



記述されますlikes.getList



メソッドはvk.likes.get_list



としてvk.likes.get_list



ことができます。



すべてのAPIパラメーターには名前が付けられ、パラメーター名でインデックス付けされたハッシュとして渡されますvk.users.get(uid: 1)



vk.users.get(uid: 1)



。 APIがコンマで区切られたパラメーターのオブジェクトのコレクションを受け取ることを期待する場合、配列として渡すことができますvkontakte_api



自動的にそれvkontakte_api



接着します(承認のscope



パラメーターも同様に処理されます)。 この場合、文字列の代わりに文字を使用できます。



そのため、現在のユーザーのニュースフィード、友人、グループが必要です。 ナビゲーションにユーザー名とアバターも表示します。 このデータを取得するためのnewsfeed.get



groups.get



groups.get



およびusers.get



メソッドがそれぞれあります(ユーザーIDパラメーターを渡すことで後者を呼び出します)。 newsfeed.get



の結果には、ユーザーとグループのIDを含むニュース自体が個別に含まれ、前述のユーザーとグループの配列が個別に含まれます。 ここに示されていないMainController#process_feed



メソッドは、各ニュースにそのソース(投稿を書いたユーザーまたはグループ)をキーsource



下に追加します。



 class MainController < ApplicationController def index #    API vk = VkontakteApi::Client.new(session[:token]) #     @user = vk.users.get(uid: session[:vk_id], fields: [:screen_name, :photo]).first #   @friends = vk.friends.get(fields: [:screen_name, :sex, :photo, :last_seen]) #   ,      @friends_online = @friends.select { |friend| friend.online == 1 } #  @groups = vk.groups.get(extended: 1) #    - - ;    @groups.shift #    raw_feed = vk.newsfeed.get(filters: 'post') #     @newsfeed = process_feed(raw_feed) end end
      
      





メソッドの結果はHashie::Mash



の形式で返されます。Mashhashie gemの標準Hash



拡張で、 Hash



内のこの要素のキーに対応する名前のメソッドを介して要素にアクセスできます( user.name == user[:name]



)。



ナビゲーションでは、VKontakteから受け取った現在のユーザーのアバターと名前を表示する必要があります。



 <%= link_to vk_url(@user), target: '_blank' do %> <%= image_tag(@user.photo, width: 20) %> <%= "#{@user.first_name} #{@user.last_name}" %> <% end %>
      
      





以下、アプリケーションで定義されたいくつかの単純なヘルパー( vk_url



name_for



avatar_for



など)が使用されます-それらはすべて非常に簡単であり、必要に応じてここでコードを読むことができます。



次に、ページにニュースフィードを表示します。



 <!-- app/views/main/index.html.erb --> <% @newsfeed.each do |item| %> <tr> <td> <%= link_to vk_url(item.source), target: '_blank' do %> <%= image_tag avatar_for(item.source) %> <% end %> </td> <td class="wide"> <div class="pull-right"><%= formatted_time_for(item.date) %></div> <%= link_to name_for(item.source), vk_url(item.source), target: '_blank' %> <p><%=raw render_links(item.text) %></p> <% item.attachments.each do |attachment| %> <%= render 'attachment', attachment: attachment %> <% end if item.attachments? %> </td> </tr> <% end %> <!-- app/views/main/_attachment.html.erb --> <p> <% case attachment.type %> <% when 'link' %> <%= link_to attachment.link.title, attachment.link.url, target: '_blank' %> <% when 'photo' %> <%= image_tag attachment.photo.src_big %> <% when 'video' %> <%= image_tag attachment.video.image_big %> <% end %> </p> <div class="clearfix"></div>
      
      





最後に、サイドバーの友人とユーザーグループに表示します。



 <!-- app/views/main/_sidebar.html.erb --> <div class="tab-pane active" id="friends_online"> <h6> </h6> <%= render 'friends', friends: @friends_online %> </div> <div class="tab-pane" id="friends"> <h6> </h6> <%= render 'friends', friends: @friends %> </div> <div class="tab-pane" id="groups"> <h6></h6> <%= render 'groups' %> </div> <!-- app/views/main/_friends.html.erb --> <table class="table"> <% if friends.empty? %> <tr> <td>  </td> </tr> <% else %> <% friends.each do |friend| %> <tr> <td> <%= link_to image_tag(friend.photo), vk_url(friend), target: '_blank' %> </td> <td class="wide"> <i class="icon-user"></i> <%= link_to "#{friend.first_name} #{friend.last_name}", vk_url(friend), target: '_blank' %> <br /> <%= online_status(friend) %> </td> </tr> <% end %> <% end %> </table> <!-- app/views/main/_groups.html.erb --> <table class="table"> <% if @groups.empty? %> <tr> <td>    </td> </tr> <% else %> <% @groups.each do |group| %> <tr> <td> <%= link_to image_tag(group.photo), vk_url(group), target: '_blank' %> </td> <td class="wide"> <i class="icon-comment"></i> <%= link_to group.name, vk_url(group), target: '_blank' %> </td> </tr> <% end %> <% end %> </table>
      
      





ライブデモはここで見ることができます (慎重に、無料のheroku)。 VKontakteには何も書き込まれません-すべてのAPIメソッドは、データを読み取り、ページに表示するためにのみ使用されます。 すべてのコードはGithubにあります。



vkontakte_api



に関するその他の資料






All Articles