vk_cozy 0.2 → 0.3.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -0
- data/lib/vk_cozy/api/api.rb +36 -37
- data/lib/vk_cozy/bot.rb +60 -48
- data/lib/vk_cozy/dev/keyboard/action.rb +72 -0
- data/lib/vk_cozy/dev/keyboard/button.rb +34 -0
- data/lib/vk_cozy/dev/keyboard/color.rb +10 -0
- data/lib/vk_cozy/dev/keyboard/keyboard.rb +48 -0
- data/lib/vk_cozy/dispatch/views/bot/event.rb +60 -52
- data/lib/vk_cozy/dispatch/views/user/event.rb +65 -64
- data/lib/vk_cozy/framework/labeler/bot.rb +74 -32
- data/lib/vk_cozy/framework/labeler/filters/filters.rb +88 -45
- data/lib/vk_cozy/framework/labeler/user.rb +34 -29
- data/lib/vk_cozy/polling/bot_polling.rb +32 -34
- data/lib/vk_cozy/polling/user_polling.rb +34 -34
- data/lib/vk_cozy/types/events/bot_events.rb +45 -45
- data/lib/vk_cozy/types/events/user_events.rb +57 -57
- data/lib/vk_cozy/user.rb +38 -27
- data/lib/vk_cozy.rb +1 -1
- metadata +10 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88f8d21019678635297581f40f48e83e71cc79bfe2db701cd3c6b6815df8c5d0
|
4
|
+
data.tar.gz: 2a3e5cfce38ec22b4d20f36b3f50e6c2d5b508a09e854186c5aeb90fa858ff80
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b02bf27e35dd324d7497ff0d2bd7f4a952b313cb94fc897c3e190b510881d870efe4e17c1c912dcdf5a596aaf2842608d94d44f6b6432c8cbae7778cb38340e9
|
7
|
+
data.tar.gz: f2b9dbac5adb7488dcf8db32189ab9d80c514ed8acefc20782ba9ded4275ea6214c8023747e0d5dee8bef70f9bdb804911a31c58f856d8ffce100a4d2160401e
|
data/Gemfile
CHANGED
data/lib/vk_cozy/api/api.rb
CHANGED
@@ -4,47 +4,46 @@ require 'net/http'
|
|
4
4
|
require "resolv-replace"
|
5
5
|
|
6
6
|
class Api
|
7
|
-
|
7
|
+
attr_accessor :access_token, :version
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
SCHEME = 'https'
|
10
|
+
HOST = 'api.vk.com'
|
11
|
+
PATH = '/method/'
|
12
|
+
PORT = 443
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
def initialize(access_token, version=5.92)
|
15
|
+
@access_token = access_token
|
16
|
+
@version = version
|
17
|
+
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
19
|
+
def request_thr(method_vk, data)
|
20
|
+
thr = Thread.new {
|
21
|
+
request(method_vk, data)
|
22
|
+
}
|
23
|
+
thr.run
|
24
|
+
end
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
26
|
+
def request(method_vk, data)
|
27
|
+
data = data.to_hash
|
28
|
+
data = data.merge(v: version)
|
29
|
+
data = data.merge(access_token: access_token)
|
30
|
+
data.each do |argument, value|
|
31
|
+
data[argument] = value.join(',') if value.is_a?(Array)
|
32
|
+
end
|
33
|
+
http_response = Net::HTTP.post_form(url_for_method(method_vk), data).body
|
34
|
+
# return unless http_response.present?
|
35
|
+
json_response = JSON.parse(http_response)
|
36
|
+
if json_response['error']
|
37
|
+
raise json_response['error']['error_msg']
|
38
|
+
end
|
39
|
+
json_response
|
40
|
+
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
def url_for_method(method_vk)
|
43
|
+
URI.parse("#{SCHEME}://#{HOST}#{PATH}#{method_vk}")
|
44
|
+
end
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
def method_missing name, **kwargs
|
47
|
+
return request(name.to_s.sub('_', '.'), kwargs)['response']
|
48
|
+
end
|
50
49
|
end
|
data/lib/vk_cozy/bot.rb
CHANGED
@@ -2,54 +2,66 @@ require_relative 'types/events/bot_events'
|
|
2
2
|
require_relative 'dispatch/views/bot/event'
|
3
3
|
require_relative 'framework/labeler/bot'
|
4
4
|
require_relative 'polling/bot_polling'
|
5
|
+
require_relative 'dev/keyboard/keyboard'
|
5
6
|
|
6
7
|
module VkCozy
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
8
|
+
class Bot
|
9
|
+
attr_reader :api
|
10
|
+
|
11
|
+
CLASS_BY_EVENT_TYPE = {
|
12
|
+
BotEventType::MESSAGE_NEW => BotMessageEvent,
|
13
|
+
BotEventType::MESSAGE_REPLY => BotMessageEvent,
|
14
|
+
BotEventType::MESSAGE_EDIT => BotMessageEvent
|
15
|
+
}
|
16
|
+
|
17
|
+
DEFAULT_EVENT_CLASS = BotEvent
|
18
|
+
|
19
|
+
def initialize(access_token, version=5.92)
|
20
|
+
@access_token = access_token
|
21
|
+
@api = Api.new(access_token, version)
|
22
|
+
|
23
|
+
@polling = VkCozy::BotPolling.new(@api)
|
24
|
+
@labeler = VkCozy::BotLabeler.new(@api)
|
25
|
+
end
|
26
|
+
|
27
|
+
def on
|
28
|
+
return @labeler
|
29
|
+
end
|
30
|
+
|
31
|
+
def on_startup
|
32
|
+
puts 'Run polling'
|
33
|
+
end
|
34
|
+
|
35
|
+
def run_polling(startup=nil)
|
36
|
+
if startup.nil?
|
37
|
+
on_startup
|
38
|
+
elsif startup.is_a?(Proc)
|
39
|
+
startup.call
|
40
|
+
else
|
41
|
+
startup
|
42
|
+
end
|
43
|
+
@polling.listen do |event|
|
44
|
+
for event_raw in event['updates']
|
45
|
+
begin
|
46
|
+
event_raw = parse_event(event_raw)
|
47
|
+
if @labeler.filter(event_raw)
|
48
|
+
next
|
49
|
+
end
|
50
|
+
rescue Exception => e
|
51
|
+
raise e
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def parse_event(event_raw)
|
60
|
+
event_class = CLASS_BY_EVENT_TYPE.fetch(
|
61
|
+
event_raw['type'],
|
62
|
+
DEFAULT_EVENT_CLASS
|
63
|
+
)
|
64
|
+
return event_class.new(@api, event_raw)
|
65
|
+
end
|
66
|
+
end
|
55
67
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Keyboard
|
2
|
+
class BaseAction
|
3
|
+
attr_reader :type
|
4
|
+
|
5
|
+
def get_data
|
6
|
+
instance_variables.each_with_object({}) do |k, h|
|
7
|
+
var = instance_variable_get("#{k}")
|
8
|
+
if not var.nil?
|
9
|
+
h[k.to_s.gsub('@', '')] = var
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Text < BaseAction
|
16
|
+
def initialize(label, payload: nil)
|
17
|
+
@type = 'text'
|
18
|
+
|
19
|
+
@label = label
|
20
|
+
@payload = payload
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class OpenLink < BaseAction
|
25
|
+
def initialize(label, link, payload: nil)
|
26
|
+
@type = 'open_link'
|
27
|
+
|
28
|
+
@label = label
|
29
|
+
@link = link
|
30
|
+
@payload = payload
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Location < BaseAction
|
35
|
+
def initialize(payload: nil)
|
36
|
+
@type = 'location'
|
37
|
+
|
38
|
+
@payload = payload
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class VkPay < BaseAction
|
43
|
+
def initialize(payload: nil, hash: nil)
|
44
|
+
@type = 'vkpay'
|
45
|
+
|
46
|
+
@payload = payload
|
47
|
+
@hash = hash
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class VkApps < BaseAction
|
52
|
+
def initialize(app_id, owner_id, payload: nil, label: nil, hash: nil)
|
53
|
+
@type = 'open_app'
|
54
|
+
|
55
|
+
@app_id = app_id
|
56
|
+
@owner_id = owner_id
|
57
|
+
@payload = payload
|
58
|
+
@label = label
|
59
|
+
@hash = hash
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
class Callback < BaseAction
|
65
|
+
def initialize(label, payload)
|
66
|
+
@type = 'callback'
|
67
|
+
|
68
|
+
@label = label
|
69
|
+
@payload = payload
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Keyboard
|
2
|
+
class KeyboardButton
|
3
|
+
def initialize(action, color: nil, data: nil)
|
4
|
+
@action = action
|
5
|
+
@color = color
|
6
|
+
@data = data
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.from_typed(action, color: nil)
|
10
|
+
return self.new(action, color: color, data: nil)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.from_hash(data)
|
14
|
+
color = data.key('color')
|
15
|
+
keyboard_data = {'action' => data}
|
16
|
+
if color.nil?
|
17
|
+
keyboard_data['action'].delete('color')
|
18
|
+
keyboard_data['color'] = color
|
19
|
+
end
|
20
|
+
return self.new(self.action, self.color, keyboard_data)
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_data
|
24
|
+
if not @data.nil?
|
25
|
+
return @data
|
26
|
+
end
|
27
|
+
data = {'action' => @action.get_data()}
|
28
|
+
if ['text', 'callback'].include?(@action.type) and not @color.nil?
|
29
|
+
data['color'] = @color
|
30
|
+
end
|
31
|
+
return data
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative 'action'
|
2
|
+
require_relative 'button'
|
3
|
+
require_relative 'color'
|
4
|
+
|
5
|
+
module Keyboard
|
6
|
+
class Keyboard
|
7
|
+
def initialize(one_time: false, inline: false)
|
8
|
+
@one_time = one_time
|
9
|
+
@inline = inline
|
10
|
+
@buttons = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def row()
|
14
|
+
@buttons << []
|
15
|
+
return self
|
16
|
+
end
|
17
|
+
|
18
|
+
def add(action, color=nil)
|
19
|
+
if @buttons.length == 0
|
20
|
+
row()
|
21
|
+
end
|
22
|
+
button = KeyboardButton.from_typed(action, color: color)
|
23
|
+
@buttons[-1] << button
|
24
|
+
return self
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_json()
|
28
|
+
_buttons = []
|
29
|
+
for row in @buttons
|
30
|
+
buttons = []
|
31
|
+
for button in row
|
32
|
+
buttons << button.get_data()
|
33
|
+
end
|
34
|
+
_buttons << buttons
|
35
|
+
end
|
36
|
+
data = {
|
37
|
+
'one_time' => @one_time,
|
38
|
+
'inline' => @inline,
|
39
|
+
'buttons' => _buttons
|
40
|
+
}
|
41
|
+
return data
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_s
|
45
|
+
return JSON.generate(get_json())
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,67 +1,75 @@
|
|
1
1
|
module VkCozy
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
class BotEvent
|
3
|
+
attr_reader :api, :raw, :t, :type, :obj, :object, :client_info, :message, :group_id
|
4
|
+
def initialize(api, event_raw)
|
5
|
+
@api = api
|
6
|
+
@raw = event_raw
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
@type = event_raw['type']
|
9
|
+
@t = @type
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
@object = event_raw['object'].to_dot
|
12
|
+
@obj = @object
|
13
13
|
|
14
|
-
|
14
|
+
@message = @obj['message']
|
15
15
|
|
16
|
-
|
16
|
+
@client_info = @obj['client_info']
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
@group_id = @raw['group_id']
|
19
|
+
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
def answer(text)
|
23
|
+
return @api.messages_send(
|
24
|
+
peer_id: @obj.peer_id,
|
25
|
+
message: text,
|
26
|
+
random_id: 0
|
27
|
+
)
|
28
|
+
end
|
25
29
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
+
def [] key
|
31
|
+
instance_variable_get("@#{key}")
|
32
|
+
end
|
30
33
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
@from_user = false
|
36
|
-
@from_chat = false
|
37
|
-
@from_group = false
|
34
|
+
def to_s
|
35
|
+
"BotEvent(#{@raw.to_s})"
|
36
|
+
end
|
37
|
+
end
|
38
38
|
|
39
|
+
class BotMessageEvent < BotEvent
|
40
|
+
attr_reader :from_user, :from_chat, :from_group, :chat_id
|
41
|
+
def initialize(api, event_raw)
|
42
|
+
super(api, event_raw)
|
43
|
+
@from_user = false
|
44
|
+
@from_chat = false
|
45
|
+
@from_group = false
|
39
46
|
|
40
|
-
peer_id = @raw['object']['peer_id']
|
41
|
-
if peer_id.nil?
|
42
|
-
peer_id = @raw['object']['message']['peer_id']
|
43
|
-
end
|
44
47
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
else
|
50
|
-
from_user = true
|
51
|
-
@chat_id = peer_id - 2e9
|
52
|
-
end
|
53
|
-
end
|
48
|
+
peer_id = @raw['object']['peer_id']
|
49
|
+
if peer_id.nil?
|
50
|
+
peer_id = @raw['object']['message']['peer_id']
|
51
|
+
end
|
54
52
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
53
|
+
if peer_id < 0
|
54
|
+
@from_group = true
|
55
|
+
elsif peer_id < 2e9
|
56
|
+
@from_user = true
|
57
|
+
else
|
58
|
+
from_user = true
|
59
|
+
@chat_id = peer_id - 2e9
|
60
|
+
end
|
61
|
+
end
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
63
|
+
def answer(text)
|
64
|
+
return @api.messages_send(
|
65
|
+
peer_id: @message.peer_id,
|
66
|
+
message: text,
|
67
|
+
random_id: 0
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_s
|
72
|
+
"BotMessageEvent(#{@raw.to_s})"
|
73
|
+
end
|
74
|
+
end
|
67
75
|
end
|
@@ -1,80 +1,81 @@
|
|
1
1
|
module VkCozy
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
class UserEvent
|
3
|
+
attr_accessor :api, :raw, :type,
|
4
|
+
:from_user, :from_chat, :from_group, :from_me, :to_me,
|
5
|
+
:attachments, :message_data,
|
6
|
+
:message_id, :timestamp, :text, :peer_id, :flags, :extra, :extra_values, :type_id
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
def initialize(api, raw_event)
|
9
|
+
@api = api
|
10
|
+
@raw = raw_event
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
@from_user = false
|
13
|
+
@from_chat = false
|
14
|
+
@from_group = false
|
15
|
+
@from_me = false
|
16
|
+
@to_me = false
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
begin
|
19
|
+
@type = UserEventType.parse(@raw[0])
|
20
|
+
list_to_attr(@raw[1, @raw.length], EVENT_ATTRS_MAPPING[@type])
|
21
|
+
rescue StandardError => e
|
22
|
+
@type = @raw[0]
|
23
|
+
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
if VkCozy::PARSE_PEER_ID_EVENTS.include?(@type)
|
26
|
+
parse_peer_id()
|
27
|
+
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
if VkCozy::PARSE_MESSAGE_FLAGS_EVENTS
|
30
|
+
parse_message()
|
31
|
+
end
|
32
|
+
end
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
def to_s
|
35
|
+
instance_variables.each_with_object({}) do |k, h|
|
36
|
+
h[k] = instance_variable_get("#{k}")
|
37
|
+
end.to_json
|
38
|
+
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
40
|
+
def answer(text)
|
41
|
+
return @api.messages_send(
|
42
|
+
peer_id: @peer_id,
|
43
|
+
message: text,
|
44
|
+
random_id: 0
|
45
|
+
)
|
46
|
+
end
|
47
47
|
|
48
|
-
|
48
|
+
private
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
50
|
+
def list_to_attr(raw, attrs)
|
51
|
+
for i in (0..[raw.length, attrs.length].min)
|
52
|
+
instance_variable_set("@#{attrs[i]}", raw[i]) if respond_to? "#{attrs[i]}="
|
53
|
+
end
|
54
|
+
end
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
def parse_peer_id
|
57
|
+
if @peer_id < 0
|
58
|
+
@from_group = true
|
59
|
+
@group_id = peer_id
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
|
61
|
+
elsif @peer_id > 2e9
|
62
|
+
@from_chat = true
|
63
|
+
@chat_id = @peer_id-2e9
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
65
|
+
if @extra_values and @extra_values.include?('from')
|
66
|
+
@user_id = @extra_values['from'].to_i
|
67
|
+
end
|
68
|
+
else
|
69
|
+
@from_user = true
|
70
|
+
@user_id = @peer_id
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
73
74
|
|
74
|
-
|
75
|
-
|
75
|
+
def parse_message
|
76
|
+
if @type == UserEventType::MESSAGE_NEW
|
76
77
|
|
77
|
-
|
78
|
-
|
79
|
-
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
80
81
|
end
|