bot_mob 0.2.2 → 0.3.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.env +1 -0
  3. data/.gitignore +0 -1
  4. data/.rubocop.yml +16 -0
  5. data/.travis.yml +1 -1
  6. data/Gemfile +0 -2
  7. data/LICENSE.txt +21 -0
  8. data/README.md +5 -4
  9. data/bin/console +8 -4
  10. data/bin/mob +4 -0
  11. data/bot_mob.gemspec +8 -14
  12. data/examples/fizz_buzz_bot.rb +30 -0
  13. data/examples/hello_bot.rb +14 -0
  14. data/examples/server.rb +7 -0
  15. data/lib/bot_mob.rb +46 -32
  16. data/lib/bot_mob/bot.rb +146 -29
  17. data/lib/bot_mob/command.rb +38 -0
  18. data/lib/bot_mob/connection.rb +18 -50
  19. data/lib/bot_mob/core_ext/hash.rb +148 -0
  20. data/lib/bot_mob/core_ext/string.rb +8 -0
  21. data/lib/bot_mob/environment.rb +25 -0
  22. data/lib/bot_mob/inbound_message.rb +13 -32
  23. data/lib/bot_mob/networks/roaming.rb +12 -0
  24. data/lib/bot_mob/networks/roaming/connection.rb +34 -0
  25. data/lib/bot_mob/networks/roaming/outbound_message.rb +15 -0
  26. data/lib/bot_mob/networks/slack.rb +11 -0
  27. data/lib/bot_mob/networks/slack/connection.rb +37 -0
  28. data/lib/bot_mob/networks/slack/outbound_message.rb +18 -0
  29. data/lib/bot_mob/outbound_message.rb +23 -10
  30. data/lib/bot_mob/public/console.js +10 -0
  31. data/lib/bot_mob/roster.rb +8 -80
  32. data/lib/bot_mob/server.rb +47 -0
  33. data/lib/bot_mob/version.rb +1 -1
  34. data/lib/bot_mob/views/authorize.erb +1 -0
  35. data/lib/bot_mob/views/console.erb +6 -0
  36. data/lib/bot_mob/views/index.erb +1 -0
  37. data/lib/bot_mob/views/layout.erb +11 -0
  38. metadata +50 -110
  39. data/lib/bot_mob/ambassador.rb +0 -34
  40. data/lib/bot_mob/application.rb +0 -43
  41. data/lib/bot_mob/authority.rb +0 -41
  42. data/lib/bot_mob/development/ambassador.rb +0 -21
  43. data/lib/bot_mob/development/connection.rb +0 -34
  44. data/lib/bot_mob/development/inbound_message.rb +0 -17
  45. data/lib/bot_mob/errors.rb +0 -12
  46. data/lib/bot_mob/install.rb +0 -16
  47. data/lib/bot_mob/nil_connection.rb +0 -29
  48. data/lib/bot_mob/slack.rb +0 -10
  49. data/lib/bot_mob/slack/ambassador.rb +0 -58
  50. data/lib/bot_mob/slack/connection.rb +0 -87
  51. data/lib/bot_mob/slack/inbound_message.rb +0 -52
  52. data/lib/bot_mob/wire.rb +0 -69
@@ -0,0 +1,18 @@
1
+ module BotMob
2
+ module Networks
3
+ module Slack
4
+ # # BotMob::Networks::Slack::OutboundMessage
5
+ #
6
+ # Formatted message for delivery to slack
7
+ class OutboundMessage < BotMob::OutboundMessage
8
+ attr_reader :inbound, :channel
9
+
10
+ def initialize(**options)
11
+ @network = :slack
12
+ @channel = '#general'
13
+ super
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,19 +1,32 @@
1
1
  module BotMob
2
- # ## BotMob::Outbound Message
2
+ # # BotMob::OutboundMessage
3
3
  #
4
- # The OutboundMessage class provides a convenient
5
- # way to consistently allow your bot to respond
6
- # to a given network
4
+ # Strucutred data for all messages leaving your bot
7
5
  class OutboundMessage
8
- attr_reader :text, :channel_id
6
+ attr_reader :body, :network, :inbound
9
7
 
10
- def initialize(data)
11
- @text = data[:text]
12
- @channel_id = data[:channel_id]
8
+ def initialize(**options)
9
+ @network ||= options[:network]
10
+ @inbound = options[:inbound]
11
+ @body = options[:body]
13
12
  end
14
13
 
