slack-ruby-bot 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +8 -0
- data/README.md +45 -4
- data/examples/weather/weatherbot.rb +15 -0
- data/lib/config/application.rb +0 -2
- data/lib/config/boot.rb +0 -1
- data/lib/slack-ruby-bot.rb +1 -0
- data/lib/slack-ruby-bot/commands/base.rb +6 -2
- data/lib/slack-ruby-bot/commands/help.rb +35 -3
- data/lib/slack-ruby-bot/commands/help/attrs.rb +34 -0
- data/lib/slack-ruby-bot/commands/hi.rb +5 -0
- data/lib/slack-ruby-bot/rspec/support/bots_for_tests.rb +33 -0
- data/lib/slack-ruby-bot/server.rb +10 -4
- data/lib/slack-ruby-bot/support/commands_helper.rb +76 -0
- data/lib/slack-ruby-bot/support/loggable.rb +12 -11
- data/lib/slack-ruby-bot/version.rb +1 -1
- data/screenshots/help.png +0 -0
- data/slack-ruby-bot.gemspec +0 -1
- data/spec/slack-ruby-bot/app_spec.rb +7 -0
- data/spec/slack-ruby-bot/commands/help/attrs_spec.rb +25 -0
- data/spec/slack-ruby-bot/commands/help_spec.rb +19 -1
- data/spec/slack-ruby-bot/hooks/message_spec.rb +1 -1
- data/spec/slack-ruby-bot/server_spec.rb +17 -0
- data/spec/slack-ruby-bot/support/commands_helper_spec.rb +121 -0
- metadata +11 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f872fa7b4cc7c405bc25e0802e243826672c098f
|
4
|
+
data.tar.gz: ed6a6038cf90aea81894759e73b2991a484f0d09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2823b93a71bd803ebdbd3d753785e457250275dc2a0bb9eee72a4b7e9986f9060fa42487676d7ca6ed32513173c5ee51cc33274f69fc6c1e43d5c7311fce1386
|
7
|
+
data.tar.gz: 6d08cab72ee6db777d275550654154d9186b35643107529ee25c59e449fb19b52f6a7dde58bcef583dba4c19fb201bfe140cfe832daff91f07321e6cec0483c2
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
### 0.8.1 (6/10/2016)
|
2
|
+
|
3
|
+
* [#69](https://github.com/dblock/slack-ruby-bot/pull/69): Ability to add help info to bot and commands - [@accessd](https://github.com/accessd).
|
4
|
+
* [#75](https://github.com/dblock/slack-ruby-bot/issues/75): Guarantee order of command evaluation - [@dblock](https://github.com/dblock).
|
5
|
+
* [#76](https://github.com/dblock/slack-ruby-bot/issues/76): Infinity error when app disabled - [@slayershadow](https://github.com/SlayerShadow).
|
6
|
+
* [#81](https://github.com/dblock/slack-ruby-bot/pull/81): Removed dependency on Bundler - [@derekddecker](https://github.com/derekddecker).
|
7
|
+
* [#84](https://github.com/dblock/slack-ruby-bot/pull/84): Removed dependency on ActiveSupport - [@rmulligan](https://github.com/rmulligan).
|
8
|
+
|
1
9
|
### 0.8.0 (5/5/2016)
|
2
10
|
|
3
11
|
* [#32](https://github.com/dblock/slack-ruby-bot/issues/32): Don't include `faye-websocket` by default, support `celluloid-io` - [@dblock](https://github.com/dblock).
|
data/README.md
CHANGED
@@ -7,17 +7,19 @@ Slack-Ruby-Bot
|
|
7
7
|
|
8
8
|
A generic Slack bot framework written in Ruby on top of [slack-ruby-client](https://github.com/dblock/slack-ruby-client). This library does all the heavy lifting, such as message parsing, so you can focus on implementing slack bot commands. It also attempts to introduce the bare minimum number of requirements or any sorts of limitations. It's a Slack bot boilerplate.
|
9
9
|
|
10
|
+
If you are not familiar with Slack bots or Slack API concepts, you might want to watch [this video](http://code.dblock.org/2016/03/11/your-first-slack-bot-service-video.html).
|
11
|
+
|
10
12
|
![](slack.png)
|
11
13
|
|
12
14
|
## Useful to Me?
|
13
15
|
|
14
16
|
* If you are just trying to send messages to Slack, use [slack-ruby-client](https://github.com/dblock/slack-ruby-client), which this library is built on top of.
|
15
|
-
* If you're trying to roll out a full service with Slack button integration, check out [slack-bot-server](https://github.com/dblock/slack-bot-server), which uses this library.
|
17
|
+
* If you're trying to roll out a full service with Slack button integration, check out [slack-ruby-bot-server](https://github.com/dblock/slack-ruby-bot-server), which uses this library.
|
16
18
|
* Otherwise, this piece of the puzzle will help you create a single bot instance for one team.
|
17
19
|
|
18
20
|
## Stable Release
|
19
21
|
|
20
|
-
You're reading the documentation for the **stable** release of slack-ruby-bot 0.8.
|
22
|
+
You're reading the documentation for the **stable** release of slack-ruby-bot, 0.8.1. See [CHANGELOG](CHANGELOG.md) for a history of changes and [UPGRADING](UPGRADING.md) for how to upgrade to more recent versions.
|
21
23
|
|
22
24
|
## Usage
|
23
25
|
|
@@ -140,6 +142,47 @@ end
|
|
140
142
|
|
141
143
|
See [examples/market](examples/market/marketbot.rb) for a working example.
|
142
144
|
|
145
|
+
### Providing description for your bot and commands
|
146
|
+
|
147
|
+
You can specify help information for bot or commands with `help` block, for example:
|
148
|
+
|
149
|
+
in case of bot:
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
class WeatherBot < SlackRubyBot::Bot
|
153
|
+
help do
|
154
|
+
title 'Weather Bot'
|
155
|
+
desc 'This bot tells you the weather.'
|
156
|
+
|
157
|
+
command 'clouds' do
|
158
|
+
desc 'Tells you how many clouds there\'re above you.'
|
159
|
+
end
|
160
|
+
|
161
|
+
command 'What\'s the weather in <city>?' do
|
162
|
+
desc 'Tells you the weather in a <city>.'
|
163
|
+
long_desc "Accurate 10 Day Weather Forecasts for thousands of places around the World.\n" \
|
164
|
+
'Bot provides detailed Weather Forecasts over a 10 day period updated four times a day.'
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# commands implementation
|
169
|
+
end
|
170
|
+
```
|
171
|
+
|
172
|
+
![](screenshots/help.png)
|
173
|
+
|
174
|
+
in case of your own command:
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
class Deploy < SlackRubyBot::Commands::Base
|
178
|
+
help do
|
179
|
+
title 'deploy'
|
180
|
+
desc 'deploys your app'
|
181
|
+
long_desc 'command format: *deploy <branch> to <env>* where <env> is production or staging'
|
182
|
+
end
|
183
|
+
end
|
184
|
+
```
|
185
|
+
|
143
186
|
### SlackRubyBot::Commands::Base
|
144
187
|
|
145
188
|
The `SlackRubyBot::Bot` class is DSL sugar deriving from `SlackRubyBot::Commands::Base`. For more involved bots you can organize the bot implementation into subclasses of `SlackRubyBot::Commands::Base` manually. 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.
|
@@ -221,8 +264,6 @@ For example, the following hook handles [user_change](https://api.slack.com/even
|
|
221
264
|
module MyBot
|
222
265
|
module Hooks
|
223
266
|
class UserChange
|
224
|
-
extend SlackRubyBot::Hooks::Base
|
225
|
-
|
226
267
|
def call(client, data)
|
227
268
|
# data['user']['id'] contains the user ID
|
228
269
|
# data['user']['name'] contains the new user name
|
@@ -3,6 +3,21 @@ require 'slack-ruby-bot'
|
|
3
3
|
SlackRubyBot::Client.logger.level = Logger::WARN
|
4
4
|
|
5
5
|
class WeatherBot < SlackRubyBot::Bot
|
6
|
+
help do
|
7
|
+
title 'Weather Bot'
|
8
|
+
desc 'This bot tells you the weather.'
|
9
|
+
|
10
|
+
command 'clouds' do
|
11
|
+
desc 'Tells you how many clouds there\'re above you.'
|
12
|
+
end
|
13
|
+
|
14
|
+
command 'What\'s the weather in <city>?' do
|
15
|
+
desc 'Tells you the weather in a <city>.'
|
16
|
+
long_desc "Accurate 10 Day Weather Forecasts for thousands of places around the World.\n" \
|
17
|
+
'We provide detailed Weather Forecasts over a 10 day period updated four times a day.'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
6
21
|
match(/^How is the weather in (?<location>\w*)\?$/i) do |client, data, match|
|
7
22
|
client.say(channel: data.channel, text: "The weather in #{match[:location]} is nice.")
|
8
23
|
end
|
data/lib/config/application.rb
CHANGED
data/lib/config/boot.rb
CHANGED
data/lib/slack-ruby-bot.rb
CHANGED
@@ -24,6 +24,10 @@ module SlackRubyBot
|
|
24
24
|
client.say(options.merge(channel: channel, text: '', gif: keywords))
|
25
25
|
end
|
26
26
|
|
27
|
+
def help(&block)
|
28
|
+
CommandsHelper.instance.capture_help(name, &block)
|
29
|
+
end
|
30
|
+
|
27
31
|
def default_command_name
|
28
32
|
name && name.split(':').last.downcase
|
29
33
|
end
|
@@ -69,12 +73,12 @@ module SlackRubyBot
|
|
69
73
|
end
|
70
74
|
|
71
75
|
def match(match, &block)
|
72
|
-
self.routes ||=
|
76
|
+
self.routes ||= ActiveSupport::OrderedHash.new
|
73
77
|
self.routes[match] = { match_method: :match, call: block }
|
74
78
|
end
|
75
79
|
|
76
80
|
def scan(match, &block)
|
77
|
-
self.routes ||=
|
81
|
+
self.routes ||= ActiveSupport::OrderedHash.new
|
78
82
|
self.routes[match] = { match_method: :scan, call: block }
|
79
83
|
end
|
80
84
|
|
@@ -1,8 +1,40 @@
|
|
1
1
|
module SlackRubyBot
|
2
2
|
module Commands
|
3
|
-
class
|
4
|
-
|
5
|
-
|
3
|
+
class HelpCommand < Base
|
4
|
+
help do
|
5
|
+
title 'help'
|
6
|
+
desc 'Shows help information.'
|
7
|
+
end
|
8
|
+
|
9
|
+
command 'help' do |client, data, match|
|
10
|
+
command = match[:expression]
|
11
|
+
|
12
|
+
text = if command.present?
|
13
|
+
CommandsHelper.instance.command_full_desc(command)
|
14
|
+
else
|
15
|
+
general_text
|
16
|
+
end
|
17
|
+
|
18
|
+
client.say(channel: data.channel, text: text, gif: 'help')
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
private
|
23
|
+
|
24
|
+
def general_text
|
25
|
+
bot_desc = CommandsHelper.instance.bot_desc_and_commands
|
26
|
+
other_commands_descs = CommandsHelper.instance.other_commands_descs
|
27
|
+
<<TEXT
|
28
|
+
#{bot_desc.join("\n")}
|
29
|
+
|
30
|
+
*Other commands:*
|
31
|
+
#{other_commands_descs.join("\n")}
|
32
|
+
|
33
|
+
For getting description of the command use: *help <command>*
|
34
|
+
|
35
|
+
For more information see https://github.com/dblock/slack-ruby-bot, please.
|
36
|
+
TEXT
|
37
|
+
end
|
6
38
|
end
|
7
39
|
end
|
8
40
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module SlackRubyBot
|
2
|
+
module Commands
|
3
|
+
module Help
|
4
|
+
class Attrs
|
5
|
+
attr_accessor :command_name, :command_desc, :command_long_desc
|
6
|
+
attr_reader :class_name, :commands
|
7
|
+
|
8
|
+
def initialize(class_name)
|
9
|
+
@class_name = class_name
|
10
|
+
@commands = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def title(title)
|
14
|
+
self.command_name = title
|
15
|
+
end
|
16
|
+
|
17
|
+
def desc(desc)
|
18
|
+
self.command_desc = desc
|
19
|
+
end
|
20
|
+
|
21
|
+
def long_desc(long_desc)
|
22
|
+
self.command_long_desc = long_desc
|
23
|
+
end
|
24
|
+
|
25
|
+
def command(title, &block)
|
26
|
+
@commands << self.class.new(class_name).tap do |k|
|
27
|
+
k.title(title)
|
28
|
+
k.instance_eval(&block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Testing
|
2
|
+
class WeatherBot < SlackRubyBot::Bot
|
3
|
+
help do
|
4
|
+
title 'Weather Bot'
|
5
|
+
desc 'This bot tells you the weather.'
|
6
|
+
|
7
|
+
command 'clouds' do
|
8
|
+
desc 'Tells you how many clouds there\'re above you.'
|
9
|
+
end
|
10
|
+
|
11
|
+
command '' do
|
12
|
+
desc 'empty description'
|
13
|
+
end
|
14
|
+
|
15
|
+
command 'command_without_description' do
|
16
|
+
end
|
17
|
+
|
18
|
+
command 'What\'s the weather in <city>?' do
|
19
|
+
desc 'Tells you the weather in a <city>.'
|
20
|
+
long_desc "Accurate 10 Day Weather Forecasts for thousands of places around the World.\n" \
|
21
|
+
'We provide detailed Weather Forecasts over a 10 day period updated four times a day.'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class HelloCommand < SlackRubyBot::Commands::Base
|
27
|
+
help do
|
28
|
+
title 'hello'
|
29
|
+
desc 'Says hello.'
|
30
|
+
long_desc 'The long description'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -51,10 +51,16 @@ module SlackRubyBot
|
|
51
51
|
def restart!(wait = 1)
|
52
52
|
@async ? start_async : start!
|
53
53
|
rescue StandardError => e
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
54
|
+
case e.message
|
55
|
+
when 'account_inactive', 'invalid_auth'
|
56
|
+
logger.error "#{token}: #{e.message}, team will be deactivated."
|
57
|
+
@stopping = true
|
58
|
+
else
|
59
|
+
sleep wait
|
60
|
+
logger.error "#{e.message}, reconnecting in #{wait} second(s)."
|
61
|
+
logger.debug e
|
62
|
+
restart! [wait * 2, 60].min
|
63
|
+
end
|
58
64
|
end
|
59
65
|
|
60
66
|
private
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require_relative '../commands/help/attrs'
|
3
|
+
|
4
|
+
module SlackRubyBot
|
5
|
+
class CommandsHelper
|
6
|
+
include Singleton
|
7
|
+
attr_reader :commands_help_attrs
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@commands_help_attrs = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def capture_help(class_name, &block)
|
14
|
+
k = Commands::Help::Attrs.new(class_name)
|
15
|
+
k.instance_eval(&block)
|
16
|
+
@commands_help_attrs << k
|
17
|
+
end
|
18
|
+
|
19
|
+
def bot_desc_and_commands
|
20
|
+
collect_help_attrs(bot_help_attrs) do |help_attrs|
|
21
|
+
bot_commands_descs = collect_name_and_desc(help_attrs.commands)
|
22
|
+
"#{command_name_and_desc(help_attrs)}\n\n*Commands:*\n#{bot_commands_descs.join("\n")}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def other_commands_descs
|
27
|
+
collect_name_and_desc(other_commands_help_attrs)
|
28
|
+
end
|
29
|
+
|
30
|
+
def command_full_desc(name)
|
31
|
+
unescaped_name = Slack::Messages::Formatting.unescape(name)
|
32
|
+
help_attrs = find_command_help_attrs(unescaped_name)
|
33
|
+
return "There's no command *#{unescaped_name}*" unless help_attrs
|
34
|
+
return "There's no description for command *#{unescaped_name}*" if help_attrs.command_long_desc.blank?
|
35
|
+
"#{command_name_and_desc(help_attrs)}\n\n#{help_attrs.command_long_desc}"
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def find_command_help_attrs(name)
|
41
|
+
help_attrs = commands_help_attrs.find { |k| k.command_name == name }
|
42
|
+
return help_attrs if help_attrs
|
43
|
+
commands_help_attrs.each { |k| k.commands.each { |c| return c if c.command_name == name } }
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
|
47
|
+
def collect_help_attrs(help_attrs)
|
48
|
+
help_attrs_with_present_names(help_attrs).map do |ha|
|
49
|
+
yield(ha)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def collect_name_and_desc(help_attrs)
|
54
|
+
collect_help_attrs(help_attrs) do |ha|
|
55
|
+
command_name_and_desc(ha)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def command_name_and_desc(help_attrs)
|
60
|
+
desc = help_attrs.command_desc.present? ? " - #{help_attrs.command_desc}" : ''
|
61
|
+
"*#{help_attrs.command_name}*#{desc}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def help_attrs_with_present_names(help_attrs)
|
65
|
+
help_attrs.select { |k| k.command_name.present? }
|
66
|
+
end
|
67
|
+
|
68
|
+
def bot_help_attrs
|
69
|
+
commands_help_attrs.select { |k| k.class_name.constantize.superclass == SlackRubyBot::Bot }
|
70
|
+
end
|
71
|
+
|
72
|
+
def other_commands_help_attrs
|
73
|
+
commands_help_attrs.select { |k| k.class_name.constantize.superclass == SlackRubyBot::Commands::Base }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -1,20 +1,21 @@
|
|
1
1
|
module SlackRubyBot
|
2
2
|
module Loggable
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
def logger
|
7
|
-
@logger ||= begin
|
8
|
-
$stdout.sync = true
|
9
|
-
Logger.new(STDOUT)
|
10
|
-
end
|
11
|
-
end
|
3
|
+
def self.included(base)
|
4
|
+
base.send :include, LoggingMethods
|
5
|
+
base.extend(LoggingMethods)
|
12
6
|
end
|
13
7
|
|
14
|
-
|
8
|
+
def self.logger
|
9
|
+
@logger ||= begin
|
10
|
+
$stdout.sync = true
|
11
|
+
Logger.new(STDOUT)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
15
|
|
16
|
+
module LoggingMethods
|
16
17
|
def logger
|
17
|
-
|
18
|
+
Loggable.logger
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
Binary file
|
data/slack-ruby-bot.gemspec
CHANGED
@@ -16,7 +16,6 @@ Gem::Specification.new do |s|
|
|
16
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-ruby-client', '>= 0.6.0'
|
19
|
-
s.add_dependency 'activesupport'
|
20
19
|
s.add_dependency 'giphy', '~> 2.0.2'
|
21
20
|
s.add_development_dependency 'rake'
|
22
21
|
s.add_development_dependency 'rspec'
|
@@ -12,4 +12,11 @@ describe SlackRubyBot::App do
|
|
12
12
|
expect(klass.instance.class).to be klass
|
13
13
|
end
|
14
14
|
end
|
15
|
+
|
16
|
+
describe 'executable' do
|
17
|
+
it 'can be required as a dependency' do
|
18
|
+
response = system("ruby -e \"Bundler = nil ; require 'slack-ruby-bot'\"")
|
19
|
+
expect(response).to be true
|
20
|
+
end
|
21
|
+
end
|
15
22
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SlackRubyBot::Commands::Help::Attrs do
|
4
|
+
let(:help_attrs) { described_class.new('WeatherBot') }
|
5
|
+
|
6
|
+
it 'captures commands help attributes' do
|
7
|
+
expect(help_attrs.commands).to be_empty
|
8
|
+
|
9
|
+
sample_title = 'how\'s the weather?'
|
10
|
+
sample_desc = 'Tells you the weather in a <city>.'
|
11
|
+
sample_long_desc = "Accurate 10 Day Weather Forecasts for thousands of places around the World.\n" \
|
12
|
+
'We provide detailed Weather Forecasts over a 10 day period updated four times a day.'
|
13
|
+
|
14
|
+
help_attrs.command(sample_title) do
|
15
|
+
desc sample_desc
|
16
|
+
long_desc sample_long_desc
|
17
|
+
end
|
18
|
+
|
19
|
+
expect(help_attrs.commands.count).to eq(1)
|
20
|
+
command = help_attrs.commands.first
|
21
|
+
expect(command.command_name).to eq(sample_title)
|
22
|
+
expect(command.command_desc).to eq(sample_desc)
|
23
|
+
expect(command.command_long_desc).to eq(sample_long_desc)
|
24
|
+
end
|
25
|
+
end
|
@@ -5,6 +5,24 @@ describe SlackRubyBot::Commands::Help do
|
|
5
5
|
SlackRubyBot::App.new
|
6
6
|
end
|
7
7
|
it 'help' do
|
8
|
-
|
8
|
+
message = <<MSG
|
9
|
+
*Weather Bot* - This bot tells you the weather.
|
10
|
+
|
11
|
+
*Commands:*
|
12
|
+
*clouds* - Tells you how many clouds there're above you.
|
13
|
+
*command_without_description*
|
14
|
+
*What's the weather in <city>?* - Tells you the weather in a <city>.
|
15
|
+
|
16
|
+
*Other commands:*
|
17
|
+
*help* - Shows help information.
|
18
|
+
*hi* - Says hello.
|
19
|
+
*hello* - Says hello.
|
20
|
+
|
21
|
+
For getting description of the command use: *help <command>*
|
22
|
+
|
23
|
+
For more information see https://github.com/dblock/slack-ruby-bot, please.
|
24
|
+
MSG
|
25
|
+
|
26
|
+
expect(message: "#{SlackRubyBot.config.user} help").to respond_with_slack_message(message)
|
9
27
|
end
|
10
28
|
end
|
@@ -16,7 +16,7 @@ describe SlackRubyBot::Hooks::Message do
|
|
16
16
|
it 'returns only built in command classes' do
|
17
17
|
expect(built_in_command_classes).to include SlackRubyBot::Commands::Hi
|
18
18
|
expect(built_in_command_classes).to include SlackRubyBot::Commands::Default
|
19
|
-
expect(built_in_command_classes).to include SlackRubyBot::Commands::
|
19
|
+
expect(built_in_command_classes).to include SlackRubyBot::Commands::HelpCommand
|
20
20
|
expect(built_in_command_classes).to_not include SlackRubyBot::Bot
|
21
21
|
end
|
22
22
|
it 'does not return unknown command class' do
|
@@ -88,4 +88,21 @@ describe SlackRubyBot::Server do
|
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
91
|
+
context '#restart!' do
|
92
|
+
subject do
|
93
|
+
SlackRubyBot::Server.new(token: 'token')
|
94
|
+
end
|
95
|
+
it 'reloads server after disconnection' do
|
96
|
+
expect(subject).to receive(:restart!)
|
97
|
+
subject.send(:client).send(:callbacks)['close'].first.call
|
98
|
+
expect(subject.instance_variable_get(:@stopping)).to be_falsy
|
99
|
+
end
|
100
|
+
it 'does not reload server for inactive account' do
|
101
|
+
stopping = -> { subject.instance_variable_get :@stopping }
|
102
|
+
allow(subject).to receive(:start!) { raise StandardError, 'account_inactive' }
|
103
|
+
expect(stopping.call).to be_falsy
|
104
|
+
subject.restart!
|
105
|
+
expect(stopping.call).to be true
|
106
|
+
end
|
107
|
+
end
|
91
108
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SlackRubyBot::CommandsHelper do
|
4
|
+
let(:bot_class_name) { 'Testing::WeatherBot' }
|
5
|
+
let(:command_class_name) { 'Testing::HelloCommand' }
|
6
|
+
let(:commands_helper) { described_class.instance }
|
7
|
+
|
8
|
+
describe '#capture_help' do
|
9
|
+
let(:help_attrs) { commands_helper.commands_help_attrs }
|
10
|
+
let(:bot_help_attrs) { help_attrs.find { |k| k.class_name == bot_class_name } }
|
11
|
+
let(:command_help_attrs) { help_attrs.find { |k| k.class_name == command_class_name } }
|
12
|
+
|
13
|
+
it 'should save bot class name' do
|
14
|
+
expect(bot_help_attrs).to be
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'captures help attributes correctly' do
|
18
|
+
context 'for command' do
|
19
|
+
it 'command name' do
|
20
|
+
expect(command_help_attrs.command_name).to eq('hello')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'command description' do
|
24
|
+
expect(command_help_attrs.command_desc).to eq('Says hello.')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'command long description' do
|
28
|
+
expect(command_help_attrs.command_long_desc).to eq('The long description')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'for bot' do
|
33
|
+
it 'name' do
|
34
|
+
expect(bot_help_attrs.command_name).to eq('Weather Bot')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'description' do
|
38
|
+
expect(bot_help_attrs.command_desc).to eq('This bot tells you the weather.')
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'commands' do
|
42
|
+
let(:clouds_command) { bot_help_attrs.commands.find { |k| k.command_name == 'clouds' } }
|
43
|
+
let(:weather_command) { bot_help_attrs.commands.find { |k| k.command_name == "What's the weather in <city>?" } }
|
44
|
+
|
45
|
+
it 'command name' do
|
46
|
+
expect(clouds_command).to be
|
47
|
+
expect(weather_command).to be
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'command description' do
|
51
|
+
expect(clouds_command.command_desc).to eq("Tells you how many clouds there're above you.")
|
52
|
+
expect(weather_command.command_desc).to eq('Tells you the weather in a <city>.')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'command long description' do
|
56
|
+
expect(weather_command.command_long_desc).to eq("Accurate 10 Day Weather Forecasts for thousands of places around the World.\n" \
|
57
|
+
'We provide detailed Weather Forecasts over a 10 day period updated four times a day.')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#bot_desc_and_commands' do
|
65
|
+
let(:bot_desc) { commands_helper.bot_desc_and_commands.first }
|
66
|
+
|
67
|
+
it 'returns bot name and description' do
|
68
|
+
expect(bot_desc).to include('*Weather Bot* - This bot tells you the weather.')
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'returns possible commands for bot' do
|
72
|
+
expect(bot_desc).to include("\n\n*Commands:*\n")
|
73
|
+
expect(bot_desc).to include("*clouds* - Tells you how many clouds there're above you.\n")
|
74
|
+
expect(bot_desc).to include("*What's the weather in <city>?* - Tells you the weather in a <city>.")
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'do not return command with empty name' do
|
78
|
+
expect(bot_desc).to_not include('**')
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'do not show description for command without description' do
|
82
|
+
expect(bot_desc).to include("*command_without_description*\n")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#other_commands_descs' do
|
87
|
+
let(:commands_desc) { commands_helper.other_commands_descs }
|
88
|
+
let(:hello_command_desc) { commands_desc.find { |desc| desc =~ /\*hello\*/ } }
|
89
|
+
|
90
|
+
it 'returns command name and description' do
|
91
|
+
expect(hello_command_desc).to eq('*hello* - Says hello.')
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe '#command_full_desc' do
|
96
|
+
context 'for bot commands' do
|
97
|
+
it 'returns long description' do
|
98
|
+
full_desc = commands_helper.command_full_desc("What's the weather in <city>?")
|
99
|
+
expect(full_desc).to include "Accurate 10 Day Weather Forecasts for thousands of places around the World.\n" \
|
100
|
+
'We provide detailed Weather Forecasts over a 10 day period updated four times a day.'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'for other commands' do
|
105
|
+
it 'returns long description' do
|
106
|
+
full_desc = commands_helper.command_full_desc('hello')
|
107
|
+
expect(full_desc).to include 'The long description'
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'returns correct message if there is no such command' do
|
112
|
+
full_desc = commands_helper.command_full_desc('deploy')
|
113
|
+
expect(full_desc).to eq "There's no command *deploy*"
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'returns correct message if there is no long description for the command' do
|
117
|
+
full_desc = commands_helper.command_full_desc('clouds')
|
118
|
+
expect(full_desc).to eq "There's no description for command *clouds*"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
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.8.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Doubrovkine
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.6.0
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: activesupport
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: giphy
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -193,6 +179,7 @@ files:
|
|
193
179
|
- lib/slack-ruby-bot/commands/about.rb
|
194
180
|
- lib/slack-ruby-bot/commands/base.rb
|
195
181
|
- lib/slack-ruby-bot/commands/help.rb
|
182
|
+
- lib/slack-ruby-bot/commands/help/attrs.rb
|
196
183
|
- lib/slack-ruby-bot/commands/hi.rb
|
197
184
|
- lib/slack-ruby-bot/commands/unknown.rb
|
198
185
|
- lib/slack-ruby-bot/config.rb
|
@@ -202,6 +189,7 @@ files:
|
|
202
189
|
- lib/slack-ruby-bot/hooks/message.rb
|
203
190
|
- lib/slack-ruby-bot/hooks/set.rb
|
204
191
|
- lib/slack-ruby-bot/rspec.rb
|
192
|
+
- lib/slack-ruby-bot/rspec/support/bots_for_tests.rb
|
205
193
|
- lib/slack-ruby-bot/rspec/support/fixtures/slack/migration_in_progress.yml
|
206
194
|
- lib/slack-ruby-bot/rspec/support/slack-ruby-bot/it_behaves_like_a_slack_bot.rb
|
207
195
|
- lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_error.rb
|
@@ -210,12 +198,14 @@ files:
|
|
210
198
|
- lib/slack-ruby-bot/rspec/support/slack_ruby_bot_configure.rb
|
211
199
|
- lib/slack-ruby-bot/rspec/support/vcr.rb
|
212
200
|
- lib/slack-ruby-bot/server.rb
|
201
|
+
- lib/slack-ruby-bot/support/commands_helper.rb
|
213
202
|
- lib/slack-ruby-bot/support/loggable.rb
|
214
203
|
- lib/slack-ruby-bot/version.rb
|
215
204
|
- lib/slack_ruby_bot.rb
|
216
205
|
- screenshots/aliases.gif
|
217
206
|
- screenshots/demo.gif
|
218
207
|
- screenshots/dms.gif
|
208
|
+
- screenshots/help.png
|
219
209
|
- screenshots/market.gif
|
220
210
|
- screenshots/register-bot.png
|
221
211
|
- screenshots/weather.gif
|
@@ -234,6 +224,7 @@ files:
|
|
234
224
|
- spec/slack-ruby-bot/commands/commands_with_expression_spec.rb
|
235
225
|
- spec/slack-ruby-bot/commands/direct_messages_spec.rb
|
236
226
|
- spec/slack-ruby-bot/commands/empty_text_spec.rb
|
227
|
+
- spec/slack-ruby-bot/commands/help/attrs_spec.rb
|
237
228
|
- spec/slack-ruby-bot/commands/help_spec.rb
|
238
229
|
- spec/slack-ruby-bot/commands/hi_spec.rb
|
239
230
|
- spec/slack-ruby-bot/commands/match_spec.rb
|
@@ -253,6 +244,7 @@ files:
|
|
253
244
|
- spec/slack-ruby-bot/hooks/set_spec.rb
|
254
245
|
- spec/slack-ruby-bot/rspec/respond_with_error_spec.rb
|
255
246
|
- spec/slack-ruby-bot/server_spec.rb
|
247
|
+
- spec/slack-ruby-bot/support/commands_helper_spec.rb
|
256
248
|
- spec/slack-ruby-bot/support/loggable_spec.rb
|
257
249
|
- spec/slack-ruby-bot/version_spec.rb
|
258
250
|
- spec/spec_helper.rb
|
@@ -276,7 +268,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
276
268
|
version: 1.3.6
|
277
269
|
requirements: []
|
278
270
|
rubyforge_project:
|
279
|
-
rubygems_version: 2.
|
271
|
+
rubygems_version: 2.4.8
|
280
272
|
signing_key:
|
281
273
|
specification_version: 4
|
282
274
|
summary: The easiest way to write a Slack bot in Ruby.
|
@@ -294,6 +286,7 @@ test_files:
|
|
294
286
|
- spec/slack-ruby-bot/commands/commands_with_expression_spec.rb
|
295
287
|
- spec/slack-ruby-bot/commands/direct_messages_spec.rb
|
296
288
|
- spec/slack-ruby-bot/commands/empty_text_spec.rb
|
289
|
+
- spec/slack-ruby-bot/commands/help/attrs_spec.rb
|
297
290
|
- spec/slack-ruby-bot/commands/help_spec.rb
|
298
291
|
- spec/slack-ruby-bot/commands/hi_spec.rb
|
299
292
|
- spec/slack-ruby-bot/commands/match_spec.rb
|
@@ -313,6 +306,7 @@ test_files:
|
|
313
306
|
- spec/slack-ruby-bot/hooks/set_spec.rb
|
314
307
|
- spec/slack-ruby-bot/rspec/respond_with_error_spec.rb
|
315
308
|
- spec/slack-ruby-bot/server_spec.rb
|
309
|
+
- spec/slack-ruby-bot/support/commands_helper_spec.rb
|
316
310
|
- spec/slack-ruby-bot/support/loggable_spec.rb
|
317
311
|
- spec/slack-ruby-bot/version_spec.rb
|
318
312
|
- spec/spec_helper.rb
|