slack-ruby-bot 0.11.2 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/.gitignore +3 -2
  4. data/.rubocop.yml +14 -1
  5. data/.rubocop_todo.yml +14 -42
  6. data/.travis.yml +11 -13
  7. data/CHANGELOG.md +39 -6
  8. data/CONTRIBUTING.md +5 -1
  9. data/DEPLOYMENT.md +63 -9
  10. data/Dangerfile +4 -0
  11. data/Gemfile +11 -7
  12. data/LICENSE.md +1 -1
  13. data/MIGRATION.md +13 -0
  14. data/README.md +133 -65
  15. data/Rakefile +2 -0
  16. data/TUTORIAL.md +23 -0
  17. data/UPGRADING.md +50 -0
  18. data/examples/inventory/Gemfile +2 -0
  19. data/examples/inventory/inventorybot.rb +5 -1
  20. data/examples/market/Gemfile +4 -3
  21. data/examples/market/marketbot.rb +22 -15
  22. data/examples/minimal/Gemfile +3 -1
  23. data/examples/minimal/pongbot.rb +2 -0
  24. data/examples/weather/Gemfile +2 -0
  25. data/examples/weather/weatherbot.rb +2 -0
  26. data/lib/config/application.rb +4 -2
  27. data/lib/config/boot.rb +2 -0
  28. data/lib/config/environment.rb +3 -1
  29. data/lib/slack-ruby-bot.rb +3 -1
  30. data/lib/slack-ruby-bot/about.rb +3 -1
  31. data/lib/slack-ruby-bot/app.rb +18 -12
  32. data/lib/slack-ruby-bot/bot.rb +3 -1
  33. data/lib/slack-ruby-bot/client.rb +25 -23
  34. data/lib/slack-ruby-bot/commands.rb +2 -0
  35. data/lib/slack-ruby-bot/commands/about.rb +3 -1
  36. data/lib/slack-ruby-bot/commands/base.rb +13 -21
  37. data/lib/slack-ruby-bot/commands/help.rb +10 -8
  38. data/lib/slack-ruby-bot/commands/hi.rb +3 -1
  39. data/lib/slack-ruby-bot/commands/support/attrs.rb +2 -0
  40. data/lib/slack-ruby-bot/commands/support/help.rb +4 -0
  41. data/lib/slack-ruby-bot/commands/support/match.rb +4 -3
  42. data/lib/slack-ruby-bot/commands/unknown.rb +3 -1
  43. data/lib/slack-ruby-bot/config.rb +7 -7
  44. data/lib/slack-ruby-bot/hooks.rb +2 -0
  45. data/lib/slack-ruby-bot/hooks/hello.rb +22 -3
  46. data/lib/slack-ruby-bot/hooks/hook_support.rb +2 -6
  47. data/lib/slack-ruby-bot/hooks/message.rb +11 -10
  48. data/lib/slack-ruby-bot/hooks/set.rb +3 -1
  49. data/lib/slack-ruby-bot/mvc.rb +2 -0
  50. data/lib/slack-ruby-bot/mvc/controller/base.rb +4 -3
  51. data/lib/slack-ruby-bot/mvc/model/base.rb +2 -0
  52. data/lib/slack-ruby-bot/mvc/mvc.rb +2 -0
  53. data/lib/slack-ruby-bot/mvc/view/base.rb +2 -0
  54. data/lib/slack-ruby-bot/rspec.rb +3 -1
  55. data/lib/slack-ruby-bot/rspec/support/bots_for_tests.rb +2 -0
  56. data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/it_behaves_like_a_slack_bot.rb +4 -1
  57. data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/not_respond.rb +3 -5
  58. data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_error.rb +3 -7
  59. data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_slack_message.rb +15 -14
  60. data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_slack_messages.rb +26 -19
  61. data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/start_typing.rb +32 -0
  62. data/lib/slack-ruby-bot/rspec/support/slack_api_key.rb +3 -1
  63. data/lib/slack-ruby-bot/rspec/support/slack_ruby_bot_configure.rb +2 -0
  64. data/lib/slack-ruby-bot/rspec/support/spec_helpers.rb +2 -0
  65. data/lib/slack-ruby-bot/server.rb +5 -28
  66. data/lib/slack-ruby-bot/support/loggable.rb +2 -0
  67. data/lib/slack-ruby-bot/version.rb +3 -1
  68. data/lib/slack_ruby_bot.rb +2 -0
  69. data/screenshots/create-classic-app.png +0 -0
  70. data/slack-ruby-bot.gemspec +6 -3
  71. data/spec/slack-ruby-bot/app_spec.rb +64 -1
  72. data/spec/slack-ruby-bot/client_spec.rb +103 -28
  73. data/spec/slack-ruby-bot/commands/about_spec.rb +2 -0
  74. data/spec/slack-ruby-bot/commands/aliases_spec.rb +2 -0
  75. data/spec/slack-ruby-bot/commands/attachment_spec.rb +2 -0
  76. data/spec/slack-ruby-bot/commands/bot_message_spec.rb +2 -0
  77. data/spec/slack-ruby-bot/commands/bot_messages_spec.rb +26 -0
  78. data/spec/slack-ruby-bot/commands/bot_spec.rb +2 -0
  79. data/spec/slack-ruby-bot/commands/commands_command_classes_spec.rb +2 -0
  80. data/spec/slack-ruby-bot/commands/commands_permitted_spec.rb +2 -0
  81. data/spec/slack-ruby-bot/commands/commands_precedence_spec.rb +2 -0
  82. data/spec/slack-ruby-bot/commands/commands_regexp_escape_spec.rb +2 -0
  83. data/spec/slack-ruby-bot/commands/commands_regexp_spec.rb +2 -0
  84. data/spec/slack-ruby-bot/commands/commands_spaces_spec.rb +2 -0
  85. data/spec/slack-ruby-bot/commands/commands_spec.rb +2 -0
  86. data/spec/slack-ruby-bot/commands/commands_with_block_spec.rb +2 -0
  87. data/spec/slack-ruby-bot/commands/commands_with_expression_spec.rb +2 -0
  88. data/spec/slack-ruby-bot/commands/direct_messages_spec.rb +2 -0
  89. data/spec/slack-ruby-bot/commands/empty_text_spec.rb +2 -0
  90. data/spec/slack-ruby-bot/commands/help_spec.rb +15 -13
  91. data/spec/slack-ruby-bot/commands/hi_spec.rb +2 -0
  92. data/spec/slack-ruby-bot/commands/match_spec.rb +2 -0
  93. data/spec/slack-ruby-bot/commands/message_loop_spec.rb +2 -0
  94. data/spec/slack-ruby-bot/commands/nil_message_spec.rb +2 -0
  95. data/spec/slack-ruby-bot/commands/non_breaking_space_spec.rb +29 -0
  96. data/spec/slack-ruby-bot/commands/not_implemented_spec.rb +2 -0
  97. data/spec/slack-ruby-bot/commands/operators_spec.rb +2 -0
  98. data/spec/slack-ruby-bot/commands/operators_with_block_spec.rb +2 -0
  99. data/spec/slack-ruby-bot/commands/scan_spec.rb +2 -0
  100. data/spec/slack-ruby-bot/commands/send_message_spec.rb +2 -0
  101. data/spec/slack-ruby-bot/commands/support/attrs_spec.rb +2 -0
  102. data/spec/slack-ruby-bot/commands/support/help_spec.rb +2 -0
  103. data/spec/slack-ruby-bot/commands/support/match_spec.rb +2 -0
  104. data/spec/slack-ruby-bot/commands/unknown_spec.rb +2 -0
  105. data/spec/slack-ruby-bot/config_spec.rb +2 -57
  106. data/spec/slack-ruby-bot/hooks/hello_spec.rb +51 -0
  107. data/spec/slack-ruby-bot/hooks/hook_support_spec.rb +2 -5
  108. data/spec/slack-ruby-bot/hooks/message_spec.rb +8 -35
  109. data/spec/slack-ruby-bot/hooks/set_spec.rb +2 -0
  110. data/spec/slack-ruby-bot/mvc/controller/controller_to_command_spec.rb +2 -0
  111. data/spec/slack-ruby-bot/rspec/respond_with_error_spec.rb +2 -0
  112. data/spec/slack-ruby-bot/rspec/respond_with_slack_message_spec.rb +20 -0
  113. data/spec/slack-ruby-bot/rspec/respond_with_slack_messages_spec.rb +36 -0
  114. data/spec/slack-ruby-bot/rspec/start_typing_spec.rb +36 -0
  115. data/spec/slack-ruby-bot/server_spec.rb +6 -33
  116. data/spec/slack-ruby-bot/support/loggable_spec.rb +2 -0
  117. data/spec/slack-ruby-bot/version_spec.rb +2 -0
  118. data/spec/spec_helper.rb +3 -6
  119. data/{lib/slack-ruby-bot/rspec → spec}/support/fixtures/slack/migration_in_progress.yml +0 -0
  120. data/{lib/slack-ruby-bot/rspec → spec}/support/vcr.rb +2 -0
  121. metadata +28 -29
  122. data/lib/initializers/giphy.rb +0 -8
  123. data/lib/initializers/giphy_client.rb +0 -39
  124. data/lib/slack-ruby-bot/rspec/support/fixtures/slack/giphy_burrito.yml +0 -69
  125. data/lib/slack-ruby-bot/rspec/support/fixtures/slack/giphy_client_burrito.yml +0 -71
  126. data/lib/slack-ruby-bot/rspec/support/fixtures/slack/giphy_client_burrito_rated_y.yml +0 -71
  127. data/screenshots/register-bot.png +0 -0
  128. data/spec/slack-ruby-bot/commands/send_gif_spec.rb +0 -25
  129. data/spec/slack-ruby-bot/commands/send_message_with_gif_spec.rb +0 -38
  130. data/spec/slack-ruby-bot/initializers/giphy_client_spec.rb +0 -28
  131. data/spec/slack-ruby-bot/initializers/giphy_spec.rb +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5ce2b630c8c8febedc5e967ff7fddeaa50cea17b881fb73fa2a7bf58e486005c
