slack-ruby-bot-server 0.11.1 → 0.12.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
  SHA256:
3
- metadata.gz: 34d650b165e330149dfc1e8a0045660f9e2dbb3440d504c188496d90f5c25ac6
4
- data.tar.gz: b29fdf9948bdccddc4bd5a08a0b0cbb701fb0aab40f03ed836d9fd438a67e9fc
3
+ metadata.gz: 6ebd73ca8473ea0f3e86d030538fcfdf3fe54ae9689aee50c24669506ce1b1fe
4
+ data.tar.gz: 07471fb459f7dc25e2203a9279e0db2d34650c07792b0b6b1931d71bb4e9f37c
5
5
  SHA512:
6
- metadata.gz: a45158dd0b039e8d4fa70b565303c989f171594d021b60d8e00eb174ecc9c3073c535ba01f7a707e5b763a40db8e14b0cb4bc2adf397b7bdcc1fee25a72d7741
7
- data.tar.gz: 3c6eeca00c91392fc41168688593052f51ad1b342427f13ab250f6b56f8fcb9924d751c11c1ed38571033479cbe975e371563e960cdb7d603eed6011d8cc4314
6
+ metadata.gz: bde46306261b7eb8088eaa03647672bea884c23f54dee33935fc6eccbb8ed6993cf55ab7791c25cc329b19506ac5aca2e215f5e90e3de0050bff97ac182288ec
7
+ data.tar.gz: c060a2835f112300914d70817d4f503e1972dd5cea4a230e7ce13d1faa996e72cbb77d2262df0dfa89020229a0721f5302e644ddeafbf1f4e8a99c9ef66cccf8
@@ -1,7 +1,7 @@
1
1
  Metrics:
2
2
  Enabled: false
3
3
 
4
- Metrics/LineLength:
4
+ Layout/LineLength:
5
5
  Max: 500
6
6
  Enabled: false
7
7
 
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2019-03-23 14:16:02 -0400 using RuboCop version 0.58.2.
3
+ # on 2020-04-26 17:46:16 -0400 using RuboCop version 0.81.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
@@ -9,26 +9,61 @@
9
9
  # Offense count: 3
10
10
  # Cop supports --auto-correct.
11
11
  # Configuration parameters: EnforcedStyle.
12
- # SupportedStyles: auto_detection, squiggly, active_support, powerpack, unindent
13
- Layout/IndentHeredoc:
12
+ # SupportedStyles: squiggly, active_support, powerpack, unindent
13
+ Layout/HeredocIndentation:
14
14
  Exclude:
15
15
  - 'lib/slack-ruby-bot-server/info.rb'
16
16
  - 'sample_apps/sample_app_activerecord/commands/help.rb'
17
17
  - 'sample_apps/sample_app_mongoid/commands/help.rb'
18
18
 
19
+ # Offense count: 1
20
+ Lint/AmbiguousOperator:
21
+ Exclude:
22
+ - 'spec/slack-ruby-bot-server/service_spec.rb'
23
+
24
+ # Offense count: 2
25
+ # Cop supports --auto-correct.
26
+ Lint/NonDeterministicRequireOrder:
27
+ Exclude:
28
+ - 'spec/spec_helper.rb'
29
+
30
+ # Offense count: 2
31
+ # Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
32
+ # 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
33
+ Naming/FileName:
34
+ Exclude:
35
+ - 'lib/slack-ruby-bot-server.rb'
36
+ - 'lib/slack-ruby-bot-server/ext/slack-ruby-bot.rb'
37
+
19
38
  # Offense count: 3
20
- # Configuration parameters: Blacklist.
21
- # Blacklist: (?-mix:(^|\s)(EO[A-Z]{1}|END)(\s|$))
39
+ # Configuration parameters: ForbiddenDelimiters.
40
+ # ForbiddenDelimiters: (?-mix:(^|\s)(EO[A-Z]{1}|END)(\s|$))
22
41
  Naming/HeredocDelimiterNaming:
23
42
  Exclude:
24
43
  - 'lib/slack-ruby-bot-server/info.rb'
25
44
  - 'sample_apps/sample_app_activerecord/commands/help.rb'
26
45
  - 'sample_apps/sample_app_mongoid/commands/help.rb'
27
46
 
47
+ # Offense count: 1
48
+ # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
49
+ # AllowedNames: io, id, to, by, on, in, at, ip, db, os, pp
50
+ Naming/MethodParameterName:
51
+ Exclude:
52
+ - 'lib/slack-ruby-bot-server/service.rb'
53
+
28
54
  # Offense count: 1
29
55
  # Cop supports --auto-correct.
30
- # Configuration parameters: EnforcedStyle.
31
- # SupportedStyles: module_function, extend_self
56
+ # Configuration parameters: EnforcedStyle, Autocorrect.
57
+ # SupportedStyles: module_function, extend_self, forbidden
32
58
  Style/ModuleFunction:
33
59
  Exclude:
34
60
  - 'lib/slack-ruby-bot-server/config.rb'
61
+
62
+ # Offense count: 1
63
+ # Cop supports --auto-correct.
64
+ # Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods.
65
+ # SupportedStyles: predicate, comparison
66
+ Style/NumericPredicate:
67
+ Exclude:
68
+ - 'spec/**/*'
69
+ - 'lib/slack-ruby-bot-server/service.rb'
@@ -4,24 +4,26 @@ cache: bundler
4
4
 
5
5
  matrix:
6
6
  include:
7
- - rvm: 2.3.1
7
+ - rvm: 2.6.2
8
8
  script:
9
9
  - bundle exec danger
10
- - rvm: 2.3.1
10
+ services:
11
+ - xvfb
12
+ - rvm: 2.6.2
11
13
  env: DATABASE_ADAPTER=activerecord
12
14
  services:
15
+ - xvfb
13
16
  - postgresql
