vkontakte_client 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|