slack-ruby-bot-server 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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.