slack-ruby-bot-server 1.0.0 → 1.2.1

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: 3999b9e5a783666fcf1cebfe6d07d50e0228d7a1e3c17ca52217c7677705a1c2
4
- data.tar.gz: 6294712aae7ca330fa3c13764e369084ed7f097772e22b54e5a8c1964ec2e130
3
+ metadata.gz: ce55bd11d1164eaaa7985395b77ac8d104f69adfd1a5d3ccd1e6a195e02aceb2
4
+ data.tar.gz: '08700bcdc5768db23d313ac4cdde14c4b315f83f407b26fcff764b0249d5ca31'
5
5
  SHA512:
6
- metadata.gz: 17c1e6474f1a45c964d67210d96669dc4bbb5910c3571d1720916f9a13b469741d08462e6feb57185a9745ffb373164f68c88f91bbf71691313215a23264a0a5
7
- data.tar.gz: 43c5fde5d25f993be6da99758303026ff2870b26e50435cda7bc10218ae0fea1c7a9ab321d946f62485fc59f37da845ee425804327b1a5c7a4c2575d1f9ccfd3
6
+ metadata.gz: 4f2585a8f933f806ff9cb998e58d7a03efda4a0aee1afeccd5f07289156e37c8ccf9092058b19413a22986031c0a82cca7dd35a9f6dbc9d7211d0823b363e708
7
+ data.tar.gz: b5139b404dfc9c6c1b5027286126438e81da1c577805aedd3273f07e5e0f2ee9fdb89572d32f652d2e9c8f372c062b74c5ae948b4b2a0347383b908ac29648b9
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: danger
3
+ on: [pull_request]
4
+ jobs:
5
+ danger:
6
+ runs-on: ubuntu-latest
7
+ steps:
8
+ - uses: actions/checkout@v2
9
+ with:
10
+ fetch-depth: 0
11
+ - name: Set up Ruby
12
+ uses: ruby/setup-ruby@v1
13
+ with:
14
+ ruby-version: 2.6
15
+ bundler-cache: true
16
+ - name: Run Danger
17
+ env:
18
+ BUNDLE_GEMFILE: Gemfile.danger
19
+ run: |
20
+ bundle install
21
+ # the personal token is public, this is ok, base64 encode to avoid tripping Github
22
+ TOKEN=$(echo -n NWY1ZmM5MzEyMzNlYWY4OTZiOGU3MmI3MWQ3Mzk0MzgxMWE4OGVmYwo= | base64 --decode)
23
+ DANGER_GITHUB_API_TOKEN=$TOKEN bundle exec danger --verbose
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: test
3
+ on: [push, pull_request]
4
+ jobs:
5
+ lint:
6
+ name: RuboCop
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - uses: actions/checkout@v2
10
+ - name: Set up Ruby
11
+ uses: ruby/setup-ruby@v1
12
+ with:
13
+ ruby-version: 2.7
14
+ bundler-cache: true
15
+ - name: Run RuboCop
16
+ run: bundle exec rubocop
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: test
3
+ on: [push, pull_request]
4
+ jobs:
5
+ test:
6
+ runs-on: ubuntu-latest
7
+ strategy:
8
+ matrix:
9
+ entry:
10
+ - { ruby: 2.6.2, mongoid: 6.4.8, mongodb: 4.4 }
11
+ - { ruby: 2.6.2, mongoid: 7.2.3, mongodb: 4.4 }
12
+ - { ruby: 2.6.2, mongoid: 7.3.0, mongodb: 4.4 }
13
+ name: test (ruby=${{ matrix.entry.ruby }}, mongoid=${{ matrix.entry.mongoid }}, mongodb=${{ matrix.entry.mongodb }})
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+ - uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: ${{ matrix.entry.ruby }}
19
+ - uses: browser-actions/setup-geckodriver@latest
20
+ - run: geckodriver --version
21
+ - uses: supercharge/mongodb-github-action@1.7.0
22
+ with:
23
+ mongodb-version: ${{ matrix.entry.mongodb }}
24
+ - name: Test
25
+ uses: GabrielBB/xvfb-action@v1
26
+ env:
27
+ DATABASE_ADAPTER: mongoid
28
+ MONGOID_VERSION: ${{ matrix.entry.mongoid }}
29
+ with:
30
+ run: |
31
+ bundle install
32
+ bundle exec rake spec
@@ -0,0 +1,33 @@
1
+ ---
2
+ name: test
3
+ on: [push, pull_request]
4
+ jobs:
5
+ test:
6
+ runs-on: ubuntu-latest
7
+ strategy:
8
+ matrix:
9
+ entry:
10
+ - { ruby: 2.6.2, postgresql: 11 }
11
+ name: test (ruby=${{ matrix.entry.ruby }}, postgresql=${{ matrix.entry.postgresql }})
12
+ steps:
13
+ - uses: actions/checkout@v2
14
+ - uses: ruby/setup-ruby@v1
15
+ with:
16
+ ruby-version: ${{ matrix.entry.ruby }}
17
+ - uses: browser-actions/setup-geckodriver@latest
18
+ - run: geckodriver --version
19
+ - uses: harmon758/postgresql-action@v1
20
+ with:
21
+ postgresql version: ${{ matrix.entry.postgresql }}
22
+ postgresql db: slack_ruby_bot_server_test
23
+ postgresql user: test
24
+ postgresql password: password
25
+ - name: Test
26
+ uses: GabrielBB/xvfb-action@v1
27
+ env:
28
+ DATABASE_ADAPTER: activerecord
29
+ DATABASE_URL: postgres://test:password@localhost/slack_ruby_bot_server_test
30
+ with:
31
+ run: |
32
+ bundle install
33
+ bundle exec rake spec
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2020-11-15 11:38:22 -0500 using RuboCop version 0.81.0.
3
+ # on 2020-11-16 09:56:54 -0500 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
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  ### Changelog
2
2
 
