slack-ruby-bot-server 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4f6c5511a9161eb4105b995b780da2be43a4e10d
4
- data.tar.gz: c597b55c62c0da9d73fcbc9403efe72ec9d461e1
3
+ metadata.gz: fe3d4e567729e994efcff5222076507a045bb6ed
4
+ data.tar.gz: 0cabe19a3a25a1d6c396a86b9f357ceb6f753faa
5
5
  SHA512:
6
- metadata.gz: 34c926d67dc9be7450fe7447f259e593fa92e4aaeb989ddb838d0a987f37dfd7ccc4abb46aa008e81b889a84746bdd1b54ff6b4761c19b549bcda99d4e5aa49e
7
- data.tar.gz: 2b006e96aca517a203dc2085bf6095abd4c3059e9d2d19121e59864d2cf4dd0f576cd366706f01ea986ebd6d63e1c528bc03abbf1ee3b6ac7d554e646c2d94d6
6
+ metadata.gz: 2e6fbb4ee203832c867036bff4e20a814b64d6d722306c616a677e04a6fe67627019edba8893d974a7ff5b09890faadf39c88aee074915cae058078aa6030964
7
+ data.tar.gz: 458eb4c1e9c41be7b509239acdd16d92d9c12ad41d9d99f33d54a8dca4770d5353cc889a33f27d1b53e2a472c23a52f7130591f89f0cbc13cc943f9dfd4dfc33
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2016-06-20 12:01:59 -0400 using RuboCop version 0.40.0.
3
+ # on 2016-07-01 09:34:39 +0100 using RuboCop version 0.40.0.
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
@@ -11,21 +11,26 @@ Lint/RescueException:
11
11
  Exclude:
12
12
  - 'lib/slack-ruby-bot-server/app.rb'
13
13
 
14
- # Offense count: 7
14
+ # Offense count: 9
15
15
  Metrics/AbcSize:
16
16
  Max: 33
17
17
 
18
+ # Offense count: 1
19
+ # Configuration parameters: CountComments.
20
+ Metrics/ClassLength:
21
+ Max: 117
22
+
18
23
  # Offense count: 2
19
24
  Metrics/CyclomaticComplexity:
20
25
  Max: 11
21
26
 
22
- # Offense count: 77
27
+ # Offense count: 68
23
28
  # Configuration parameters: AllowHeredoc, AllowURI, URISchemes.
24
29
  # URISchemes: http, https
25
30
  Metrics/LineLength:
26
31
  Max: 163
27
32
 
28
- # Offense count: 5
33
+ # Offense count: 8
29
34
  # Configuration parameters: CountComments.
30
35
  Metrics/MethodLength:
31
36
  Max: 23
@@ -34,7 +39,7 @@ Metrics/MethodLength:
34
39
  Metrics/PerceivedComplexity:
35
40
  Max: 11
36
41
 
37
- # Offense count: 23
42
+ # Offense count: 25
38
43
  Style/Documentation:
39
44
  Enabled: false
40
45
 
@@ -44,3 +49,8 @@ Style/FileName:
44
49
  Exclude:
45
50
  - 'lib/slack-ruby-bot-server.rb'
46
51
  - 'lib/slack-ruby-bot-server/ext/slack-ruby-bot.rb'
52
+
53
+ # Offense count: 1
54
+ Style/ModuleFunction:
55
+ Exclude:
56
+ - 'lib/slack-ruby-bot-server/config.rb'
@@ -1,5 +1,10 @@
1
1
  ### Changelog
2
2
 
