Skip to content
Ruby-адаптер для ВКонтакте API
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
bin
lib
spec
.gitignore
.rspec
.travis.yml run tests on Travis in modern rubies Jun 3, 2018
.yardopts explicit creation of VK alias by VkontakteApi.register_alias Jul 17, 2012
CHANGELOG.md
Gemfile HTTPS url in Gemfile Jul 7, 2013
Guardfile stylistic fixed Aug 24, 2015
MIT-LICENSE release 0.1 Jan 31, 2012
README.md
README_en.md
Rakefile goodbye 1.8 Mar 7, 2013
vkontakte_api.gemspec

README.md

vkontakte_api Build Status Gem Version Dependency Status Code Climate Gitter

vkontakte_api — ruby-адаптер для ВКонтакте API. Он позволяет вызывать методы API, загружать файлы на сервера ВКонтакте, а также поддерживает все 3 доступных способа авторизации (при этом позволяя использовать стороннее решение).

English version

For English version please go here.

Установка

# Gemfile
gem 'vkontakte_api', '~> 1.4'

или просто

$ gem install vkontakte_api

Использование

Вызов методов

# создаем клиент
@vk = VkontakteApi::Client.new
# и вызываем методы API
@vk.users.get(user_ids: 1)

# в ruby принято использовать snake_case в названиях методов,
# поэтому likes.getList становится likes.get_list
@vk.likes.get_list
# также названия методов, которые возвращают '1' или '0',
# заканчиваются на '?', а возвращаемые значения приводятся
# к true или false
@vk.is_app_user? # => false

# если ВКонтакте ожидает получить параметр в виде списка,
# разделенного запятыми, то его можно передать массивом
users = @vk.users.get(user_ids: [1, 2, 3])

# большинство методов возвращает структуры Hashie::Mash
# и массивы из них
users.first.uid        # => 1
users.first.first_name # => "Павел"
users.first.last_name  # => "Дуров"

# если метод, возвращающий массив, вызывается с блоком,
# то блок будет выполнен для каждого элемента,
# и метод вернет обработанный массив
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' Дуров"]

Загрузка файлов

Загрузка файлов на сервера ВКонтакте осуществляется в несколько этапов: сначала вызывается метод API, возвращающий URL для загрузки, затем происходит сама загрузка файлов, и после этого в некоторых случаях нужно вызвать другой метод API, передав в параметрах данные, возвращенные сервером после предыдущего запроса. Вызываемые методы API зависят от типа загружаемых файлов и описаны в соответствующем разделе документации.

Файлы передаются в формате хэша, где ключом является название параметра в запросе (указано в документации, например для загрузки фото на стену это будет photo), а значением — массив из 2 строк: полный путь к файлу и его MIME-тип:

url = 'http://cs303110.vkontakte.ru/upload.php?act=do_add'
VkontakteApi.upload(url: url, photo: ['/path/to/file.jpg', 'image/jpeg'])

Если загружаемый файл доступен как открытый IO-объект, его можно передать альтернативным синтаксисом — IO-объект, MIME-тип и путь к файлу:

url = 'http://cs303110.vkontakte.ru/upload.php?act=do_add'
VkontakteApi.upload(url: url, photo: [file_io, 'image/jpeg', '/path/to/file.jpg'])

Метод вернет ответ сервера ВКонтакте, преобразованный в Hashie::Mash; его можно использовать при вызове метода API на последнем этапе процесса загрузки.

Авторизация

Для вызова большинства методов требуется токен доступа (access token). Чтобы получить его, можно использовать авторизацию, встроенную в vkontakte_api, либо положиться на какой-то другой механизм (например, OmniAuth). В последнем случае в результате авторизации будет получен токен, который нужно будет передать в VkontakteApi::Client.new.

Для работы с ВКонтакте API предусмотрено 3 типа авторизации: для сайтов, для клиентских приложений (мобильных либо десктопных, имеющих доступ к управлению браузером) и специальный тип авторизации серверов приложений для вызова административных методов без авторизации самого пользователя. Более подробно они описаны тут; рассмотрим, как работать с ними средствами vkontakte_api.

