slack-ruby-bot 0.2.0 → 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.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +13 -4
- data/CHANGELOG.md +6 -0
- data/README.md +57 -3
- data/RELEASING.md +67 -0
- data/TUTORIAL.md +49 -2
- data/examples/minimal/pongbot.rb +1 -1
- data/examples/weather/Gemfile +3 -0
- data/examples/weather/weatherbot.rb +14 -0
- data/lib/slack-ruby-bot.rb +3 -2
- data/lib/slack-ruby-bot/app.rb +1 -1
- data/lib/slack-ruby-bot/commands/about.rb +2 -2
- data/lib/slack-ruby-bot/commands/base.rb +50 -19
- data/lib/slack-ruby-bot/commands/help.rb +1 -1
- data/lib/slack-ruby-bot/commands/hi.rb +1 -1
- data/lib/slack-ruby-bot/commands/unknown.rb +3 -1
- data/lib/slack-ruby-bot/hooks/message.rb +6 -80
- data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_error.rb +2 -3
- data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_slack_message.rb +1 -1
- data/lib/slack-ruby-bot/version.rb +1 -1
- data/screenshots/weather.gif +0 -0
- data/slack-ruby-bot.gemspec +1 -1
- data/spec/slack-ruby-bot/commands/commands_precedence_spec.rb +22 -0
- data/spec/slack-ruby-bot/commands/commands_spaces_spec.rb +20 -0
- data/spec/slack-ruby-bot/commands/commands_spec.rb +4 -4
- data/spec/slack-ruby-bot/commands/commands_with_block_spec.rb +23 -0
- data/spec/slack-ruby-bot/commands/empty_text_spec.rb +4 -4
- data/spec/slack-ruby-bot/commands/not_implemented_spec.rb +15 -0
- data/spec/slack-ruby-bot/commands/operators_spec.rb +3 -3
- data/spec/slack-ruby-bot/commands/operators_with_block_spec.rb +23 -0
- data/spec/slack-ruby-bot/rspec/respond_with_error_spec.rb +3 -3
- metadata +45 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e767ee739a4eb2e86b7b03affd315f7d20fdc866
|
4
|
+
data.tar.gz: 5123671ea14bf10c590955d6a2391b436d3578bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d13566b081e81835c685886917ba096bc0ec3c525287feab3ca50c6691f48139710ed4d0fb65c7e7369aee9a8608d83099f5e14b28c8a7d3fe5f85380beac3f4
|
7
|
+
data.tar.gz: 4b6ed30645c1a9cc2ffaecd1924db4fd71bf6d4c845bc716e6107e76876066964f1f711ed0fc380d546ae192ab4ca1ca080fb89b15d95a59b02274a65d4b2d9b
|
data/.rubocop_todo.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# This configuration was generated by `rubocop --auto-gen-config`
|
2
|
-
# on 2015-07-
|
2
|
+
# on 2015-07-19 12:16:52 -0400 using RuboCop version 0.32.1.
|
3
3
|
# The point is for the user to remove these configuration records
|
4
4
|
# one by one as the offenses are removed from the code base.
|
5
5
|
# Note that changes in the inspected code, or installation of new
|
@@ -10,18 +10,22 @@ Lint/HandleExceptions:
|
|
10
10
|
Enabled: false
|
11
11
|
|
12
12
|
# Offense count: 1
|
13
|
+
Lint/UselessAccessModifier:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
# Offense count: 2
|
13
17
|
Metrics/AbcSize:
|
14
18
|
Max: 21
|
15
19
|
|
16
|
-
# Offense count:
|
20
|
+
# Offense count: 37
|
17
21
|
# Configuration parameters: AllowURI, URISchemes.
|
18
22
|
Metrics/LineLength:
|
19
23
|
Max: 142
|
20
24
|
|
21
|
-
# Offense count:
|
25
|
+
# Offense count: 2
|
22
26
|
# Configuration parameters: CountComments.
|
23
27
|
Metrics/MethodLength:
|
24
|
-
Max:
|
28
|
+
Max: 18
|
25
29
|
|
26
30
|
# Offense count: 15
|
27
31
|
Style/Documentation:
|
@@ -32,6 +36,11 @@ Style/Documentation:
|
|
32
36
|
Style/FileName:
|
33
37
|
Enabled: false
|
34
38
|
|
39
|
+
# Offense count: 1
|
40
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
41
|
+
Style/MethodName:
|
42
|
+
Enabled: false
|
43
|
+
|
35
44
|
# Offense count: 1
|
36
45
|
Style/ModuleFunction:
|
37
46
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
### 0.3.0 (7/19/2015)
|
2
|
+
|
3
|
+
* [#5](https://github.com/dblock/slack-ruby-bot/issues/5): Added support for free-formed routes via `match` - [@dblock](https://github.com/dblock).
|
4
|
+
* [#6](https://github.com/dblock/slack-ruby-bot/issues/6): Commands and operators take blocks - [@dblock](https://github.com/dblock).
|
5
|
+
* [#4](https://github.com/dblock/slack-ruby-bot/issues/4): Messages are posted with `as_user: true` by default - [@dblock](https://github.com/dblock).
|
6
|
+
|
1
7
|
### 0.2.0 (7/10/2015)
|
2
8
|
|
3
9
|
* Sending `send_message` with nil or empty text will yield `Nothing to see here.` with a GIF instead of `no_text` - [@dblock](https://github.com/dblock).
|
data/README.md
CHANGED
@@ -28,7 +28,7 @@ module PongBot
|
|
28
28
|
end
|
29
29
|
|
30
30
|
class Ping < SlackRubyBot::Commands::Base
|
31
|
-
|
31
|
+
command 'ping' do |data, _match|
|
32
32
|
send_message data.channel, 'pong'
|
33
33
|
end
|
34
34
|
end
|
@@ -54,23 +54,69 @@ The following examples of production-grade bots based on slack-ruby-bot are list
|
|
54
54
|
|
55
55
|
### Commands and Operators
|
56
56
|
|
57
|
-
Bots are addressed by name and respond to commands and operators. By default a command class responds, case-insensitively, to its name. A class called `Phone` that inherits from `SlackRubyBot::Commands::Base` responds to `phone` and `Phone
|
57
|
+
Bots are addressed by name and respond to commands and operators. By default a command class responds, case-insensitively, to its name. A class called `Phone` that inherits from `SlackRubyBot::Commands::Base` responds to `phone` and `Phone` and calls the `call` method when implemented.
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
class Phone < SlackRubyBot::Commands::Base
|
61
|
+
command 'call'
|
62
|
+
|
63
|
+
def self.call(data, _match)
|
64
|
+
send_message data.channel, 'called'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
To respond to custom commands and to disable automatic class name matching, use the `command` keyword. The following command responds to `call` and `呼び出し` (call in Japanese).
|
58
70
|
|
59
71
|
```ruby
|
60
72
|
class Phone < SlackRubyBot::Commands::Base
|
61
73
|
command 'call'
|
62
74
|
command '呼び出し'
|
75
|
+
|
76
|
+
def self.call(data, _match)
|
77
|
+
send_message data.channel, 'called'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
You can combine multiple commands and use a block to implement them.
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
class Phone < SlackRubyBot::Commands::Base
|
86
|
+
command 'call', '呼び出し' do |data, _match|
|
87
|
+
send_message data.channel, 'called'
|
88
|
+
end
|
63
89
|
end
|
64
90
|
```
|
65
91
|
|
92
|
+
Command match data includes `match['bot']`, `match['command']` and `match['expression']`. The `bot` match always checks against the `SlackRubyBot::Config.user` setting.
|
93
|
+
|
66
94
|
Operators are 1-letter long and are similar to commands. They don't require addressing a bot nor separating an operator from its arguments. The following class responds to `=2+2`.
|
67
95
|
|
68
96
|
```ruby
|
69
97
|
class Calculator < SlackRubyBot::Commands::Base
|
70
|
-
operator '='
|
98
|
+
operator '=' do |_data, _match|
|
99
|
+
# implementation detail
|
100
|
+
end
|
101
|
+
end
|
102
|
+
```
|
103
|
+
|
104
|
+
Operator match data includes `match['operator']` and `match['expression']`. The `bot` match always checks against the `SlackRubyBot::Config.user` setting.
|
105
|
+
|
106
|
+
### Generic Routing
|
107
|
+
|
108
|
+
Commands and operators are generic versions of bot routes. You can respond to just about anything by defining a custom route.
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
class Weather < SlackRubyBot::Commands::Base
|
112
|
+
match /^How is the weather in (<?location>\w*)\?$/ do |data, match|
|
113
|
+
send_message data.channel, "The weather in #{match[:location]} is nice."
|
114
|
+
end
|
71
115
|
end
|
72
116
|
```
|
73
117
|
|
118
|
+

|
119
|
+
|
74
120
|
### Built-In Commands
|
75
121
|
|
76
122
|
Slack-ruby-bot comes with several built-in commands. You can re-define built-in commands, normally, as described above.
|
@@ -87,6 +133,14 @@ Politely says 'hi' back.
|
|
87
133
|
|
88
134
|
Get help.
|
89
135
|
|
136
|
+
### RSpec Shared Behaviors
|
137
|
+
|
138
|
+
Slack-ruby-bot ships with a number of shared RSpec behaviors that can be used in your RSpec tests. Require 'slack-ruby-bot/rspec' in your `spec_helper.rb`.
|
139
|
+
|
140
|
+
* [behaves like a slack bot](lib/slack-ruby-bot/rspec/support/slack-ruby-bot/it_behaves_like_a_slack_bot.rb): A bot quacks like a Slack Ruby bot.
|
141
|
+
* [respond with slack message](lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_slack_message.rb): The bot responds with a message.
|
142
|
+
* [respond with error](lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_error.rb): An exception is raised inside a bot command.
|
143
|
+
|
90
144
|
## Contributing
|
91
145
|
|
92
146
|
See [CONTRIBUTING](CONTRIBUTING.md).
|
data/RELEASING.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# Releasing Slack-Ruby-Bot
|
2
|
+
|
3
|
+
There're no particular rules about when to release slack-ruby-bot. Release bug fixes frequenty, features not so frequently and breaking API changes rarely.
|
4
|
+
|
5
|
+
### Release
|
6
|
+
|
7
|
+
Run tests, check that all tests succeed locally.
|
8
|
+
|
9
|
+
```
|
10
|
+
bundle install
|
11
|
+
rake
|
12
|
+
```
|
13
|
+
|
14
|
+
Check that the last build succeeded in [Travis CI](https://travis-ci.org/dblock/slack-ruby-bot) for all supported platforms.
|
15
|
+
|
16
|
+
Increment the version, modify [lib/slack-ruby-bot/version.rb](lib/slack-ruby-bot/version.rb).
|
17
|
+
|
18
|
+
* Increment the third number if the release has bug fixes and/or very minor features, only (eg. change `0.2.1` to `0.2.2`).
|
19
|
+
* Increment the second number if the release contains major features or breaking API changes (eg. change `0.2.1` to `0.3.0`).
|
20
|
+
|
21
|
+
Change "Next Release" in [CHANGELOG.md](CHANGELOG.md) to the new version.
|
22
|
+
|
23
|
+
```
|
24
|
+
### 0.2.2 (7/10/2015)
|
25
|
+
```
|
26
|
+
|
27
|
+
Remove the line with "Your contribution here.", since there will be no more contributions to this release.
|
28
|
+
|
29
|
+
Commit your changes.
|
30
|
+
|
31
|
+
```
|
32
|
+
git add CHANGELOG.md lib/slack-ruby-bot/version.rb
|
33
|
+
git commit -m "Preparing for release, 0.2.2."
|
34
|
+
git push origin master
|
35
|
+
```
|
36
|
+
|
37
|
+
Release.
|
38
|
+
|
39
|
+
```
|
40
|
+
$ rake release
|
41
|
+
|
42
|
+
slack-ruby-bot 0.2.2 built to pkg/slack-ruby-bot-0.2.2.gem.
|
43
|
+
Tagged v0.2.2.
|
44
|
+
Pushed git commits and tags.
|
45
|
+
Pushed slack-ruby-bot 0.2.2 to rubygems.org.
|
46
|
+
```
|
47
|
+
|
48
|
+
### Prepare for the Next Version
|
49
|
+
|
50
|
+
Add the next release to [CHANGELOG.md](CHANGELOG.md).
|
51
|
+
|
52
|
+
```
|
53
|
+
Next Release
|
54
|
+
============
|
55
|
+
|
56
|
+
* Your contribution here.
|
57
|
+
```
|
58
|
+
|
59
|
+
Increment the third version number in [lib/slack-ruby-bot/version.rb](lib/slack-ruby-bot/version.rb).
|
60
|
+
|
61
|
+
Comit your changes.
|
62
|
+
|
63
|
+
```
|
64
|
+
git add CHANGELOG.md lib/slack-ruby-bot/version.rb
|
65
|
+
git commit -m "Preparing for next development iteration, 0.2.3."
|
66
|
+
git push origin master
|
67
|
+
```
|
data/TUTORIAL.md
CHANGED
@@ -51,7 +51,7 @@ Create a folder called `slack-mathbot/commands` and inside of it create `calcula
|
|
51
51
|
module SlackMathbot
|
52
52
|
module Commands
|
53
53
|
class Calculate < SlackRubyBot::Commands::Base
|
54
|
-
|
54
|
+
command 'calculate' do |data, _match|
|
55
55
|
send_message data.channel, '4'
|
56
56
|
end
|
57
57
|
end
|
@@ -139,10 +139,57 @@ Run `foreman start`. Your bot should be running.
|
|
139
139
|
14:32:36 web.1 | I, [2015-07-10T14:32:36.766955 #98948] INFO -- : Successfully connected to https://xyz.slack.com/.
|
140
140
|
```
|
141
141
|
|
142
|
-
###
|
142
|
+
### Try
|
143
143
|
|
144
144
|
Invite the bot to a channel via `/invite [bot name]` and send it a `calculate` command with `[bot name] calculate 2+2`. It will respond with `4` from the code above.
|
145
145
|
|
146
|
+
### Write Tests
|
147
|
+
|
148
|
+
#### Spec Helper
|
149
|
+
|
150
|
+
Create `spec/spec_helper.rb` that includes the bot files and shared RSpec support from slack-ruby-bot.
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..'))
|
154
|
+
|
155
|
+
require 'slack-ruby-bot/rspec'
|
156
|
+
require 'slack-mathbot'
|
157
|
+
```
|
158
|
+
|
159
|
+
#### Test the Bot Application
|
160
|
+
|
161
|
+
Create a test for the bot application itself in `spec/slack-mathbot/app_spec.rb`.
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
require 'spec_helper'
|
165
|
+
|
166
|
+
describe SlackMathbot::App do
|
167
|
+
def app
|
168
|
+
SlackMathbot::App.new
|
169
|
+
end
|
170
|
+
it_behaves_like 'a slack ruby bot'
|
171
|
+
end
|
172
|
+
```
|
173
|
+
|
174
|
+
#### Test a Command
|
175
|
+
|
176
|
+
Create a test for the `calculate` command in `spec/slack-mathbot/commands/calculate_spec.rb`. The bot is addressed by its user name.
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
require 'spec_helper'
|
180
|
+
|
181
|
+
describe SlackMathbot::Commands::Calculate do
|
182
|
+
def app
|
183
|
+
SlackMathbot::App.new
|
184
|
+
end
|
185
|
+
it 'returns 4' do
|
186
|
+
expect(message: "#{SlackRubyBot.config.user} calculate 2+2", channel: 'channel').to respond_with_slack_message('4')
|
187
|
+
end
|
188
|
+
end
|
189
|
+
```
|
190
|
+
|
191
|
+
See [lib/slack-ruby-bot/rspec/support/slack-ruby-bot](lib/slack-ruby-bot/rspec/support/slack-ruby-bot) for other shared RSpec behaviors.
|
192
|
+
|
146
193
|
### Deploy
|
147
194
|
|
148
195
|
See [DEPLOYMENT](DEPLOYMENT.md) for how to deploy your bot to production.
|
data/examples/minimal/pongbot.rb
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'slack-ruby-bot'
|
2
|
+
|
3
|
+
module WeatherBot
|
4
|
+
class App < SlackRubyBot::App
|
5
|
+
end
|
6
|
+
|
7
|
+
class Weather < SlackRubyBot::Commands::Base
|
8
|
+
match(/^How is the weather in (?<location>\w*)\?$/i) do |data, match|
|
9
|
+
send_message data.channel, "The weather in #{match[:location]} is nice."
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
WeatherBot::App.instance.run
|
data/lib/slack-ruby-bot.rb
CHANGED
@@ -4,8 +4,6 @@ require 'slack-ruby-bot/version'
|
|
4
4
|
require 'slack-ruby-bot/about'
|
5
5
|
require 'slack-ruby-bot/config'
|
6
6
|
require 'slack-ruby-bot/hooks'
|
7
|
-
require 'slack-ruby-bot/commands'
|
8
|
-
require 'slack-ruby-bot/app'
|
9
7
|
|
10
8
|
module SlackRubyBot
|
11
9
|
class << self
|
@@ -18,3 +16,6 @@ module SlackRubyBot
|
|
18
16
|
end
|
19
17
|
end
|
20
18
|
end
|
19
|
+
|
20
|
+
require 'slack-ruby-bot/commands'
|
21
|
+
require 'slack-ruby-bot/app'
|
data/lib/slack-ruby-bot/app.rb
CHANGED
@@ -57,7 +57,7 @@ module SlackRubyBot
|
|
57
57
|
rescue StandardError => e
|
58
58
|
logger.error e
|
59
59
|
begin
|
60
|
-
Slack.chat_postMessage(channel: data['channel'], text: e.message) if data.key?('channel')
|
60
|
+
Slack.chat_postMessage(channel: data['channel'], text: e.message, as_user: true) if data.key?('channel')
|
61
61
|
rescue
|
62
62
|
# ignore
|
63
63
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module SlackRubyBot
|
2
2
|
module Commands
|
3
3
|
class Default < Base
|
4
|
-
command 'default'
|
5
4
|
command 'about'
|
5
|
+
match(/^(?<bot>\w*)$/)
|
6
6
|
|
7
|
-
def self.call(data,
|
7
|
+
def self.call(data, _match)
|
8
8
|
send_message_with_gif data.channel, SlackRubyBot::ABOUT, 'selfie'
|
9
9
|
end
|
10
10
|
end
|
@@ -1,18 +1,17 @@
|
|
1
1
|
module SlackRubyBot
|
2
2
|
module Commands
|
3
3
|
class Base
|
4
|
-
class_attribute :
|
5
|
-
class_attribute :commands
|
4
|
+
class_attribute :routes
|
6
5
|
|
7
|
-
def self.send_message(channel, text)
|
6
|
+
def self.send_message(channel, text, options = { as_user: true })
|
8
7
|
if text && text.length > 0
|
9
|
-
|
8
|
+
chat_postMessage({ channel: channel, text: text }.merge(options))
|
10
9
|
else
|
11
|
-
send_message_with_gif channel, 'Nothing to see here.', 'nothing'
|
10
|
+
send_message_with_gif channel, 'Nothing to see here.', 'nothing', options
|
12
11
|
end
|
13
12
|
end
|
14
13
|
|
15
|
-
def self.send_message_with_gif(channel, text, keywords)
|
14
|
+
def self.send_message_with_gif(channel, text, keywords, options = { as_user: true })
|
16
15
|
gif = begin
|
17
16
|
Giphy.random(keywords)
|
18
17
|
rescue StandardError => e
|
@@ -20,7 +19,7 @@ module SlackRubyBot
|
|
20
19
|
nil
|
21
20
|
end
|
22
21
|
text = text + "\n" + gif.image_url.to_s if gif
|
23
|
-
send_message channel, text
|
22
|
+
send_message channel, text, options
|
24
23
|
end
|
25
24
|
|
26
25
|
def self.logger
|
@@ -30,26 +29,58 @@ module SlackRubyBot
|
|
30
29
|
end
|
31
30
|
end
|
32
31
|
|
33
|
-
def self.responds_to_command?(command)
|
34
|
-
commands ? commands.include?(command) : command == default_command_name
|
35
|
-
end
|
36
|
-
|
37
32
|
def self.default_command_name
|
38
33
|
name && name.split(':').last.downcase
|
39
34
|
end
|
40
35
|
|
41
|
-
def self.
|
42
|
-
|
36
|
+
def self.operator(*values, &block)
|
37
|
+
values.each do |value|
|
38
|
+
match Regexp.new("^(?<operator>\\#{value})(?<expression>.*)$", Regexp::IGNORECASE), &block
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.command(*values, &block)
|
43
|
+
values.each do |value|
|
44
|
+
match Regexp.new("^(?<bot>\\w*)[\\s]+(?<command>#{value})$", Regexp::IGNORECASE), &block
|
45
|
+
match Regexp.new("^(?<bot>\\w*)[\\s]+(?<command>#{value})[\\s]+(?<expression>.*)$", Regexp::IGNORECASE), &block
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.invoke(data)
|
50
|
+
self.finalize_routes!
|
51
|
+
expression = data.text
|
52
|
+
called = false
|
53
|
+
routes.each_pair do |route, method|
|
54
|
+
match = route.match(expression)
|
55
|
+
next unless match
|
56
|
+
next if match.names.include?('bot') && match['bot'].downcase != SlackRubyBot.config.user
|
57
|
+
called = true
|
58
|
+
if method
|
59
|
+
method.call(data, match)
|
60
|
+
elsif self.respond_to?(:call)
|
61
|
+
send(:call, data, match)
|
62
|
+
else
|
63
|
+
fail NotImplementedError, data.text
|
64
|
+
end
|
65
|
+
break
|
66
|
+
end
|
67
|
+
called
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.match(match, &block)
|
71
|
+
self.routes ||= {}
|
72
|
+
self.routes[match] = block
|
43
73
|
end
|
44
74
|
|
45
|
-
|
46
|
-
|
47
|
-
|
75
|
+
private
|
76
|
+
|
77
|
+
def self.chat_postMessage(message)
|
78
|
+
Slack.chat_postMessage(message)
|
48
79
|
end
|
49
80
|
|
50
|
-
def self.
|
51
|
-
self.
|
52
|
-
|
81
|
+
def self.finalize_routes!
|
82
|
+
return if self.routes && self.routes.any?
|
83
|
+
command default_command_name
|
53
84
|
end
|
54
85
|
end
|
55
86
|
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
module SlackRubyBot
|
2
2
|
module Commands
|
3
3
|
class Unknown < Base
|
4
|
-
|
4
|
+
match(/^(?<bot>\w*)[\s]*(?<expression>.*)$/)
|
5
|
+
|
6
|
+
def self.call(data, _match)
|
5
7
|
send_message_with_gif data.channel, "Sorry <@#{data.user}>, I don't understand that command!", 'idiot'
|
6
8
|
end
|
7
9
|
end
|
@@ -5,62 +5,15 @@ module SlackRubyBot
|
|
5
5
|
|
6
6
|
def message(data)
|
7
7
|
data = Hashie::Mash.new(data)
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
data.text.strip!
|
9
|
+
result = child_command_classes.detect { |d| d.invoke(data) }
|
10
|
+
result ||= built_in_command_classes.detect { |d| d.invoke(data) }
|
11
|
+
result ||= SlackRubyBot::Commands::Unknown.tap { |d| d.invoke(data) }
|
12
|
+
result
|
11
13
|
end
|
12
14
|
|
13
15
|
private
|
14
16
|
|
15
|
-
#
|
16
|
-
# Lookup a class that can execute a command or an operator.
|
17
|
-
#
|
18
|
-
# @param [String] text Free-formed text from Slack.
|
19
|
-
#
|
20
|
-
# @return [SlackRubyBot::Commands::Base] A child class of SlackRubyBot::Commands::Base.
|
21
|
-
#
|
22
|
-
def text_to_class(text)
|
23
|
-
return unless text
|
24
|
-
command, arguments = parse_command(text)
|
25
|
-
if command
|
26
|
-
[command_to_class(command) || SlackRubyBot::Commands::Unknown, command, arguments]
|
27
|
-
else
|
28
|
-
command, arguments = parse_operator(text)
|
29
|
-
[operator_to_class(command), command, arguments]
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
#
|
34
|
-
# Split text into a command and its arguments.
|
35
|
-
#
|
36
|
-
# @param [String] text Free-formed text from Slack, eg. `bot do something`.
|
37
|
-
#
|
38
|
-
# @return [Array] An array of command and arguments or nil.
|
39
|
-
#
|
40
|
-
def parse_command(text)
|
41
|
-
return unless text
|
42
|
-
parts = text.split.reject(&:blank?)
|
43
|
-
return unless parts && parts.any?
|
44
|
-
# command is [bot] <command> (argument1, ...)
|
45
|
-
bot_or_operator = parts.first.downcase
|
46
|
-
return unless SlackRubyBot.config.user == bot_or_operator
|
47
|
-
command = parts[1].try(:downcase) || 'default'
|
48
|
-
arguments = parts[2..parts.length]
|
49
|
-
[command, arguments]
|
50
|
-
end
|
51
|
-
|
52
|
-
#
|
53
|
-
# Split text into an operator and its arguments.
|
54
|
-
#
|
55
|
-
# @param [String] text Free-formed text from Slack, eg. =2+2.
|
56
|
-
#
|
57
|
-
# @return [Array] An array and arguments or nil.
|
58
|
-
#
|
59
|
-
def parse_operator(text)
|
60
|
-
return unless text && text.length > 0
|
61
|
-
[text[0], text[1..text.length].split.reject(&:blank?)]
|
62
|
-
end
|
63
|
-
|
64
17
|
#
|
65
18
|
# All commands.
|
66
19
|
#
|
@@ -88,34 +41,7 @@ module SlackRubyBot
|
|
88
41
|
#
|
89
42
|
def built_in_command_classes
|
90
43
|
command_classes.select do |k|
|
91
|
-
k.name && k.name.starts_with?('SlackRubyBot::Commands::')
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
#
|
96
|
-
# Converts a command to a class.
|
97
|
-
#
|
98
|
-
# @param [String] command Command tet.
|
99
|
-
#
|
100
|
-
# @return [SlackRubyBot::Commands::Base] A command implementation.
|
101
|
-
#
|
102
|
-
def command_to_class(command)
|
103
|
-
# prioritize implementations to built-in classes
|
104
|
-
klass = child_command_classes.detect { |d| d.responds_to_command?(command) }
|
105
|
-
klass ||= built_in_command_classes.detect { |d| d.responds_to_command?(command) }
|
106
|
-
klass
|
107
|
-
end
|
108
|
-
|
109
|
-
#
|
110
|
-
# Converts an operator to a class.
|
111
|
-
#
|
112
|
-
# @param [String] operator Operator text.
|
113
|
-
#
|
114
|
-
# @return [<type>] An operator implementation.
|
115
|
-
#
|
116
|
-
def operator_to_class(operator)
|
117
|
-
command_classes.detect do |k|
|
118
|
-
k.responds_to_operator?(operator)
|
44
|
+
k.name && k.name.starts_with?('SlackRubyBot::Commands::') && k != SlackRubyBot::Commands::Unknown
|
119
45
|
end
|
120
46
|
end
|
121
47
|
end
|
@@ -1,14 +1,13 @@
|
|
1
1
|
require 'rspec/expectations'
|
2
2
|
|
3
|
-
RSpec::Matchers.define :respond_with_error do |
|
3
|
+
RSpec::Matchers.define :respond_with_error do |error, error_message|
|
4
4
|
match do |actual|
|
5
5
|
channel, user, message = parse(actual)
|
6
|
-
app = SlackRubyBot::App.new
|
7
6
|
allow(Giphy).to receive(:random)
|
8
7
|
begin
|
9
8
|
expect do
|
10
9
|
app.send(:message, text: message, channel: channel, user: user)
|
11
|
-
end.to raise_error
|
10
|
+
end.to raise_error error, error_message
|
12
11
|
rescue RSpec::Expectations::ExpectationNotMetError => e
|
13
12
|
@error_message = e.message
|
14
13
|
raise e
|
@@ -4,7 +4,7 @@ RSpec::Matchers.define :respond_with_slack_message do |expected|
|
|
4
4
|
match do |actual|
|
5
5
|
channel, user, message = parse(actual)
|
6
6
|
allow(Giphy).to receive(:random)
|
7
|
-
expect(SlackRubyBot::Commands::Base).to receive(:
|
7
|
+
expect(SlackRubyBot::Commands::Base).to receive(:chat_postMessage).with(channel: channel, text: expected, as_user: true)
|
8
8
|
app.send(:message, text: message, channel: channel, user: user)
|
9
9
|
true
|
10
10
|
end
|
Binary file
|
data/slack-ruby-bot.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.require_paths = ['lib']
|
14
14
|
s.homepage = 'http://github.com/dblock/slack-ruby-bot'
|
15
15
|
s.licenses = ['MIT']
|
16
|
-
s.summary = '
|
16
|
+
s.summary = 'The easiest way to write a Slack bot in Ruby.'
|
17
17
|
s.add_dependency 'hashie'
|
18
18
|
s.add_dependency 'slack-api', '~> 1.1.6'
|
19
19
|
s.add_dependency 'activesupport'
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SlackRubyBot::Commands do
|
4
|
+
let! :command do
|
5
|
+
Class.new(SlackRubyBot::Commands::Base) do
|
6
|
+
command 'tomato' do |data, match|
|
7
|
+
send_message data.channel, "#{match[:command]}: #{match[:expression]}", as_user: true
|
8
|
+
end
|
9
|
+
|
10
|
+
command 'tomatoes' do |data, match|
|
11
|
+
send_message data.channel, "#{match[:command]}: #{match[:expression]}", as_user: true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
def app
|
16
|
+
SlackRubyBot::App.new
|
17
|
+
end
|
18
|
+
it 'matches commands' do
|
19
|
+
expect(message: "#{SlackRubyBot.config.user} tomato red").to respond_with_slack_message('tomato: red')
|
20
|
+
expect(message: "#{SlackRubyBot.config.user} tomatoes green").to respond_with_slack_message('tomatoes: green')
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SlackRubyBot::Commands do
|
4
|
+
let! :command do
|
5
|
+
Class.new(SlackRubyBot::Commands::Base) do
|
6
|
+
command 'space' do |data, match|
|
7
|
+
send_message data.channel, "#{match[:command]}: #{match[:expression]}", as_user: true
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
def app
|
12
|
+
SlackRubyBot::App.new
|
13
|
+
end
|
14
|
+
it 'matches leading spaces' do
|
15
|
+
expect(message: " #{SlackRubyBot.config.user} space red").to respond_with_slack_message('space: red')
|
16
|
+
end
|
17
|
+
it 'matches trailing spaces' do
|
18
|
+
expect(message: "#{SlackRubyBot.config.user} space red ").to respond_with_slack_message('space: red')
|
19
|
+
end
|
20
|
+
end
|
@@ -6,8 +6,8 @@ describe SlackRubyBot::Commands do
|
|
6
6
|
command 'sayhi'
|
7
7
|
command 'saybye'
|
8
8
|
|
9
|
-
def self.call(data,
|
10
|
-
send_message data.channel, "#{command}: #{
|
9
|
+
def self.call(data, match)
|
10
|
+
send_message data.channel, "#{match[:command]}: #{match[:expression]}", as_user: true
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -15,7 +15,7 @@ describe SlackRubyBot::Commands do
|
|
15
15
|
SlackRubyBot::App.new
|
16
16
|
end
|
17
17
|
it 'supports multiple commands' do
|
18
|
-
expect(message: "#{SlackRubyBot.config.user} sayhi arg1 arg2").to respond_with_slack_message('sayhi:
|
19
|
-
expect(message: "#{SlackRubyBot.config.user} saybye arg1 arg2").to respond_with_slack_message('saybye:
|
18
|
+
expect(message: "#{SlackRubyBot.config.user} sayhi arg1 arg2").to respond_with_slack_message('sayhi: arg1 arg2')
|
19
|
+
expect(message: "#{SlackRubyBot.config.user} saybye arg1 arg2").to respond_with_slack_message('saybye: arg1 arg2')
|
20
20
|
end
|
21
21
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SlackRubyBot::Commands do
|
4
|
+
let! :command do
|
5
|
+
Class.new(SlackRubyBot::Commands::Base) do
|
6
|
+
command 'sayhi' do |data, match|
|
7
|
+
send_message data.channel, "#{match[:command]}: #{match[:expression]}", as_user: true
|
8
|
+
end
|
9
|
+
|
10
|
+
command 'one', 'two' do |data, match|
|
11
|
+
send_message data.channel, "#{match[:command]}: #{match[:expression]}", as_user: true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
def app
|
16
|
+
SlackRubyBot::App.new
|
17
|
+
end
|
18
|
+
it 'supports multiple commands' do
|
19
|
+
expect(message: "#{SlackRubyBot.config.user} sayhi arg1 arg2").to respond_with_slack_message('sayhi: arg1 arg2')
|
20
|
+
expect(message: "#{SlackRubyBot.config.user} one arg1 arg2").to respond_with_slack_message('one: arg1 arg2')
|
21
|
+
expect(message: "#{SlackRubyBot.config.user} two arg1 arg2").to respond_with_slack_message('two: arg1 arg2')
|
22
|
+
end
|
23
|
+
end
|
@@ -3,9 +3,9 @@ require 'spec_helper'
|
|
3
3
|
describe SlackRubyBot::Commands do
|
4
4
|
let! :command do
|
5
5
|
Class.new(SlackRubyBot::Commands::Base) do
|
6
|
-
command '
|
6
|
+
command 'empty_text'
|
7
7
|
|
8
|
-
def self.call(data,
|
8
|
+
def self.call(data, _match)
|
9
9
|
send_message data.channel, nil
|
10
10
|
end
|
11
11
|
end
|
@@ -15,7 +15,7 @@ describe SlackRubyBot::Commands do
|
|
15
15
|
end
|
16
16
|
it 'sends default text' do
|
17
17
|
allow(Giphy).to receive(:random)
|
18
|
-
expect(SlackRubyBot::Commands::Base).to receive(:send_message_with_gif).with('channel', 'Nothing to see here.', 'nothing')
|
19
|
-
app.send(:message, text: "#{SlackRubyBot.config.user}
|
18
|
+
expect(SlackRubyBot::Commands::Base).to receive(:send_message_with_gif).with('channel', 'Nothing to see here.', 'nothing', as_user: true)
|
19
|
+
app.send(:message, text: "#{SlackRubyBot.config.user} empty_text", channel: 'channel', user: 'user')
|
20
20
|
end
|
21
21
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SlackRubyBot::Commands::Base do
|
4
|
+
let! :command do
|
5
|
+
Class.new(SlackRubyBot::Commands::Base) do
|
6
|
+
command 'not_implemented'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
def app
|
10
|
+
SlackRubyBot::App.new
|
11
|
+
end
|
12
|
+
it 'raises not implemented' do
|
13
|
+
expect(message: "#{SlackRubyBot.config.user} not_implemented").to respond_with_error(NotImplementedError, 'rubybot not_implemented')
|
14
|
+
end
|
15
|
+
end
|
@@ -6,8 +6,8 @@ describe SlackRubyBot::Commands do
|
|
6
6
|
operator '='
|
7
7
|
operator '-'
|
8
8
|
|
9
|
-
def self.call(data,
|
10
|
-
send_message data.channel, "#{
|
9
|
+
def self.call(data, match)
|
10
|
+
send_message data.channel, "#{match[:operator]}: #{match[:expression]}", as_user: true
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -15,6 +15,6 @@ describe SlackRubyBot::Commands do
|
|
15
15
|
SlackRubyBot::App.new
|
16
16
|
end
|
17
17
|
it 'supports operators' do
|
18
|
-
expect(message: '=2+2').to respond_with_slack_message('=:
|
18
|
+
expect(message: '=2+2').to respond_with_slack_message('=: 2+2')
|
19
19
|
end
|
20
20
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SlackRubyBot::Commands do
|
4
|
+
let! :command do
|
5
|
+
Class.new(SlackRubyBot::Commands::Base) do
|
6
|
+
operator '=' do |data, match|
|
7
|
+
send_message data.channel, "#{match[:operator]}: #{match[:expression]}", as_user: true
|
8
|
+
end
|
9
|
+
|
10
|
+
operator '+', '-' do |data, match|
|
11
|
+
send_message data.channel, "#{match[:operator]}: #{match[:expression]}", as_user: true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
def app
|
16
|
+
SlackRubyBot::App.new
|
17
|
+
end
|
18
|
+
it 'supports operator blocks' do
|
19
|
+
expect(message: '=2+2').to respond_with_slack_message('=: 2+2')
|
20
|
+
expect(message: '+2+2').to respond_with_slack_message('+: 2+2')
|
21
|
+
expect(message: '-2+2').to respond_with_slack_message('-: 2+2')
|
22
|
+
end
|
23
|
+
end
|
@@ -5,8 +5,8 @@ describe RSpec do
|
|
5
5
|
Class.new(SlackRubyBot::Commands::Base) do
|
6
6
|
command 'raise'
|
7
7
|
|
8
|
-
def self.call(_data,
|
9
|
-
fail ArgumentError, command
|
8
|
+
def self.call(_data, match)
|
9
|
+
fail ArgumentError, match[:command]
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -14,6 +14,6 @@ describe RSpec do
|
|
14
14
|
SlackRubyBot::App.new
|
15
15
|
end
|
16
16
|
it 'respond_with_error' do
|
17
|
-
expect(message: "#{SlackRubyBot.config.user} raise").to respond_with_error('raise')
|
17
|
+
expect(message: "#{SlackRubyBot.config.user} raise").to respond_with_error(ArgumentError, 'raise')
|
18
18
|
end
|
19
19
|
end
|
metadata
CHANGED
@@ -1,153 +1,153 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slack-ruby-bot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Doubrovkine
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-07-
|
11
|
+
date: 2015-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
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
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: slack-api
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 1.1.6
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 1.1.6
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: activesupport
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: giphy
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 2.0.2
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 2.0.2
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: websocket-driver
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: 0.5.4
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - ~>
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 0.5.4
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rake
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rspec
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: rack-test
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: vcr
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- -
|
129
|
+
- - ">="
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- -
|
136
|
+
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: webmock
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- -
|
143
|
+
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '0'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- -
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
- !ruby/object:Gem::Dependency
|
@@ -170,22 +170,25 @@ executables: []
|
|
170
170
|
extensions: []
|
171
171
|
extra_rdoc_files: []
|
172
172
|
files:
|
173
|
-
- .gitignore
|
174
|
-
- .rspec
|
175
|
-
- .rubocop.yml
|
176
|
-
- .rubocop_todo.yml
|
177
|
-
- .travis.yml
|
173
|
+
- ".gitignore"
|
174
|
+
- ".rspec"
|
175
|
+
- ".rubocop.yml"
|
176
|
+
- ".rubocop_todo.yml"
|
177
|
+
- ".travis.yml"
|
178
178
|
- CHANGELOG.md
|
179
179
|
- CONTRIBUTING.md
|
180
180
|
- DEPLOYMENT.md
|
181
181
|
- Gemfile
|
182
182
|
- LICENSE.md
|
183
183
|
- README.md
|
184
|
+
- RELEASING.md
|
184
185
|
- Rakefile
|
185
186
|
- TUTORIAL.md
|
186
187
|
- examples/minimal/Gemfile
|
187
188
|
- examples/minimal/Gemfile.lock
|
188
189
|
- examples/minimal/pongbot.rb
|
190
|
+
- examples/weather/Gemfile
|
191
|
+
- examples/weather/weatherbot.rb
|
189
192
|
- lib/config/application.rb
|
190
193
|
- lib/config/boot.rb
|
191
194
|
- lib/config/environment.rb
|
@@ -217,14 +220,20 @@ files:
|
|
217
220
|
- lib/slack_ruby_bot.rb
|
218
221
|
- screenshots/demo.gif
|
219
222
|
- screenshots/register-bot.png
|
223
|
+
- screenshots/weather.gif
|
220
224
|
- slack-ruby-bot.gemspec
|
221
225
|
- spec/slack-ruby-bot/app_spec.rb
|
222
226
|
- spec/slack-ruby-bot/commands/about_spec.rb
|
227
|
+
- spec/slack-ruby-bot/commands/commands_precedence_spec.rb
|
228
|
+
- spec/slack-ruby-bot/commands/commands_spaces_spec.rb
|
223
229
|
- spec/slack-ruby-bot/commands/commands_spec.rb
|
230
|
+
- spec/slack-ruby-bot/commands/commands_with_block_spec.rb
|
224
231
|
- spec/slack-ruby-bot/commands/empty_text_spec.rb
|
225
232
|
- spec/slack-ruby-bot/commands/help_spec.rb
|
226
233
|
- spec/slack-ruby-bot/commands/hi_spec.rb
|
234
|
+
- spec/slack-ruby-bot/commands/not_implemented_spec.rb
|
227
235
|
- spec/slack-ruby-bot/commands/operators_spec.rb
|
236
|
+
- spec/slack-ruby-bot/commands/operators_with_block_spec.rb
|
228
237
|
- spec/slack-ruby-bot/commands/unknown_spec.rb
|
229
238
|
- spec/slack-ruby-bot/rspec/respond_with_error_spec.rb
|
230
239
|
- spec/slack-ruby-bot/version_spec.rb
|
@@ -239,28 +248,33 @@ require_paths:
|
|
239
248
|
- lib
|
240
249
|
required_ruby_version: !ruby/object:Gem::Requirement
|
241
250
|
requirements:
|
242
|
-
- -
|
251
|
+
- - ">="
|
243
252
|
- !ruby/object:Gem::Version
|
244
253
|
version: '0'
|
245
254
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
246
255
|
requirements:
|
247
|
-
- -
|
256
|
+
- - ">="
|
248
257
|
- !ruby/object:Gem::Version
|
249
258
|
version: 1.3.6
|
250
259
|
requirements: []
|
251
260
|
rubyforge_project:
|
252
|
-
rubygems_version: 2.
|
261
|
+
rubygems_version: 2.2.2
|
253
262
|
signing_key:
|
254
263
|
specification_version: 4
|
255
|
-
summary:
|
264
|
+
summary: The easiest way to write a Slack bot in Ruby.
|
256
265
|
test_files:
|
257
266
|
- spec/slack-ruby-bot/app_spec.rb
|
258
267
|
- spec/slack-ruby-bot/commands/about_spec.rb
|
268
|
+
- spec/slack-ruby-bot/commands/commands_precedence_spec.rb
|
269
|
+
- spec/slack-ruby-bot/commands/commands_spaces_spec.rb
|
259
270
|
- spec/slack-ruby-bot/commands/commands_spec.rb
|
271
|
+
- spec/slack-ruby-bot/commands/commands_with_block_spec.rb
|
260
272
|
- spec/slack-ruby-bot/commands/empty_text_spec.rb
|
261
273
|
- spec/slack-ruby-bot/commands/help_spec.rb
|
262
274
|
- spec/slack-ruby-bot/commands/hi_spec.rb
|
275
|
+
- spec/slack-ruby-bot/commands/not_implemented_spec.rb
|
263
276
|
- spec/slack-ruby-bot/commands/operators_spec.rb
|
277
|
+
- spec/slack-ruby-bot/commands/operators_with_block_spec.rb
|
264
278
|
- spec/slack-ruby-bot/commands/unknown_spec.rb
|
265
279
|
- spec/slack-ruby-bot/rspec/respond_with_error_spec.rb
|
266
280
|
- spec/slack-ruby-bot/version_spec.rb
|