3
+ #### 1.2.1 (2022/03/06)
4
+
5
+ * [#140](https://github.com/slack-ruby/slack-ruby-bot-server/pull/140): Fix: `NameError` for `Boolean` types with mongoid >= 7.3.0 - [@dblock](https://github.com/dblock).
6
+ * [#142](https://github.com/slack-ruby/slack-ruby-bot-server/pull/142): Replace Travis-CI with GitHub Actions - [@dblock](https://github.com/dblock).
7
+
8
+ #### 1.2.0 (2020/11/27)
9
+
10
+ * [#133](https://github.com/slack-ruby/slack-ruby-bot-server/pull/133): Added `Team#oauth_version` and `#scope` - [@dblock](https://github.com/dblock).
11
+
12
+ #### 1.1.0 (2020/11/17)
13
+
14
+ * [#132](https://github.com/slack-ruby/slack-ruby-bot-server/pull/132): Added support for OAuth v2 - [@dblock](https://github.com/dblock).
15
+
3
16
  #### 1.0.0 (2020/11/15)
4
17
 
5
18
  * [#129](https://github.com/slack-ruby/slack-ruby-bot-server/pull/129): Extracted RealTime components into [slack-ruby-bot-server-rtm](https://github.com/slack-ruby/slack-ruby-bot-server-rtm) - [@dblock](https://github.com/dblock).
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source 'https://rubygems.org'
3
3
  case ENV['DATABASE_ADAPTER']
4
4
  when 'mongoid' then
5
5
  gem 'kaminari-mongoid'
6
- gem 'mongoid'
6
+ gem 'mongoid', ENV['MONGOID_VERSION'] || '~> 7.3.0'
7
7
  gem 'mongoid-scroll'
8
8
  gem 'mongoid-shell'
9
9
  when 'activerecord' then
@@ -23,10 +23,11 @@ group :development, :test do
23
23
  gem 'bundler'
24
24
  gem 'byebug'
25
25
  gem 'capybara', '~> 2.15.1'
26
- gem 'database_cleaner'
26
+ gem 'database_cleaner', '~> 1.8.5'
27
27
  gem 'fabrication'
28
28
  gem 'faker'
29
- gem 'hyperclient'
29
+ gem 'faraday', '0.17.5'
30
+ gem 'hyperclient', '~> 0.9.3'
30
31
  gem 'rack-server-pages'
31
32
  gem 'rack-test'
32
33
  gem 'rake'
@@ -35,9 +36,5 @@ group :development, :test do
35
36
  gem 'selenium-webdriver', '~> 3.4.4'
36
37
  gem 'vcr'
37
38
  gem 'webmock'
38
- end
39
-
40
- group :test do
41
- gem 'danger-toc', '~> 0.2.0', require: false
42
- gem 'slack-ruby-danger', '~> 0.1.0', require: false
39
+ gem 'webrick', '~> 1.6.1'
43
40
  end
data/Gemfile.danger ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :test do
4
+ gem 'danger-toc', '~> 0.2.0', require: false
5
+ gem 'slack-ruby-danger', '~> 0.2.0', require: false
6
+ end
data/MIGRATING.md ADDED
@@ -0,0 +1,98 @@
1
+ ### Introduction
2
+
3
+ Slack recently [introduced granular permissions](https://medium.com/slack-developer-blog/more-precision-less-restrictions-a3550006f9c3) and is now requiring all new apps to use them. The old apps are called _classic_ apps. Slack also provided a [migration guide](https://api.slack.com/authentication/migration).
4
+
5
+ > As of December 4th, 2020 Slack no longer accept resubmissions from apps that are not using granular permissions. On November 18, 2021 Slack will start delisting apps that have not migrated to use granular permissions. So you better get going with a migration ASAP.
6
+
7
+ New bots cannot use real-time, and there's no way to automatically migrate existing installations - users must reinstall a newer version of the bot. This migration guide avoids a data migration by allowing you to operate both the old and the new version on top of the same database.
8
+
9
+ > The migration effectively involves replacing `slack-ruby-bot-server-rtm` with `slack-ruby-bot-server-events`.
10
+
11
+ ### Upgrade to Slack-Ruby-Bot-Server 1.2.0 and Slack-Ruby-Bot-Server-Rtm
12
+
13
+ Upgrade to the latest version of [slack-ruby-bot-server-rtm](https://github.com/slack-ruby/slack-ruby-bot-server-rtm) , which extracts real-time components. This involves replacing `SlackRubyBotServer::Server` with `SlackRubyBotServer::RealTime::Server`.
14
+
15
+ Upgrade to [slack-ruby-bot-server](https://github.com/slack-ruby/slack-ruby-bot-server) >= 1.2.0. This version introduces two new `Team` fields, `oauth_version` and `oauth_scope` to store which version of the bot performed the install. This allows slack-ruby-bot-server-rtm to ignore newer bots and only boot RTM for legacy bots.
16
+
17
+ See [UPGRADING](https://github.com/slack-ruby/slack-ruby-bot-server/blob/master/UPGRADING.md#upgrading-to--120) for more information on ActiveRecord database migrations.
18
+
19
+ Deploy your bot and make sure everything is working without any changes.
20
+
21
+ ### Create a New Slack App
22
+
23
+ In order not to affect existing users, [create a new Slack app](https://api.slack.com/apps) with new granular permissions and scopes. For example, to send messages to Slack you will need `chat:write`. To read messages in public channels, `channels:history`. To receive bot mentions you'll need `app_mentions:read` and to receive DMs, `im:history`.
24
+
25
+ ### Respond to Slack Events
26
+
27
+ #### App Mentions
28
+
29
+ A typical bot may want to respond to mentions, which is made very easy by the new [slack-ruby-bot-server-events-app-mentions](https://github.com/slack-ruby/slack-ruby-bot-server-events-app-mentions) gem. This is similar to the [commands in slack-ruby-bot](https://github.com/slack-ruby/slack-ruby-bot#commands-and-operators), but you'll need to do the work to actually migrate functionality to mentions, and not all variations of commands and operators are currently supported.
30
+
31
+ ```ruby
32
+ SlackRubyBotServer.configure do |config|
33
+ config.oauth_version = :v2
34
+ config.oauth_scope = ['app_mentions:read', 'im:history', 'chat:write']
35
+ end
36
+ ```
37
+
38
+ ```ruby
39
+ class Ping < SlackRubyBotServer::Events::AppMentions::Mention
40
+ mention 'ping'
41
+
42
+ def self.call(data)
43
+ client = Slack::Web::Client.new(token: data.team.token)
44
+ client.chat_postMessage(channel: data.channel, text: 'pong')
45
+ end
46
+ end
47
+ ```
48
+
49
+ See a [complete sample](https://github.com/slack-ruby/slack-ruby-bot-server-events-app-mentions-sample) for more details.
50
+
51
+ #### Other Messages
52
+
53
+ More advanced bots may want to handle all kinds of messages. For example, [slack-shellbot#22](https://github.com/slack-ruby/slack-shellbot/pull/22) configures scopes to receive the kitchen sink of events, then handles them carefully avoiding handling its own messages.
54
+
55
+ ```ruby
56
+ SlackRubyBotServer.configure do |config|
57
+ config.oauth_version = :v2
58
+ config.oauth_scope = ['chat:write', 'im:history', 'mpim:history', 'channels:history', 'groups:history']
59
+ end
60
+ ```
61
+
62
+ ```ruby
63
+ SlackRubyBotServer::Events.configure do |config|
64
+ config.on :event, 'event_callback', 'message' do |event|
65
+ # SlackShellbot::Commands::Base.logger.info event
66
+
67
+ next true if event['event']['subtype'] # updates, etc.
68
+ next true if event['authorizations'][0]['user_id'] == event['event']['user'] # self
69
+
70
+ team = Team.where(team_id: event['team_id']).first
71
+ next true unless team
72
+
73
+ data = Slack::Messages::Message.new(event['event'])
74
+
75
+ # handles event data here
76
+
77
+ true
78
+ end
79
+ end
80
+ ```
81
+
82
+ ### Deploy
83
+
84
+ Create a new app deployment, use the same database as your production bot. The new bot needs a configuration with the `SLACK_CLIENT_ID`, `SLACK_CLIENT_SECRET` and `SLACK_SIGNING_SECRET` from the new app with granular permissions. Use the same database instance as the old RTM bot.
85
+
86
+ Now there are two versions of the app running on top of the same database: one is the legacy one, and the other is the granular scopes app. The old app will ignore new bot installations that use granular permissions. The new app should ignore any old bot installations. Thus both apps should work.
87
+
88
+ ### Switch DNS
89
+
90
+ Switch DNS, new bot registrations can use the new granular scopes app. Make sure in Slack the event URLs are configured properly to point to this DNS.
91
+
92
+ ### Slow Migration for Existing Teams
93
+
94
+ Existing teams can uninstall the old bot and re-install the new one. The old real-time implementation will stop working once the token has been switched, but the data will remain intact and the team will get reactivated using the new bot with granular permissions.
95
+
96
+ ### Long Version
97
+
98
+ See [this blog post](http://localhost:4000/2020/11/30/migrating-classic-slack-ruby-bots-to-granular-permissions.html) for a longer, opinionated version of this migration guide.
data/README.md CHANGED
@@ -2,51 +2,57 @@ Slack Ruby Bot Server
2
2
  =====================
3
3
 
4
4
  [![Gem Version](https://badge.fury.io/rb/slack-ruby-bot-server.svg)](https://badge.fury.io/rb/slack-ruby-bot-server)
5
- [![Build Status](https://travis-ci.org/slack-ruby/slack-ruby-bot-server.svg?branch=master)](https://travis-ci.org/slack-ruby/slack-ruby-bot-server)
6
5
  [![Code Climate](https://codeclimate.com/github/slack-ruby/slack-ruby-bot-server.svg)](https://codeclimate.com/github/slack-ruby/slack-ruby-bot-server)
6
+ [![mongodb](https://github.com/slack-ruby/slack-ruby-bot-server/actions/workflows/test-mongodb.yml/badge.svg)](https://github.com/slack-ruby/slack-ruby-bot-server/actions/workflows/test-mongodb.yml)
7
+ [![postgresql](https://github.com/slack-ruby/slack-ruby-bot-server/actions/workflows/test-postgresql.yml/badge.svg)](https://github.com/slack-ruby/slack-ruby-bot-server/actions/workflows/test-postgresql.yml)
8
+ [![rubocop](https://github.com/slack-ruby/slack-ruby-bot-server/actions/workflows/rubocop.yml/badge.svg)](https://github.com/slack-ruby/slack-ruby-bot-server/actions/workflows/rubocop.yml)
7
9
 
8
10
  Build a complete Slack bot service with Slack button integration, in Ruby.
9
11
 
10
- # Table of Contents
12
+ ## Table of Contents
11
13
 
12
14
  - [What is this?](#what-is-this)
13
15
  - [Stable Release](#stable-release)
14
16
  - [Make Your Own](#make-your-own)
15
- - [Storage](#storage)
16
- - [MongoDB](#mongodb)
17
- - [ActiveRecord](#activerecord)
18
17
  - [Usage](#usage)
19
- - [API](#api)
20
- - [App](#app)
21
- - [Service Manager](#service-manager)
22
- - [Lifecycle Callbacks](#lifecycle-callbacks)
23
- - [Service Timers](#service-timers)
24
- - [Extensions](#extensions)
25
- - [Service Class](#service-class)
26
- - [HTML Templates](#html-templates)
27
- - [Access Tokens](#access-tokens)
18
+ - [Storage](#storage)
19
+ - [MongoDB](#mongodb)
20
+ - [ActiveRecord](#activerecord)
21
+ - [OAuth Version and Scopes](#oauth-version-and-scopes)
22
+ - [Slack App](#slack-app)
23
+ - [API](#api)
24
+ - [App](#app)
25
+ - [Service Manager](#service-manager)
26
+ - [Lifecycle Callbacks](#lifecycle-callbacks)
27
+ - [Service Timers](#service-timers)
28
+ - [Extensions](#extensions)
29
+ - [Service Class](#service-class)
30
+ - [HTML Templates](#html-templates)
31
+ - [Access Tokens](#access-tokens)
28
32
  - [Sample Bots Using Slack Ruby Bot Server](#sample-bots-using-slack-ruby-bot-server)
29
33
  - [Slack Bots with Granular Permissions](#slack-bots-with-granular-permissions)
30
34
  - [Legacy Slack Bots](#legacy-slack-bots)
31
35
  - [Copyright & License](#copyright--license)
32
36
 
33
- ### What is this?
37
+ ## What is this?
34
38
 
35
- A library that contains a web server and a RESTful [Grape](http://github.com/ruby-grape/grape) API serving a Slack bot to multiple teams. Use in conjunction with [slack-ruby-bot-server-events](https://github.com/slack-ruby/slack-ruby-bot-server-events) to build a complete Slack bot service, or [slack-ruby-bot-server-rtm](https://github.com/slack-ruby/slack-ruby-bot-server-rtm) to build a Class RealTime Slack bot. Your customers can use a Slack button to install the bot.
39
+ A library that contains a web server and a RESTful [Grape](http://github.com/ruby-grape/grape) API serving a Slack bot to multiple teams. Use in conjunction with [slack-ruby-bot-server-events](https://github.com/slack-ruby/slack-ruby-bot-server-events) to build a complete Slack bot service, or [slack-ruby-bot-server-rtm](https://github.com/slack-ruby/slack-ruby-bot-server-rtm) to build a (legacy) Classic RealTime Slack bot. Your customers can use a Slack button to install the bot.
36
40
 
37
- ### Stable Release
41
+ ## Stable Release
38
42
 
39
- You're reading the documentation for the **stable** release of slack-ruby-bot-server, v1.0.0. See [UPGRADING](UPGRADING.md) when upgrading from an older version.
43
+ You're reading the documentation for the **stable** release of slack-ruby-bot-server. See [UPGRADING](UPGRADING.md) when upgrading from an older version. See [MIGRATING](MIGRATING.md) for help with migrating Legacy Slack Apps to Granular Scopes.
40
44
 
41
- ### Make Your Own
45
+ ## Make Your Own
42
46
 
43
- We recommend you get started from a [slack-ruby-bot-events-sample](https://github.com/slack-ruby/slack-ruby-bot-server-events-sample) app to bootstrap your project.
47
+ This library alone will only register a new bot, but will not include any bot functionality. To make something useful, we recommend you get started from either [slack-ruby-bot-server-events-app-mentions-sample](https://github.com/slack-ruby/slack-ruby-bot-server-events-app-mentions-sample) (handles a single kind of event), or [slack-ruby-bot-server-events-sample](https://github.com/slack-ruby/slack-ruby-bot-server-events-sample) (handles all kinds of events) to bootstrap your project.
48
+
49
+ ## Usage
44
50
 
45
51
  ### Storage
46
52
 
47
53
  A database is required to store teams.
48
54
 
49
- ### MongoDB
55
+ #### MongoDB
50
56
 
51
57
  Use MongoDB with [Mongoid](https://github.com/mongodb/mongoid) as ODM. Configure the database connection in `mongoid.yml`. Add the `mongoid` gem in your Gemfile.
52
58
 
@@ -57,9 +63,9 @@ gem 'mongoid-scroll'
57
63
  gem 'slack-ruby-bot-server'
58
64
  ```
59
65
 
60
- ### ActiveRecord
66
+ #### ActiveRecord
61
67
 
62
- Use ActiveRecord with, for example, PostgreSQL via [pg](https://github.com/ged/ruby-pg). Configure the database connection in `postgresql.yml`. Add the `activerecord`, `pg`, `otr-activerecord` and `cursor_pagination` gems to your Gemfile.
68
+ Use ActiveRecord with, for example, PostgreSQL via [pg](https://github.com/ged/ruby-pg). Add the `activerecord`, `pg`, `otr-activerecord` and `cursor_pagination` gems to your Gemfile.
63
69
 
64
70
  ```
65
71
  gem 'pg'
@@ -69,27 +75,79 @@ gem 'otr-activerecord'
69
75
  gem 'cursor_pagination'
70
76
  ```
71
77
 
72
- ### Usage
78
+ Configure the database connection in `config/postgresql.yml`.
73
79
 
74
- Start with the [slack-ruby-bot-events-sample](https://github.com/slack-ruby/slack-ruby-bot-server-events-sample) sample, which contain a couple of custom commands, necessary dependencies and tests, then [create a new Slack App](https://api.slack.com/applications/new).
80
+ ```yaml
81
+ default: &default
82
+ adapter: postgresql
83
+ pool: 10
84
+ timeout: 5000
85
+ encoding: unicode
75
86
 
76
- ![](images/create-app.png)
87
+ development:
88
+ <<: *default
89
+ database: bot_development
77
90
 
78
- 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.
91
+ test:
92
+ <<: *default
93
+ database: bot_test
79
94
 
80
- Within your application, edit your `.env` file and add `SLACK_CLIENT_ID=...` and `SLACK_CLIENT_SECRET=...` in it.
95
+ production:
96
+ <<: *default
97
+ database: bot
98
+ ```
99
+
100
+ Establish a connection in your startup code.
101
+
102
+ ```ruby
103
+ ActiveRecord::Base.establish_connection(
104
+ YAML.safe_load(
105
+ ERB.new(
106
+ File.read('config/postgresql.yml')
107
+ ).result, [], [], true
108
+ )[ENV['RACK_ENV']]
109
+ )
110
+ ```
111
+
112
+ ### OAuth Version and Scopes
81
113
 
82
- Configure your app's [OAuth scopes](https://api.slack.com/legacy/oauth-scopes) as needed by your application.
114
+ Configure your app's [OAuth version](https://api.slack.com/authentication/oauth-v2) and [scopes](https://api.slack.com/legacy/oauth-scopes) as needed by your application.
83
115
 
84
116
  ```ruby
85
117
  SlackRubyBotServer.configure do |config|
86
- config.oauth_scope = ['channels:read', 'chat:write:user']
118
+ config.oauth_version = :v2
119
+ config.oauth_scope = ['channels:read', 'chat:write']
87
120
  end
88
121
  ```
89
122
 
90
123
  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). 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 persists the bot token each time a Slack client is instantiated for the specific team.
91
124
 
92
- 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.
125
+ ### Slack App
126
+
127
+ Create a new Slack App [here](https://api.slack.com/applications/new).
128
+
129
+ ![](images/create-app.png)
130
+
131
+ Follow Slack's instructions, note the app client ID and secret, give the bot a default name, etc.
132
+
133
+ Within your application, edit your `.env` file and add `SLACK_CLIENT_ID=...` and `SLACK_CLIENT_SECRET=...` in it.
134
+
135
+ Run `bundle install` and `foreman start` to boot the app.
136
+
137
+ ```
138
+ $ foreman start
139
+ 07:44:47 web.1 | started with pid 59258
140
+ 07:44:50 web.1 | * Listening on tcp://0.0.0.0:5000
141
+ ```
142
+
143
+ Set the redirect URL in "OAuth & Permissions" be the location of your app. Since you cannot receive notifications on localhost from Slack use a public tunneling service such as [ngrok](https://ngrok.com/) to expose local port 9292 for testing.
144
+
145
+ ```
146
+ $ ngrok http 5000
147
+ Forwarding https://ddfd97f80615.ngrok.io -> http://localhost:5000
148
+ ```
149
+
150
+ Navigate to either [localhost:9292](http://localhost:9292) or the ngrok URL above. You should see an "Add to Slack" button. Use it to install the app into your own Slack team.
93
151
 
94
152
  ### API
95
153
 
@@ -168,7 +226,7 @@ The [Add to Slack button](https://api.slack.com/docs/slack-button) also allows f
168
226
  auth = OpenSSL::HMAC.hexdigest("SHA256", "key", "data")
169
227
  ```
170
228
  ```html
171
- <a href="https://slack.com/oauth/authorize?scope=<%= SlackRubyBotServer::Config.oauth_scope_s %>&client_id=<%= ENV['SLACK_CLIENT_ID'] %>&state=#{auth)"> ... </a>
229
+ <a href="<%= SlackRubyBotServer::Config.oauth_authorize_url %>?scope=<%= SlackRubyBotServer::Config.oauth_scope_s %>&client_id=<%= ENV['SLACK_CLIENT_ID'] %>&state=#{auth)"> ... </a>
172
230
  ```
173
231
  ```ruby
174
232
  instance = SlackRubyBotServer::Service.instance
@@ -250,16 +308,16 @@ end
250
308
 
251
309
  ### Access Tokens
252
310
 
253
- By default the implementation of [Team](lib/slack-ruby-bot-server/models/team) stores the value of the token with all the requested OAuth scopes in both `token` and `activated_user_access_token` (for backwards compatibility). If a legacy Slack bot integration `bot_access_token` is present, it is stored as `token`, and `activated_user_access_token`is the token that has all the requested OAuth scopes.
311
+ By default the implementation of [Team](lib/slack-ruby-bot-server/models/team) stores the value of the token with all the requested OAuth scopes in both `token` and `activated_user_access_token` (for backwards compatibility), along with `oauth_version` and `oauth_scope`. If a legacy Slack bot integration `bot_access_token` is present, it is stored as `token`, and `activated_user_access_token` is the token that has all the requested OAuth scopes.
254
312
 
255
- ### Sample Bots Using Slack Ruby Bot Server
313
+ ## Sample Bots Using Slack Ruby Bot Server
256
314
 
257
- #### Slack Bots with Granular Permissions
315
+ ### Slack Bots with Granular Permissions
258
316
 
259
317
  * [slack-ruby-bot-server-events-sample](https://github.com/slack-ruby/slack-ruby-bot-server-events-sample), a generic sample
260
318
  * [slack-rails-bot-starter](https://github.com/CrazyOptimist/slack-rails-bot-starter), an all-in-one Rails starter kit
261
319
 
262
- #### Legacy Slack Bots
320
+ ### Legacy Slack Bots
263
321
 
264
322
  * [slack-ruby-bot-server-sample](https://github.com/slack-ruby/slack-ruby-bot-server-sample), a generic sample
265
323
  * [slack-sup](https://github.com/dblock/slack-sup), see [sup.playplay.io](https://sup.playplay.io)
@@ -270,7 +328,7 @@ By default the implementation of [Team](lib/slack-ruby-bot-server/models/team) s
270
328
  * [slack-strava](https://github.com/dblock/slack-strava), see [slava.playplay.io](https://slava.playplay.io)
271
329
  * [slack-arena](https://github.com/dblock/slack-arena), see [arena.playplay.io](https://arena.playplay.io)
272
330
 
273
- ### Copyright & License
331
+ ## Copyright & License
274
332
 
275
333
  Copyright [Daniel Doubrovkine](http://code.dblock.org) and Contributors, 2015-2020
276
334
 
data/UPGRADING.md CHANGED
@@ -1,7 +1,31 @@
1
1
  Upgrading Slack-Ruby-Bot-Server
2
2
  ===============================
3
3
 
4
- ### Upgrading to >= 1.0.0
4
+ ### Upgrading to >= 1.2.0
5
+
6
+ #### New Team Fields
7
+
8
+ The following fields have been added to `Team`.
9
+
10
+ * `oauth_scope`: Slack OAuth scope
11
+ * `oauth_version`: Slack OAuth version used
12
+
13
+ No action is required for Mongoid.
14
+
15
+ If you're using ActiveRecord, create a migration to add these fields.
16
+
17
+ ```ruby
18
+ class AddOauthFields < ActiveRecord::Migration[5.0]
19
+ def change
20
+ add_column :teams, :oauth_scope, :string
21
+ add_column :teams, :oauth_version, :string, default: 'v1', null: false
22
+ end
23
+ end
24
+ ```
25
+
26
+ See [MIGRATING](MIGRATING.md) for help with migrating Legacy Slack Apps to Granular Scopes.
27
+
28
+ ### Upgrading to >= 1.1.0
5
29
 
6
30
  #### Extracted RealTime (Legacy) Support
7
31
 
@@ -12,6 +36,13 @@ To upgrade an existing classic Slack app that uses slack-ruby-bot-server do the
12
36
  1. Add `slack-ruby-bot-server-rtm` as an additional dependency.
13
37
  2. Replace any reference to `SlackRubyBotServer::Server` to `SlackRubyBotServer::RealTime::Server`.
14
38
  3. Replace any `require 'slack-ruby-bot-server/rspec'` with `require 'slack-ruby-bot-server-rtm/rspec'`.
39
+ 4. Use Slack OAuth 1.0 and configure scopes.
40
+ ```ruby
41
+ SlackRubyBotServer.configure do |config|
42
+ config.oauth_version = :v1
43
+ config.oauth_scope = ['bot']
44
+ end
45
+ ```
15
46
 
16
47
  Existing RTM Slack bots will continue working and be listed in the Slack App Directory. On December 4th, 2020 Slack will no longer accept resubmissions from apps that are not using granular permissions. On November 18, 2021 Slack will start delisting apps that have not migrated to use granular permissions. Use [slack-ruby-bot-server-events](https://github.com/slack-ruby/slack-ruby-bot-server-events) to create a Slack bot with granular permissions. See [migration](https://api.slack.com/authentication/migration) for more details.
17
48
 
@@ -19,7 +19,7 @@ module SlackRubyBotServer
19
19
 
20
20
  desc 'Get all the teams.'
21
21
  params do
22
- optional :active, type: Boolean, desc: 'Return active teams only.'
22
+ optional :active, type: ::Grape::API::Boolean, desc: 'Return active teams only.'
23
23
  use :pagination
24
24
  end
25
25
  sort Team::SORT_ORDERS
@@ -40,27 +40,53 @@ module SlackRubyBotServer
40
40
 
41
41
  raise 'Missing SLACK_CLIENT_ID or SLACK_CLIENT_SECRET.' unless ENV.key?('SLACK_CLIENT_ID') && ENV.key?('SLACK_CLIENT_SECRET')
42
42
 
43
- rc = client.oauth_access(
43
+ options = {
44
44
  client_id: ENV['SLACK_CLIENT_ID'],
45
45
  client_secret: ENV['SLACK_CLIENT_SECRET'],
46
46
  code: params[:code]
47
- )
47
+ }
48
48
 
49
- access_token = rc['access_token']
50
- user_id = rc['user_id']
49
+ rc = client.send(SlackRubyBotServer.config.oauth_access_method, options)
51
50
 
52
- bot = rc['bot']
51
+ token = nil
52
+ access_token = nil
53
+ user_id = nil
54
+ bot_user_id = nil
55
+ team_id = nil
56
+ team_name = nil
57
+ oauth_scope = nil
58
+ oauth_version = SlackRubyBotServer::Config.oauth_version
53
59
 
54
- token = bot ? bot['bot_access_token'] : access_token
55
- bot_user_id = bot['bot_user_id'] if bot
60
+ case oauth_version
61
+ when :v2
62
+ access_token = rc.access_token
63
+ token = rc.access_token
64
+ user_id = rc.authed_user&.id
65
+ bot_user_id = rc.bot_user_id
66
+ team_id = rc.team&.id
67
+ team_name = rc.team&.name
68
+ oauth_scope = rc.scope
69
+ when :v1
70
+ access_token = rc.access_token
71
+ bot = rc.bot if rc.key?(:bot)
72
+ token = bot ? bot.bot_access_token : access_token
73
+ user_id = rc.user_id
74
+ bot_user_id = bot ? bot.bot_user_id : nil
75
+ team_id = rc.team_id
76
+ team_name = rc.team_name
77
+ oauth_scope = rc.scope
78
+ end
56
79
 
57
80
  team = Team.where(token: token).first
58
- team ||= Team.where(team_id: rc['team_id']).first
81
+ team ||= Team.where(team_id: team_id, oauth_version: oauth_version).first
82
+ team ||= Team.where(team_id: team_id).first
59
83
 
60
84
  if team
61
85
  team.ping_if_active!
62
86
 
63
87
  team.update_attributes!(
88
+ oauth_version: oauth_version,
89
+ oauth_scope: oauth_scope,
64
90
  activated_user_id: user_id,
65
91
  activated_user_access_token: access_token,
66
92
  bot_user_id: bot_user_id
@@ -72,8 +98,10 @@ module SlackRubyBotServer
72
98
  else
73
99
  team = Team.create!(
74
100
  token: token,
75
- team_id: rc['team_id'],
76
- name: rc['team_name'],
101
+ oauth_version: oauth_version,
102
+ oauth_scope: oauth_scope,
103
+ team_id: team_id,
104
+ name: team_name,
77
105
  activated_user_id: user_id,
78
106
  activated_user_access_token: access_token,
79
107
  bot_user_id: bot_user_id
@@ -10,7 +10,7 @@ module SlackRubyBotServer
10
10
  property :team_id, type: String, desc: 'Slack team ID.'
11
11
  property :name, type: String, desc: 'Team name.'
12
12
  property :domain, type: String, desc: 'Team domain.'
13
- property :active, type: Boolean, desc: 'Team is active.'
13
+ property :active, type: ::Grape::API::Boolean, desc: 'Team is active.'
14
14
  property :created_at, type: DateTime, desc: 'Date/time when the team was created.'
15
15
  property :updated_at, type: DateTime, desc: 'Date/time when the team was accepted, declined or canceled.'
16
16
 
@@ -1,10 +1,11 @@
1
1
  module SlackRubyBotServer
2
2
  class App
3
+ include SlackRubyBotServer::Loggable
4
+
3
5
  def prepare!
4
6
  check_database!
5
7
  init_database!
6
8
  purge_inactive_teams!
7
- configure_global_aliases!
8
9
  end
9
10
 
10
11
  def self.instance
@@ -13,13 +14,6 @@ module SlackRubyBotServer
13
14
 
14
15
  private
15
16
 
16
- def logger
17
- @logger ||= begin
18
- STDOUT.sync = true
19
- Logger.new(STDOUT)
20
- end
21
- end
22
-
23
17
  def check_database!
24
18
  SlackRubyBotServer::DatabaseAdapter.check!
25
19
  end
@@ -31,11 +25,5 @@ module SlackRubyBotServer
31
25
  def purge_inactive_teams!
32
26
  Team.purge!
33
27
  end
34
-
35
- def configure_global_aliases!
36
- SlackRubyBot.configure do |config|
37
- config.aliases = ENV['SLACK_RUBY_BOT_ALIASES'].split(' ') if ENV['SLACK_RUBY_BOT_ALIASES']
38
- end
39
- end
40
28
  end
41
29
  end
@@ -18,6 +18,8 @@ module SlackRubyBotServer
18
18
  t.string :name
19
19
  t.string :domain
20
20
  t.string :token
21
+ t.string :oauth_scope
22
+ t.string :oauth_version, default: 'v1', null: false
21
23
  t.string :bot_user_id
22
24
  t.string :activated_user_id
23
25
  t.string :activated_user_access_token
@@ -7,11 +7,13 @@ module SlackRubyBotServer
7
7
  attr_accessor :database_adapter
8
8
  attr_accessor :view_paths
9
9
  attr_accessor :oauth_scope
10
+ attr_accessor :oauth_version
10
11
 
11
12
  def reset!
12
13
  self.logger = nil
13
14
  self.service_class = SlackRubyBotServer::Service
14
15
  self.oauth_scope = nil
16
+ self.oauth_version = :v2
15
17
 
16
18
  self.view_paths = [
17
19
  'views',
@@ -28,6 +30,28 @@ module SlackRubyBotServer
28
30
  end
29
31
  end
30
32
 
33
+ def oauth_authorize_url
34
+ case oauth_version
35
+ when :v2
36
+ 'https://slack.com/oauth/v2/authorize'
37
+ when :v1
38
+ 'https://slack.com/oauth/authorize'
39
+ else
40
+ raise ArgumentError, 'Invalid oauth_version, must be one of :v1 or v2.'
41
+ end
42
+ end
43
+
44
+ def oauth_access_method
45
+ case oauth_version
46
+ when :v2
47
+ :oauth_v2_access
48
+ when :v1
49
+ :oauth_access
50
+ else
51
+ raise ArgumentError, 'Invalid oauth_version, must be one of :v1 or v2.'
52
+ end
53
+ end
54
+
31
55
  def oauth_scope_s
32
56
  oauth_scope&.join('+')
33
57
  end
@@ -32,10 +32,18 @@ module Methods
32
32
 
33
33
  def ping!
34
34
  client = Slack::Web::Client.new(token: token)
35
+
35
36
  auth = client.auth_test
37
+
38
+ presence = begin
39
+ client.users_getPresence(user: auth['user_id'])
40
+ rescue Slack::Web::Api::Errors::MissingScope
41
+ nil
42
+ end
43
+
36
44
  {
37
45
  auth: auth,
38
- presence: client.users_getPresence(user: auth['user_id'])
46
+ presence: presence
39
47
  }
40
48
  end
41
49
 
@@ -8,7 +8,9 @@ class Team
8
8
  field :name, type: String
9
9
  field :domain, type: String
10
10
  field :token, type: String
11
- field :active, type: Boolean, default: true
11
+ field :oauth_scope, type: String
12
+ field :oauth_version, type: String, default: 'v1'
13
+ field :active, type: Mongoid::Boolean, default: true
12
14
  field :bot_user_id, type: String
13
15
  field :activated_user_id, type: String
14
16
  field :activated_user_access_token, type: String
@@ -1,3 +1,3 @@
1
1
  module SlackRubyBotServer
2
- VERSION = '1.0.0'.freeze
2
+ VERSION = '1.2.1'.freeze
3
3
  end
@@ -16,7 +16,7 @@
16
16
  </p>
17
17
  <p id='messages' />
18
18
  <p id='register'>
19
- <a href="https://slack.com/oauth/authorize?scope=<%= SlackRubyBotServer::Config.oauth_scope_s %>&client_id=<%= ENV['SLACK_CLIENT_ID'] %>"><img alt="Add to Slack" height="40" width="139" src="https://platform.slack-edge.com/img/add_to_slack.png" srcset="https://platform.slack-edge.com/img/add_to_slack.png 1x, https://platform.slack-edge.com/img/add_to_slack@2x.png 2x"></a>
19
+ <a href="<%= SlackRubyBotServer::Config.oauth_authorize_url %>?scope=<%= SlackRubyBotServer::Config.oauth_scope_s %>&client_id=<%= ENV['SLACK_CLIENT_ID'] %>"><img alt="Add to Slack" height="40" width="139" src="https://platform.slack-edge.com/img/add_to_slack.png" srcset="https://platform.slack-edge.com/img/add_to_slack.png 1x, https://platform.slack-edge.com/img/add_to_slack@2x.png 2x"></a>
20
20
  </p>
21
21
  <p id='active_teams_count'>&nbsp;</p>
22
22
  <p>
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: 1.0.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Doubrovkine
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-15 00:00:00.000000000 Z
11
+ date: 2022-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -158,18 +158,23 @@ extensions: []
158
158
  extra_rdoc_files: []
159
159
  files:
160
160
  - ".github/FUNDING.yml"
161
+ - ".github/workflows/danger.yml"
162
+ - ".github/workflows/rubocop.yml"
163
+ - ".github/workflows/test-mongodb.yml"
164
+ - ".github/workflows/test-postgresql.yml"
161
165
  - ".gitignore"
162
166
  - ".rspec"
163
167
  - ".rubocop.yml"
164
168
  - ".rubocop_todo.yml"
165
- - ".travis.yml"
166
169
  - CHANGELOG.md
167
170
  - CONTRIBUTING.md
168
171
  - DEBUGGING.md
169
172
  - Dangerfile
170
173
  - Gemfile
174
+ - Gemfile.danger
171
175
  - Guardfile
172
176
  - LICENSE
177
+ - MIGRATING.md
173
178
  - README.md
174
179
  - RELEASING.md
175
180
  - Rakefile
data/.travis.yml DELETED
@@ -1,33 +0,0 @@
1
- language: ruby
2
-
3
- cache: bundler
4
-
5
- matrix:
6
- include:
7
- - rvm: 2.6.2
8
- script:
9
- - bundle exec danger
10
- services:
11
- - xvfb
12
- - rvm: 2.6.2
13
- env: DATABASE_ADAPTER=activerecord
14
- services:
15
- - xvfb
16
- - postgresql
17
- - rvm: 2.6.2
18
- env: DATABASE_ADAPTER=mongoid
19
- services:
20
- - xvfb
21
- - mongodb
22
-
23
- addons:
24
- firefox: 54.0
25
-
26
- before_install:
27
- - wget https://github.com/mozilla/geckodriver/releases/download/v0.18.0/geckodriver-v0.18.0-linux64.tar.gz
28
- - mkdir geckodriver
29
- - tar -xzf geckodriver-v0.18.0-linux64.tar.gz -C geckodriver
30
- - export PATH=$PATH:$PWD/geckodriver
31
-
32
- script:
33
- - bundle exec rake