# vkontakte_api

`vkontakte_api` - ruby-обертка для API ВКонтакте. Она позволяет вызывать методы API настолько просто, насколько это возможно.

Это русская версия readme. Английская версия лежит [здесь](https://github.com/7even/vkontakte_api/blob/master/README.md).

## Установка

``` bash
gem install vkontakte_api
```

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

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

``` ruby
VkontakteApi.configure do |config|
  config.adapter = :net_http
end
```

Все запросы к API отправляются через объект класса `VkontakteApi::Client`. Чтобы создать его, нужно просто передать в конструктор токен доступа.

``` ruby
@app = VkontakteApi::Client.new('my_access_token')
```

Пожалуй, самый простой способ получить токен в веб-приложении - использовать [OmniAuth](https://github.com/intridea/omniauth), но если это неприемлемо, можно реализовать свой механизм авторизации. На данный момент `vkontakte_api` не умеет получать токен.

Теперь можно вызывать методы API. Все названия методов переведены в underscore_case - в отличие от [официальной документации](http://vk.com/developers.php?oid=-17680044&p=API_Method_Description), где они в camelCase, т.е. `getGroups` становится `get_groups`. Можно по прежнему писать методы в camelCase, но это не соответствует стандартам стиля кода, принятым в ruby.

``` ruby
@app.get_user_settings  # => 327710
@app.groups.get         # => [1, 31022447]
```

Предикатные методы (названия которых начинаются с `is`, например `is_app_user`) должны возвращать результат какого-то условия, поэтому в конец названия метода добавляется '?', и возвращается булево значение (`true` или `false`):

``` ruby
@app.is_app_user? # => true
```

Можно вызывать эти методы и без '?' на конце, тогда они будут возвращать `'0'` или `'1'`.

Теперь о параметрах. Все параметры именованные, и передаются в методы в виде хэша, где ключи соответствуют названиям параметров, а значения - соответственно, их значениям:

``` ruby
@app.friends.get(fields: 'uid,first_name,last_name')
# => [
  {
    :uid          => "1",
    :first_name   => "Павел",
    :last_name    => "Дуров"
  },
  {
    :uid          => "6492",
    :first_name   => "Andrew",
    :last_name    => "Rogozov"
  }
]
```

Также следует заметить, что все возвращаемые хэши имеют символьные ключи.

Если результат метода - Enumerable, то методу можно передать блок, который будет вызван для каждого элемента результата. В этом случае метод вернет массив из результатов выполнения блока с каждым элементом (аналогично `Enumerable#map`):

``` ruby
@app.friends.get(fields: 'first_name,last_name') do |friend|
  "#{friend[:first_name]} #{friend[:last_name]}"
end
# => ["Павел Дуров", "Andrew Rogozov"]
```

`vkontakte_api` не содержит списка названий методов (если не считать пространств имен, вроде `friends` или `groups`) - когда вызывается метод, его название переводится в camelCase, а уже потом отправляется запрос к ВКонтакте. Поэтому когда новый метод добавляется в API, не нужно ждать новой версии гема `vkontakte_api` - можно использовать этот новый метод сразу же. Если в названии запрошенного метода допущены ошибки, или вызван метод, на выполнение которого отсутствуют права, будет выброшено исключение с соответствующим сообщением (об исключениях чуть ниже).

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

Если ВКонтакте возвращает ошибку, выбрасывается исключение класса `VkontakteApi::Error` со всей значимой информацией, которую можно получить:

``` ruby
@app.audio.get_by_id
# => VkontakteApi::Error: VKontakte returned an error 1: 'Unknown error occured' after calling method 'audio.getById' with parameters {}.
```

## Планы

* Авторизация (получение токена доступа с ВКонтакте)
* Документация RDoc

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

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

`vkontakte_api` тестируется под MRI `1.8.7`, `1.9.2` и `1.9.3`. Если в одной из этих сред что-то работает неправильно, либо вообще не работает, то это следует считать багом, и написать об этом в issues на Github.