slack-ruby-bot 0.10.2 → 0.10.3
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/CHANGELOG.md +5 -0
- data/README.md +26 -22
- data/RELEASING.md +1 -0
- data/lib/slack-ruby-bot/mvc/controller/base.rb +65 -9
- data/lib/slack-ruby-bot/version.rb +1 -1
- data/spec/slack-ruby-bot/mvc/controller/controller_to_command_spec.rb +53 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88982b31e113e853ff4c707a7718f0739ccf260e
|
4
|
+
data.tar.gz: 9f818712b6659e1281a89b0a144b922f9b66e61d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 537ee07e13e6500c453b71cbfffa1b9eeda032baaf86319af4c298a6e65b3adc51de771694e6cc5107e4858d3344633bfaca7b70f23025afc6c5a1eb8bb23580
|
7
|
+
data.tar.gz: 6e2f758c616871af780b376613ef9eac7c0bfe6438f65e5950b035e4e450da31d207674b558b9e3726ca3287f0e468adda333988fa3c2a53b7fe0ac50757b660
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
### 0.10.3 (06/15/2017)
|
2
|
+
|
3
|
+
* [#145](https://github.com/slack-ruby/slack-ruby-bot/pull/145): Map multiple command strings to same controller method - [@chuckremes](https://github.com/chuckremes).
|
4
|
+
* [#144](https://github.com/slack-ruby/slack-ruby-bot/pull/144): Support usage of commands with embedded spaces when using Controller methods - [@chuckremes](https://github.com/chuckremes).
|
5
|
+
|
1
6
|
### 0.10.2 (06/03/2017)
|
2
7
|
|
3
8
|
* [#137](https://github.com/slack-ruby/slack-ruby-bot/pull/137): Add Model-View-Controller classes to allow for more explicit control over how `command`s are designed - [@chuckremes](https://github.com/chuckremes).
|
data/README.md
CHANGED
@@ -364,10 +364,11 @@ Consider the following `Agent` class which is the simplest default approach to t
|
|
364
364
|
|
365
365
|
```ruby
|
366
366
|
class Agent < SlackRubyBot::Bot
|
367
|
-
command 'sayhello' do |client, data, match|
|
367
|
+
command 'sayhello', 'alternate way to call hello' do |client, data, match|
|
368
368
|
client.say(channel: data.channel, text: "Received command #{match[:command]} with args #{match[:expression]}")
|
369
369
|
end
|
370
370
|
end
|
371
|
+
```
|
371
372
|
|
372
373
|
Using the MVC functionality, we would create a controller instead to encapsulate this function.
|
373
374
|
```ruby
|
@@ -375,6 +376,7 @@ class MyController < SlackRubyBot::MVC::Controller::Base
|
|
375
376
|
def sayhello
|
376
377
|
client.say(channel: data.channel, text: "Received command #{match[:command]} with args #{match[:expression]}")
|
377
378
|
end
|
379
|
+
alternate_name :sayhello, :alternate_way_to_call_hello
|
378
380
|
end
|
379
381
|
MyController.new(MyModel.new, MyView.new)
|
380
382
|
```
|
@@ -384,6 +386,8 @@ However, the Controller anticipates that the model and view objects should conta
|
|
384
386
|
|
385
387
|
A Controller may need helper methods for certain work. To prevent the helper method from creating a route that the bot will respond to directly, the instance method name should begin with an underscore (e.g. `_my_helper_method`). When building the bot routes, these methods will be skipped.
|
386
388
|
|
389
|
+
Calling `alternate_name` after the method definition allows for method aliases similar to the regular `command` structure. When commands can be triggered by multiple text strings it's useful to have that ability map to the controller methods too.
|
390
|
+
|
387
391
|
Lastly, the Controller class includes `ActiveSupport::Callbacks` which allows for full flexibility in creating `before`, `after`, and `around` hooks for all methods. Again, see the [inventory example](examples/inventory/inventorybot.rb) for more information.
|
388
392
|
|
389
393
|
#### Model
|
@@ -404,18 +408,18 @@ class MyModel < SlackRubyBot::MVC::Model::Base
|
|
404
408
|
|
405
409
|
def read(resource)
|
406
410
|
self._resource = resource
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
+
run_callbacks :sanitize do
|
412
|
+
@db.select(:column1 => resource)
|
413
|
+
# ... do some expensive work
|
414
|
+
end
|
411
415
|
end
|
412
416
|
|
413
417
|
private
|
414
418
|
|
415
419
|
def sanitize_resource
|
416
420
|
self._resource.downcase
|
417
|
-
|
418
|
-
|
421
|
+
result = yield
|
422
|
+
puts "After read, result is #{result.inspect}"
|
419
423
|
end
|
420
424
|
end
|
421
425
|
```
|
@@ -435,37 +439,37 @@ class MyView < SlackRubyBot::MVC::View::Base
|
|
435
439
|
|
436
440
|
def initialize
|
437
441
|
@mailer = setup_mailer
|
438
|
-
|
442
|
+
@ftp = setup_ftp_handler
|
439
443
|
end
|
440
444
|
|
441
445
|
def email_admin(message)
|
442
446
|
run_callbacks :logit do
|
443
|
-
|
444
|
-
|
447
|
+
@mailer.send(:administrator, message)
|
448
|
+
end
|
445
449
|
end
|
446
450
|
|
447
451
|
def react_thumbsup
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
452
|
+
client.web_client.reactions_add(
|
453
|
+
name: :thumbs_up,
|
454
|
+
channel: data.channel,
|
455
|
+
timestamp: data.ts,
|
456
|
+
as_user: true)
|
453
457
|
end
|
454
458
|
|
455
459
|
def react_thumbsdown
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
460
|
+
client.web_client.reactions_remove(
|
461
|
+
name: :thumbs_up,
|
462
|
+
channel: data.channel,
|
463
|
+
timestamp: data.ts,
|
464
|
+
as_user: true)
|
461
465
|
end
|
462
466
|
|
463
467
|
private
|
464
468
|
|
465
469
|
def audit_trail
|
466
470
|
Logger.audit("Sending email at [#{Time.now}]")
|
467
|
-
|
468
|
-
|
471
|
+
yield
|
472
|
+
Logger.audit("Email sent by [#{Time.now}]")
|
469
473
|
end
|
470
474
|
end
|
471
475
|
```
|
data/RELEASING.md
CHANGED
@@ -16,6 +16,10 @@ module SlackRubyBot
|
|
16
16
|
Base.instance_variable_get(:@command_class)
|
17
17
|
end
|
18
18
|
|
19
|
+
def aliases
|
20
|
+
Base.instance_variable_get(:@aliases)
|
21
|
+
end
|
22
|
+
|
19
23
|
def reset!
|
20
24
|
# Remove any earlier anonymous classes from prior calls so we don't leak them
|
21
25
|
Commands::Base.command_classes.delete(Controller::Base.command_class) if Base.command_class
|
@@ -43,6 +47,7 @@ module SlackRubyBot
|
|
43
47
|
def register_controller(controller)
|
44
48
|
# Only used to keep a reference around so the instance object doesn't get garbage collected
|
45
49
|
Base.instance_variable_set(:@controllers, []) unless controllers
|
50
|
+
Base.instance_variable_set(:@aliases, Hash.new { |h, k| h[k] = [] }) unless aliases
|
46
51
|
controller_ary = Base.instance_variable_get(:@controllers)
|
47
52
|
controller_ary << controller
|
48
53
|
klass = controller.class
|
@@ -53,14 +58,18 @@ module SlackRubyBot
|
|
53
58
|
# Be sure to include shadowed public instance methods of this class
|
54
59
|
klass.public_instance_methods(false)).uniq.map(&:to_s)
|
55
60
|
|
56
|
-
methods.each do |
|
57
|
-
next if
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
61
|
+
methods.each do |name|
|
62
|
+
next if name[0] == '_'
|
63
|
+
commands = lookup_command_name(name)
|
64
|
+
|
65
|
+
# Generates a command for each controller method *and* its aliases
|
66
|
+
commands.each do |command_string|
|
67
|
+
# sprinkle a little syntactic sugar on top of existing `command` infrastructure
|
68
|
+
command_class.class_eval do
|
69
|
+
command command_string do |client, data, match|
|
70
|
+
controller.use_args(client, data, match)
|
71
|
+
controller.call_command
|
72
|
+
end
|
64
73
|
end
|
65
74
|
end
|
66
75
|
end
|
@@ -76,6 +85,47 @@ module SlackRubyBot
|
|
76
85
|
controller = controller.superclass until controller.abstract?
|
77
86
|
controller.public_instance_methods(true)
|
78
87
|
end
|
88
|
+
|
89
|
+
# Maps a controller method name to an alternate command name. Used in cases where
|
90
|
+
# a command can be called via multiple text strings.
|
91
|
+
#
|
92
|
+
# Call this method *after* defining the original method.
|
93
|
+
#
|
94
|
+
# Class.new(SlackRubyBot::MVC::Controller::Base) do
|
95
|
+
# def quxo_foo_bar
|
96
|
+
# client.say(channel: data.channel, text: "quxo foo bar: #{match[:expression]}")
|
97
|
+
# end
|
98
|
+
# # setup alias name after original method definition
|
99
|
+
# alternate_name :quxo_foo_bar, :another_text_string
|
100
|
+
# end
|
101
|
+
#
|
102
|
+
# This is equivalent to:
|
103
|
+
#
|
104
|
+
# e.g.
|
105
|
+
# command 'quxo foo bar', 'another text string' do |*args|
|
106
|
+
# ..
|
107
|
+
# end
|
108
|
+
def alternate_name(original_name, *alias_names)
|
109
|
+
command_name = convert_method_name_to_command_string(original_name)
|
110
|
+
command_aliases = alias_names.map do |name|
|
111
|
+
convert_method_name_to_command_string(name)
|
112
|
+
end
|
113
|
+
|
114
|
+
aliases[command_name] += command_aliases
|
115
|
+
|
116
|
+
alias_names.each { |alias_name| alias_method(alias_name, original_name) }
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def lookup_command_name(name)
|
122
|
+
name = convert_method_name_to_command_string(name)
|
123
|
+
[name] + aliases[name]
|
124
|
+
end
|
125
|
+
|
126
|
+
def convert_method_name_to_command_string(name)
|
127
|
+
name.to_s.tr('_', ' ')
|
128
|
+
end
|
79
129
|
end
|
80
130
|
|
81
131
|
abstract!
|
@@ -102,9 +152,15 @@ module SlackRubyBot
|
|
102
152
|
# Determine the command issued and call the corresponding instance method
|
103
153
|
def call_command
|
104
154
|
verb = match.captures[match.names.index('command')]
|
105
|
-
verb = verb
|
155
|
+
verb = normalize_command_string(verb)
|
106
156
|
public_send(verb)
|
107
157
|
end
|
158
|
+
|
159
|
+
private
|
160
|
+
|
161
|
+
def normalize_command_string(string)
|
162
|
+
string.downcase.tr(' ', '_')
|
163
|
+
end
|
108
164
|
end
|
109
165
|
end
|
110
166
|
end
|
@@ -95,3 +95,56 @@ describe SlackRubyBot::MVC::Controller::Base, 'execution' do
|
|
95
95
|
expect(instance.__flag).to be_truthy
|
96
96
|
end
|
97
97
|
end
|
98
|
+
|
99
|
+
describe SlackRubyBot::MVC::Controller::Base, 'command text conversion' do
|
100
|
+
let(:controller) do
|
101
|
+
Class.new(SlackRubyBot::MVC::Controller::Base) do
|
102
|
+
def quxo_foo_bar
|
103
|
+
client.say(channel: data.channel, text: "#{match[:command].downcase}: #{match[:expression]}")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
after(:each) { controller.reset! }
|
109
|
+
|
110
|
+
it 'converts a command with spaces into a controller method with underscores separating the tokens' do
|
111
|
+
model = SlackRubyBot::MVC::Model::Base.new
|
112
|
+
view = SlackRubyBot::MVC::View::Base.new
|
113
|
+
controller.new(model, view)
|
114
|
+
expect(message: " #{SlackRubyBot.config.user} quxo foo bar red").to respond_with_slack_message('quxo foo bar: red')
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'converts a command with upper case letters into a lower case method call' do
|
118
|
+
model = SlackRubyBot::MVC::Model::Base.new
|
119
|
+
view = SlackRubyBot::MVC::View::Base.new
|
120
|
+
controller.new(model, view)
|
121
|
+
expect(message: " #{SlackRubyBot.config.user} Quxo Foo Bar red").to respond_with_slack_message('quxo foo bar: red')
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe SlackRubyBot::MVC::Controller::Base, 'alternate command text conversion' do
|
126
|
+
let(:controller) do
|
127
|
+
Class.new(SlackRubyBot::MVC::Controller::Base) do
|
128
|
+
def quxo_foo_bar
|
129
|
+
client.say(channel: data.channel, text: "quxo foo bar: #{match[:expression]}")
|
130
|
+
end
|
131
|
+
alternate_name :quxo_foo_bar, :another_text_string, :third_text_string
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
after(:each) { controller.reset! }
|
136
|
+
|
137
|
+
it 'aliases another valid command string to the controller method' do
|
138
|
+
model = SlackRubyBot::MVC::Model::Base.new
|
139
|
+
view = SlackRubyBot::MVC::View::Base.new
|
140
|
+
controller.new(model, view)
|
141
|
+
expect(message: " #{SlackRubyBot.config.user} another text string red").to respond_with_slack_message('quxo foo bar: red')
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'allows for aliasing multiple names in a single call' do
|
145
|
+
model = SlackRubyBot::MVC::Model::Base.new
|
146
|
+
view = SlackRubyBot::MVC::View::Base.new
|
147
|
+
controller.new(model, view)
|
148
|
+
expect(message: " #{SlackRubyBot.config.user} third text string red").to respond_with_slack_message('quxo foo bar: red')
|
149
|
+
end
|
150
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slack-ruby-bot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Doubrovkine
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06-
|
11
|
+
date: 2017-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -266,7 +266,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
266
266
|
version: 1.3.6
|
267
267
|
requirements: []
|
268
268
|
rubyforge_project:
|
269
|
-
rubygems_version: 2.6.
|
269
|
+
rubygems_version: 2.6.8
|
270
270
|
signing_key:
|
271
271
|
specification_version: 4
|
272
272
|
summary: The easiest way to write a Slack bot in Ruby.
|