vkontakte_client 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +33 -0
- data/LICENSE +21 -0
- data/README.md +90 -0
- data/README.ru.md +79 -0
- data/examples/accept_all_requests.rb +37 -0
- data/examples/add_suggestions.rb +40 -0
- data/examples/ban_news_from_all_friends.rb +72 -0
- data/examples/friends_of_friends.rb +125 -0
- data/examples/get_online_friends.rb +30 -0
- data/examples/last_seen.rb +32 -0
- data/examples/long_poll.rb +105 -0
- data/examples/mechanize.rb +55 -0
- data/examples/remove_out_requests.rb +44 -0
- data/examples/remove_suspended_friends.rb +30 -0
- data/examples/users_get_offline.rb +17 -0
- data/examples/users_info.rb +25 -0
- data/gems.rb +5 -0
- data/lib/socksify_mechanize.rb +24 -0
- data/lib/vkontakte/api.rb +86 -0
- data/lib/vkontakte/api_error.rb +22 -0
- data/lib/vkontakte/ask_for_credentials.rb +57 -0
- data/lib/vkontakte/client.rb +129 -0
- data/lib/vkontakte/proxy.rb +23 -0
- data/lib/vkontakte/version.rb +5 -0
- data/lib/vkontakte_client.rb +18 -0
- data/vkontakte_client.gemspec +25 -0
- metadata +150 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e7caa5eb916dc2794f24440aabd7b58090b89fdf2230a363d3e949a3403ca8a0
|
4
|
+
data.tar.gz: f781826918653d3a1d65c7ef1c841c36881e0dab8d4f75715483068dced00a96
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 65976cc3532beec29405f2a92d1ccb0cb6a759d171ec72f98e6aec2989647e32a909b4d76f620699530a42ff7610aba95c5b3bb3ca68a9ee014f7309b7daad5e
|
7
|
+
data.tar.gz: 908def64e9eeb7d8566f3db6dce54733e9e811f2a5adde8b3db8731039ecdaa52d811c948edc5cf26dd10957387ed1658706e3c61abe7c6fde59c06eca9fd3fa
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.7
|
3
|
+
NewCops: enable
|
4
|
+
|
5
|
+
Metrics/AbcSize:
|
6
|
+
Max: 36
|
7
|
+
|
8
|
+
Metrics/CyclomaticComplexity:
|
9
|
+
Max: 8
|
10
|
+
|
11
|
+
Metrics/BlockLength:
|
12
|
+
Max: 57
|
13
|
+
|
14
|
+
Metrics/LineLength:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
Metrics/MethodLength:
|
18
|
+
Max: 33
|
19
|
+
|
20
|
+
Style/AsciiComments:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
Lint/MissingSuper:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
Style/MissingRespondToMissing:
|
27
|
+
Enabled: false
|
28
|
+
|
29
|
+
Style/ClassAndModuleChildren:
|
30
|
+
Enabled: false
|
31
|
+
|
32
|
+
Style/PreferredHashMethods:
|
33
|
+
Enabled: false
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2010-2021 Anton Maminov
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# Vkontakte Client
|
2
|
+
|
3
|
+
Ruby library for authorization of client applications and for access to the VK API
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
``` ruby
|
8
|
+
require 'vkontakte_client'
|
9
|
+
```
|
10
|
+
|
11
|
+
## Application registration
|
12
|
+
|
13
|
+
You must register your application in order to use all the capabilities of API VKontakte.
|
14
|
+
|
15
|
+
Open the page “Managed apps” in the left menu, then press “Create an app”. You will be directed to the page <https://vk.com/editapp?act=create>.
|
16
|
+
|
17
|
+
You need to choose _Standalone-app_.
|
18
|
+
|
19
|
+
After confirming the action, you will be redirected to the page with information about the app. Open the page "Settings" in the left-hand menu and you will see the field "ID applications", in which a number will be located. For example, `5490057`. This number is the application identification, a.k.a. `API_ID`, `APP_ID`, `client_id`, and you will need it for your future work.
|
20
|
+
|
21
|
+
### Initialize Vkontakte client
|
22
|
+
|
23
|
+
With client authorization, the access key to the API `access_token`.
|
24
|
+
The constructor takes only one argument - the VK application ID - `CLIENT_ID`.
|
25
|
+
|
26
|
+
``` ruby
|
27
|
+
vk = Vkontakte::Client.new(CLIENT_ID)
|
28
|
+
```
|
29
|
+
|
30
|
+
### Login and password authorization
|
31
|
+
|
32
|
+
In general, for API identification, a special access key is used which is called `access_token`. This token is a string of numbers and Latin letters which you send to the server along with the request.
|
33
|
+
|
34
|
+
This library supports the [Implicit flow](https://vk.com/dev/implicit_flow_user) way to obtain an OAuth 2.0 access key:
|
35
|
+
th 2.0:
|
36
|
+
|
37
|
+
The `login!` method takes the following arguments:
|
38
|
+
|
39
|
+
* `email`: user login
|
40
|
+
* `pass`: user password
|
41
|
+
* `permissions`: requeste [application permissions](https://vk.com/dev/permissions)
|
42
|
+
|
43
|
+
``` ruby
|
44
|
+
vk.login!(email, pass, permissions: 'friends')
|
45
|
+
```
|
46
|
+
|
47
|
+
### API Requests
|
48
|
+
|
49
|
+
After successful authorization, you can [make requests to the API](http://vk.com/dev/api_requests) using the method name from the [API function list](http://vk.com/dev/methods).
|
50
|
+
|
51
|
+
The parameters of the corresponding API method are passed as `Hash`.
|
52
|
+
Note that a method like `friends.get` needs to be passed as `friends_get`.
|
53
|
+
|
54
|
+
``` ruby
|
55
|
+
vk.api.friends_get(fields: 'online', order: 'name', name_case: 'dat')
|
56
|
+
```
|
57
|
+
|
58
|
+
To avoid errors, you can pre-check the status of the user using the `account.getInfo` method.
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
vk.api.account_getInfo
|
62
|
+
```
|
63
|
+
|
64
|
+
### Token Authorization
|
65
|
+
|
66
|
+
It is useful to save the received `access_token` (and, if necessary, the `user_id`) to reuse them
|
67
|
+
|
68
|
+
``` ruby
|
69
|
+
access_token = vk.access_token
|
70
|
+
user_id = vk.user_id
|
71
|
+
```
|
72
|
+
|
73
|
+
``` ruby
|
74
|
+
api = Vkontakte::API.new(access_token)
|
75
|
+
api.friends_get(fields: 'online', order: 'name', name_case: 'dat')
|
76
|
+
```
|
77
|
+
|
78
|
+
## Contributing
|
79
|
+
|
80
|
+
1. Fork it (<https://github.com/mamantoha/vkontakte_client/fork>)
|
81
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
82
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
83
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
84
|
+
5. Create a new Pull Request
|
85
|
+
|
86
|
+
## License
|
87
|
+
|
88
|
+
Copyright: 2010-2021 Anton Maminov (anton.maminov@gmail.com)
|
89
|
+
|
90
|
+
This library is distributed under the MIT license. Please see the LICENSE file.
|
data/README.ru.md
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# Vkontakte Client
|
2
|
+
|
3
|
+
Библиотека для авторизация клиентских приложений и для доступа к API ВКонтакте
|
4
|
+
|
5
|
+
## Использование
|
6
|
+
|
7
|
+
``` ruby
|
8
|
+
require 'vkontakte_client'
|
9
|
+
```
|
10
|
+
|
11
|
+
## Регистрация приложения
|
12
|
+
|
13
|
+
Вам необходимо зарегистрировать свое приложение, чтобы использовать все возможности API ВКонтакте.
|
14
|
+
|
15
|
+
Откройте страницу «Управление» в левом меню, затем нажмите «Создать приложение» — Вы попадете на страницу <https://vk.com/editapp?act=create>
|
16
|
+
|
17
|
+
Нужно выбрать Standalone-приложение.
|
18
|
+
|
19
|
+
После подтверждения действия Вы попадете на страницу с информацией о приложении.
|
20
|
+
Откройте вкладку "Настройки" в меню слева. Вы увидите поле "ID приложения", в котором будет указано число, например, 5490057.
|
21
|
+
Это число — идентификатор приложения, он же `API_ID`, `APP_ID`, `CLIENT_ID`, оно потребуется Вам в дальнейшей работе.
|
22
|
+
|
23
|
+
### Создание клиента
|
24
|
+
|
25
|
+
При клиентской авторизации ключ доступа к API `access_token` выдаётся приложению без необходимости раскрытия секретного ключа приложения.
|
26
|
+
Конструктор получает только один аргумент - идентификатор приложения ВКонтакте - `CLIENT_ID`.
|
27
|
+
|
28
|
+
``` ruby
|
29
|
+
vk = Vkontakte::Client.new(CLIENT_ID)
|
30
|
+
```
|
31
|
+
|
32
|
+
### Авторизация по логину и паролю
|
33
|
+
|
34
|
+
Для работы с большинством методов API Вам необходимо передавать в запросе `access_token` — специальный ключ доступа.
|
35
|
+
|
36
|
+
Эта библиотека поддерживаем [Implicit flow](https://vk.com/dev/implicit_flow_user) способ получения ключа доступа по OAuth 2.0:
|
37
|
+
|
38
|
+
Метод `login!` принимает следующие аргументы:
|
39
|
+
|
40
|
+
* `email`: логин пользователя
|
41
|
+
* `pass`: пароль
|
42
|
+
* `permissions`: запрашиваемые [права доступа приложения](https://vk.com/dev/permissions)
|
43
|
+
|
44
|
+
``` ruby
|
45
|
+
vk.login!(email, pass, permissions: 'friends')
|
46
|
+
```
|
47
|
+
|
48
|
+
### Вызов методов
|
49
|
+
|
50
|
+
После успешной авторизации Вы можете [осуществлять запросы к API](http://vk.com/dev/api_requests) используя название метода из [списка функций API](http://vk.com/dev/methods).
|
51
|
+
|
52
|
+
Параметры соответствующего метода API передаются как `Hash`.
|
53
|
+
Следует заметить что метод вида `friends.get` нужно передавать как `friends_get`.
|
54
|
+
|
55
|
+
``` ruby
|
56
|
+
vk.api.friends_get(fields: 'online', order: 'name', name_case: 'dat')
|
57
|
+
```
|
58
|
+
|
59
|
+
Чтобы избежать появления ошибок, Вы можете предварительно проверять состояние пользователя методом `account.getInfo`.
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
vk.api.account_getInfo
|
63
|
+
```
|
64
|
+
|
65
|
+
### Авторизация по токену
|
66
|
+
|
67
|
+
Полезно сохранить полученный токен (и, при необходимости, id пользователя)
|
68
|
+
|
69
|
+
``` ruby
|
70
|
+
access_token = vk.access_token
|
71
|
+
user_id = vk.user_id
|
72
|
+
```
|
73
|
+
|
74
|
+
чтобы использовать их повторно
|
75
|
+
|
76
|
+
``` ruby
|
77
|
+
api = Vkontakte::API.new(access_token)
|
78
|
+
api.friends_get(fields: 'online', order: 'name', name_case: 'dat')
|
79
|
+
```
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
Bundler.setup :default
|
5
|
+
|
6
|
+
require 'vkontakte_client'
|
7
|
+
|
8
|
+
puts Vkontakte::VERSION
|
9
|
+
|
10
|
+
if $PROGRAM_NAME == __FILE__
|
11
|
+
CLIENT_ID = '5987497'
|
12
|
+
|
13
|
+
email = ARGV[0]
|
14
|
+
pass = ARGV[1]
|
15
|
+
|
16
|
+
vk = Vkontakte::Client.new(CLIENT_ID)
|
17
|
+
|
18
|
+
vk.login!(email, pass, open_captcha: true, permissions: 'friends')
|
19
|
+
vk_api = vk.api
|
20
|
+
puts "Access token: #{vk.access_token}"
|
21
|
+
|
22
|
+
friend_ids = vk_api.friends_getRequests(need_viewed: 1, out: 0)['items']
|
23
|
+
puts "You have #{friend_ids.size} friends requests."
|
24
|
+
|
25
|
+
friend_ids.each_slice(100) do |user_ids|
|
26
|
+
user_ids.each do |user_id|
|
27
|
+
print "Accept user with id `#{user_id}`"
|
28
|
+
begin
|
29
|
+
vk_api.friends_add(user_id: user_id)
|
30
|
+
puts ' - OK'
|
31
|
+
rescue Vkontakte::API::Error => e
|
32
|
+
vk_api.account_banUser(user_id: user_id) if e.error_code == 177
|
33
|
+
puts ' - Skip'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
Bundler.setup :default
|
5
|
+
|
6
|
+
require 'vkontakte_client'
|
7
|
+
|
8
|
+
puts Vkontakte::VERSION
|
9
|
+
|
10
|
+
if $PROGRAM_NAME == __FILE__
|
11
|
+
CLIENT_ID = '5987497'
|
12
|
+
|
13
|
+
email = ARGV[0]
|
14
|
+
pass = ARGV[1]
|
15
|
+
|
16
|
+
vk = Vkontakte::Client.new(CLIENT_ID)
|
17
|
+
vk.login!(email, pass, permissions: 'friends', open_captcha: true)
|
18
|
+
|
19
|
+
suggestions = vk.api.friends_getSuggestions(filter: 'mutual')['items']
|
20
|
+
suggestions.each do |user|
|
21
|
+
sleep 1
|
22
|
+
|
23
|
+
puts "Add [#{user['id']}] #{user['first_name']} #{user['last_name']}"
|
24
|
+
vk.api.friends_add(user_id: user['id'])
|
25
|
+
rescue Vkontakte::API::Error => e
|
26
|
+
puts e.message
|
27
|
+
|
28
|
+
case e.error_code
|
29
|
+
when 1
|
30
|
+
puts 'Come back tomorrow'
|
31
|
+
break
|
32
|
+
when 175, 176
|
33
|
+
next
|
34
|
+
else
|
35
|
+
sleep 60
|
36
|
+
retry
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
Bundler.setup :default
|
5
|
+
|
6
|
+
require 'vkontakte_client'
|
7
|
+
|
8
|
+
puts Vkontakte::VERSION
|
9
|
+
|
10
|
+
if $PROGRAM_NAME == __FILE__
|
11
|
+
CLIENT_ID = '5987497'
|
12
|
+
|
13
|
+
email = ARGV[0]
|
14
|
+
pass = ARGV[1]
|
15
|
+
|
16
|
+
vk = Vkontakte::Client.new(CLIENT_ID)
|
17
|
+
|
18
|
+
# proxy = Vkontakte::Proxy.new(:socks, 'localhost', 9050)
|
19
|
+
# vk = Vkontakte::Client.new(CLIENT_ID, proxy: proxy)
|
20
|
+
|
21
|
+
vk.login!(email, pass, open_captcha: true, permissions: 'friends,wall')
|
22
|
+
vk_api = vk.api
|
23
|
+
puts "Access token: #{vk.access_token}"
|
24
|
+
|
25
|
+
banned_ids = vk_api.newsfeed_getBanned['members']
|
26
|
+
|
27
|
+
my_friends = []
|
28
|
+
fr_count = 5000
|
29
|
+
fr_offset = 0
|
30
|
+
puts 'Get friends'
|
31
|
+
loop do
|
32
|
+
fr = vk.api.friends_get(count: fr_count, offset: fr_offset * fr_count)['items']
|
33
|
+
break if fr.empty?
|
34
|
+
|
35
|
+
my_friends << fr
|
36
|
+
fr_offset += 1
|
37
|
+
end
|
38
|
+
my_friends.flatten!
|
39
|
+
|
40
|
+
my_requests = []
|
41
|
+
fr_count = 1000
|
42
|
+
fr_offset = 0
|
43
|
+
puts 'Received applications to friends'
|
44
|
+
loop do
|
45
|
+
fr = vk.api.friends_getRequests(count: fr_count, offset: fr_offset * fr_count, out: 0)['items']
|
46
|
+
break if fr.empty?
|
47
|
+
|
48
|
+
my_requests << fr
|
49
|
+
fr_offset += 1
|
50
|
+
end
|
51
|
+
|
52
|
+
fr_count = 1000
|
53
|
+
fr_offset = 0
|
54
|
+
puts 'Get requests sent by the me'
|
55
|
+
loop do
|
56
|
+
fr = vk.api.friends_getRequests(count: fr_count, offset: fr_offset * fr_count, out: 1)['items']
|
57
|
+
break if fr.empty?
|
58
|
+
|
59
|
+
my_requests << fr
|
60
|
+
fr_offset += 1
|
61
|
+
end
|
62
|
+
|
63
|
+
my_requests.flatten!
|
64
|
+
|
65
|
+
all_users = (my_friends | my_requests) - banned_ids
|
66
|
+
|
67
|
+
puts "Clean news feed from #{all_users.size} new users"
|
68
|
+
all_users.each_slice(100) do |user_ids|
|
69
|
+
vk_api.newsfeed_addBan(user_ids: user_ids.join(','))
|
70
|
+
end
|
71
|
+
puts "#{vk_api.newsfeed_getBanned['members'].size} are banned."
|
72
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
Bundler.setup :default
|
5
|
+
|
6
|
+
require 'pp'
|
7
|
+
require 'vkontakte_client'
|
8
|
+
require 'pry'
|
9
|
+
|
10
|
+
puts Vkontakte::VERSION
|
11
|
+
|
12
|
+
if $PROGRAM_NAME == __FILE__
|
13
|
+
CLIENT_ID = '5987497'
|
14
|
+
|
15
|
+
email = ARGV[0]
|
16
|
+
pass = ARGV[1]
|
17
|
+
|
18
|
+
vk = Vkontakte::Client.new(CLIENT_ID, timeout: 500)
|
19
|
+
vk.login!(email, pass, open_captcha: true, permissions: 'friends,wall')
|
20
|
+
|
21
|
+
current_user = vk.api.users_get.first
|
22
|
+
|
23
|
+
second_circle = {}
|
24
|
+
second_circle.default = 0
|
25
|
+
# [uid, uid, ...]
|
26
|
+
|
27
|
+
my_friends = []
|
28
|
+
fr_count = 5000
|
29
|
+
fr_offset = 0
|
30
|
+
loop do
|
31
|
+
fr = vk.api.friends_get(order: 'hints', count: fr_count, offset: fr_offset * fr_count)['items']
|
32
|
+
break if fr.empty?
|
33
|
+
|
34
|
+
my_friends << fr
|
35
|
+
fr_offset += 1
|
36
|
+
end
|
37
|
+
my_friends.flatten!
|
38
|
+
|
39
|
+
good_friends = 0
|
40
|
+
bad_friends = 0
|
41
|
+
|
42
|
+
fr_count = 1000
|
43
|
+
fr_offset = 0
|
44
|
+
friends_requests = []
|
45
|
+
|
46
|
+
loop do
|
47
|
+
fr = vk.api.friends_getRequests(out: 1, count: fr_count, offset: fr_offset * fr_count)['items']
|
48
|
+
break if fr.empty?
|
49
|
+
|
50
|
+
friends_requests << fr
|
51
|
+
fr_offset += 1
|
52
|
+
end
|
53
|
+
friends_requests.flatten!
|
54
|
+
|
55
|
+
parse_friends_count = 30
|
56
|
+
puts "You have #{my_friends.count} friends"
|
57
|
+
puts "#{friends_requests.count} people already receive request"
|
58
|
+
|
59
|
+
my_friends[0...parse_friends_count].each_with_index do |uid, index|
|
60
|
+
begin
|
61
|
+
print "Parsing your friends: #{index + 1} of #{parse_friends_count}. Good: #{good_friends}. Bad: #{bad_friends}\r"
|
62
|
+
friends = vk.api.friends_get(user_id: uid)['items']
|
63
|
+
good_friends += 1
|
64
|
+
rescue Vkontakte::API::Error
|
65
|
+
# Permission to perform this action is denied by user
|
66
|
+
bad_friends += 1
|
67
|
+
next
|
68
|
+
end
|
69
|
+
friends.each { |f| second_circle[f] += 1 }
|
70
|
+
end
|
71
|
+
|
72
|
+
puts "\nComplete"
|
73
|
+
|
74
|
+
second_circle.reject! { |uid, count| my_friends.include?(uid) || friends_requests.include?(uid) || current_user['id'] == uid || count < 2 }
|
75
|
+
|
76
|
+
puts "Total people in 2nd circle: #{second_circle.size}"
|
77
|
+
|
78
|
+
sorted_second_circle = second_circle.sort { |a, b| b[1] <=> a[1] } # <-- Hash sorting by value
|
79
|
+
|
80
|
+
# sorted_second_circle # => [['uid1', 1], ['uid2', 2], ['uid3', 3]]
|
81
|
+
# sorted_second_circle.transpose # => [["uid1", "uid2", "uid3"], [1, 2, 3]]
|
82
|
+
|
83
|
+
common_friends = vk.api.users_get(user_ids: sorted_second_circle[0...99].transpose[0].join(',').to_s)
|
84
|
+
|
85
|
+
puts 'Getting common friends.'
|
86
|
+
common_friends = []
|
87
|
+
sorted_second_circle.each_slice(300) do |ids|
|
88
|
+
sleep 1
|
89
|
+
cf = vk.api.users_get(user_ids: ids.transpose[0].join(',').to_s)
|
90
|
+
break if cf.empty?
|
91
|
+
|
92
|
+
common_friends << cf
|
93
|
+
end
|
94
|
+
|
95
|
+
common_friends.flatten!
|
96
|
+
puts "Total common friends: #{common_friends.size}"
|
97
|
+
|
98
|
+
sorted_second_circle.each do |uid, count|
|
99
|
+
sleep 1
|
100
|
+
user = vk.api.users_get(user_id: uid).first
|
101
|
+
|
102
|
+
next if user['deactivated']
|
103
|
+
|
104
|
+
friend = common_friends.find { |f| f['id'] == uid }
|
105
|
+
|
106
|
+
next unless friend
|
107
|
+
|
108
|
+
puts "[#{count}]: [#{friend['id']}] #{friend['first_name']} #{friend['last_name']}"
|
109
|
+
vk.api.friends_add(user_id: friend['id'])
|
110
|
+
rescue Vkontakte::API::Error => e
|
111
|
+
puts e.message
|
112
|
+
|
113
|
+
case e.error_code
|
114
|
+
when 1
|
115
|
+
puts 'Come back tomorrow'
|
116
|
+
break
|
117
|
+
when 175, 176
|
118
|
+
next
|
119
|
+
else
|
120
|
+
sleep 60
|
121
|
+
retry
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|