kybus-bot 0.7.0 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5c13b85c7bdfcde5cf2aabfa9c07e78a59da781c06d86ca91842605e3467b61
4
- data.tar.gz: ef7f22cea28720b25bbbee6930b397b28eb5890e1e470bb66155c691050ed101
3
+ metadata.gz: c7c076fdf29d45a346d07aa5639349a66cff1a83ed15f0cfbafc4e6d4698cbd9
4
+ data.tar.gz: 0fa6891cd37efd3a37b87b59e3dc90fd1628384c43863237e70ea6f757f2086a
5
5
  SHA512:
6
- metadata.gz: c01b8aadc1b567f9181ad731baa7861882ec535482c79c51eb45fee0257ab443ee9fc8857e133eab1b4dd814b725b4170fff2513484a1759f08ed1add74741ad
7
- data.tar.gz: e80319c534274c58df1cf58e8794a56c44100ac46c0483e0d7b9a193e612944efbf610dc3b6da24f91648ad764fa45fb8e7503f4a0774c5b1c541e8c41be3b6b
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
- msg = @channels.values.find(&:open?)
148
- return @last_message = msg.read_message if msg
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(channel_name, contents, attachment = nil)
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, caption = nil)
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, caption = nil)
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, caption = nil)
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(channel_name, contents)
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[:error_code] == '403'
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
@@ -43,6 +43,10 @@ module Kybus
43
43
  meta.dig('result', 'file_name')
44
44
  end
45
45
 
46
+ def file_name
47
+ original_name
48
+ end
49
+
46
50
  def download
47
51
  token = cli.api.token
48
52
  file_path = meta.dig('result', 'file_path')
@@ -17,7 +17,7 @@ module Kybus
17
17
  end
18
18
 
19
19
  def reply?
20
- !!@message.reply_to_message
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 || @message.photo&.last || @message.audio
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
@@ -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
- attr_reader :block, :params, :name
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, params, &block)
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.ready?(params)
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(name)
18
- @definitions[name]
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
- next unless name.is_a?(String)
32
- return [command, name_with_arg.gsub(name, '')] if name_with_arg.start_with?(name)
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, command_or_default(data[:cmd]))
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, value = @channel_factory.command_with_inline_arg(message.raw_message)
49
+ command, values = @channel_factory.command_with_inline_arg(message.raw_message)
49
50
  if command
50
51
  execution_context.command = command
51
- execution_context.next_param = execution_context.next_missing_param
52
- execution_context.add_param(value)
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 message.command?
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
- ask_param(execution_context.next_missing_param)
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.class)
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
- log_debug(msg)
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
- provider.send_message(channel || current_channel, content)
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
@@ -21,12 +21,17 @@ module Kybus
21
21
  }.freeze
22
22
 
23
23
  def self.make_test_bot(extra_configs = {})
24
- new(CONFIG.merge(extra_configs))
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, 'testing', attachments)
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Kybus
4
4
  module Bot
5
- VERSION = '0.7.0'
5
+ VERSION = '0.8.2'
6
6
  end
7
7
  end
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.7.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: 2022-11-17 00:00:00.000000000 Z
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.3.7
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