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 +4 -4
- data/.github/workflows/danger.yml +23 -0
- data/.github/workflows/rubocop.yml +16 -0
- data/.github/workflows/test-mongodb.yml +32 -0
- data/.github/workflows/test-postgresql.yml +33 -0
- data/.rubocop_todo.yml +1 -1
- data/CHANGELOG.md +13 -0
- data/Gemfile +5 -8
- data/Gemfile.danger +6 -0
- data/MIGRATING.md +98 -0
- data/README.md +95 -37
- data/UPGRADING.md +32 -1
- data/lib/slack-ruby-bot-server/api/endpoints/teams_endpoint.rb +39 -11
- data/lib/slack-ruby-bot-server/api/presenters/team_presenter.rb +1 -1
- data/lib/slack-ruby-bot-server/app.rb +2 -14
- data/lib/slack-ruby-bot-server/config/database_adapters/activerecord.rb +2 -0
- data/lib/slack-ruby-bot-server/config.rb +24 -0
- data/lib/slack-ruby-bot-server/models/team/methods.rb +9 -1
- data/lib/slack-ruby-bot-server/models/team/mongoid.rb +3 -1
- data/lib/slack-ruby-bot-server/version.rb +1 -1
- data/public/index.html.erb +1 -1
- metadata +8 -3
- data/.travis.yml +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce55bd11d1164eaaa7985395b77ac8d104f69adfd1a5d3ccd1e6a195e02aceb2
|
4
|
+
data.tar.gz: '08700bcdc5768db23d313ac4cdde14c4b315f83f407b26fcff764b0249d5ca31'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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-
|
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 '
|
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
|
-
|
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
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
|
-
|
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
|
-
- [
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
- [
|
27
|
-
- [
|
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
|
-
|
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
|
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
|
-
|
41
|
+
## Stable Release
|
38
42
|
|
39
|
-
You're reading the documentation for the **stable** release of slack-ruby-bot-server
|
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
|
-
|
45
|
+
## Make Your Own
|
42
46
|
|
43
|
-
|
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
|
-
|
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
|
-
|
66
|
+
#### ActiveRecord
|
61
67
|
|
62
|
-
Use ActiveRecord with, for example, PostgreSQL via [pg](https://github.com/ged/ruby-pg).
|
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
|
-
|
78
|
+
Configure the database connection in `config/postgresql.yml`.
|
73
79
|
|
74
|
-
|
80
|
+
```yaml
|
81
|
+
default: &default
|
82
|
+
adapter: postgresql
|
83
|
+
pool: 10
|
84
|
+
timeout: 5000
|
85
|
+
encoding: unicode
|
75
86
|
|
76
|
-
|
87
|
+
development:
|
88
|
+
<<: *default
|
89
|
+
database: bot_development
|
77
90
|
|
78
|
-
|
91
|
+
test:
|
92
|
+
<<: *default
|
93
|
+
database: bot_test
|
79
94
|
|
80
|
-
|
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.
|
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
|
-
|
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="
|
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)
|
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
|
-
|
313
|
+
## Sample Bots Using Slack Ruby Bot Server
|
256
314
|
|
257
|
-
|
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
|
-
|
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
|
-
|
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.
|
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
|
-
|
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
|
-
|
50
|
-
user_id = rc['user_id']
|
49
|
+
rc = client.send(SlackRubyBotServer.config.oauth_access_method, options)
|
51
50
|
|
52
|
-
|
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
|
-
|
55
|
-
|
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:
|
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
|
-
|
76
|
-
|
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
|
@@ -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:
|
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 :
|
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
|
data/public/index.html.erb
CHANGED
@@ -16,7 +16,7 @@
|
|
16
16
|
</p>
|
17
17
|
<p id='messages' />
|
18
18
|
<p id='register'>
|
19
|
-
<a href="
|
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'> </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.
|
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:
|
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
|