15
- def to_h
16
- { channel: channel_id, text: text }
14
+ def self.prepare(message, options = {})
15
+ return message if message.is_a?(BotMob::OutboundMessage)
16
+
17
+ target_network = options[:inbound].network
18
+ message_delegate(target_network).new(options.merge(body: message))
19
+ end
20
+
21
+ class << self
22
+ private
23
+
24
+ def message_delegate(network)
25
+ delegate = BotMob::Networks.const_get(network.to_s.camelize)
26
+ delegate.const_get('OutboundMessage')
27
+ rescue NameError
28
+ raise BotMob::InvalidNetworkError
29
+ end
17
30
  end
18
31
  end
19
32
  end
@@ -0,0 +1,10 @@
1
+ $(document).on('submit', '#chat-entry', function(e) {
2
+ e.preventDefault();
3
+ var field = $('#chat-field');
4
+
5
+ $.post('/message', {
6
+ text: field.val()
7
+ });
8
+
9
+ field.val('');
10
+ });
@@ -1,89 +1,17 @@
1
1
  module BotMob
2
+ # ## BotMob::Roster
3
+ #
4
+ # This manages the pool of bots made available
5
+ # by the application
2
6
  class Roster
3
- attr_reader :registry
7
+ attr_reader :bots
4
8
 
5
9
  def initialize
6
- @registry = {}
7
- @bots = {}
10
+ @bots = []
8
11
  end
9
12
 
10
- # `connect`
11
- #
12
- # `connect` receives an auth hash that contains a bot_class
13
- # along with any accompanying metadata that the bot will need
14
- # to connect to the specified network. Provided by BotMob::Authority
15
- # delivered over the wire.
16
- #
17
- # Example `auth` param:
18
- #
19
- # {
20
- # bot_class: 'FooBot',
21
- # network: 'slack',
22
- # external_id: 'USER1',
23
- # data: {
24
- # token: 'abc123'
25
- # }
26
- # }
27
- #
28
- def connect(auth)
29
- # { network: :dev, external_id: 'foo', bot_class: 'FooBot', data: {} }
30
- class_name = auth['bot_class'].to_s
31
- bot_class = registry[class_name]
32
- raise BotMob::UnregisteredBotError, 'You must explicitly register your bot class with the roster before connecting that bot type' if bot_class.nil?
33
- BotMob.logger.info "Selecting #{class_name.inspect} from registry: #{bot_class.inspect}"
34
-
35
- unless auth.is_a?(BotMob::Install)
36
- begin
37
- BotMob.logger.info "Updating #{class_name} database record for #{auth['external_id']}..."
38
- BotMob::Install.create_with_auth(auth)
39
- rescue ActiveRecord::StatementInvalid => e
40
- BotMob.logger.info "Unable to save record: #{e.message}"
41
- end
42
- end
43
-
44
- network = auth['network']
45
- allocate(bot_class, network, auth)
46
- end
47
-
48
- def load
49
- begin
50
- BotMob::Install.all.each do |install|
51
- connect(install)
52
- end
53
-
54
- BotMob.logger.info '=> Roster loaded'
55
- @available = true
56
- rescue ActiveRecord::ConnectionNotEstablished => e
57
- @available = false
58
- BotMob.logger.info "=> Database unavailable, skipping roster load"
59
- end
60
- end
61
-
62
- def [](key)
63
- registry[key.to_s]
64
- end
65
-
66
- def register(bot_class)
67
- @registry[bot_class.to_s] = bot_class
68
- end
69
-
70
- private
71
-
72
- def available?
73
- @available.nil? || @available
74
- end
75
-
76
- def allocate(bot_class, network, auth)
77
- key = "#{bot_class}##{auth['network']}.#{auth['external_id']}"
78
-
79
- if @bots[key]
80
- BotMob.logger.info "Using existing #{key} bot"
81
- else
82
- BotMob.logger.info "Setting up a new #{bot_class} bot: #{key}"
83
- @bots[key] = bot_class.new(auth['network'].to_sym, auth['external_id'], auth['data'] || {})
84
- end
85
-
86
- @bots[key].refresh
13
+ def register(bot, **_options)
14
+ @bots << (bot.is_a?(Class) ? bot.new : bot)
87
15
  end
88
16
  end
89
17
  end
@@ -0,0 +1,47 @@
1
+ require 'sinatra/base'
2
+
3
+ module BotMob
4
+ # # BotMob::Server
5
+ #
6
+ # Basic server for external access to
7
+ # connected bots.
8
+ class Server < Sinatra::Base
9
+ def self.run!(**options)
10
+ set :roster, options[:roster] || BotMob::Roster.new
11
+ super
12
+ end
13
+
14
+ get '/' do
15
+ erb :index
16
+ end
17
+
18
+ get '/console' do
19
+ erb :console
20
+ end
21
+
22
+ get '/authorize' do
23
+ erb :authorize
24
+ end
25
+
26
+ get '/message' do
27
+ results = []
28
+ settings.roster.bots.map do |bot|
29
+ result = bot.receive(params[:text], network: params[:network])
30
+ results << result.body unless result.nil?
31
+ end
32
+
33
+ results.join(', ')
34
+ end
35
+
36
+ get '/command/:method' do
37
+ results = []
38
+ settings.roster.bots.map do |bot|
39
+ method_name = params[:method].to_sym
40
+ result = bot.receive_command(method_name)
41
+ results << result unless result.nil?
42
+ end
43
+
44
+ results.join(', ')
45
+ end
46
+ end
47
+ end
@@ -1,3 +1,3 @@
1
1
  module BotMob
