kybus-bot 0.7.0 → 0.8.2
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 +4 -4
- data/lib/kybus/bot/adapters/debug.rb +17 -6
- data/lib/kybus/bot/adapters/discord.rb +1 -1
- data/lib/kybus/bot/adapters/telegram.rb +7 -3
- data/lib/kybus/bot/adapters/telegram_file.rb +4 -0
- data/lib/kybus/bot/adapters/telegram_message.rb +8 -2
- data/lib/kybus/bot/base.rb +13 -0
- data/lib/kybus/bot/command/command.rb +19 -3
- data/lib/kybus/bot/command/command_state.rb +1 -2
- data/lib/kybus/bot/command/command_state_factory.rb +31 -7
- data/lib/kybus/bot/command/execution_context.rb +6 -1
- data/lib/kybus/bot/command_executor.rb +32 -13
- data/lib/kybus/bot/dsl_methods.rb +11 -2
- data/lib/kybus/bot/test.rb +7 -2
- data/lib/kybus/bot/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7c076fdf29d45a346d07aa5639349a66cff1a83ed15f0cfbafc4e6d4698cbd9
|
4
|
+
data.tar.gz: 0fa6891cd37efd3a37b87b59e3dc90fd1628384c43863237e70ea6f757f2086a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f620f4d3674eb392f61f7a50abf378c1fa2fef5b718a93cf4ec1c340f906b1d924948f374fc0214d817664c26a97e4d5cdfa301c6588ba0c2e30bf5af8d7fb75
|
7
|
+
data.tar.gz: f2b708234bb392bfaf98d75f29720ea081ead5e3ea4cba36a7703abd9dcc7516e8328eb8f2583604c0de819e15c391ba1a7066cb3b74bf4ef39c0713186f6e96
|
@@ -11,7 +11,7 @@ module Kybus
|
|
11
11
|
# Wraps a debugging message inside a class.
|
12
12
|
class DebugMessage < Kybus::Bot::Message
|
13
13
|
# It receives a string with the raw text and the id of the channel
|
14
|
-
attr_reader :attachment
|
14
|
+
attr_reader :attachment, :message_id
|
15
15
|
|
16
16
|
class DebugFile
|
17
17
|
def initialize(path)
|
@@ -40,6 +40,9 @@ module Kybus
|
|
40
40
|
@text = text
|
41
41
|
@channel = channel
|
42
42
|
@attachment = attachment
|
43
|
+
@@message_id ||= 0
|
44
|
+
@@message_id += 1
|
45
|
+
@message_id = @@message_id + 1
|
43
46
|
end
|
44
47
|
|
45
48
|
# Returns the channel id
|
@@ -110,6 +113,7 @@ module Kybus
|
|
110
113
|
def answer(message, attachment = nil)
|
111
114
|
send_data(message, attachment)
|
112
115
|
@state = :open
|
116
|
+
DebugMessage.new(message, @name)
|
113
117
|
end
|
114
118
|
end
|
115
119
|
|
@@ -144,8 +148,8 @@ module Kybus
|
|
144
148
|
loop do
|
145
149
|
raise NoMoreMessageException if @channels.values.all?(&:empty?)
|
146
150
|
|
147
|
-
|
148
|
-
return @last_message =
|
151
|
+
open_channel = @channels.values.find(&:open?)
|
152
|
+
return @last_message = open_channel.read_message if open_channel
|
149
153
|
end
|
150
154
|
end
|
151
155
|
|
@@ -155,12 +159,12 @@ module Kybus
|
|
155
159
|
end
|
156
160
|
|
157
161
|
# interface for sending messages
|
158
|
-
def send_message(
|
162
|
+
def send_message(contents, channel_name, attachment = nil)
|
159
163
|
channel(channel_name).answer(contents, attachment)
|
160
164
|
end
|
161
165
|
|
162
166
|
# interface for sending video
|
163
|
-
def send_video(channel_name, video_url,
|
167
|
+
def send_video(channel_name, video_url, _caption = nil)
|
164
168
|
channel(channel_name).answer("VIDEO: #{video_url}")
|
165
169
|
end
|
166
170
|
|
@@ -170,7 +174,7 @@ module Kybus
|
|
170
174
|
end
|
171
175
|
|
172
176
|
# interface for sending image
|
173
|
-
def send_image(channel_name, image_url,
|
177
|
+
def send_image(channel_name, image_url, _caption = nil)
|
174
178
|
channel(channel_name).answer("IMG: #{image_url}")
|
175
179
|
end
|
176
180
|
|
@@ -188,6 +192,13 @@ module Kybus
|
|
188
192
|
end
|
189
193
|
end
|
190
194
|
|
195
|
+
include Kybus::Logger
|
196
|
+
|
197
|
+
def message_builder(msg)
|
198
|
+
log_info('Building message object', msg:, msg_class: msg.class.name)
|
199
|
+
msg
|
200
|
+
end
|
201
|
+
|
191
202
|
def mention(user)
|
192
203
|
"@#{user}"
|
193
204
|
end
|
@@ -80,7 +80,7 @@ module Kybus
|
|
80
80
|
end
|
81
81
|
|
82
82
|
# interface for sending messages
|
83
|
-
def send_message(channel_name, contents,
|
83
|
+
def send_message(channel_name, contents, _caption = nil)
|
84
84
|
puts "#{channel_name} => #{contents}" if @config['debug']
|
85
85
|
channel = @client.channel(channel_name)
|
86
86
|
if channel
|
@@ -47,12 +47,12 @@ module Kybus
|
|
47
47
|
end
|
48
48
|
|
49
49
|
# interface for sending messages
|
50
|
-
def send_message(
|
50
|
+
def send_message(contents, channel_name)
|
51
51
|
puts "#{channel_name} => #{contents}" if @config['debug']
|
52
|
-
@client.api.send_message(chat_id: channel_name, text: contents)
|
52
|
+
@client.api.send_message(chat_id: channel_name.to_i, text: contents, parse_mode: @config['parse_mode'])
|
53
53
|
# :nocov:
|
54
54
|
rescue ::Telegram::Bot::Exceptions::ResponseError => e
|
55
|
-
return if e
|
55
|
+
return if e.error_code == '403'
|
56
56
|
end
|
57
57
|
# :nocov:
|
58
58
|
|
@@ -80,6 +80,10 @@ module Kybus
|
|
80
80
|
@client.api.send_document(chat_id: channel_name, document: file)
|
81
81
|
end
|
82
82
|
|
83
|
+
def message_builder(raw_message)
|
84
|
+
TelegramMessage.new(raw_message)
|
85
|
+
end
|
86
|
+
|
83
87
|
def file_builder(file)
|
84
88
|
TelegramFile.new(file)
|
85
89
|
end
|
@@ -17,7 +17,7 @@ module Kybus
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def reply?
|
20
|
-
|
20
|
+
@message.respond_to?(:reply_to_message) && @message.reply_to_message
|
21
21
|
end
|
22
22
|
|
23
23
|
def replied_message
|
@@ -29,6 +29,10 @@ module Kybus
|
|
29
29
|
@message.chat.id
|
30
30
|
end
|
31
31
|
|
32
|
+
def message_id
|
33
|
+
@message.respond_to?(:message_id) ? @message.message_id : @message['result']['message_id']
|
34
|
+
end
|
35
|
+
|
32
36
|
# Returns the message contents
|
33
37
|
def raw_message
|
34
38
|
@message.to_s
|
@@ -43,7 +47,9 @@ module Kybus
|
|
43
47
|
end
|
44
48
|
|
45
49
|
def attachment
|
46
|
-
@message.document
|
50
|
+
(@message.respond_to?(:document) && @message&.document) ||
|
51
|
+
(@message.respond_to?(:photo) && @message.photo&.last) ||
|
52
|
+
(@message.respond_to?(:audio) && @message&.audio)
|
47
53
|
end
|
48
54
|
|
49
55
|
def user
|
data/lib/kybus/bot/base.rb
CHANGED
@@ -63,6 +63,10 @@ module Kybus
|
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
+
def dsl
|
67
|
+
@executor.dsl
|
68
|
+
end
|
69
|
+
|
66
70
|
# Starts the bot execution, this is a blocking call.
|
67
71
|
def run
|
68
72
|
# TODO: Implement an interface for killing the process
|
@@ -72,6 +76,15 @@ module Kybus
|
|
72
76
|
# :nocov: #
|
73
77
|
end
|
74
78
|
|
79
|
+
def redirect(command, *params)
|
80
|
+
@executor.invoke(command, params)
|
81
|
+
end
|
82
|
+
|
83
|
+
def send_message(contents, channel)
|
84
|
+
log_debug('Sending message', contents:, channel:)
|
85
|
+
provider.message_builder(@provider.send_message(contents, channel))
|
86
|
+
end
|
87
|
+
|
75
88
|
def register_command(klass, params = [], &block)
|
76
89
|
definitions.register_command(klass, params, &block)
|
77
90
|
end
|
@@ -6,13 +6,21 @@ module Kybus
|
|
6
6
|
# it currently only gets a param list, but it will be extended to a more
|
7
7
|
# complex DSL.
|
8
8
|
class Command
|
9
|
-
|
9
|
+
attr_accessor :name
|
10
|
+
attr_reader :block, :params
|
10
11
|
|
11
12
|
# Receives a list of params as symbols and the lambda with the block.
|
12
|
-
def initialize(name,
|
13
|
+
def initialize(name, params_config, &block)
|
13
14
|
@name = name
|
14
|
-
@params = params
|
15
15
|
@block = block
|
16
|
+
case params_config
|
17
|
+
when Array
|
18
|
+
@params = params_config
|
19
|
+
@params_config = {}
|
20
|
+
when Hash
|
21
|
+
@params = params_config.keys
|
22
|
+
@params_config = params_config
|
23
|
+
end
|
16
24
|
end
|
17
25
|
|
18
26
|
# Checks if the params object given contains all the needed values
|
@@ -24,6 +32,14 @@ module Kybus
|
|
24
32
|
def next_missing_param(current_params)
|
25
33
|
params.find { |key| !current_params.key?(key) }.to_s
|
26
34
|
end
|
35
|
+
|
36
|
+
def params_ask_label(param)
|
37
|
+
@params_config[param.to_sym]
|
38
|
+
end
|
39
|
+
|
40
|
+
def params_size
|
41
|
+
@params.size
|
42
|
+
end
|
27
43
|
end
|
28
44
|
end
|
29
45
|
end
|
@@ -17,7 +17,7 @@ module Kybus
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def ready?
|
20
|
-
command
|
20
|
+
command&.ready?(params)
|
21
21
|
end
|
22
22
|
|
23
23
|
# validates which is the following parameter required
|
@@ -66,7 +66,6 @@ module Kybus
|
|
66
66
|
%i[params files].each do |param|
|
67
67
|
@data[param] = @data[param].to_json
|
68
68
|
end
|
69
|
-
|
70
69
|
@data.store
|
71
70
|
%i[params files].each do |param|
|
72
71
|
@data[param] = backup[param]
|
@@ -14,8 +14,22 @@ module Kybus
|
|
14
14
|
@definitions = definitions
|
15
15
|
end
|
16
16
|
|
17
|
-
def command(
|
18
|
-
@definitions
|
17
|
+
def command(search)
|
18
|
+
@definitions.each do |name, command|
|
19
|
+
case name
|
20
|
+
when String
|
21
|
+
return command if name == search
|
22
|
+
when Class
|
23
|
+
return command if search.is_a?(name)
|
24
|
+
when Regexp
|
25
|
+
if search.is_a?(String) && name.match?(search)
|
26
|
+
storable_command = command.clone
|
27
|
+
storable_command.name = search
|
28
|
+
return storable_command
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
nil
|
19
33
|
end
|
20
34
|
|
21
35
|
def default_command
|
@@ -28,17 +42,27 @@ module Kybus
|
|
28
42
|
|
29
43
|
def command_with_inline_arg(name_with_arg)
|
30
44
|
@definitions.each do |name, command|
|
31
|
-
|
32
|
-
|
45
|
+
case name
|
46
|
+
when Class
|
47
|
+
return [command, []] if name_with_arg.is_a?(name)
|
48
|
+
when String
|
49
|
+
return [command, name_with_arg.gsub(name, '').split('__')] if name_with_arg.start_with?(name)
|
50
|
+
when Regexp
|
51
|
+
next unless name_with_arg.match?(name)
|
52
|
+
|
53
|
+
storable_command = command.dup
|
54
|
+
storable_command.name = name_with_arg
|
55
|
+
return [storable_command, [name_with_arg]]
|
56
|
+
end
|
33
57
|
end
|
34
58
|
nil
|
35
59
|
end
|
36
60
|
|
37
61
|
def load_state(channel)
|
38
|
-
data = factory.get(channel)
|
39
|
-
CommandState.new(data,
|
62
|
+
data = factory.get(channel.to_s)
|
63
|
+
CommandState.new(data, command(data[:cmd]))
|
40
64
|
rescue Kybus::Storage::Exceptions::ObjectNotFound
|
41
|
-
CommandState.new(factory.create(channel_id: channel, params: '{}'), nil)
|
65
|
+
CommandState.new(factory.create(channel_id: channel.to_s, params: '{}'), nil)
|
42
66
|
end
|
43
67
|
end
|
44
68
|
end
|
@@ -17,8 +17,9 @@ module Kybus
|
|
17
17
|
|
18
18
|
def call!(context)
|
19
19
|
context.state = state
|
20
|
-
context.instance_eval(&block)
|
20
|
+
statement = context.instance_eval(&block)
|
21
21
|
clear_command
|
22
|
+
statement
|
22
23
|
end
|
23
24
|
|
24
25
|
def initialize(channel_id, channel_factory)
|
@@ -35,6 +36,10 @@ module Kybus
|
|
35
36
|
state.store_param(param.to_sym, value)
|
36
37
|
end
|
37
38
|
|
39
|
+
def expecting_command?
|
40
|
+
state.command.nil?
|
41
|
+
end
|
42
|
+
|
38
43
|
def add_file(file)
|
39
44
|
param = state.requested_param
|
40
45
|
return unless param
|
@@ -22,7 +22,7 @@ module Kybus
|
|
22
22
|
def initialize(bot, channel_factory, inline_args)
|
23
23
|
@bot = bot
|
24
24
|
@channel_factory = channel_factory
|
25
|
-
@dsl = DSLMethods.new(bot.provider, state)
|
25
|
+
@dsl = DSLMethods.new(bot.provider, state, bot)
|
26
26
|
@inline_args = inline_args
|
27
27
|
@precommand_hook = proc {}
|
28
28
|
end
|
@@ -32,8 +32,9 @@ module Kybus
|
|
32
32
|
def process_message(message)
|
33
33
|
@execution_context = ExecutionContest.new(message.channel_id, @channel_factory)
|
34
34
|
save_token!(message)
|
35
|
-
run_command_or_prepare!
|
35
|
+
msg = run_command_or_prepare!
|
36
36
|
save_execution_context!
|
37
|
+
msg
|
37
38
|
end
|
38
39
|
|
39
40
|
def save_param!(message)
|
@@ -45,18 +46,20 @@ module Kybus
|
|
45
46
|
end
|
46
47
|
|
47
48
|
def search_command_with_inline_arg(message)
|
48
|
-
command,
|
49
|
+
command, values = @channel_factory.command_with_inline_arg(message.raw_message)
|
49
50
|
if command
|
50
51
|
execution_context.command = command
|
51
|
-
|
52
|
-
|
52
|
+
values.each do |value|
|
53
|
+
execution_context.next_param = execution_context.next_missing_param
|
54
|
+
execution_context.add_param(value)
|
55
|
+
end
|
53
56
|
else
|
54
57
|
execution_context.command = @channel_factory.default_command
|
55
58
|
end
|
56
59
|
end
|
57
60
|
|
58
61
|
def save_token!(message)
|
59
|
-
if
|
62
|
+
if execution_context.expecting_command?
|
60
63
|
command = @channel_factory.command(message.command)
|
61
64
|
if @inline_args && !command
|
62
65
|
search_command_with_inline_arg(message)
|
@@ -74,9 +77,12 @@ module Kybus
|
|
74
77
|
if execution_context.ready?
|
75
78
|
@dsl.state = execution_context.state
|
76
79
|
@dsl.instance_eval(&@precommand_hook)
|
77
|
-
run_command!
|
80
|
+
msg = run_command!
|
81
|
+
execution_context.clear_command
|
82
|
+
msg
|
78
83
|
else
|
79
|
-
|
84
|
+
param = execution_context.next_missing_param
|
85
|
+
ask_param(param, execution_context.state.command.params_ask_label(param))
|
80
86
|
end
|
81
87
|
end
|
82
88
|
|
@@ -85,7 +91,7 @@ module Kybus
|
|
85
91
|
end
|
86
92
|
|
87
93
|
def fallback(error)
|
88
|
-
catch = @channel_factory.command(error
|
94
|
+
catch = @channel_factory.command(error)
|
89
95
|
log_error('Unexpected error', error)
|
90
96
|
execution_context.command = catch if catch
|
91
97
|
end
|
@@ -96,15 +102,28 @@ module Kybus
|
|
96
102
|
rescue StandardError => e
|
97
103
|
raise unless fallback(e)
|
98
104
|
|
105
|
+
execution_context.state.store_param(:_last_exception, e)
|
99
106
|
retry
|
100
107
|
end
|
101
108
|
|
109
|
+
def invoke(command_name, args)
|
110
|
+
command = @channel_factory.command(command_name)
|
111
|
+
if command.nil? || command.params_size != args.size
|
112
|
+
raise "Wrong redirect #{command_name}, #{bot.registered_commands}"
|
113
|
+
end
|
114
|
+
|
115
|
+
state.command = command
|
116
|
+
command.params.zip(args).each do |param, value|
|
117
|
+
state.store_param(param, value)
|
118
|
+
end
|
119
|
+
run_command_or_prepare!
|
120
|
+
end
|
121
|
+
|
102
122
|
# Sends a message to get the next parameter from the user
|
103
|
-
def ask_param(param)
|
123
|
+
def ask_param(param, label = nil)
|
104
124
|
provider = bot.provider
|
105
|
-
msg = "I need you to tell me #{param}"
|
106
|
-
|
107
|
-
provider.send_message(provider.last_message.channel_id, msg)
|
125
|
+
msg = label || "I need you to tell me #{param}"
|
126
|
+
bot.send_message(msg, provider.last_message.channel_id)
|
108
127
|
execution_context.next_param = param
|
109
128
|
end
|
110
129
|
end
|
@@ -6,15 +6,16 @@ module Kybus
|
|
6
6
|
attr_accessor :state
|
7
7
|
attr_reader :provider
|
8
8
|
|
9
|
-
def initialize(provider, state)
|
9
|
+
def initialize(provider, state, bot)
|
10
10
|
@provider = provider
|
11
11
|
@state = state
|
12
|
+
@bot = bot
|
12
13
|
end
|
13
14
|
|
14
15
|
def send_message(content, channel = nil)
|
15
16
|
raise(Base::EmptyMessageError) unless content
|
16
17
|
|
17
|
-
|
18
|
+
@bot.send_message(content, channel || current_channel)
|
18
19
|
end
|
19
20
|
|
20
21
|
def send_image(content, channel = nil, caption: nil)
|
@@ -65,6 +66,14 @@ module Kybus
|
|
65
66
|
def current_channel
|
66
67
|
state.channel_id
|
67
68
|
end
|
69
|
+
|
70
|
+
def command_name
|
71
|
+
state&.command&.name
|
72
|
+
end
|
73
|
+
|
74
|
+
def method_missing(method, *args, &block)
|
75
|
+
@bot.send(method, *args, &block)
|
76
|
+
end
|
68
77
|
end
|
69
78
|
end
|
70
79
|
end
|
data/lib/kybus/bot/test.rb
CHANGED
@@ -21,12 +21,17 @@ module Kybus
|
|
21
21
|
}.freeze
|
22
22
|
|
23
23
|
def self.make_test_bot(extra_configs = {})
|
24
|
-
|
24
|
+
conf = CONFIG.merge(extra_configs)
|
25
|
+
conf['provider']['channels'] = { conf['channel_id'] => [] } if conf['channel_id']
|
26
|
+
bot = new(conf)
|
27
|
+
bot.instance_variable_set(:@default_channel_id, conf['provider']['channels'].keys.first)
|
28
|
+
bot
|
25
29
|
end
|
26
30
|
|
27
31
|
def receives(msg, attachments = nil)
|
28
32
|
attachments = Adapter::DebugMessage::DebugFile.new(attachments) if attachments
|
29
|
-
msg = Adapter::DebugMessage.new(msg,
|
33
|
+
msg = Adapter::DebugMessage.new(msg, @default_channel_id, attachments)
|
34
|
+
log_info('Received message', channel: @default_channel_id, msg:)
|
30
35
|
provider.last_message = msg
|
31
36
|
executor.process_message(msg)
|
32
37
|
end
|
data/lib/kybus/bot/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kybus-bot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gilberto Vargas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kybus-core
|
@@ -253,7 +253,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
253
253
|
- !ruby/object:Gem::Version
|
254
254
|
version: '0'
|
255
255
|
requirements: []
|
256
|
-
rubygems_version: 3.
|
256
|
+
rubygems_version: 3.4.10
|
257
257
|
signing_key:
|
258
258
|
specification_version: 4
|
259
259
|
summary: Provides a framework for building bots with ruby
|