Для авторизации необходимо задать параметры app_id (ID приложения), app_secret (защищенный ключ) и redirect_uri (адрес, куда пользователь будет направлен после предоставления прав приложению) в настройках VkontakteApi.configure. Более подробно о конфигурировании vkontakte_api см. далее в соответствующем разделе.

Сайт

Авторизация сайтов проходит в 2 шага. Сначала пользователь перенаправляется на страницу ВКонтакте для подтверждения запрошенных у него прав сайта на доступ к его данным. Со списком возможных прав можно ознакомиться здесь. Допустим, нужно получить доступ к друзьям (friends) и фотографиям (photos) пользователя.

В соответствии с рекомендациями в протоколе OAuth2 для защиты от CSRF, нужно передать параметр state, содержащий случайное значение.

session[:state] = Digest::MD5.hexdigest(rand.to_s)
redirect_to VkontakteApi.authorization_url(scope: [:notify, :friends, :photos], state: session[:state])

После подтверждения пользователь перенаправляется на указанный в настройках redirect_uri, причем в параметрах будет передан код, по которому можно получить токен доступа, а также переданный ранее state. Если state не совпадает с тем, который был использован при отправлении пользователя на ВКонтакте, то скорее всего это попытка CSRF-атаки — стоит отправить пользователя на повторную авторизацию.

redirect_to login_url, alert: 'Ошибка авторизации' if params[:state] != session[:state]

vkontakte_api предоставляет метод VkontakteApi.authorize, который делает запрос к ВКонтакте, получает токен и создает клиент; нужно лишь передать ему код:

@vk = VkontakteApi.authorize(code: params[:code])
# и теперь можно вызывать методы API на объекте @vk
@vk.is_app_user?

Клиент будет содержать id пользователя, авторизовавшего приложение; его можно получить с помощью метода VkontakteApi::Client#user_id:

@vk.user_id # => 123456

Также в этот момент полезно сохранить полученный токен (и, при необходимости, id пользователя) в БД либо в сессии, чтобы использовать их повторно:

current_user.token = @vk.token
current_user.vk_id = @vk.user_id
current_user.save
# позже
@vk = VkontakteApi::Client.new(current_user.token)
Клиентское приложение

Авторизация клиентского приложения несколько проще — не нужно получать токен отдельным запросом, он выдается сразу после редиректа пользователя.

# пользователь направляется на следующий урл
VkontakteApi.authorization_url(type: :client, scope: [:friends, :photos])

Необходимо принимать во внимание, что redirect_uri нужно выставлять на http://api.vkontakte.ru/blank.html, иначе не получится вызывать методы, доступные клиентским приложениям.

Когда пользователь подтвердит права приложения, он будет перенаправлен на redirect_uri, при этом в параметре access_token будет токен, который нужно передать в VkontakteApi::Client.new.

Сервер приложения

Последний тип авторизации — самый простой, т.к. не предполагает участия пользователя.

@vk = VkontakteApi.authorize(type: :app_server)

Прочее

Если клиент API (объект класса VkontakteApi::Client) был создан с помощью метода VkontakteApi.authorize, он будет содержать информацию об id текущего пользователя (user_id) и о времени истечения токена (expires_at). Получить их можно с помощью соответствующих методов:

vk = VkontakteApi.authorize(code: 'c1493e81f69fce1b43')
# => #<VkontakteApi::Client:0x007fa578f00ad0>
vk.user_id    # => 628985
vk.expires_at # => 2012-12-18 23:22:55 +0400
# можно проверить, истекло ли время жизни токена
vk.expired?   # => false

Также можно получить список прав доступа, которые дает данный токен, в виде, аналогичном формату параметра scope в авторизации:

vk.scope # => [:friends, :groups]

Это работает на основе метода getUserSettings, причем результат запоминается после первого обращения.

Чтобы создать короткий синоним VK для модуля VkontakteApi, достаточно вызвать метод VkontakteApi.register_alias:

VkontakteApi.register_alias
VK::Client.new # => #<VkontakteApi::Client:0x007fa578d6d948>

При необходимости можно удалить синоним методом VkontakteApi.unregister_alias:

VK.unregister_alias
VK # => NameError: uninitialized constant VK