2
- VERSION = '0.2.2'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
@@ -0,0 +1 @@
1
+ <div>Authorize</div>
@@ -0,0 +1,6 @@
1
+ <div id="chat-window"></div>
2
+
3
+ <form id="chat-entry" action="/message">
4
+ <input type="text" id="chat-field" placeholder="Message..." value="asdf" />
5
+ <input type="submit" />
6
+ </form>
@@ -0,0 +1 @@
1
+ Homepage
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Hi</title>
5
+ </head>
6
+ <body>
7
+ Layout
8
+ <%= yield %>
9
+ <script type="text/javascript" src="./console.js"></script>
10
+ </body>
11
+ </html>
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bot_mob
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Werner
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-08-31 00:00:00.000000000 Z
11
+ date: 2016-12-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bunny
14
+ name: sinatra
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.5'
19
+ version: '1.4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.5'
26
+ version: '1.4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: slack-ruby-client
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,48 +38,6 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.7'
41
- - !ruby/object:Gem::Dependency
42
- name: celluloid-io
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '0.17'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '0.17'
55
- - !ruby/object:Gem::Dependency
56
- name: activerecord
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '4.1'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '4.1'
69
- - !ruby/object:Gem::Dependency
70
- name: dotenv
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
41
  - !ruby/object:Gem::Dependency
84
42
  name: bundler
85
43
  requirement: !ruby/object:Gem::Requirement
@@ -109,143 +67,125 @@ dependencies:
109
67
  - !ruby/object:Gem::Version
110
68
  version: '10.0'
111
69
  - !ruby/object:Gem::Dependency
112
- name: rubocop
70
+ name: rspec
113
71
  requirement: !ruby/object:Gem::Requirement
114
72
  requirements:
115
73
  - - "~>"
116
74
  - !ruby/object:Gem::Version
117
- version: '0.40'
75
+ version: '3.0'
118
76
  type: :development
119
77
  prerelease: false
120
78
  version_requirements: !ruby/object:Gem::Requirement
121
79
  requirements:
122
80
  - - "~>"
123
81
  - !ruby/object:Gem::Version
124
- version: '0.40'
125
- - !ruby/object:Gem::Dependency
126
- name: rubocop-rspec
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
82
+ version: '3.0'
139
83
  - !ruby/object:Gem::Dependency
140
- name: simplecov
84
+ name: dotenv
141
85
  requirement: !ruby/object:Gem::Requirement
142
86
  requirements:
143
87
  - - "~>"
144
88
  - !ruby/object:Gem::Version
145
- version: '0.12'
89
+ version: '2.1'
146
90
  type: :development
147
91
  prerelease: false
148
92
  version_requirements: !ruby/object:Gem::Requirement
149
93
  requirements:
150
94
  - - "~>"
151
95
  - !ruby/object:Gem::Version
152
- version: '0.12'
96
+ version: '2.1'
153
97
  - !ruby/object:Gem::Dependency
154
- name: rspec
98
+ name: rubocop
155
99
  requirement: !ruby/object:Gem::Requirement
156
100
  requirements:
157
101
  - - "~>"
158
102
  - !ruby/object:Gem::Version
159
- version: '3.0'
103
+ version: '0.45'
160
104
  type: :development
161
105
  prerelease: false
162
106
  version_requirements: !ruby/object:Gem::Requirement
163
107
  requirements:
164
108
  - - "~>"
165
109
  - !ruby/object:Gem::Version
166
- version: '3.0'
110
+ version: '0.45'
167
111
  - !ruby/object:Gem::Dependency
168
- name: rack-test
112
+ name: simplecov
169
113
  requirement: !ruby/object:Gem::Requirement
170
114
  requirements:
171
- - - ">="
115
+ - - "~>"
172
116
  - !ruby/object:Gem::Version
173
- version: '0'
117
+ version: '0.12'
174
118
  type: :development
175
119
  prerelease: false
176
120
  version_requirements: !ruby/object:Gem::Requirement
177
121
  requirements:
178
- - - ">="
122
+ - - "~>"
179
123
  - !ruby/object:Gem::Version