4
- data.tar.gz: 7eb5553808ed92fbcb256e35f2d7fb85b5943841a5205fb3b05b73f271f18817
3
+ metadata.gz: 9684c9f89d4dfb8fa0b6d57c65392979f40a6371bac3021d427f662e0a4c64db
4
+ data.tar.gz: 67d12056a667d6670b9f3f90c1df15f9e437a87b11a5aa438616bb3774d27b89
5
5
  SHA512:
6
- metadata.gz: 3b6b488d4b4b2aa1911429abac4d591a977926c715580d534d8b21ebc88f9c3babad8dcbf5e9a773e123abaa882e2a98267aa8befefe9d8f11dc396c307246c0
7
- data.tar.gz: 12859a82a5f268068b630efe1535c18206d2cee981839110aa6113e05fabf02f5024a0d3ca297972f4de81de7403d3b77f26af6e5f6f08c58fbea2e65ea4e111
6
+ metadata.gz: a702d1e2016adf8903fa0283201e51e572663e0bafa8fd2b4ffa255764ce99779022bc653ed8dbc5888490521c6d9ebe8b24774084afb056526c62d9c4b3507c
7
+ data.tar.gz: d05e13f9c714eb5c97e1257e775126a42579cd5f41181e285aa79df54ceb0175f6138a056c4c7a89160e5ff53fa13fa53fff02a7d2f507c9c05fea0d9ef958f2
@@ -0,0 +1 @@
1
+ github: [dblock]
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
+ .bundle
2
+ .DS_Store
1
3
  .env
2
- pkg
3
4
  Gemfile.lock
4
- .bundle
5
+ pkg
@@ -1,4 +1,5 @@
1
1
  AllCops:
2
+ TargetRubyVersion: 2.3
2
3
  Exclude:
3
4
  - vendor/**/*
4
5
  - examples/**/vendor/**/*
@@ -7,10 +8,22 @@ AllCops:
7
8
  Metrics:
8
9
  Enabled: false
9
10
 
10
- Metrics/LineLength:
11
+ Layout/LineLength:
11
12
  Max: 512
12
13
 
13
14
  Style/Documentation:
14
15
  Enabled: false
15
16
 
17
+ Style/HashEachMethods:
18
+ Enabled: true
19
+
20
+ Style/HashTransformKeys:
21
+ Enabled: true
22
+
23
+ Style/HashTransformValues:
24
+ Enabled: true
25
+
26
+ Style/ModuleFunction:
27
+ Enabled: false
28
+
16
29
  inherit_from: .rubocop_todo.yml