Обработка ошибок

Если ВКонтакте API возвращает ошибку, выбрасывается исключение класса VkontakteApi::Error.

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"}.

Особый случай ошибки — 14: необходимо ввести код с captcha. В этом случае можно получить параметры капчи методами VkontakteApi::Error#captcha_sid и VkontakteApi::Error#captcha_img — например, так.

Логгирование

vkontakte_api логгирует служебную информацию о запросах при вызове методов. По умолчанию все пишется в STDOUT, но в настройке можно указать любой другой совместимый логгер, например Rails.logger.

Есть возможность логгирования 3 типов информации, каждому соответствует ключ в глобальных настройках.

ключ настройки по умолчанию уровень логгирования
URL запроса log_requests true debug
JSON ответа при ошибке log_errors true warn
JSON удачного ответа log_responses false debug

Таким образом, в rails-приложении с настройками по умолчанию в production записываются только ответы сервера при ошибках; в development также логгируются URL-ы запросов.

Пример использования

Пример использования vkontakte_api совместно с eventmachine можно посмотреть здесь.

Также был написан пример использования с rails, но он больше не работает из-за отсутствия прав на вызов метода newsfeed.get.

Настройка

Глобальные параметры vkontakte_api задаются в блоке VkontakteApi.configure следующим образом:

VkontakteApi.configure do |config|
  # параметры, необходимые для авторизации средствами vkontakte_api
  # (не нужны при использовании сторонней авторизации)
  config.app_id       = '123'
  config.app_secret   = 'AbCdE654'
  config.redirect_uri = 'http://example.com/oauth/callback'

  # faraday-адаптер для сетевых запросов
  config.adapter = :net_http
  # HTTP-метод для вызова методов API (:get или :post)
  config.http_verb = :post
  # параметры для faraday-соединения
  config.faraday_options = {
    ssl: {
      ca_path:  '/usr/lib/ssl/certs'
    },
    proxy: {
      uri:      'http://proxy.example.com',
      user:     'foo',
      password: 'bar'
    }
  }
  # максимальное количество повторов запроса при ошибках
  # работает только если переключить http_verb в :get
  config.max_retries = 2

  # логгер
  config.logger        = Rails.logger
  config.log_requests  = true  # URL-ы запросов
  config.log_errors    = true  # ошибки
  config.log_responses = false # удачные ответы

  # используемая версия API
  config.api_version = '5.21'
end

По умолчанию для HTTP-запросов используется Net::HTTP; можно выбрать любой другой адаптер, поддерживаемый faraday.

ВКонтакте позволяет использовать как GET-, так и POST-запросы при вызове методов API. По умолчанию vkontakte_api использует POST, но в настройке http_verb можно указать :get, чтобы совершать GET-запросы.

При необходимости можно указать параметры для faraday-соединения — например, параметры прокси-сервера или путь к SSL-сертификатам.

Чтобы при каждом вызове API-метода передавалась определенная версия API, можно указать ее в конфигурации в api_version. По умолчанию версия не указана.

Чтобы сгенерировать файл с настройками по умолчанию в rails-приложении, можно воспользоваться генератором vkontakte_api:install:

$ cd /path/to/app
$ rails generate vkontakte_api:install

JSON-парсер

vkontakte_api использует парсер Oj — это единственный парсер, который не показал ошибок при парсинге JSON, генерируемого ВКонтакте.

Также в библиотеке multi_json (обертка для различных JSON-парсеров, которая выбирает самый быстрый из установленных в системе и парсит им) Oj поддерживается и имеет наивысший приоритет; поэтому если он установлен в системе, multi_json будет использовать именно его.

Roadmap

  • CLI-интерфейс с автоматической авторизацией

Участие в разработке

Если вы хотите поучаствовать в разработке проекта, форкните репозиторий, положите свои изменения в отдельную ветку, покройте их спеками и отправьте мне pull request.

vkontakte_api тестируется под MRI 2.1, 2.2, 2.3 и 2.4, а также JRuby 9.x. Если в одной из этих сред что-то работает неправильно, либо вообще не работает, то это следует считать багом, и написать об этом в issues на Github.

You can’t perform that action at this time.