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アプリケーションが役立ちます。 そして、次のようになります。
![](https://habrastorage.org/storage2/8b7/d78/30a/8b7d7830abb59658eb68501d470abaec.png)
カスタマイズ
認可では、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
の形式で返されます。Mashはhashie 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
に関するその他の資料
- プロジェクトホームページ
- README.md
- 100%を網羅したRDocドキュメント
- vkontakte_api(Webソケット上の非同期メッセンジャーアプリケーション) を使用したより高度な例