slack-ruby-bot-server 0.10.0 → 0.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +1 -0
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +44 -7
- data/.travis.yml +7 -5
- data/CHANGELOG.md +48 -20
- data/Dangerfile +1 -0
- data/Gemfile +3 -2
- data/LICENSE +1 -1
- data/README.md +129 -18
- data/UPGRADING.md +14 -0
- data/images/create-app.png +0 -0
- data/lib/slack-ruby-bot-server.rb +9 -11
- data/lib/slack-ruby-bot-server/api.rb +4 -4
- data/lib/slack-ruby-bot-server/api/endpoints.rb +3 -3
- data/lib/slack-ruby-bot-server/api/endpoints/teams_endpoint.rb +1 -0
- data/lib/slack-ruby-bot-server/api/helpers.rb +4 -4
- data/lib/slack-ruby-bot-server/api/helpers/cursor_helpers.rb +2 -0
- data/lib/slack-ruby-bot-server/api/helpers/sort_helpers.rb +1 -0
- data/lib/slack-ruby-bot-server/api/middleware.rb +1 -5
- data/lib/slack-ruby-bot-server/api/presenters.rb +5 -5
- data/lib/slack-ruby-bot-server/api/presenters/status_presenter.rb +1 -0
- data/lib/slack-ruby-bot-server/app.rb +0 -27
- data/lib/slack-ruby-bot-server/config.rb +8 -0
- data/lib/slack-ruby-bot-server/config/database_adapters/activerecord.rb +2 -2
- data/lib/slack-ruby-bot-server/config/database_adapters/mongoid.rb +4 -2
- data/lib/slack-ruby-bot-server/ext/activerecord/slack-ruby-bot/commands/base.rb +1 -1
- data/lib/slack-ruby-bot-server/ext/mongoid/slack-ruby-bot/commands/base.rb +2 -2
- data/lib/slack-ruby-bot-server/models/team/activerecord.rb +8 -5
- data/lib/slack-ruby-bot-server/models/team/methods.rb +0 -13
- data/lib/slack-ruby-bot-server/models/team/mongoid.rb +8 -4
- data/lib/slack-ruby-bot-server/server.rb +1 -0
- data/lib/slack-ruby-bot-server/service.rb +45 -3
- data/lib/slack-ruby-bot-server/version.rb +1 -1
- data/public/index.html.erb +1 -0
- data/public/scripts/messages.js +33 -0
- data/public/scripts/register.js +0 -31
- data/sample_apps/sample_app_activerecord/Gemfile +1 -0
- data/sample_apps/sample_app_activerecord/README.md +1 -0
- data/sample_apps/sample_app_activerecord/commands/help.rb +1 -1
- data/sample_apps/sample_app_activerecord/config.ru +8 -1
- data/sample_apps/sample_app_activerecord/config/postgresql.yml +1 -1
- data/sample_apps/sample_app_activerecord/spec/commands/help_spec.rb +1 -1
- data/sample_apps/sample_app_mongoid/Gemfile +1 -0
- data/sample_apps/sample_app_mongoid/commands/help.rb +1 -1
- data/sample_apps/sample_app_mongoid/spec/commands/help_spec.rb +1 -1
- data/slack-ruby-bot-server.gemspec +2 -3
- metadata +14 -28
- data/app.json +0 -9
- data/images/new.png +0 -0
data/UPGRADING.md
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
Upgrading Slack-Ruby-Bot-Server
|
|
2
2
|
===============================
|
|
3
3
|
|
|
4
|
+
### Upgrading to >= 0.11.0
|
|
5
|
+
|
|
6
|
+
#### Removed Legacy Migrations
|
|
7
|
+
|
|
8
|
+
Several legacy migrations have been removed, including the code to automatically create a team from a legacy `SLACK_API_TOKEN`, setting `Team#active`, `name` and `team_id`.
|
|
9
|
+
|
|
10
|
+
See [#101](https://github.com/slack-ruby/slack-ruby-bot-server/pull/101) for more information.
|
|
11
|
+
|
|
12
|
+
#### Unicorn Dependency
|
|
13
|
+
|
|
14
|
+
The dependency on `unicorn` has been removed from gemspec. Use `unicorn` or `puma` or another application server as you see fit by explicitly adding a dependency in your Gemfile.
|
|
15
|
+
|
|
16
|
+
See [#98](https://github.com/slack-ruby/slack-ruby-bot-server/pull/98) for more information.
|
|
17
|
+
|
|
4
18
|
### Upgrading to >= 0.10.0
|
|
5
19
|
|
|
6
20
|
#### New Team Fields
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
require_relative 'endpoints/teams_endpoint'
|
|
2
|
+
require_relative 'endpoints/status_endpoint'
|
|
3
|
+
require_relative 'endpoints/root_endpoint'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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'
|
|
@@ -3,9 +3,6 @@ module SlackRubyBotServer
|
|
|
3
3
|
def prepare!
|
|
4
4
|
check_database!
|
|
5
5
|
init_database!
|
|
6
|
-
mark_teams_active!
|
|
7
|
-
migrate_from_single_team!
|
|
8
|
-
update_team_name_and_id!
|
|
9
6
|
purge_inactive_teams!
|
|
10
7
|
configure_global_aliases!
|
|
11
8
|
end
|
|
@@ -31,30 +28,6 @@ module SlackRubyBotServer
|
|
|
31
28
|
SlackRubyBotServer::DatabaseAdapter.init!
|
|
32
29
|
end
|
|
33
30
|
|
|
34
|
-
def mark_teams_active!
|
|
35
|
-
Team.where(active: nil).update_all(active: true)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def update_team_name_and_id!
|
|
39
|
-
Team.active.where(team_id: nil).each do |team|
|
|
40
|
-
begin
|
|
41
|
-
auth = team.ping![:auth]
|
|
42
|
-
team.update_attributes!(team_id: auth['team_id'], name: auth['team'])
|
|
43
|
-
rescue StandardError => e
|
|
44
|
-
logger.warn "Error pinging team #{team.id}: #{e.message}."
|
|
45
|
-
team.set(active: false)
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def migrate_from_single_team!
|
|
51
|
-
return unless ENV.key?('SLACK_API_TOKEN')
|
|
52
|
-
logger.info 'Migrating from env SLACK_API_TOKEN ...'
|
|
53
|
-
team = Team.find_or_create_from_env!
|
|
54
|
-
logger.info "Automatically migrated team: #{team}."
|
|
55
|
-
logger.warn "You should unset ENV['SLACK_API_TOKEN']."
|
|
56
|
-
end
|
|
57
|
-
|
|
58
31
|
def purge_inactive_teams!
|
|
59
32
|
Team.purge!
|
|
60
33
|
end
|
|
@@ -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
|
-
|
|
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 =
|
|
31
|
+
::Boolean = Grape::API::Boolean
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
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
|
|
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}"
|
|
@@ -9,7 +9,7 @@ module SlackRubyBot
|
|
|
9
9
|
rescue StandardError => e
|
|
10
10
|
logger.info "#{name.demodulize.upcase}: #{client.owner}, #{e.class}: #{e}"
|
|
11
11
|
logger.debug e.backtrace.join("\n")
|
|
12
|
-
client.say(channel: data.channel, text: e.message
|
|
12
|
+
client.say(channel: data.channel, text: e.message)
|
|
13
13
|
true
|
|
14
14
|
end
|
|
15
15
|
end
|
|
@@ -8,12 +8,12 @@ module SlackRubyBot
|
|
|
8
8
|
_invoke client, data
|
|
9
9
|
rescue Mongoid::Errors::Validations => e
|
|
10
10
|
logger.info "#{name.demodulize.upcase}: #{client.owner}, error - #{e.document.class}, #{e.document.errors.to_hash}"
|
|
11
|
-
client.say(channel: data.channel, text: e.document.errors.first[1]
|
|
11
|
+
client.say(channel: data.channel, text: e.document.errors.first[1])
|
|
12
12
|
true
|
|
13
13
|
rescue StandardError => e
|
|
14
14
|
logger.info "#{name.demodulize.upcase}: #{client.owner}, #{e.class}: #{e}"
|
|
15
15
|
logger.debug e.backtrace.join("\n")
|
|
16
|
-
client.say(channel: data.channel, text: e.message
|
|
16
|
+
client.say(channel: data.channel, text: e.message)
|
|
17
17
|
true
|
|
18
18
|
end
|
|
19
19
|
end
|
|
@@ -3,11 +3,14 @@ require_relative 'methods'
|
|
|
3
3
|
class Team < ActiveRecord::Base
|
|
4
4
|
include Methods
|
|
5
5
|
|
|
6
|
-
def self.purge!
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
def self.purge!(dt = 2.weeks.ago)
|
|
7
|
+
Team.where(active: false).where('updated_at <= ?', dt).each do |team|
|
|
8
|
+
begin
|
|
9
|
+
logger.info "Destroying #{team}, inactive since #{team.updated_at}."
|
|
10
|
+
team.destroy
|
|
11
|
+
rescue StandardError => e
|
|
12
|
+
logger.warn "Error destroying #{team}, #{e.message}."
|
|
13
|
+
end
|
|
11
14
|
end
|
|
12
15
|
end
|
|
13
16
|
end
|
|
@@ -38,18 +38,5 @@ module Methods
|
|
|
38
38
|
presence: client.users_getPresence(user: auth['user_id'])
|
|
39
39
|
}
|
|
40
40
|
end
|
|
41
|
-
|
|
42
|
-
def self.find_or_create_from_env!
|
|
43
|
-
token = ENV['SLACK_API_TOKEN']
|
|
44
|
-
return unless token
|
|
45
|
-
team = Team.where(token: token).first
|
|
46
|
-
team ||= Team.new(token: token)
|
|
47
|
-
info = Slack::Web::Client.new(token: token).team_info
|
|
48
|
-
team.team_id = info['team']['id']
|
|
49
|
-
team.name = info['team']['name']
|
|
50
|
-
team.domain = info['team']['domain']
|
|
51
|
-
team.save!
|
|
52
|
-
team
|
|
53
|
-
end
|
|
54
41
|
end
|
|
55
42
|
end
|
|
@@ -15,11 +15,15 @@ class Team
|
|
|
15
15
|
|
|
16
16
|
include Methods
|
|
17
17
|
|
|
18
|
-
def self.purge!
|
|
18
|
+
def self.purge!(dt = 2.weeks.ago)
|
|
19
19
|
# destroy teams inactive for two weeks
|
|
20
|
-
Team.where(active: false, :updated_at.lte =>
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
Team.where(active: false, :updated_at.lte => dt).each do |team|
|
|
21
|
+
begin
|
|
22
|
+
logger.info "Destroying #{team}, inactive since #{team.updated_at}."
|
|
23
|
+
team.destroy
|
|
24
|
+
rescue StandardError => e
|
|
25
|
+
logger.warn "Error destroying #{team}, #{e.message}."
|
|
26
|
+
end
|
|
23
27
|
end
|
|
24
28
|
end
|
|
25
29
|
end
|
|
@@ -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(
|
|
21
|
-
|
|
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
|
|
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
|
data/public/index.html.erb
CHANGED
|
@@ -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
|
+
});
|