3
+ #### 0.3.0 (7/4/2016)
4
+
5
+ * Specify the server class via `SlackRubyBotServer.configure`, default is `SlackRubyBotServer::Server` - [@dblock](https://github.com/dblock).
6
+ * Added service management lifecycle callbacks when a new team is registered, deactivated, etc - [@dblock](https://github.com/dblock).
7
+
3
8
  #### 0.2.0 (6/21/2016)
4
9
 
5
10
  * Relaxed dependency versions, notably enabling grape 0.16.2 and Swagger 0.21.0 that uses Swagger 2.0 spec - [@dblock](https://github.com/dblock).
data/README.md CHANGED
@@ -7,6 +7,14 @@ Slack Ruby Bot Server
7
7
 
8
8
  A library that enables you to write a complete Slack bot service with Slack button integration, in Ruby. 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). A good demo of a service built on top of this is [missingkidsbot.org](http://missingkidsbot.org).
9
9
 
10
+ ### What is this?
11
+
12
+ A library that contains a [Grape](http://github.com/ruby-grape/grape) API serving a [Slack Ruby Bot](https://github.com/dblock/slack-ruby-bot) to multiple teams. This gem combines a web server, a RESTful API and multiple instances of [slack-ruby-bot](https://github.com/dblock/slack-ruby-bot). It integrates with the [Slack Platform API](https://medium.com/slack-developer-blog/launch-platform-114754258b91#.od3y71dyo). Your customers can use a Slack button to install the bot.
13
+
14
+ ### Stable Release
15
+
16
+ You're reading the documentation for the **stable** release of slack-ruby-bot-server, 0.3.0. See [UPGRADING](UPGRADING.md) when upgrading from an older version.
17
+
10
18
  ### Try Me
11
19
 
12
20
  A demo version of the [sample app](sample_app) is running on Heroku at [slack-ruby-bot-server.herokuapp.com](https://slack-ruby-bot-server.herokuapp.com). Use the _Add to Slack_ button. The bot will join your team as _@slackbotserver_.
@@ -17,10 +25,6 @@ Once a bot is registered, you can invite to a channel with `/invite @slackbotser
17
25
 
18
26
  ![](images/slackbotserver.gif)
19
27
 
20
- ### What is this?
21
-
22
- A [Grape](http://github.com/ruby-grape/grape) API serving a [Slack Ruby Bot](https://github.com/dblock/slack-ruby-bot) to multiple teams. This gem combines a web server, a RESTful API and multiple instances of [slack-ruby-bot](https://github.com/dblock/slack-ruby-bot). It integrates with the [Slack Platform API](https://medium.com/slack-developer-blog/launch-platform-114754258b91#.od3y71dyo). Your customers can use a Slack button to install the bot.
23
-
24
28
  ### Run Your Own
25
29
 
26
30
  You can use the [sample application](sample_app) to bootstrap your project and start adding slack command handlers on top of this code.
@@ -35,6 +39,68 @@ Follow the instructions, note the app's client ID and secret, give the bot a def
35
39
 
36
40
  If you deploy to Heroku set `SLACK_CLIENT_ID` and `SLACK_CLIENT_SECRET` via `heroku config:add SLACK_CLIENT_ID=... SLACK_CLIENT_SECRET=...`.
37
41
 
42
+ ### API
43
+
44
+ This library implements a service manager, [SlackRubyBotServer::Service](lib/slack-ruby-bot-server/service.rb) that creates multiple instances of a bot server class, [SlackRubyBotServer::Server](lib/slack-ruby-bot-server/server.rb), one per team.
45
+
46
+ #### Service Manager
47
+
48
+ You can introduce custom behavior into the service lifecycle via callbacks. This can be useful when new team has been registered via the API or a team has been deactivated from Slack.
49
+
50
+ ```ruby
51
+ instance = SlackRubyBotServer::Service.instance
52
+
53
+ instance.on :created do |team, server, error|
54
+ # a new team has been registered
55
+ end
56
+
57
+ instance.on :deactivated do |team, server, error|
58
+ # an existing team has been deactivated in Slack
59
+ end
60
+
61
+ instance.on :error do |team, server, error|
62
+ # an error has occurred
63
+ end
64
+ ```
65
+
66
+ The following callbacks are supported. All callbacks receive a `team`, except `error`, which receives a `StandardError` object.
67
+
68
+ | callback | description |
69
+ |:--------------:|:-----------------------------------------------------------------|
70
+ | error | an error has occurred |
71
+ | creating | a new team is being registered |
72
+ | created | a new team has been registered |
73
+ | booting | the service is starting and is connecting a team to Slack |
74
+ | booted | the service is starting and has connected a team to Slack |
75
+ | stopping | the service is about to disconnect a team from Slack |
76
+ | stopped | the service has disconnected a team from Slack |
77
+ | starting | the service is (re)connecting a team to Slack |
78
+ | started | the service has (re)connected a team to Slack |
79
+ | deactivating | a team is being deactivated |
80
+ | deactivated | a team has been deactivated |
81
+ | resetting | the service is resetting, all teams being stopped |
82
+ | reset | the service has been reset, all teams have been stopped |
83
+
84
+ #### Server Class
85
+
86
+ You can override the server class to handle additional events, and configure the service to use it.
87
+
88
+ ```ruby
89
+ class MyServerClass < SlackRubyBotServer::Server
90
+ on :hello do |client, data|
91
+ # connected to Slack
92
+ end
93
+
94
+ on :channel_joined do |client, data|
95
+ # the bot joined a channel in data.channel['id']
96
+ end
97
+ end
98
+
99
+ SlackRubyBotServer.configure do |config|
100
+ config.server_class = MyServerClass
101
+ end
102
+ ```
103
+
38
104
  ### Examples Using Slack Ruby Bot Server
39
105
 
40
106
  * [slack-amber-alert](https://github.com/dblock/slack-amber-alert), free service at [missingkidsbot.org](https://www.missingkidsbot.org)
@@ -0,0 +1,26 @@
1
+ Upgrading Slack-Ruby-Bot-Server
2
+ ===============================
3
+
4
+ ### Upgrading to >= 0.3.0
5
+
6
+ #### Remove Monkey-Patching of SlackRubyBotServer::Server
7
+
8
+ In the past adding events required monkey-patching of the server class. You can now override the server class to handle additional events, and configure the service to use yours.
9
+
10
+ ```ruby
11
+ class MyServerClass < SlackRubyBotServer::Server
12
+ on :hello do |client, data|
13
+ # connected to Slack
14
+ end
15
+
16
+ on :channel_joined do |client, data|
17
+ # the bot joined a channel in data.channel['id']
18
+ end
19
+ end
20
+
21
+ SlackRubyBotServer.configure do |config|
22
+ config.server_class = MyServerClass
23
+ end
24
+ ```
25
+
26
+ See [#18](https://github.com/dblock/slack-ruby-bot-server/issues/18) for more information.
@@ -11,4 +11,5 @@ require 'slack-ruby-bot-server/models'
11
11
  require 'slack-ruby-bot-server/api'
12
12
  require 'slack-ruby-bot-server/app'
13
13
  require 'slack-ruby-bot-server/server'
14
+ require 'slack-ruby-bot-server/config'
14
15
  require 'slack-ruby-bot-server/service'
@@ -60,7 +60,7 @@ module SlackRubyBotServer
60
60
  )
61
61
  end
62
62
 
63
- Service.instance.start!(team)
63
+ Service.instance.create!(team)
64
64
  present team, with: Presenters::TeamPresenter
65
65
  end
66
66
  end
@@ -0,0 +1,23 @@
1
+ module SlackRubyBotServer
2
+ module Config
3
+ extend self
4
+
5
+ attr_accessor :server_class
6
+
7
+ def reset!
8
+ self.server_class = SlackRubyBotServer::Server
9
+ end
10
+
11
+ reset!
12
+ end
13
+
14
+ class << self
15
+ def configure
16
+ block_given? ? yield(Config) : Config
17
+ end
18
+
19
+ def config
20
+ Config
21
+ end
22
+ end
23
+ end
@@ -16,66 +16,121 @@ module SlackRubyBotServer
16
16
  def initialize
17
17
  @lock = Mutex.new
18
18
  @services = {}
19
+ @callbacks = Hash.new { |h, k| h[k] = [] }
20
+ end
21
+
22
+ def on(type, &block)
23
+ @callbacks[type.to_s] << block
24
+ end
25
+
26
+ def create!(team)
27
+ run_callbacks :creating, team
28
+ server = start!(team)
29
+ run_callbacks :created, team, server
19
30
  end
20
31
 
21
32
  def start!(team)
22
33
  raise 'Token already known.' if @services.key?(team.token)
34
+ run_callbacks :starting, team
23
35
  logger.info "Starting team #{team}."
24
- server = SlackRubyBotServer::Server.new(team: team)
36
+ server = SlackRubyBotServer::Config.server_class.new(team: team)
25
37
  @lock.synchronize do
26
38
  @services[team.token] = server
27
39
  end
28
- restart!(team, server)
40
+ start_server! team, server
41
+ run_callbacks :started, team, server
42
+ server
29
43
  rescue StandardError => e
44
+ run_callbacks :error, team, nil, e
30
45
  logger.error e
31
46
  end
32
47
 
48
+ def restart!(team, server, wait = 1)
49
+ run_callbacks :restarting, team, server
50
+ start_server! team, server, wait
51
+ run_callbacks :restarted, team, server
52
+ end
53
+
33
54
  def stop!(team)
55
+ logger.info "Stopping team #{team}."
34
56
  @lock.synchronize do
35
57
  raise 'Token unknown.' unless @services.key?(team.token)
36
- logger.info "Stopping team #{team}."
37
- @services[team.token].stop!
58
+ server = @services[team.token]
59
+ run_callbacks :stopping, team, server
60
+ server.stop!
38
61
  @services.delete(team.token)
62
+ run_callbacks :stopped, team, server
39
63
  end
40
64
  rescue StandardError => e
65
+ run_callbacks :error, team, @services[team.token], e
41
66
  logger.error e
42
67
  end
43
68
 
44
69
  def start_from_database!
45
70
  Team.active.each do |team|
46
- start!(team)
47
- end
48
- end
49
-
50
- def restart!(team, server, wait = 1)
51
- server.start_async
52
- rescue StandardError => e
53
- case e.message
54
- when 'account_inactive', 'invalid_auth' then
55
- logger.error "#{team.name}: #{e.message}, team will be deactivated."
56
- deactivate!(team)
57
- else
58
- logger.error "#{team.name}: #{e.message}, restarting in #{wait} second(s)."
59
- sleep(wait)
60
- restart! team, server, [wait * 2, 60].min
71
+ run_callbacks :booting, team
72
+ server = start!(team)
73
+ run_callbacks :booted, team, server
61
74
  end
62
75
  end
63
76
 
64
77
  def deactivate!(team)
65
- team.deactivate!
66
78
  @lock.synchronize do
79
+ raise 'Token unknown.' unless @services.key?(team.token)
80
+ server = @services[team.token]
81
+ run_callbacks :deactivating, team, server
82
+ team.deactivate!
67
83
  @services.delete(team.token)
84
+ run_callbacks :deactivated, team, server
68
85
  end
69
86
  rescue Mongoid::Errors::Validations => e
87
+ run_callbacks :error, team, @services[team.token], e
70
88
  logger.error "#{team.name}: #{e.message}, error - #{e.document.class}, #{e.document.errors.to_hash}, ignored."
71
89
  rescue StandardError => e
90
+ run_callbacks :error, team, @services[team.token], e
72
91
  logger.error "#{team.name}: #{e.class}, #{e.message}, ignored."
73
92
  end
74
93
 
75
94
  def reset!
95
+ run_callbacks :resetting
76
96
  @services.values.to_a.each do |server|
77
97
  stop!(server.team)
78
98
  end
99
+ run_callbacks :reset
100
+ end
101
+
102
+ def self.reset!
103
+ @instance.reset! if @instance
104
+ @instance = nil
105
+ end
106
+
107
+ private
108
+
109
+ def start_server!(team, server, wait = 1)
110
+ server.start_async
111
+ rescue StandardError => e
112
+ run_callbacks :error, team, server, e
113
+ case e.message
114
+ when 'account_inactive', 'invalid_auth' then
115
+ logger.error "#{team.name}: #{e.message}, team will be deactivated."
116
+ deactivate!(team)
117
+ else
118
+ logger.error "#{team.name}: #{e.message}, restarting in #{wait} second(s)."
119
+ sleep(wait)
120
+ start_server! team, server, [wait * 2, 60].min
121
+ end
122
+ end
123
+
124
+ def run_callbacks(type, team = nil, server = nil, error = nil)
125
+ callbacks = @callbacks[type.to_s]
126
+ return false unless callbacks
127
+ callbacks.each do |c|
128
+ c.call team, server, error
129
+ end
130
+ true
131
+ rescue StandardError => e
132
+ logger.error e
133
+ false
79
134
  end
80
135
  end
81
136
  end
@@ -1,3 +1,3 @@
1
1
  module SlackRubyBotServer
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slack-ruby-bot-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.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: 2016-06-21 00:00:00.000000000 Z
11
+ date: 2016-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: slack-ruby-bot
@@ -213,6 +213,7 @@ files:
213
213
  - README.md
214
214
  - RELEASING.md
215
215
  - Rakefile
216
+ - UPGRADING.md
216
217
  - app.json
217
218
  - images/new.png
218
219
  - images/slackbotserver.gif
@@ -236,6 +237,7 @@ files:
236
237
  - lib/slack-ruby-bot-server/api/presenters/team_presenter.rb
237
238
  - lib/slack-ruby-bot-server/api/presenters/teams_presenter.rb
238
239
  - lib/slack-ruby-bot-server/app.rb
240
+ - lib/slack-ruby-bot-server/config.rb
239
241
  - lib/slack-ruby-bot-server/ext.rb
240
242
  - lib/slack-ruby-bot-server/ext/bson/object_id.rb
241
243
  - lib/slack-ruby-bot-server/ext/grape/sort_extension.rb
@@ -294,7 +296,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
294
296
  version: '0'
295
297
  requirements: []
296
298
  rubyforge_project:
297
- rubygems_version: 2.6.4
299
+ rubygems_version: 2.4.8
298
300
  signing_key:
299
301
  specification_version: 4
300
302
  summary: A Grape API serving a Slack bot to multiple teams.