vkontakte_api
is a ruby-adapter for VKontakte API. It allows you to call API methods, upload files to VKontakte servers and also supports 3 available authorization methods (while allowing to use third-party solutions).
# Gemfile
gem 'vkontakte_api', '~> 1.4'
or simply
$ gem install vkontakte_api
# creating client
@vk = VkontakteApi::Client.new
# and calling API method
@vk.users.get(user_ids: 1)
# snake_case convention is a de-facto standard
# for method names in ruby
# so likes.getList becomes likes.get_list
@vk.likes.get_list
# names of methods that return '1' or '0'
# end with '?', and returned values
# are typecasted to true or false
@vk.is_app_user? # => false
# if some VKontakte method expects a list of parameters
# separated by commas, you can pass an array
users = @vk.users.get(user_ids: [1, 2, 3])
# most methods return a Hashie::Mash structure
# or an array of them
users.first.uid # => 1
users.first.first_name # => "Павел"
users.first.last_name # => "Дуров"
# when a method that returns an array is being called with a block
# then block will be executed for each element
# and the final result will be a processed array (like Enumerable#map)
fields = [:first_name, :last_name, :screen_name]
@vk.friends.get(user_id: 2, fields: fields) do |friend|
"#{friend.first_name} '#{friend.screen_name}' #{friend.last_name}"
end
# => ["Павел 'durov' Дуров"]
Files can be uploaded to VKontakte in several steps: first you need to call an API method that returns a URL to upload to; then upload the file(s) and in some cases call another finalization API method with uploaded file params. The API methods to call depend on the uploaded file type and are described in the documentation.
Files are transferred in a Hash format, where key is the name of the request parameter (described in documentation, for example photo
when uploading photos), and the value is an array composed of 2 strings: full path to the file and it's MIME-type:
url = 'http://cs303110.vkontakte.ru/upload.php?act=do_add'
VkontakteApi.upload(url: url, photo: ['/path/to/file.jpg', 'image/jpeg'])
If the file was opened as an IO object, then it can be passed using alternative syntax — IO-object, MIME-type and the file path:
url = 'http://cs303110.vkontakte.ru/upload.php?act=do_add'
VkontakteApi.upload(url: url, photo: [file_io, 'image/jpeg', '/path/to/file.jpg'])
The upload
method returns VKontakte server response converted to Hashie::Mash
; it can be used when calling API method in the last step of upload process.
Most of methods require an access token to be called. To get this token, you can use authorization built in vkontakte_api
or any other solution (for example OmniAuth). In the latter case the result of authorization process is a token, which needs to be passed into VkontakteApi::Client.new
.
VKontakte API provides 3 types of authorization: for webpages, for client applications (mobile or desktop, having access to authorized browsers) and special authorization type for servers to invoke administration methods without user authorization. More details are available here; let's see how to use them with vkontakte_api
.
For the purposes of authorization you have to specify app_id
(application ID), app_secret
(secret key) and redirect_uri
(a URL where the user will be redirected after successful authorization) in the VkontakteApi.configure
settings. For more information about configuring vkontakte_api
see below.
Website authorization goes in 2 steps. First user is redirected to VKontakte website to confirm the rights of a website to access his data. The list of available permissions is avaliable here. Let's suppose one wants to access friends (friends
) and photos (photos
) of the user.
According to the guidelines in OAuth2 protocol the state
parameter should be passed with a random number in order to prevent CSRF.
session[:state] = Digest::MD5.hexdigest(rand.to_s)
redirect_to VkontakteApi.authorization_url(scope: [:notify, :friends, :photos], state: session[:state])
After successful authorization the user is redirected to redirect_uri
and the parameters will contain the code that can be used to obtain an access token, as well as the state
. When state
differs from the one used in the first step there is a high probability of CSRF-attack — the user should be forced to begin the authorization process from the beginning.
redirect_to login_url, alert: 'Authorization error' if params[:state] != session[:state]
vkontakte_api
provides a VkontakteApi.authorize
method which makes a request to VKontakte with a given code, gets a token and creates a client:
@vk = VkontakteApi.authorize(code: params[:code])
# now API methods can be called on @vk object
@vk.is_app_user?
Client will contain the id of the user who authorized the application; it can be obtained using the VkontakteApi::Client#user_id
method:
@vk.user_id # => 123456
It's also helpful to keep the obtained token at this point (and the user id if necessary) in the DB or in session so they can be used again in the future:
current_user.token = @vk.token
current_user.vk_id = @vk.user_id
current_user.save
# later
@vk = VkontakteApi::Client.new(current_user.token)
Client application authorization is much easier: you don't need a separate request to obtain the token — it's returned right after the user is redirected back to the application.
# user is redirected to the following URL
VkontakteApi.authorization_url(type: :client, scope: [:friends, :photos])
You should note that redirect_uri
must be assigned to http://api.vkontakte.ru/blank.html
, otherwise it won't be possible to call methods available to client applications.
After user confirms his access rights he will be redirected to redirect_uri
with the access_token
parameter containing the token that should be passed to VkontakteApi::Client.new
.
The last type of authorization is the easiest one since it does not require any user involvement.
@vk = VkontakteApi.authorize(type: :app_server)
If the API client (instance of VkontakteApi::Client
) was created by calling VkontakteApi.authorize
method, it will contain the information about current user id (user_id
) and about expiry time of token (expires_at
). You can check it using these methods:
vk = VkontakteApi.authorize(code: 'c1493e81f69fce1b43')
# => #<VkontakteApi::Client:0x007fa578f00ad0>
vk.user_id # => 628985
vk.expires_at # => 2012-12-18 23:22:55 +0400
# VkontakteApi::Client#expired can be used to check if the token has expired
vk.expired? # => false
You can also get the list of access rights given by this token, in the form similar to the form of scope
parameter in authorization process:
vk.scope # => [:friends, :groups]
It uses the getUserSettings
API method with the result cached after the first call.
To create a VK
alias for VkontakteApi
module just call VkontakteApi.register_alias
:
VkontakteApi.register_alias
VK::Client.new # => #<VkontakteApi::Client:0x007fa578d6d948>
This alias can be removed with VkontakteApi.unregister_alias
:
VK.unregister_alias
VK # => NameError: uninitialized constant VK
When VKontakte API returns an error, a VkontakteApi::Error
exception is raised.
vk = VK::Client.new
vk.friends.get(user_id: 1, fields: [:first_name, :last_name, :photo])
# VkontakteApi::Error: VKontakte returned an error 7: 'Permission to perform this action is denied' after calling method 'friends.get' with parameters {"user_id"=>"1", "fields"=>"first_name,last_name,photo"}.
There is special case of errors — 14: the user has to enter a captcha code.
In this case captcha parameters can be obtained using VkontakteApi::Error#captcha_sid
method
and VkontakteApi::Error#captcha_img
— for example,
like this.
vkontakte_api
logs information about requests when calling methods.
By default they are all written in STDOUT
but you can choose any
other data logger, Rails.logger
for example.
It is possible to log 3 types of information, and each one has a corresponding key in the global settings.
setting key | default value | message level | |
---|---|---|---|
request URL | log_requests |
true |
debug |
JSON response of error | log_errors |
true |
warn |
JSON successful response | log_responses |
false |
debug |
In Rails application with default settings in production only server responses with errors are being saved; in development there are also logged URL addresses of requests.
An example of using vkontakte_api
together with eventmachine
can be seen
here.
An example with rails also
exists, but it no longer works due to the lack of access rights to call
the newsfeed.get
method from websites.
Global parameters of vkontakte_api
should be set in VkontakteApi.configure
block as follows:
VkontakteApi.configure do |config|
# parameters required for authorization with vkontakte_api
# (not needed when using a third-party authorization solution)
config.app_id = '123'
config.app_secret = 'AbCdE654'
config.redirect_uri = 'http://example.com/oauth/callback'
# faraday adapter for network requests
config.adapter = :net_http
# HTTP method for calling API methods (:get or :post)
config.http_verb = :post
# parameters for faraday connection
config.faraday_options = {
ssl: {
ca_path: '/usr/lib/ssl/certs'
},
proxy: {
uri: 'http://proxy.example.com',
user: 'foo',
password: 'bar'
}
}
# maximum number of retries after an error
# works only when using http_verb :get
config.max_retries = 2
# logger
config.logger = Rails.logger
config.log_requests = true # request URLs
config.log_errors = true # errors
config.log_responses = false # successful responses
# API version
config.api_version = '5.21'
end
By default the Net::HTTP
Faraday adapter is used but you can choose
any other adapter
supported by faraday
.
VKontakte allows
using either GET
or POST
requests when calling API methods.
vkontakte_api
uses POST
by default but you can change that by
setting http_verb
to :get
.
You can specify custom parameters for faraday-connection if necessary — parameters of a proxy server or a path to SSL certificates for example.
In order to use a specific API version in every method call you can specify it
in the api_version
key of configuration. By default it is not set.
To generate a file with default settings in Rails application
you can use the vkontakte_api:install
generator:
$ cd /path/to/app
$ rails generate vkontakte_api:install
vkontakte_api
uses the Oj parser — it is
the only parser that has not thrown any errors
while parsing JSON generated by VKontakte API.
Oj has the top priority in multi_json
library (a wrapper for different
JSON parsers which selects the fastest parser installed on the system and uses it)
so when Oj
is present in your bundle it will also be used by MultiJSON.
- CLI-interface with automatic authorization
If you want to participate in the vkontakte_api development fork the repository, create changes on separate branch, cover them with specs and create a pull request.
vkontakte_api
is tested under MRI 1.9.3
, 2.0.0
and 2.1.2
.
If it is not working properly in any of these versions it should be considered
a bug and reported to issues on Github.