180
- version: '0'
124
+ version: '0.12'
181
125
  - !ruby/object:Gem::Dependency
182
126
  name: webmock
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - ">="
186
- - !ruby/object:Gem::Version
187
- version: '0'
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- version: '0'
195
- - !ruby/object:Gem::Dependency
196
- name: sqlite3
197
127
  requirement: !ruby/object:Gem::Requirement
198
128
  requirements:
199
129
  - - "~>"
200
130
  - !ruby/object:Gem::Version
201
- version: '1.3'
131
+ version: '1.22'
202
132
  type: :development
203
133
  prerelease: false
204
134
  version_requirements: !ruby/object:Gem::Requirement
205
135
  requirements:
206
136
  - - "~>"
207
137
  - !ruby/object:Gem::Version
208
- version: '1.3'
209
- description: Easily create your own bot mob
138
+ version: '1.22'
139
+ description: Easily create and manage bots
210
140
  email:
211
141
  - m@mjw.io
212
142
  executables: []
213
143
  extensions: []
214
144
  extra_rdoc_files: []
215
145
  files:
146
+ - ".env"
216
147
  - ".env.test"
217
148
  - ".gitignore"
149
+ - ".rubocop.yml"
218
150
  - ".travis.yml"
219
151
  - CODE_OF_CONDUCT.md
220
152
  - Gemfile
153
+ - LICENSE.txt
221
154
  - README.md
222
155
  - Rakefile
223
156
  - bin/console
157
+ - bin/mob
224
158
  - bin/setup
225
159
  - bot_mob.gemspec
160
+ - examples/fizz_buzz_bot.rb
161
+ - examples/hello_bot.rb
162
+ - examples/server.rb
226
163
  - lib/bot_mob.rb
227
- - lib/bot_mob/ambassador.rb
228
- - lib/bot_mob/application.rb
229
- - lib/bot_mob/authority.rb
230
164
  - lib/bot_mob/bot.rb
165
+ - lib/bot_mob/command.rb
231
166
  - lib/bot_mob/connection.rb
232
- - lib/bot_mob/development/ambassador.rb
233
- - lib/bot_mob/development/connection.rb
234
- - lib/bot_mob/development/inbound_message.rb
235
- - lib/bot_mob/errors.rb
167
+ - lib/bot_mob/core_ext/hash.rb
168
+ - lib/bot_mob/core_ext/string.rb
169
+ - lib/bot_mob/environment.rb
236
170
  - lib/bot_mob/inbound_message.rb
237
- - lib/bot_mob/install.rb
238
- - lib/bot_mob/nil_connection.rb
171
+ - lib/bot_mob/networks/roaming.rb
172
+ - lib/bot_mob/networks/roaming/connection.rb
173
+ - lib/bot_mob/networks/roaming/outbound_message.rb
174
+ - lib/bot_mob/networks/slack.rb
175
+ - lib/bot_mob/networks/slack/connection.rb
176
+ - lib/bot_mob/networks/slack/outbound_message.rb
239
177
  - lib/bot_mob/outbound_message.rb
178
+ - lib/bot_mob/public/console.js
240
179
  - lib/bot_mob/roster.rb
241
- - lib/bot_mob/slack.rb
242
- - lib/bot_mob/slack/ambassador.rb
243
- - lib/bot_mob/slack/connection.rb
244
- - lib/bot_mob/slack/inbound_message.rb
180
+ - lib/bot_mob/server.rb
245
181
  - lib/bot_mob/version.rb
246
- - lib/bot_mob/wire.rb
182
+ - lib/bot_mob/views/authorize.erb
183
+ - lib/bot_mob/views/console.erb
184
+ - lib/bot_mob/views/index.erb
185
+ - lib/bot_mob/views/layout.erb
247
186
  homepage: https://github.com/mwerner/bot_mob
248
- licenses: []
187
+ licenses:
188
+ - MIT
249
189
  metadata: {}
250
190
  post_install_message:
251
191
  rdoc_options: []
@@ -255,7 +195,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
255
195
  requirements:
256
196
  - - ">="
257
197
  - !ruby/object:Gem::Version
258
- version: '2.2'
198
+ version: '0'
259
199
  required_rubygems_version: !ruby/object:Gem::Requirement
260
200
  requirements:
261
201
  - - ">="
@@ -263,8 +203,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
263
203
  version: '0'
264
204
  requirements: []
265
205
  rubyforge_project:
266
- rubygems_version: 2.4.8
206
+ rubygems_version: 2.4.5.1
267
207
  signing_key:
268
208
  specification_version: 4
269
- summary: Build your bots
209
+ summary: The bot mob framework
270
210
  test_files: []