14
- - rvm: 2.3.1
17
+ - rvm: 2.6.2
15
18
  env: DATABASE_ADAPTER=mongoid
16
19
  services:
20
+ - xvfb
17
21
  - mongodb
18
22
 
19
23
  addons:
20
24
  firefox: 54.0
21
25
 
22
26
  before_install:
23
- - export DISPLAY=:99.0
24
- - sh -e /etc/init.d/xvfb start
25
27
  - wget https://github.com/mozilla/geckodriver/releases/download/v0.18.0/geckodriver-v0.18.0-linux64.tar.gz
26
28
  - mkdir geckodriver
27
29
  - tar -xzf geckodriver-v0.18.0-linux64.tar.gz -C geckodriver
@@ -1,20 +1,29 @@
1
1
  ### Changelog
2
2
 
3
+ #### 0.12.0 (2020/4/26)
4
+
5
+ * [#113](https://github.com/slack-ruby/slack-ruby-bot-server/pull/113): Added support for intervals with `.every` - [@dblock](https://github.com/dblock).
6
+ * [#112](https://github.com/slack-ruby/slack-ruby-bot-server/pull/112): Added support for multiple `.on` events as an argument - [@dblock](https://github.com/dblock).
7
+ * [#111](https://github.com/slack-ruby/slack-ruby-bot-server/pull/111): Removed dependency on Virtus - [@dblock](https://github.com/dblock).
8
+ * [#110](https://github.com/slack-ruby/slack-ruby-bot-server/pull/110): Fixed ActiveRecord sample app - [@CeeBeeUK](https://github.com/CeeBeeUK).
9
+ * [#114](https://github.com/slack-ruby/slack-ruby-bot-server/pull/114): Used `require_relative` to prevent local collisions - [@dblock](https://github.com/dblock).
10
+ * [#115](https://github.com/slack-ruby/slack-ruby-bot-server/pull/115): Added `Config#view_paths` to be used by Rack middleware - [@dblock](https://github.com/dblock).
11
+
3
12
  #### 0.11.1 (2019/5/17)
4
13
 
5
- * [#104](https://github.com/slack-ruby/slack-ruby-bot-server/pull/104): Lock async-websocket at a compatible 0.8.0 version - [@dblock](https://github.com/dblock).
14
+ * [#104](https://github.com/slack-ruby/slack-ruby-bot-server/pull/104): Locked async-websocket at a compatible 0.8.0 version - [@dblock](https://github.com/dblock).
6
15
 
7
16
  #### 0.11.0 (2019/4/12)
8
17
 
9
18
  * [#101](https://github.com/slack-ruby/slack-ruby-bot-server/pull/101): Removed legacy migrations, including `SLACK_API_TOKEN`, team `name`, `team_id` and `active` - [@dblock](https://github.com/dblock).
10
19
  * [#98](https://github.com/slack-ruby/slack-ruby-bot-server/pull/98): Removed `unicorn` from gem dependencies - [@dblock](https://github.com/dblock).
11
- * [#90](https://github.com/slack-ruby/slack-ruby-bot-server/pull/90): Update ActiveRecord sample app to support ENV variables in `postgresql.yml` - [@ashkan18](https://github.com/ashkan18).
20
+ * [#90](https://github.com/slack-ruby/slack-ruby-bot-server/pull/90): Updated ActiveRecord sample app to support ENV variables in `postgresql.yml` - [@ashkan18](https://github.com/ashkan18).
12
21
 
13
22
  #### 0.10.0 (2019/3/23)
14
23
 
15
24
  * [#97](https://github.com/slack-ruby/slack-ruby-bot-server/pull/97): Added `Config#service_class` to override the `SlackRubyBotServer::Service.instance` singleton - [@dblock](https://github.com/dblock).
16
25
  * [#96](https://github.com/slack-ruby/slack-ruby-bot-server/pull/96): Added `Team#bot_user_id`, `activated_user_id` and `activated_user_access_token` - [@dblock](https://github.com/dblock).
17
- * [#95](https://github.com/slack-ruby/slack-ruby-bot-server/pull/95): Expose the optional `state` parameter that is returned from the Add to Slack button - [@aok-solutions](https://github.com/aok-solutions).
26
+ * [#95](https://github.com/slack-ruby/slack-ruby-bot-server/pull/95): Exposed the optional `state` parameter that is returned from the Add to Slack button - [@aok-solutions](https://github.com/aok-solutions).
18
27
 
19
28
  #### 0.9.0 (2019/2/25)
20
29
 
@@ -22,31 +31,31 @@
22
31
 
23
32
  #### 0.8.3 (2019/1/17)
24
33
 
25
- * [#88](https://github.com/slack-ruby/slack-ruby-bot-server/issues/88): Fix: compatibility with Grape 1.2.x - [@dblock](https://github.com/dblock).
34
+ * [#88](https://github.com/slack-ruby/slack-ruby-bot-server/issues/88): Fixed compatibility with Grape 1.2.x - [@dblock](https://github.com/dblock).
26
35
 
27
36
  #### 0.8.2 (2018/10/11)
28
37
 
29
- * [#80](https://github.com/slack-ruby/slack-ruby-bot-server/pull/80): Fix: closed stream when closing connection in ping worker - [@dblock](https://github.com/dblock).
38
+ * [#80](https://github.com/slack-ruby/slack-ruby-bot-server/pull/80): Fixed closed stream when closing connection in ping worker - [@dblock](https://github.com/dblock).
30
39
 
31
40
  #### 0.8.1 (2018/9/20)
32
41
 
33
- * [#79](https://github.com/slack-ruby/slack-ruby-bot-server/pull/79): Fix: ping worker terminates on a failed restart - [@dblock](https://github.com/dblock).
42
+ * [#79](https://github.com/slack-ruby/slack-ruby-bot-server/pull/79): Fixed ping worker terminates on a failed restart - [@dblock](https://github.com/dblock).
34
43
 
35
44
  #### 0.8.0 (2018/9/8)
36
45
 
37
- * [#75](https://github.com/slack-ruby/slack-ruby-bot-server/pull/75): Default to `async-websocket` instead of `celluloid-io` - [@dblock](https://github.com/dblock).
38
- * [#76](https://github.com/slack-ruby/slack-ruby-bot-server/pull/76): Adjust wait time on restart on Slack::Web::Api::Errors::TooManyRequestsError - [@dblock](https://github.com/dblock).
46
+ * [#75](https://github.com/slack-ruby/slack-ruby-bot-server/pull/75): Defaulted to `async-websocket` instead of `celluloid-io` - [@dblock](https://github.com/dblock).
47
+ * [#76](https://github.com/slack-ruby/slack-ruby-bot-server/pull/76): Adjusted wait time on restart on Slack::Web::Api::Errors::TooManyRequestsError - [@dblock](https://github.com/dblock).
39
48
 
40
49
  #### 0.7.0 (2018/8/22)
41
50
 
42
- * [#60](https://github.com/slack-ruby/slack-ruby-bot-server/pull/60): Log caught Standard::Error backtrace at debug-level - [@alexagranov](https://github.com/alexagranov).
51
+ * [#60](https://github.com/slack-ruby/slack-ruby-bot-server/pull/60): Logged caught Standard::Error backtrace at debug-level - [@alexagranov](https://github.com/alexagranov).
43
52
  * [#65](https://github.com/slack-ruby/slack-ruby-bot-server/pull/65): Updated Capybara and selenium-webdriver - [@dblock](https://github.com/dblock).
44
53
  * [#67](https://github.com/slack-ruby/slack-ruby-bot-server/pull/67): Only load the OTR::ActiveRecord::ConnectionManagement middleware when the OTR module is included. This module isn't needed when using Rails - [@darbyfrey](https://github.com/darbyfrey).
45
54
  * [#74](https://github.com/slack-ruby/slack-ruby-bot-server/pull/74): Added ping worker, will restart offline bots - [@dblock](https://github.com/dblock).
46
55
 
47
56
  #### 0.6.1 (2017/3/29)
48
57
 
49
- * [#54](https://github.com/slack-ruby/slack-ruby-bot-server/pull/54): Removing one more Mongoid dependency when rescuing from _invoke - [@alexagranov](https://github.com/alexagranov).
58
+ * [#54](https://github.com/slack-ruby/slack-ruby-bot-server/pull/54): Removed one more Mongoid dependency when rescuing from _invoke - [@alexagranov](https://github.com/alexagranov).
50
59
  * [#53](https://github.com/slack-ruby/slack-ruby-bot-server/pull/53): No need for `otr-activerecord` if using activerecord under Rails - [@alexagranov](https://github.com/alexagranov).
51
60
 
52
61
  #### 0.6.0 (2017/3/12)
@@ -57,17 +66,17 @@
57
66
 
58
67
  #### 0.5.0 (2017/2/9)
59
68
 
60
- * [#43](https://github.com/slack-ruby/slack-ruby-bot-server/pull/43): Fix: `cannot load kaminari/grape` - [@dblock](https://github.com/dblock).
61
- * [#43](https://github.com/slack-ruby/slack-ruby-bot-server/pull/43): Fix: `undefined method '[]' for nil:NilClass` in APIs - [@dblock](https://github.com/dblock).
62
- * [#28](https://github.com/slack-ruby/slack-ruby-bot-server/pull/28): Use slack-ruby-danger gem - [@dblock](https://github.com/dblock).
63
- * [#31](https://github.com/slack-ruby/slack-ruby-bot-server/pull/31): Adds MONGODB_URI as environment variable for MongoDB - [@corprew](https://github.com/corprew).
69
+ * [#43](https://github.com/slack-ruby/slack-ruby-bot-server/pull/43): Fixed `cannot load kaminari/grape` - [@dblock](https://github.com/dblock).
70
+ * [#43](https://github.com/slack-ruby/slack-ruby-bot-server/pull/43): Fixed `undefined method '[]' for nil:NilClass` in APIs - [@dblock](https://github.com/dblock).
71
+ * [#28](https://github.com/slack-ruby/slack-ruby-bot-server/pull/28): Used `slack-ruby-danger` gem - [@dblock](https://github.com/dblock).
72
+ * [#31](https://github.com/slack-ruby/slack-ruby-bot-server/pull/31): Added `MONGODB_URI` as environment variable for MongoDB - [@corprew](https://github.com/corprew).
64
73
 
65
74
  #### 0.4.0 (2016/8/29)
66
75
 
67
76
  * [#25](https://github.com/slack-ruby/slack-ruby-bot-server/pull/25): Added [danger](http://danger.systems), PR linting - [@dblock](https://github.com/dblock).
68
77
  * The `reset` and `resetting` callbacks have been removed - [@dblock](https://github.com/dblock).
69
78
  * Callbacks receive `team` and `error`, but no longer `server` - [@dblock](https://github.com/dblock).
70
- * [#23](https://github.com/slack-ruby/slack-ruby-bot-server/issues/23): Fix: server-side removal of bot doesn't deactivate it - [@dblock](https://github.com/dblock).
79
+ * [#23](https://github.com/slack-ruby/slack-ruby-bot-server/issues/23): Fixed server-side removal of bot doesn't deactivate it - [@dblock](https://github.com/dblock).
71
80
 
72
81
  #### 0.3.1 (2016/7/10)
73
82
 
@@ -91,13 +100,13 @@
91
100
 
92
101
  * Initial public release - [@dblock](https://github.com/dblock).
93
102
  * Renamed slack-bot-server to slack-ruby-bot-server - [@dblock](https://github.com/dblock).
94
- * [#11](https://github.com/slack-ruby/slack-ruby-bot-server/pull/11): Turn project into gem - [@tmsrjs](https://github.com/tmsrjs).
95
- * Use `celluloid-io` instead of `faye-websocket`, upgrade to slack-ruby-bot 0.8.0 - [@dblock](https://github.com/dblock).
103
+ * [#11](https://github.com/slack-ruby/slack-ruby-bot-server/pull/11): Turned project into gem - [@tmsrjs](https://github.com/tmsrjs).
104
+ * Used `celluloid-io` instead of `faye-websocket`, upgrade to slack-ruby-bot 0.8.0 - [@dblock](https://github.com/dblock).
96
105
  * Fixed `SlackRubyBotServer#reset` - [@dblock](https://github.com/dblock).
97
- * Use Grape 0.15.x - [@dblock](https://github.com/dblock).
106
+ * Used Grape 0.15.x - [@dblock](https://github.com/dblock).
98
107
  * Removed OOB GC - [@dblock](https://github.com/dblock).
99
- * Use Unicorn instead of Puma - [@dblock](https://github.com/dblock).
100
- * Fix: wait for EventMachine reactor to start - [@dblock](https://github.com/dblock).
101
- * Use an OOB GC - [@dblock](https://github.com/dblock).
102
- * Defer start, much faster - [@dblock](https://github.com/dblock).
108
+ * Used Unicorn instead of Puma - [@dblock](https://github.com/dblock).
109
+ * Fixed wait for EventMachine reactor to start - [@dblock](https://github.com/dblock).
110
+ * Used an OOB GC - [@dblock](https://github.com/dblock).
111
+ * Deferred start, much faster - [@dblock](https://github.com/dblock).
103
112
  * Backported changes from slack-metabot and slack-shellbot - [@dblock](https://github.com/dblock).
data/Gemfile CHANGED
@@ -11,7 +11,7 @@ when 'activerecord' then
11
11
  gem 'otr-activerecord', '~> 1.2.1'
12
12
  gem 'cursor_pagination' # rubocop:disable Bundler/OrderedGems
13
13
  gem 'pg'
14
- when nil then
14
+ when nil
15
15
  warn "Missing ENV['DATABASE_ADAPTER']."
16
16
  else
17
17
  warn "Invalid ENV['DATABASE_ADAPTER']: #{ENV['DATABASE_ADAPTER']}."
@@ -31,7 +31,7 @@ group :development, :test do
31
31
  gem 'rack-test'
32
32
  gem 'rake'
33
33
  gem 'rspec'
34
- gem 'rubocop', '0.58.2'
34
+ gem 'rubocop', '0.81.0'
35
35
  gem 'selenium-webdriver', '~> 3.4.4'
36
36
  gem 'vcr'
37
37
  gem 'webmock'
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015-2019 Daniel Doubrovkine & Contributors
3
+ Copyright (c) 2015-2020 Daniel Doubrovkine & Contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -17,7 +17,7 @@ A library that contains a [Grape](http://github.com/ruby-grape/grape) API servin
17
17
 
18
18
  ### Stable Release
19
19
 
20
- You're reading the documentation for the **stable** release of slack-ruby-bot-server, 0.11.1. See [UPGRADING](UPGRADING.md) when upgrading from an older version.
20
+ You're reading the documentation for the **stable** release of slack-ruby-bot-server, 0.12.0. See [UPGRADING](UPGRADING.md) when upgrading from an older version.
21
21
 
22
22
  ### Try Me
23
23
 
@@ -62,19 +62,48 @@ See the [sample app using ActiveRecord](sample_apps/sample_app_activerecord) for
62
62
 
63
63
  ### Usage
64
64
 
65
- Start with one of the samples above, which contain a couple of custom commands, necessary dependencies and tests, then [create a new application](https://api.slack.com/applications/new) on Slack.
65
+ Start with one of the samples above, which contain a couple of custom commands, necessary dependencies and tests, then [create a new Slack App](https://api.slack.com/applications/new).
66
66
 
67
- ![](images/new.png)
67
+ ![](images/create-app.png)
68
68
 
69
- Follow Slack's instructions, note the app client ID and secret, give the bot a default name, etc. The redirect URL should be the location of your app, for local testing purposes use `http://localhost:9292`.
69
+ Follow Slack's instructions, note the app client ID and secret, give the bot a default name, etc. The redirect URL should be the location of your app. For local testing purposes use a public tunneling service such as [ngrok](https://ngrok.com/) to expose local port 9292.
70
70
 
71
71
  Within your application, edit your `.env` file and add `SLACK_CLIENT_ID=...` and `SLACK_CLIENT_SECRET=...` in it.
72
72
 
73
73
  Run `bundle install` and `foreman start` to boot the app. Navigate to [localhost:9292](http://localhost:9292). You should see an "Add to Slack" button. Use it to install the app into your own Slack team.
74
74
 
75
+ ### OAuth Code Grant
76
+
77
+ The "Add to Slack" button uses the standard OAuth code grant flow as described in the [Slack docs](https://api.slack.com/docs/oauth#flow).
78
+
79
+ The button itself contains a link that looks like this:
80
+
81
+ ```
82
+ https://slack.com/oauth/authorize?scope=bot&client_id=<%= ENV['SLACK_CLIENT_ID'] %>
83
+ ```
84
+
85
+ Once clicked, the user is taken through the authorization process at Slack's site. Upon successful completion, a callback containing a temporary code is sent to the redirect URL you specified. The endpoint at that URL contains code that looks like this:
86
+
87
+ ```ruby
88
+ # Instantiate a web client
89
+ client = Slack::Web::Client.new
90
+
91
+ # Request a token using the temporary code
92
+ rc = client.oauth_access(
93
+ client_id: ENV['SLACK_CLIENT_ID'],
94
+ client_secret: ENV['SLACK_CLIENT_SECRET'],
95
+ code: params[:code]
96
+ )
97
+
98
+ # Pluck the token from the response
99
+ token = rc['bot']['bot_access_token']
100
+ ```
101
+
102
+ The token is stored in persistent storage and used each time a Slack client is instantiated for the specific team.
103
+
75
104
  ### API
76
105
 
77
- This library implements an app, [SlackRubyBotServer::App](lib/slack-ruby-bot-server/app.rb), 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.
106
+ This library implements an app, [SlackRubyBotServer::App](lib/slack-ruby-bot-server/app.rb), 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. It also provides [default HTML templates and JS scripts](public) for Slack integration.
78
107
 
79
108
  #### App
80
109
 
@@ -104,11 +133,17 @@ MyApp.instance.prepare!
104
133
 
105
134
  #### Service Manager
106
135
 
136
+ ##### Lifecycle Callbacks
137
+
107
138
  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.
108
139
 
109
140
  ```ruby
110
141
  instance = SlackRubyBotServer::Service.instance
111
142
 
143
+ instance.on :started, :stopped do |team|
144
+ # team has been started or stopped
145
+ end
146
+
112
147
  instance.on :created do |team, error, options|
113
148
  # a new team has been registered
114
149
  end
@@ -138,7 +173,6 @@ The following callbacks are supported. All callbacks receive a `team`, except `e
138
173
  | deactivating | a team is being deactivated |
139
174
  | deactivated | a team has been deactivated |
140
175
 
141
-
142
176
  The [Add to Slack button](https://api.slack.com/docs/slack-button) also allows for an optional `state` parameter that will be returned on completion of the request. The `creating` and `created` callbacks include an options hash where this value can be accessed (to check for forgery attacks for instance).
143
177
  ```ruby
144
178
  auth = OpenSSL::HMAC.hexdigest("SHA256", "key", "data")
@@ -153,9 +187,43 @@ instance.on :creating do |team, error, options|
153
187
  end
154
188
  ```
155
189
 
156
- A number of extensions use service manager callbacks to implement useful functionality.
190
+ ##### Service Timers
191
+
192
+ You can introduce custom behavior into the service lifecycle on a timer. For example, check whether a team's trial has expired, or periodically cleanup data.
193
+
194
+ Note that unlike callbacks, timers are global for the entire service.
195
+
196
+ ```ruby
197
+ instance = SlackRubyBotServer::Service.instance
198
+
199
+ instance.every :hour do
200
+ Team.each do |team|
201
+ begin
202
+ # do something with every team once an hour
203
+ rescue StandardError
204
+ end
205
+ end
206
+ end
207
+
208
+ instance.every :minute do
209
+ # called every minute
210
+ end
211
+
212
+ instance.every :second do
213
+ # called every second
214
+ end
215
+
216
+ instance.every 30 do
217
+ # called every 30 seconds
218
+ end
219
+ ```
220
+
221
+ ##### Extensions
222
+
223
+ A number of extensions use service manager callbacks and service timers to implement useful functionality.
157
224
 
158
225
  * [slack-ruby-bot-server-mailchimp](https://github.com/slack-ruby/slack-ruby-bot-server-mailchimp): Subscribes new bot users to a Mailchimp mailing list.
226
+ * [slack-ruby-bot-server-stripe](https://github.com/slack-ruby/slack-ruby-bot-server-stripe): Enables paid bots with trial periods and commerce through Stripe.
159
227
 
160
228
  #### Server Class
161
229
 
@@ -196,6 +264,18 @@ SlackRubyBotServer::Service.instance # MyService
196
264
  SlackRubyBotServer::Service.instance.url # https://www.example.com
197
265
  ```
198
266
 
267
+ ### HTML Templates
268
+
269
+ This library provides a [default HTML template and JS scripts](public) that implement the "Add to Slack" button workflow. Customize your pages by adding a `public` directory in your application and starting with a [index.html.erb](public/index.html.erb) template. The application's `views` and `public` folders are [loaded by default](lib/slack-ruby-bot-server/api/middleware.rb#L32).
270
+
271
+ You can add to or override template paths as follows.
272
+
273
+ ```ruby
274
+ SlackRubyBotServer.configure do |config|
275
+ config.view_paths << File.expand_path(File.join(__dir__, 'public'))
276
+ end
277
+ ```
278
+
199
279
  ### Access Tokens
200
280
 
201
281
  By default the implementation of [Team](lib/slack-ruby-bot-server/models/team) stores a `bot_access_token` as `token` that grants a certain amount of privileges to the bot user as described in [Slack OAuth Docs](https://api.slack.com/docs/oauth) along with `activated_user_access_token` that represents the token of the installing user. You may not want a bot user at all, or may require different auth scopes, such as `users.profile:read` to access user profile information via `Slack::Web::Client#users_profile_get`. To change required scopes make the following changes.
@@ -206,18 +286,19 @@ By default the implementation of [Team](lib/slack-ruby-bot-server/models/team) s
206
286
 
207
287
  You can see a sample implementation in [slack-sup#3a497b](https://github.com/dblock/slack-sup/commit/3a497b436d25d3a7738562655cda64b180ae0096).
208
288
 
209
- ### Examples Using Slack Ruby Bot Server
289
+ ### Example Bots Using Slack Ruby Bot Server
210
290
 
211
- * [slack-sup](https://github.com/dblock/slack-sup), free service at [sup.playplay.io](https://sup.playplay.io)
212
- * [slack-gamebot](https://github.com/dblock/slack-gamebot), free service at [www.playplay.io](https://www.playplay.io)
213
- * [slack-market](https://github.com/dblock/slack-market), free service at [market.playplay.io](https://market.playplay.io)
214
- * [slack-shellbot](https://github.com/slack-ruby/slack-shellbot), free service at [shell.playplay.io](https://shell.playplay.io)
215
- * [slack-api-explorer](https://github.com/slack-ruby/slack-api-explorer), free service at [api-explorer.playplay.io](https://shell.playplay.io)
216
- * [slack-strava](https://github.com/dblock/slack-strava), free service at [slava.playplay.io](https://slava.playplay.io)
217
- * [slack-arena](https://github.com/dblock/slack-arena), free service at [arena.playplay.io](https://arena.playplay.io)
291
+ * [slack-ruby-bot-server-sample](https://github.com/slack-ruby/slack-ruby-bot-server-sample), a generic sample
292
+ * [slack-sup](https://github.com/dblock/slack-sup), see [sup.playplay.io](https://sup.playplay.io)
293
+ * [slack-gamebot](https://github.com/dblock/slack-gamebot), see [www.playplay.io](https://www.playplay.io)
294
+ * [slack-market](https://github.com/dblock/slack-market), see [market.playplay.io](https://market.playplay.io)
295
+ * [slack-shellbot](https://github.com/slack-ruby/slack-shellbot), see [shell.playplay.io](https://shell.playplay.io)
296
+ * [slack-api-explorer](https://github.com/slack-ruby/slack-api-explorer), see [api-explorer.playplay.io](https://shell.playplay.io)
297
+ * [slack-strava](https://github.com/dblock/slack-strava), see [slava.playplay.io](https://slava.playplay.io)
298
+ * [slack-arena](https://github.com/dblock/slack-arena), see [arena.playplay.io](https://arena.playplay.io)
218
299
 
219
300
  ### Copyright & License
220
301
 
221
- Copyright [Daniel Doubrovkine](http://code.dblock.org) and Contributors, 2015-2019
302
+ Copyright [Daniel Doubrovkine](http://code.dblock.org) and Contributors, 2015-2020
222
303
 
223
304
  [MIT License](LICENSE)
Binary file
@@ -2,15 +2,13 @@ require 'async/websocket'
2
2
 
3
3
  require 'grape-swagger'
4
4
  require 'slack-ruby-bot'
5
- require 'slack-ruby-bot-server/service'
6
- require 'slack-ruby-bot-server/server'
7
- require 'slack-ruby-bot-server/config'
8
5
 
9
- require 'slack-ruby-bot-server/ext'
10
- require 'slack-ruby-bot-server/version'
11
- require 'slack-ruby-bot-server/info'
12
-
13
- require "slack-ruby-bot-server/config/database_adapters/#{SlackRubyBotServer::Config.database_adapter}.rb"
14
-
15
- require 'slack-ruby-bot-server/api'
16
- require 'slack-ruby-bot-server/app'
6
+ require_relative 'slack-ruby-bot-server/service'
7
+ require_relative 'slack-ruby-bot-server/server'
8
+ require_relative 'slack-ruby-bot-server/config'
9
+ require_relative 'slack-ruby-bot-server/ext'
10
+ require_relative 'slack-ruby-bot-server/version'
11
+ require_relative 'slack-ruby-bot-server/info'
12
+ require_relative "slack-ruby-bot-server/config/database_adapters/#{SlackRubyBotServer::Config.database_adapter}.rb"
13
+ require_relative 'slack-ruby-bot-server/api'
14
+ require_relative 'slack-ruby-bot-server/app'
@@ -3,7 +3,7 @@ require 'roar'
3
3
  require 'grape-roar'
4
4
 
5
5
  require_relative 'ext/grape/sort_extension'
6
- require 'slack-ruby-bot-server/api/helpers'
7
- require 'slack-ruby-bot-server/api/presenters'
8
- require 'slack-ruby-bot-server/api/endpoints'
9
- require 'slack-ruby-bot-server/api/middleware'
6
+ require_relative 'api/helpers'
7
+ require_relative 'api/presenters'
8
+ require_relative 'api/endpoints'
9
+ require_relative 'api/middleware'
@@ -1,3 +1,3 @@
1
- require 'slack-ruby-bot-server/api/endpoints/teams_endpoint'
2
- require 'slack-ruby-bot-server/api/endpoints/status_endpoint'
3
- require 'slack-ruby-bot-server/api/endpoints/root_endpoint'
1
+ require_relative 'endpoints/teams_endpoint'
2
+ require_relative 'endpoints/status_endpoint'
3
+ require_relative 'endpoints/root_endpoint'
@@ -60,6 +60,7 @@ module SlackRubyBotServer
60
60
  bot_user_id: bot_user_id
61
61
  )
62
62
  raise "Team #{team.name} is already registered." if team.active?
63
+
63
64
  team.activate!(token)
64
65
  else
65
66
  team = Team.create!(
@@ -1,4 +1,4 @@
1
- require 'slack-ruby-bot-server/api/helpers/cursor_helpers'
2
- require 'slack-ruby-bot-server/api/helpers/pagination_parameters'
3
- require 'slack-ruby-bot-server/api/helpers/sort_helpers'
4
- require 'slack-ruby-bot-server/api/helpers/error_helpers'
1
+ require_relative 'helpers/cursor_helpers'
2
+ require_relative 'helpers/pagination_parameters'
3
+ require_relative 'helpers/sort_helpers'
4
+ require_relative 'helpers/error_helpers'
@@ -11,6 +11,7 @@ module SlackRubyBotServer
11
11
  if SlackRubyBotServer::Config.mongoid?
12
12
  def paginate_by_cursor(coll, _options)
13
13
  raise 'Both cursor and offset parameters are present, these are mutually exclusive.' if params.key?(:offset) && params.key?(:cursor)
14
+
14
15
  results = { results: [], next: nil }
15
16
  coll = coll.skip(params[:offset].to_i) if params.key?(:offset)
16
17
  size = (params[:size] || 10).to_i
@@ -26,6 +27,7 @@ module SlackRubyBotServer
26
27
  elsif SlackRubyBotServer::Config.activerecord?
27
28
  def paginate_by_cursor(coll, options)
28
29
  raise 'Both cursor and offset parameters are present, these are mutually exclusive.' if params.key?(:offset) && params.key?(:cursor)
30
+
29
31
  results = { results: [], next: nil }
30
32
  size = (params[:size] || 10).to_i
31
33
  results[:total_count] = coll.count(:all) if params[:total_count]
@@ -7,6 +7,7 @@ module SlackRubyBotServer
7
7
  def sort_order(options = {})
8
8
  params[:sort] = options[:default_sort_order] unless params[:sort]
9
9
  return [] unless params[:sort]
10
+
10
11
  sort_order = params[:sort].to_s
11
12
  unless options[:default_sort_order] == sort_order
12
13
  supported_sort_orders = route_sort
@@ -30,11 +30,7 @@ module SlackRubyBotServer
30
30
  end
31
31
 
32
32
  use Rack::ServerPages do |config|
33
- config.view_path = [
34
- 'views', # relative to Dir.pwd
35
- 'public', # relative to Dir.pwd
36
- File.expand_path(File.join(__dir__, '../../../public')) # built-in fallback
37
- ]
33
+ config.view_path = SlackRubyBotServer::Config.view_paths
38
34
  end
39
35
 
40
36
  run Middleware.new
@@ -2,8 +2,8 @@ require 'roar/representer'
2
2
  require 'roar/json'
3
3
  require 'roar/json/hal'
4
4
 
5
- require 'slack-ruby-bot-server/api/presenters/paginated_presenter'
6
- require 'slack-ruby-bot-server/api/presenters/status_presenter'
7
- require 'slack-ruby-bot-server/api/presenters/team_presenter'
8
- require 'slack-ruby-bot-server/api/presenters/teams_presenter'
9
- require 'slack-ruby-bot-server/api/presenters/root_presenter'
5
+ require_relative 'presenters/paginated_presenter'
6
+ require_relative 'presenters/status_presenter'
7
+ require_relative 'presenters/team_presenter'
8
+ require_relative 'presenters/teams_presenter'
9
+ require_relative 'presenters/root_presenter'
@@ -23,6 +23,7 @@ module SlackRubyBotServer
23
23
  raise 'Unsupported database driver.'
24
24
  end
25
25
  return unless team
26
+
26
27
  team.ping!
27
28
  end
28
29
 
@@ -5,10 +5,18 @@ module SlackRubyBotServer
5
5
  attr_accessor :server_class
6
6
  attr_accessor :service_class
7
7
  attr_accessor :database_adapter
8
+ attr_accessor :view_paths
8
9
 
9
10
  def reset!
10
11
  self.server_class = SlackRubyBotServer::Server
11
12
  self.service_class = SlackRubyBotServer::Service
13
+
14
+ self.view_paths = [
15
+ 'views',
16
+ 'public',
17
+ File.expand_path(File.join(__dir__, '../../public'))
18
+ ]
19
+
12
20
  self.database_adapter = if defined?(::Mongoid)
13
21
  :mongoid
14
22
  elsif defined?(::ActiveRecord)
@@ -1,4 +1,4 @@
1
- require 'slack-ruby-bot-server/models/team/activerecord.rb'
1
+ require_relative '../../models/team/activerecord.rb'
2
2
 
3
3
  module SlackRubyBotServer
4
4
  module DatabaseAdapter
@@ -28,4 +28,4 @@ module SlackRubyBotServer
28
28
  end
29
29
  end
30
30
 
31
- ::Boolean = Virtus::Attribute::Boolean
31
+ ::Boolean = Grape::API::Boolean
@@ -1,4 +1,5 @@
1
- require 'slack-ruby-bot-server/models/team/mongoid.rb'
1
+ require_relative '../../models/team/mongoid.rb'
2
+
2
3
  require 'kaminari/grape'
3
4
  require 'mongoid-scroll'
4
5
 
@@ -6,7 +7,8 @@ module SlackRubyBotServer
6
7
  module DatabaseAdapter
7
8
  def self.check!
8
9
  rc = Mongoid.default_client.command(ping: 1)
9
- return if rc && rc.ok?
10
+ return if rc&.ok?
11
+
10
12
  raise rc.documents.first['error'] || 'Unexpected error.'
11
13
  rescue StandardError => e
12
14
  warn "Error connecting to MongoDB: #{e.message}"
@@ -8,6 +8,7 @@ module SlackRubyBotServer
8
8
  attrs = attrs.dup
9
9
  @team = attrs.delete(:team)
10
10
  raise 'Missing team' unless @team
11
+
11
12
  attrs[:token] = @team.token
12
13
  super(attrs)
13
14
  open!
@@ -15,10 +15,29 @@ module SlackRubyBotServer
15
15
 
16
16
  def initialize
17
17
  @callbacks = Hash.new { |h, k| h[k] = [] }
18
+ @intervals = Hash.new { |h, k| h[k] = [] }
18
19
  end
19
20
 
20
- def on(type, &block)
21
- @callbacks[type.to_s] << block
21
+ def on(*types, &block)
22
+ Array(types).each do |type|
23
+ @callbacks[type.to_s] << block
24
+ end
25
+ end
26
+
27
+ def every(*intervals, &block)
28
+ Array(intervals).each do |interval|
29
+ case interval
30
+ when :minute
31
+ interval = 60
32
+ when :hour
33
+ interval = 60 * 60
34
+ when :day
35
+ interval = 60 * 60 * 24
36
+ end
37
+ raise "Invalid interval \"#{interval}\"." unless interval.is_a?(Integer) && interval > 0
38
+
39
+ @intervals[interval] << block
40
+ end
22
41
  end
23
42
 
24
43
  def create!(team, options = {})
@@ -49,7 +68,7 @@ module SlackRubyBotServer
49
68
  def stop!(team)
50
69
  logger.info "Stopping team #{team}."
51
70
  run_callbacks :stopping, team
52
- team.server.stop! if team.server
71
+ team.server&.stop!
53
72
  run_callbacks :stopped, team
54
73
  rescue StandardError => e
55
74
  run_callbacks :error, team, e
@@ -64,6 +83,15 @@ module SlackRubyBotServer
64
83
  start!(team)
65
84
  run_callbacks :booted, team
66
85
  end
86
+ start_intervals!
87
+ end
88
+
89
+ def start_intervals!
90
+ @intervals.each_pair do |period, calls|
91
+ _every period do
92
+ calls.each(&:call)
93
+ end
94
+ end
67
95
  end
68
96
 
69
97
  def deactivate!(team)
@@ -86,6 +114,19 @@ module SlackRubyBotServer
86
114
 
87
115
  private
88
116
 
117
+ def _every(tt, &_block)
118
+ ::Async::Reactor.run do |task|
119
+ loop do
120
+ begin
121
+ task.sleep tt
122
+ yield
123
+ rescue StandardError => e
124
+ logger.error e
125
+ end
126
+ end
127
+ end
128
+ end
129
+
89
130
  def start_server!(team, server, wait = 1)
90
131
  team.server = server
91
132
  server.start_async
@@ -106,6 +147,7 @@ module SlackRubyBotServer
106
147
  def run_callbacks(type, team = nil, error = nil, options = {})
107
148
  callbacks = @callbacks[type.to_s]
108
149
  return false unless callbacks
150
+
109
151
  callbacks.each do |c|
110
152
  c.call team, error, options
111
153
  end
@@ -1,3 +1,3 @@
1
1
  module SlackRubyBotServer
2
- VERSION = '0.11.1'.freeze
2
+ VERSION = '0.12.0'.freeze
3
3
  end
@@ -3,6 +3,7 @@
3
3
  <title>Slack Ruby Bot Server</title>
4
4
  <script src="/scripts/jquery-1.7.1.min.js"></script>
5
5
  <script src="/scripts/url.min.js"></script>
6
+ <script src="/scripts/messages.js"></script>
6
7
  <script src="/scripts/register.js"></script>
7
8
  <script src="/scripts/stats.js"></script>
8
9
  </head>
@@ -0,0 +1,33 @@
1
+ var SlackRubyBotServer = {};
2
+
3
+ $(document).ready(function() {
4
+
5
+ SlackRubyBotServer.message = function(text) {
6
+ $('#messages').fadeOut('slow', function() {
7
+ $('#messages').fadeIn('slow').html(text)
8
+ });
9
+ };
10
+
11
+ SlackRubyBotServer.error = function(xhr) {
12
+ try {
13
+ var message;
14
+ if (xhr.responseText) {
15
+ var rc = JSON.parse(xhr.responseText);
16
+ if (rc && rc.message) {
17
+ message = rc.message;
18
+ if (message == 'invalid_code') {
19
+ message = 'The code returned from the OAuth workflow was invalid.'
20
+ } else if (message == 'code_already_used') {
21
+ message = 'The code returned from the OAuth workflow has already been used.'
22
+ }
23
+ }
24
+ }
25
+
26
+ SlackRubyBotServer.message(message || xhr.statusText || xhr.responseText || 'Unexpected Error');
27
+
28
+ } catch(err) {
29
+ SlackRubyBotServer.message(err.message);
30
+ }
31
+ };
32
+
33
+ });
@@ -1,35 +1,4 @@
1
- var SlackRubyBotServer = {};
2
-
3
1
  $(document).ready(function() {
4
-
5
- SlackRubyBotServer.message = function(text) {
6
- $('#messages').fadeOut('slow', function() {
7
- $('#messages').fadeIn('slow').html(text)
8
- });
9
- };
10
-
11
- SlackRubyBotServer.error = function(xhr) {
12
- try {
13
- var message;
14
- if (xhr.responseText) {
15
- var rc = JSON.parse(xhr.responseText);
16
- if (rc && rc.message) {
17
- message = rc.message;
18
- if (message == 'invalid_code') {
19
- message = 'The code returned from the OAuth workflow was invalid.'
20
- } else if (message == 'code_already_used') {
21
- message = 'The code returned from the OAuth workflow has already been used.'
22
- }
23
- }
24
- }
25
-
26
- SlackRubyBotServer.message(message || xhr.statusText || xhr.responseText || 'Unexpected Error');
27
-
28
- } catch(err) {
29
- SlackRubyBotServer.message(err.message);
30
- }
31
- };
32
-
33
2
  // Slack OAuth
34
3
  var code = $.url('?code')
35
4
  var state = $.url('?state')
@@ -7,5 +7,6 @@ This is a sample slack-ruby-bot-server with ActiveRecord.
7
7
  ```
8
8
  bundle install
9
9
  rake db:create db:migrate
10
+ RAILS_ENV=test rake db:migrate
10
11
  rackup
11
12
  ```
@@ -1,6 +1,6 @@
1
1
  lib = File.expand_path('lib', __dir__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'slack-ruby-bot-server/version'
3
+ require_relative 'lib/slack-ruby-bot-server/version'
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = 'slack-ruby-bot-server'
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.11.1
4
+ version: 0.12.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: 2019-05-17 00:00:00.000000000 Z
11
+ date: 2020-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-websocket
@@ -173,7 +173,7 @@ files:
173
173
  - RELEASING.md
174
174
  - Rakefile
175
175
  - UPGRADING.md
176
- - images/new.png
176
+ - images/create-app.png
177
177
  - images/slackbotserver.gif
178
178
  - images/slackbutton.gif
179
179
  - lib/slack-ruby-bot-server.rb
@@ -219,6 +219,7 @@ files:
219
219
  - public/index.html.erb
220
220
  - public/robots.txt
221
221
  - public/scripts/jquery-1.7.1.min.js
222
+ - public/scripts/messages.js
222
223
  - public/scripts/register.js
223
224
  - public/scripts/stats.js
224
225
  - public/scripts/url.min.js
Binary file