@@ -1,36 +1,22 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2018-08-27 14:16:34 +0200 using RuboCop version 0.58.2.
3
+ # on 2020-06-27 10:38:47 -0400 using RuboCop version 0.80.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 2
10
- # Cop supports --auto-correct.
11
- # Configuration parameters: EnforcedStyle.
12
- # SupportedStyles: auto_detection, squiggly, active_support, powerpack, unindent
13
- Layout/IndentHeredoc:
14
- Exclude:
15
- - 'lib/slack-ruby-bot/commands/help.rb'
16
- - 'spec/slack-ruby-bot/commands/help_spec.rb'
17
-
18
9
  # Offense count: 1
19
10
  Lint/DuplicateMethods:
20
11
  Exclude:
21
12
  - 'lib/slack-ruby-bot/hooks/set.rb'
22
13
 
23
- # Offense count: 2
24
- Lint/HandleExceptions:
25
- Exclude:
26
- - 'lib/initializers/giphy.rb'
27
- - 'lib/initializers/giphy_client.rb'
28
-
29
14
  # Offense count: 1
30
- # Cop supports --auto-correct.
31
- Lint/UnneededCopEnableDirective:
15
+ # Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
16
+ # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
17
+ Naming/FileName:
32
18
  Exclude:
33
- - 'Gemfile'
19
+ - 'lib/slack-ruby-bot.rb'
34
20
 
35
21
  # Offense count: 2
36
22
  # Configuration parameters: EnforcedStyle.
@@ -46,32 +32,18 @@ Style/AccessModifierDeclarations:
46
32
  Exclude:
47
33
  - 'lib/slack-ruby-bot/hooks/hook_support.rb'
48
34
 
49
- # Offense count: 1
35
+ # Offense count: 5
50
36
  Style/DoubleNegation:
51
37
  Exclude:
38
+ - 'lib/slack-ruby-bot/client.rb'
52
39
  - 'lib/slack-ruby-bot/commands/base.rb'
40
+ - 'lib/slack-ruby-bot/config.rb'
53
41
 
54
- # Offense count: 5
55
- # Cop supports --auto-correct.
56
- Style/ExpandPathArguments:
57
- Exclude:
58
- - 'lib/config/application.rb'
59
- - 'lib/config/environment.rb'
60
- - 'lib/slack-ruby-bot.rb'
61
- - 'slack-ruby-bot.gemspec'
62
-
63
- # Offense count: 2
64
- # Cop supports --auto-correct.
65
- Style/IfUnlessModifier:
66
- Exclude:
67
- - 'lib/slack-ruby-bot/commands/support/match.rb'
68
- - 'lib/slack-ruby-bot/mvc/controller/base.rb'
69
-
70
- # Offense count: 2
42
+ # Offense count: 1
71
43
  # Cop supports --auto-correct.
72
- # Configuration parameters: EnforcedStyle.
73
- # SupportedStyles: module_function, extend_self
74
- Style/ModuleFunction:
44
+ # Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods.
45
+ # SupportedStyles: predicate, comparison
46
+ Style/NumericPredicate:
75
47
  Exclude:
76
- - 'lib/initializers/giphy_client.rb'
77
- - 'lib/slack-ruby-bot/config.rb'
48
+ - 'spec/**/*'
49
+ - 'examples/market/marketbot.rb'
@@ -4,23 +4,21 @@ cache: bundler
4
4
 
5
5
  matrix:
6
6
  include:
7
- - rvm: 2.3.0
7
+ - rvm: 2.6.5
8
8
  script:
9
9
  - bundle exec danger
10
- - rvm: 2.3.0
10
+ - rvm: 2.4.0
11
11
  env: CONCURRENCY=celluloid-io
12
- - rvm: 2.3.0
12
+ - rvm: 2.4.0
13
13
  env: CONCURRENCY=faye-websocket
14
- - rvm: 2.3.0
15
- env: CONCURRENCY=celluloid-io WITH_GIPHY=true
16
- - rvm: 2.3.0
17
- env: CONCURRENCY=faye-websocket WITH_GIPHY=true
18
- - rvm: 2.3.0
19
- env: CONCURRENCY=celluloid-io WITH_GIPHY_CLIENT=true
20
- - rvm: 2.3.0
21
- env: CONCURRENCY=faye-websocket WITH_GIPHY_CLIENT=true
22
- - rvm: 2.5
23
- env: CONCURRENCY=async-websocket WITH_GIPHY_CLIENT=true
14
+ - rvm: 2.4.0
15
+ env: CONCURRENCY=async-websocket
16
+ - rvm: 2.6.5
17
+ env: CONCURRENCY=celluloid-io
18
+ - rvm: 2.6.5
19
+ env: CONCURRENCY=faye-websocket
20
+ - rvm: 2.6.5
21
+ env: CONCURRENCY=async-websocket
24
22
  - rvm: ruby-head
25
23
  - rvm: jruby-head
26
24
  allow_failures:
@@ -1,14 +1,47 @@
1
- ### 0.11.2 (2018/12/01)
1
+ ### 0.16.0 (2020/7/26)
2
+
3
+ * [#263](https://github.com/slack-ruby/slack-ruby-bot/pull/263): Removed Giphy support - [@dblock](https://github.com/dblock).
4
+ * [#260](https://github.com/slack-ruby/slack-ruby-bot/pull/260): Added a brief migration guide - [@wasabigeek](https://github.com/wasabigeek).
5
+ * [#264](https://github.com/slack-ruby/slack-ruby-bot/pull/264): Added TOC to README - [@dblock](https://github.com/dblock).
6
+ * [#265](https://github.com/slack-ruby/slack-ruby-bot/pull/265): Made `allow_bot_messages` and `allow_message_loops` available in `SlackRubyBot::Client` - [@dblock](https://github.com/dblock).
7
+ * [#266](https://github.com/slack-ruby/slack-ruby-bot/pull/266): Removed deprecated `Server#hooks` - [@dblock](https://github.com/dblock).
8
+ * [#267](https://github.com/slack-ruby/slack-ruby-bot/pull/267): Require Faraday >= 1.0 - [@dblock](https://github.com/dblock).
9
+
10
+ ### 0.15.0 (2020/5/8)
11
+
12
+ * [#258](https://github.com/slack-ruby/slack-ruby-bot/pull/258): Extract development dependencies (VCR) from shared rspec configuraion - [@dikond](https://github.com/dikond).
13
+ * [#256](https://github.com/slack-ruby/slack-ruby-bot/pull/256): Allow command matcher to receive no-break spaces as regular spaces - [@MichaelM-Shopify](https://github.com/MichaelM-Shopify), [@dblock](https://github.com/dblock).
14
+ * [#254](https://github.com/slack-ruby/slack-ruby-bot/pull/254): Allow setting of `config.token` and `config.aliases` in initializer - [@wasabigeek](https://github.com/wasabigeek).
15
+ * [#253](https://github.com/slack-ruby/slack-ruby-bot/pull/253): Remove reference to unsupported Giphy content rating - [@wasabigeek](https://github.com/wasabigeek).
16
+
17
+ ### 0.14.0 (2020/4/2)
18
+
19
+ * [#250](https://github.com/slack-ruby/slack-ruby-bot/pull/250): Added `config.allow_bot_messages`, defaults to `false` - [@dblock](https://github.com/dblock).
20
+
21
+ ### 0.13.0 (2020/3/28)
22
+
23
+ * [#244](https://github.com/slack-ruby/slack-ruby-bot/pull/244): Change log message when the bot is reconnected - [@wasabigeek](https://github.com/wasabigeek).
24
+ * [#209](https://github.com/slack-ruby/slack-ruby-bot/pull/209): Allow `respond_to_slack_message` and `respond_to_slack_messages` without arguments - [@dblock](https://github.com/dblock).
25
+ * [#216](https://github.com/slack-ruby/slack-ruby-bot/pull/216): Added `start_typing` RSpec matcher - [@dblock](https://github.com/dblock).
26
+ * [#214](https://github.com/slack-ruby/slack-ruby-bot/pull/214): Add passenger deployment documentation - [@cybercrediators](https://github.com/cybercrediators).
27
+ * [#220](https://github.com/slack-ruby/slack-ruby-bot/pull/220): Updated examples/market to pull from IEX instead of defunct yahoo service - [@corprew](https://github.com/corprew).
28
+ * [#246](https://github.com/slack-ruby/slack-ruby-bot/pull/246): Drop support for Ruby 2.2 - [@dblock](https://github.com/dblock).
29
+
30
+ ### 0.12.0 (2019/2/25)
31
+
32
+ * [#203](https://github.com/slack-ruby/slack-ruby-bot/pull/203): Removing restart logic - [@RodneyU215](https://github.com/RodneyU215).
33
+
34
+ ### 0.11.2 (2018/12/1)
2
35
 
3
36
  * [#198](https://github.com/slack-ruby/slack-ruby-bot/pull/198): Recommend using `async-websocket` instead of `celluloid-io` - [@dblock](https://github.com/dblock).
4
37
  * [#202](https://github.com/slack-ruby/slack-ruby-bot/pull/202): Allow frozen string in Hooks::Message - [@jonosenior](https://github.com/jonosenior).
5
38
 
6
- ### 0.11.1 (2018/05/06)
39
+ ### 0.11.1 (2018/5/6)
7
40
 
8
41
  * [#187](https://github.com/slack-ruby/slack-ruby-bot/pull/187): Added support for the [official Giphy SDK](https://github.com/Giphy/giphy-ruby-client) - [@dblock](https://github.com/dblock).
9
42
  * [#185](https://github.com/slack-ruby/slack-ruby-bot/pull/185): Log backtrace of exceptions - [@dblock](https://github.com/dblock).
10
43
 
11
- ### 0.11.0 (2018/04/02)
44
+ ### 0.11.0 (2018/4/2)
12
45
 
13
46
  * [#182](https://github.com/slack-ruby/slack-ruby-bot/pull/182): Refactor CommandsHelper class and Help module - [@mdudzinski](https://github.com/mdudzinski).
14
47
  * [#180](https://github.com/slack-ruby/slack-ruby-bot/pull/180): Allow to respond to text in attachments #177 - [@mdudzinski](https://github.com/mdudzinski).
@@ -24,18 +57,18 @@
24
57
  * [#163](https://github.com/slack-ruby/slack-ruby-bot/pull/163): Allow `command` to accept regular expressions - [@kstole](https://github.com/kstole).
25
58
  * [#166](https://github.com/slack-ruby/slack-ruby-bot/pull/166): Allow special characters and capitals in bot aliases - [@kstole](https://github.com/kstole).
26
59
 
27
- ### 0.10.4 (2017/07/05)
60
+ ### 0.10.4 (2017/7/5)
28
61
 
29
62
  * [#149](https://github.com/slack-ruby/slack-ruby-bot/pull/149): Add `logger` configuration to set a custom logger - [@upscent](https://github.com/upscent).
30
63
  * [#147](https://github.com/slack-ruby/slack-ruby-bot/pull/147): Adds `server.on` as a shortcut for `hooks.add` and deprecate `hooks` method - [@laertispappas](https://github.com/laertispappas).
31
64
  * [#143](https://github.com/slack-ruby/slack-ruby-bot/pull/143): Provide `permitted?` method to allow for simple authorization extensions - [@chuckremes](https://github.com/chuckremes).
32
65
 
33
- ### 0.10.3 (2017/06/15)
66
+ ### 0.10.3 (2017/6/15)
34
67
 
35
68
  * [#145](https://github.com/slack-ruby/slack-ruby-bot/pull/145): Map multiple command strings to same controller method - [@chuckremes](https://github.com/chuckremes).
36
69
  * [#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).
37
70
 
38
- ### 0.10.2 (2017/06/03)
71
+ ### 0.10.2 (2017/6/3)
39
72
 
40
73
  * [#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).
41
74
  * [#130](https://github.com/slack-ruby/slack-ruby-bot/issues/130): Added test dependencies in TUTORIAL.md - [@jbristow](https://github.com/jbristow).
@@ -18,13 +18,17 @@ git remote add upstream https://github.com/slack-ruby/slack-ruby-bot.git
18
18
 
19
19
  ## Bundle Install and Test
20
20
 
21
- Ensure that you can build the project and run tests.
21
+ Ensure that you can build the project and run tests. Make sure you have set `CONCURRENCY` env variable to one of the following: `celluloid-io`, `faye-websocket` or `async-websocket`.
22
22
 
23
23
  ```
24
+ export CONCURRENCY=async-websocket
24
25
  bundle install
25
26
  bundle exec rake
26
27
  ```
27
28
 
29
+ Take a look at the [travis configuration](https://github.com/slack-ruby/slack-ruby-bot/blob/master/.travis.yml) for more details.
30
+
31
+
28
32
  ## Run SlackRubyBot in Development
29
33
 
30
34
  Create a private slack group for yourself.
@@ -1,25 +1,27 @@
1
1
  ## Installation
2
2
 
3
- Create a new Bot Integration under [services/new/bot](http://slack.com/services/new/bot).
3
+ To integrate your bot with Slack, you must first create a new [Classic Slack App](https://api.slack.com/authentication/migration#classic) and a [legacy bot](https://api.slack.com/legacy/custom-integrations/bot-users).
4
4
 
5
- ![](screenshots/register-bot.png)
6
-
7
- On the next screen, note the API token.
5
+ ![](screenshots/create-classic-app.png)
8
6
 
9
7
  ### Environment
10
8
 
9
+ #### OAuth Code Grant
10
+
11
+ Once created, go to the app's Basic Info tab and grab the Client ID and Client Secret. You'll need these in order complete an [OAuth code grant flow](https://api.slack.com/docs/oauth#flow) as described at [slack-ruby-bot-server](https://github.com/slack-ruby/slack-ruby-bot-server). A successful flow will result in the receipt of an API token for the specific team that is granting access.
12
+
13
+ Alternatively, you can still [generate a legacy API token](https://api.slack.com/custom-integrations/legacy-tokens) for your app and use it for some interactions.
14
+
15
+ If you have a legacy API token, and would like to migrate to [slack-ruby-bot-server](https://github.com/slack-ruby/slack-ruby-bot-server), a brief [migration guide](MIGRATION.md) is provided.
16
+
11
17
  #### SLACK_API_TOKEN
12
18
 
13
- Set SLACK_API_TOKEN from the Bot integration settings on Slack.
19
+ Set the SLACK_API_TOKEN environment variable using the token received above.
14
20
 
15
21
  ```
16
22
  heroku config:add SLACK_API_TOKEN=...
17
23
  ```
18
24
 
19
- #### GIPHY_API_KEY
20
-
21
- The bot replies with animated GIFs. While it's currently not necessary, you may need to set GIPHY_API_KEY in the future, see [github.com/Giphy/GiphyAPI](https://github.com/Giphy/GiphyAPI) for details.
22
-
23
25
  #### SLACK_RUBY_BOT_ALIASES
24
26
 
25
27
  Optional names for this bot.
@@ -31,3 +33,55 @@ heroku config:add SLACK_RUBY_BOT_ALIASES=":pong: table-tennis ping-pong"
31
33
  ### Heroku Idling
32
34
 
33
35
  Heroku free tier applications will idle. Either pay 7$ a month for the hobby dyno or use [UptimeRobot](http://uptimerobot.com) or similar to prevent your instance from sleeping or pay for a production dyno.
36
+
37
+ ### Passenger Deployment
38
+
39
+ Deploying on your self-hosted server is fairly easy, it's pretty much following the [tutorial](https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby), but there are some configuration details to pay attention to.
40
+
41
+ + Change or add the `gem 'puma'` entry in your `Gemfile` to `gem 'passenger'` and `bundle` it
42
+ + OPTIONAL: To use passenger for developing too, change the `Procfile` to `web: bundle exec passenger start`, to configure the local passenger you could provide an optional `Passenger.json` file ([configuration options](https://www.phusionpassenger.com/library/config/standalone/reference/))
43
+ + If you want to keep your logs etc. in the correct folders, you could add empty `public/`, `tmp/` and `log` directories. Passenger e.g. will automatically use them for local log files.
44
+ + Make sure, the right ruby version is [installed](https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby/ownserver/nginx/oss/install_language_runtime.html) and your passenger is [ready](https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby/ownserver/nginx/oss/install_passenger_main.html) to go.
45
+ + Clone the repository on your server (You could create a separate user for this) and install the dependencies, by running `bundle install` ([More information](https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby/ownserver/nginx/oss/xenial/deploy_app.html))
46
+ + Edit the web-server configuration according to the examples below
47
+ + `PassengerMaxPreloaderIdleTime 0` or `passenger_max_preloader_idle_time 0;` makes sure to not automatically shut down the process after 5 minutes
48
+ + `PassengerPreStart http://url:port` or `passenger_pre_start http://url:port` will startup the application instantly, without the first HTTP GET-request needed for passenger
49
+ + To get the `/path/to/ruby` run `passenger-config about ruby-command` and copy the displayed path
50
+ + Check the config (`nginx -t`) and restart the server with `service nginx restart`
51
+ + Execute `passenger-status --verbose` to check if your app is working correctly
52
+ + Optional: restart the passenger app via `passenger-config restart-app /var/www/bot`
53
+
54
+ #### Nginx
55
+
56
+ ```
57
+ server {
58
+ listen 80;
59
+ server_name example.com;
60
+ root /var/www/bot/public;
61
+ passenger_enabled on;
62
+ passenger_ruby /path/to/ruby
63
+ passenger_max_preloader_idle_time 0;
64
+ passenger_app_type rack;
65
+ }
66
+
67
+ passenger_pre_start http://example.com:80/;
68
+ ```
69
+
70
+ #### Apache
71
+
72
+ ```
73
+ <VirtualHost *:80>
74
+ ServerName example.com
75
+ DocumentRoot /var/www/bot/public
76
+ PassengerRuby /path/to/ruby
77
+ PassengerMaxPreloaderIdleTime 0
78
+
79
+ <Directory /var/www/bot/public>
80
+ Allow from all
81
+ Options -MultiViews
82
+ Require all granted
83
+ </Directory>
84
+ </VirtualHost>
85
+
86
+ PassengerPreStart http://example.com:80/
87
+ ```
data/Dangerfile CHANGED
@@ -1 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  danger.import_dangerfile(gem: 'slack-ruby-danger')
4
+
5
+ toc.check!
data/Gemfile CHANGED
@@ -1,14 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'http://rubygems.org'
2
4
 
3
5
  gemspec
4
6
 
5
- gem ENV['CONCURRENCY'], require: false if ENV.key?('CONCURRENCY')
6
-
7
- # rubocop:enable Bundler/OrderedGems
8
-
9
- gem 'giphy', require: false if ENV.key?('WITH_GIPHY')
10
- gem 'GiphyClient', require: false if ENV.key?('WITH_GIPHY_CLIENT')
7
+ if ENV.key?('CONCURRENCY')
8
+ case ENV['CONCURRENCY']
9
+ when 'async-websocket'
10
+ gem 'async-websocket', '~> 0.8.0', require: false
11
+ else
12
+ gem ENV['CONCURRENCY'], require: false
13
+ end
14
+ end
11
15
 
12
16
  group :test do
13
- gem 'slack-ruby-danger', '~> 0.1.0', require: false
17
+ gem 'slack-ruby-danger', '~> 0.2.0', require: false
14
18
  end
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2015-2016 Daniel Doubrovkine, Artsy and Contributors
3
+ Copyright (c) 2015-2020 Daniel Doubrovkine, Artsy and Contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
@@ -0,0 +1,13 @@
1
+ # Migrating from Legacy API Tokens
2
+
3
+ New Slack Apps require authentication via OAuth, returning an access token that should be a drop-in replacement for `SLACK_API_TOKEN`. As of the time of writing, the tokens never expire, so you could potentially write your own OAuth flow to retrieve the access token separately.
4
+
5
+ Alternatively, you could migrate to [slack-ruby-bot-server](https://github.com/slack-ruby/slack-ruby-bot-server). Note that this requires more infrastructure to support the OAuth flow.
6
+
7
+ ## Migrating to slack-ruby-bot-server
8
+ 1. Setup a new `slack-ruby-bot-server` project, following the [guidelines](https://github.com/slack-ruby/slack-ruby-bot-server#run-your-own).
9
+ 2. Copy over the `SlackRubyBot::Commands::Base` or `SlackRubyBot::Bot` concrete classes from your `slack-ruby-bot` project into the new project. If you used a [sample app](https://github.com/slack-ruby/slack-ruby-bot-server/tree/master/sample_apps), copy them into the [`commands` folder](https://github.com/slack-ruby/slack-ruby-bot-server/tree/master/sample_apps/sample_app_activerecord/commands) and require it in `commands.rb`.
10
+ 3. Create a [Slack Button](https://api.slack.com/docs/slack-button), setting the redirect URL to your OAuth grant endpoint. In the sample app, this would be `<ROOT_URL>/api/teams`.
11
+ 4. Run your app and authenticate with the Slack button.
12
+
13
+ **NOTE**: By default, other teams would be able to authenticate and connect their workspaces using the same Slack button. If this is not what you want, you would need to prevent it.
data/README.md CHANGED
@@ -11,6 +11,51 @@ If you are not familiar with Slack bots or Slack API concepts, you might want to
11
11
 
12
12
  ![](slack.png)
13
13
 
14
+ # Table of Contents
15
+
16
+ - [Useful to Me?](#useful-to-me)
17
+ - [Stable Release](#stable-release)
18
+ - [Usage](#usage)
19
+ - [A Minimal Bot](#a-minimal-bot)
20
+ - [Gemfile](#gemfile)
21
+ - [pongbot.rb](#pongbotrb)
22
+ - [A Production Bot](#a-production-bot)
23
+ - [More Involved Examples](#more-involved-examples)
24
+ - [Commands and Operators](#commands-and-operators)
25
+ - [Threaded Messages](#threaded-messages)
26
+ - [Bot Aliases](#bot-aliases)
27
+ - [Generic Routing](#generic-routing)
28
+ - [Matching text in message attachments](#matching-text-in-message-attachments)
29
+ - [Providing description for your bot and commands](#providing-description-for-your-bot-and-commands)
30
+ - [Customize your command help output](#customize-your-command-help-output)
31
+ - [SlackRubyBot::Commands::Base](#slackrubybotcommandsbase)
32
+ - [Authorization](#authorization)
33
+ - [Built-In Commands](#built-in-commands)
34
+ - [[bot name]](#bot-name)
35
+ - [[bot name] hi](#bot-name-hi)
36
+ - [[bot name] help](#bot-name-help)
37
+ - [Hooks](#hooks)
38
+ - [Implementing and registering a Hook Handler](#implementing-and-registering-a-hook-handler)
39
+ - [Hooks registration on SlackRubyBot::Server initialization](#hooks-registration-on-slackrubybotserver-initialization)
40
+ - [Hooks registration on a SlackRubyBot::Server instance](#hooks-registration-on-a-slackrubybotserver-instance)
41
+ - [Hooks registration on SlackRubyBot::Server class](#hooks-registration-on-slackrubybotserver-class)
42
+ - [Bot Message Protection](#bot-message-protection)
43
+ - [Message Loop Protection](#message-loop-protection)
44
+ - [Logging](#logging)
45
+ - [Advanced Integration](#advanced-integration)
46
+ - [Proxy Configuration](#proxy-configuration)
47
+ - [Model-View-Controller Design](#model-view-controller-design)
48
+ - [Controller](#controller)
49
+ - [Model](#model)
50
+ - [View](#view)
51
+ - [Testing](#testing)
52
+ - [RSpec Shared Behaviors](#rspec-shared-behaviors)
53
+ - [Testing Lower Level Messages](#testing-lower-level-messages)
54
+ - [Useful Libraries](#useful-libraries)
55
+ - [Contributing](#contributing)
56
+ - [Upgrading](#upgrading)
57
+ - [Copyright and License](#copyright-and-license)
58
+
14
59
  ## Useful to Me?
15
60
 
16
61
  * If you are just trying to send messages to Slack, use [slack-ruby-client](https://github.com/slack-ruby/slack-ruby-client), which this library is built on top of.
@@ -19,7 +64,7 @@ If you are not familiar with Slack bots or Slack API concepts, you might want to
19
64
 
20
65
  ## Stable Release
21
66
 
22
- You're reading the documentation for the **stable** release of slack-ruby-bot, v0.11.2.
67
+ You're reading the documentation for the **stable** release of slack-ruby-bot, v0.16.0.
23
68
  See [CHANGELOG](CHANGELOG.md) for a history of changes and [UPGRADING](UPGRADING.md) for how to upgrade to more recent versions.
24
69
 
25
70
  ## Usage
@@ -32,7 +77,7 @@ See [CHANGELOG](CHANGELOG.md) for a history of changes and [UPGRADING](UPGRADING
32
77
  source 'https://rubygems.org'
33
78
 
34
79
  gem 'slack-ruby-bot'
35
- gem 'celluloid-io'
80
+ gem 'async-websocket', '~>0.8.0'
36
81
  ```
37
82
 
38
83
  #### pongbot.rb
@@ -83,7 +128,7 @@ end
83
128
 
84
129
  Command match data includes `match['bot']`, `match['command']` and `match['expression']`. The `bot` match always checks against the `SlackRubyBot::Config.user` and `SlackRubyBot::Config.user_id` values obtained when the bot starts.
85
130
 
86
- The `command` method can take strings, which will have be escaped with `Regexp.escape`, and regular expressions.
131
+ The `command` method can take strings, which will have to be escaped with `Regexp.escape`, and regular expressions.
87
132
 
88
133
  ```ruby
89
134
  class CallBot < SlackRubyBot::Bot
@@ -141,11 +186,9 @@ SlackRubyBot.configure do |config|
141
186
  end
142
187
  ```
143
188
 
144
- This is particularly fun with emoji.
145
-
146
189
  ![](screenshots/aliases.gif)
147
190
 
148
- Bots also will respond to a direct message, with or without the bot name in the message itself.
191
+ Bots will also respond to a direct message, with or without the bot name in the message itself.
149
192
 
150
193
  ![](screenshots/dms.gif)
151
194
 
@@ -269,7 +312,7 @@ class Market < SlackRubyBot::Bot
269
312
  command 'help' do |client, data, match|
270
313
  user_command = match[:expression]
271
314
  help_attrs = SlackRubyBot::Commands::Support::Help.instance.find_command_help_attrs(user_command)
272
- client.say(channel: data.channel, text: "#{help_attrs.command_desc}\n\n#{help_attrs.command_long_desc}"
315
+ client.say(channel: data.channel, text: "#{help_attrs.command_desc}\n\n#{help_attrs.command_long_desc}")
273
316
  end
274
317
  end
275
318
  ```
@@ -320,47 +363,6 @@ class AuthorizedBot < SlackRubyBot::Commands::Base
320
363
  end
321
364
  ```
322
365
 
323
- ### Animated GIFs
324
-
325
- The `SlackRubyBot::Client` implementation comes with GIF support. To enable it add `gem GiphyClient` (official Giphy SDK) or `gem giphy` (older SDK, deprecated) to your **Gemfile** and set a Giphy key via `ENV['GIPHY_API_KEY']`. Obtain one from [developers.giphy.com](https://developers.giphy.com).
326
-
327
- **Note:** Bots send animated GIFs in default commands and errors.
328
-
329
- ```ruby
330
- class Phone < SlackRubyBot::Commands::Base
331
- command 'call'
332
-
333
- def self.call(client, data, match)
334
- client.say(channel: data.channel, text: 'called', gif: 'phone')
335
- # Sends the text 'called' and a random GIF that matches the keyword 'phone'.
336
- end
337
- end
338
- ```
339
-
340
- Giphy API key is set automatically via `ENV['GIPHY_API_KEY']`. You can override this manually.
341
-
342
- ```ruby
343
- Giphy.configure do |config|
344
- config.api_key = 'key'
345
- end
346
- ```
347
-
348
- With `GiphyClient` you can configure the default GIF rating, which supports Y, G, PG, PG-13, and R. The default value is `G`.
349
-
350
- ```ruby
351
- Giphy.configure do |config|
352
- config.rating = 'Y' # illustrated content only, i.e. cartoons
353
- end
354
- ```
355
-
356
- If you use giphy for something else but don't want your bots to send GIFs you can set `ENV['SLACK_RUBY_BOT_SEND_GIFS']` or `SlackRubyBot::Config.send_gifs` to `false`. The latter takes precedence.
357
-
358
- ```ruby
359
- SlackRubyBot.configure do |config|
360
- config.send_gifs = false
361
- end
362
- ```
363
-
364
366
  ### Built-In Commands
365
367
 
366
368
  Slack-ruby-bot comes with several built-in commands. You can re-define built-in commands, normally, as described above.
@@ -381,7 +383,7 @@ Get help.
381
383
 
382
384
  Hooks are event handlers and respond to Slack RTM API [events](https://api.slack.com/events), such as [hello](lib/slack-ruby-bot/hooks/hello.rb) or [message](lib/slack-ruby-bot/hooks/message.rb). You can implement your own in a couple of ways:
383
385
 
384
- #### Implement and register a Hook Handler
386
+ #### Implementing and registering a Hook Handler
385
387
 
386
388
  A Hook Handler is any object that respond to a `call` message, like a proc, instance of an object, class with a `call` class method, etc.
387
389
 
@@ -458,22 +460,19 @@ These will get pushed into the hook set on initialization.
458
460
 
459
461
  Either by configuration, explicit assignment or hook blocks, multiple handlers can exist for the same event type.
460
462
 
463
+ ### Bot Message Protection
461
464
 
462
- #### Deprecated hook registration
463
-
464
- Registering a hook method using `hooks.add` is considered deprecated and
465
- will be removed on future versions.
465
+ By default bots do not respond to self or other bots. If you wish to change that behavior globally, set `allow_bot_messages` to `true`.
466
466
 
467
467
  ```ruby
468
- # [DEPRECATED]
469
- server.hooks.add(:hello, MyBot::Hooks::UserChange.new)
470
- server.hooks.add(:hello, ->(client, data) { puts "Hello!" })
471
-
468
+ SlackRubyBot.configure do |config|
469
+ config.allow_bot_messages = true
470
+ end
472
471
  ```
473
472
 
474
473
  ### Message Loop Protection
475
474
 
476
- By default bots do not respond to their own messages. If you wish to change that behavior, set `allow_message_loops` to `true`.
475
+ By default bots do not respond to their own messages. If you wish to change that behavior globally, set `allow_message_loops` to `true`.
477
476
 
478
477
  ```ruby
479
478
  SlackRubyBot.configure do |config|
@@ -501,14 +500,14 @@ end
501
500
 
502
501
  ### Advanced Integration
503
502
 
504
- You may want to integrate a bot or multiple bots into other systems, in which case a globally configured bot may not work for you. You may create instances of [SlackRubyBot::Server](lib/slack-ruby-bot/server.rb) which accepts `token`, `aliases` and `send_gifs`.
503
+ You may want to integrate a bot or multiple bots into other systems, in which case a globally configured bot may not work for you. You may create instances of [SlackRubyBot::Server](lib/slack-ruby-bot/server.rb) which accepts `token` and `aliases`.
505
504
 
506
505
  ```ruby
507
506
  EM.run do
508
507
  bot1 = SlackRubyBot::Server.new(token: token1, aliases: ['bot1'])
509
508
  bot1.start_async
510
509
 
511
- bot2 = SlackRubyBot::Server.new(token: token2, send_gifs: false, aliases: ['bot2'])
510
+ bot2 = SlackRubyBot::Server.new(token: token2, aliases: ['bot2'])
512
511
  bot2.start_async
513
512
  end
514
513
  ```
@@ -625,7 +624,7 @@ class MyView < SlackRubyBot::MVC::View::Base
625
624
 
626
625
  def react_thumbsup
627
626
  client.web_client.reactions_add(
628
- name: :thumbs_up,
627
+ name: :thumbsup,
629
628
  channel: data.channel,
630
629
  timestamp: data.ts,
631
630
  as_user: true)
@@ -633,7 +632,7 @@ class MyView < SlackRubyBot::MVC::View::Base
633
632
 
634
633
  def react_thumbsdown
635
634
  client.web_client.reactions_remove(
636
- name: :thumbs_up,
635
+ name: :thumbsup,
637
636
  channel: data.channel,
638
637
  timestamp: data.ts,
639
638
  as_user: true)
@@ -652,14 +651,17 @@ Again, the View will have access to the most up to date `client`, `data`, and `m
652
651
 
653
652
  View methods are not matched to routes, so there is no restriction on how to name methods as there is in Controllers.
654
653
 
655
- ### RSpec Shared Behaviors
654
+ ### Testing
655
+
656
+ #### RSpec Shared Behaviors
656
657
 
657
- Slack-ruby-bot ships with a number of shared RSpec behaviors that can be used in your RSpec tests.
658
+ Slack-ruby-bot comes with a number of shared RSpec behaviors that can be used in your RSpec tests.
658
659
 
659
660
  * [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.
660
661
  * [respond with slack message](lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_slack_message.rb): The bot responds with a message.
661
662
  * [respond with slack messages](lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_slack_messages.rb): The bot responds with a multiple messages.
662
663
  * [respond with error](lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_error.rb): An exception is raised inside a bot command.
664
+ * [start typing](lib/slack-ruby-bot/rspec/support/slack-ruby-bot/start_typing.rb): The bot calls `client.start_typing`.
663
665
 
664
666
  Require `slack-ruby-bot/rspec` in your `spec_helper.rb` along with the following dependencies in Gemfile.
665
667
 
@@ -672,6 +674,72 @@ group :development, :test do
672
674
  end
673
675
  ```
674
676
 
677
+ Use the `respond_with_slack_message` matcher.
678
+
679
+ ```ruby
680
+ describe SlackRubyBot::Commands do
681
+ it 'responds with any message' do
682
+ expect(message: "#{SlackRubyBot.config.user} hi").to respond_with_slack_message
683
+ end
684
+ it 'says hi' do
685
+ expect(message: "#{SlackRubyBot.config.user} hi").to respond_with_slack_message('hi')
686
+ end
687
+ end
688
+ ```
689
+
690
+ Use the `respond_with_slack_messages` matcher for multiple messages.
691
+
692
+ ```ruby
693
+ describe SlackRubyBot::Commands do
694
+ it 'responds with more than one message' do
695
+ expect(message: "#{SlackRubyBot.config.user} count").to respond_with_slack_messages
696
+ end
697
+ it 'says one and two' do
698
+ expect(message: "#{SlackRubyBot.config.user} count").to respond_with_slack_messages(['one', 'two'])
699
+ end
700
+ end
701
+ ```
702
+
703
+ Message matchers support regular expressions.
704
+
705
+ ```ruby
706
+ describe SlackRubyBot::Commands do
707
+ it 'says hi' do
708
+ expect(message: "#{SlackRubyBot.config.user} hi").to respond_with_slack_message(/hi/)
709
+ end
710
+ end
711
+ ```
712
+
713
+ Check that the bot called `client.start_typing(channel: 'channel')`.
714
+
715
+ ```ruby
716
+ describe SlackRubyBot::Commands do
717
+ it 'starts typing on channel' do
718
+ expect(message: "#{SlackRubyBot.config.user} hi").to start_typing(channel: 'channel')
719
+ end
720
+ end
721
+ ```
722
+
723
+ #### Testing Lower Level Messages
724
+
725
+ You can test client behavior at a lower level by fetching the message hook. The following example expects a bot command to call `client.typing(channel: data.channel)`.
726
+
727
+ ```ruby
728
+ describe SlackRubyBot::Commands do
729
+ let(:app) { Server.new }
730
+ let(:client) { app.send(:client) }
731
+ let(:message_hook) { SlackRubyBot::Hooks::Message.new }
732
+ it 'receives a typing event' do
733
+ expect(client).to receive(:typing)
734
+ message_hook.call(
735
+ client,
736
+ Hashie::Mash.new(text: "#{SlackRubyBot.config.user} type something", channel: 'channel')
737
+ )
738
+ end
739
+ end
740
+ end
741
+ ```
742
+
675
743
  ### Useful Libraries
676
744
 
677
745
  * [newrelic-slack-ruby-bot](https://github.com/dblock/newrelic-slack-ruby-bot): NewRelic instrumentation for slack-ruby-bot.
@@ -686,6 +754,6 @@ See [CHANGELOG](CHANGELOG.md) for a history of changes and [UPGRADING](UPGRADING
686
754
 
687
755
  ## Copyright and License
688
756
 
689
- Copyright (c) 2015-2016, [Daniel Doubrovkine](https://twitter.com/dblockdotorg), [Artsy](https://www.artsy.net) and [Contributors](CHANGELOG.md).
757
+ Copyright (c) 2015-2020, [Daniel Doubrovkine](https://twitter.com/dblockdotorg), [Artsy](https://www.artsy.net) and [Contributors](CHANGELOG.md).
690
758
 
691
759
  This project is licensed under the [MIT License](LICENSE.md).