Net::HTTP , blocking the reactor of the event machine I was aiming at. Also in terms of documentation for some reason, everything was very sad, and I had to constantly read the source code.faraday , the library supports calling any API methods, uploading files to VKontakte servers and optional authorization, not accepting the decisions mentioned in the previous paragraph as a programmer.vkontakte_api . As an example, an uncomplicated web application that displays a news feed (API method newsfeed.get ), a list of friends ( friends.get ) and groups ( groups.get ) of a user who has passed OAuth2 authorization will fit. And it will look something like this:
VkontakteApi.configure block, which is conveniently placed in config/initializers/vkontakte_api.rb ; In the rails application, you can generate this file with default settings using the built-in generator. $ 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 omniauth via VKontakte, so omniauth will be inappropriate to use omniauth - we use the capabilities of vkontakte_api .code parameter to the URL. Then the application, using this code, receives the token and user_id user with a separate request and saves them in the session.state parameter with an unanticipated value when sending a user for authorization, having previously saved it in a protected place; and when the user returns, check the state parameter with the saved value.vkontakte_api provides the VkontakteApi.authorization_url helper to generate the URL of this page; in the parameters you need to transfer the scope - these are the rights that the application will receive in the form of an array of characters (or strings with names separated by commas) - and the state described above. # 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 %> state if notify is not specified in scope .redirect_uri settings (containing the path to SessionsController#callback ), while the state and code parameters will be passed to the URL. As mentioned above, the state needs to be checked against the one already saved; and code stop on code in more detail.vkontakte_api also provides a helper - VkontakteApi.authorize , the only parameter - the notorious 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 VkontakteApi::Client object. In the constructor you just need to pass the token.vk.users.get(params) . In accordance with the conventions adopted in the ruby ​​community, the names of the methods are written in snake_case : the API method likes.getList can be called as vk.likes.get_list .vk.users.get(uid: 1) . If the API expects to receive a parameter with a collection of objects listed separated by commas, then they can be passed as an array - vkontakte_api stick it together automatically (the scope parameter in the authorization is processed in the same way). In this case, instead of strings, you can use symbols.newsfeed.get , friends.get , groups.get and users.get respectively (the latter will be called by passing the id parameter of our user). The result of newsfeed.get contains separately the news itself, containing the id of users and groups, and separately the arrays with the mentioned users and groups; The MainController#process_feed method, not shown here, adds to each news its source (user or group that wrote a post) under the key 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 - this is an extension of the standard Hash from the hashie gem , which allows accessing the element through a method whose name corresponds to the key of this element in the hash ( user.name == user[:name] ). <%= 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 etc.) are used, defined in the application - they are all quite trivial, if you wish, you can read the code here . <!-- 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> vkontakte_apiSource: https://habr.com/ru/post/151585/
All Articles