grape-slack-bot 1.6.11 → 1.7.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 04dc265b92f03e4dcb6d84e61ef38af6e089f8780366567e4698812e69ca57a9
4
- data.tar.gz: c9247448391075868c2a101973a08718890f872ecbf76907fb6125f4c8f42d73
3
+ metadata.gz: bf068ba32d5e7319a9e8d96710dfa364fcccedf1e0755b32305409455293b7cc
4
+ data.tar.gz: 2c7bba45e4a549dcc1ac64b707349244b19dcbc6ef0a069504e192a350c4f10e
5
5
  SHA512:
6
- metadata.gz: 5ffa34f2c2f321d5f6e150d69e0ef4382e6e06d047ed5f6ec584d6ca1f1fb0ff95b9279d28c6630a3c7c89257ed1aeadfde06ed18cc6438a541b8d872f2e5d6e
7
- data.tar.gz: 95b6338f453227ecca727accb27b5525491d68761de8ef9c773755a8bc0a731743a92385a2d12c3e7dc4ba3e4112bc9f9eb9c804478bce411ac11351b1312a13
6
+ metadata.gz: b362b4a0a379c2ff986fe11d554e1aaef10b3581190c7487833c2c69b503cc2f57d1e6b393e4afb19442176079bdc472a2717e57c8921d6dc0f51a92d64f0e9e
7
+ data.tar.gz: f150f3b05dda3a59d8b818bd574dfd5fcb08f688ad2eb6d263bba31bc821351f858a5bb1e05a3ee17199fe1d7dd0c4bab628127251314cbb6d1d7a809bc46bff
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # grape-slack-bot.rb
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/grape-slack-bot.svg)](https://badge.fury.io/rb/grape-slack-bot) [![Test Status](https://github.com/amkisko/grape-slack-bot.rb/actions/workflows/test.yml/badge.svg)](https://github.com/amkisko/grape-slack-bot.rb/actions/workflows/test.yml)
3
+ [![Gem Version](https://badge.fury.io/rb/grape-slack-bot.svg)](https://badge.fury.io/rb/grape-slack-bot) [![Test Status](https://github.com/amkisko/grape-slack-bot.rb/actions/workflows/test.yml/badge.svg)](https://github.com/amkisko/grape-slack-bot.rb/actions/workflows/test.yml) [![codecov](https://codecov.io/gh/amkisko/grape-slack-bot.rb/graph/badge.svg?token=VIZ94XFOR3)](https://codecov.io/gh/amkisko/grape-slack-bot.rb)
4
4
 
5
5
  Extensible Slack bot implementation gem for [ruby-grape](https://github.com/ruby-grape/grape)
6
6
 
@@ -53,6 +53,7 @@ Interactive component is a component that is requested to be opened by bot app f
53
53
 
54
54
  Characteristics:
55
55
  - Can be associated with slash command
56
+ - Can be associated with event
56
57
 
57
58
  References:
58
59
  - [interaction.rb](lib/slack_bot/interaction.rb)
@@ -114,19 +115,19 @@ References:
114
115
 
115
116
  ## Specification
116
117
 
117
- [x] Create any amount of endpoints that will handle Slack calls
118
- [x] Create multiple instances of bots and configure them separately or use the same configuration for all bots
119
- [x] Define and reuse slash command handlers for Slack slash commands
120
- [x] Define interactive component handlers for Slack interactive components
121
- [x] Define and reuse views for slash commands, interactive components and events
122
- [x] Define event handlers for Slack events
123
- [x] Define menu options handlers for Slack menu options
124
- [x] Store interactive component state in cache for usage in other handlers
125
- [x] Access current user session and user from any handler
126
- [x] Extend API endpoint with custom hooks and helpers within [grape specification](https://github.com/ruby-grape/grape)
127
- [x] Supports Slack signature verification
128
- [ ] Supports Slack socket mode (?)
129
- [ ] Supports Slack token rotation
118
+ - [x] Create any amount of endpoints that will handle Slack calls
119
+ - [x] Create multiple instances of bots and configure them separately or use the same configuration for all bots
120
+ - [x] Define and reuse slash command handlers for Slack slash commands
121
+ - [x] Define interactive component handlers for Slack interactive components
122
+ - [x] Define and reuse views for slash commands, interactive components and events
123
+ - [x] Define event handlers for Slack events
124
+ - [x] Define menu options handlers for Slack menu options
125
+ - [x] Store interactive component state in cache for usage in other handlers
126
+ - [x] Access current user session and user from any handler
127
+ - [x] Extend API endpoint with custom hooks and helpers within [grape specification](https://github.com/ruby-grape/grape)
128
+ - [x] Supports Slack signature verification
129
+ - [ ] Supports Slack socket mode (?)
130
+ - [ ] Supports Slack token rotation
130
131
 
131
132
  ## Usage with grape
132
133
 
@@ -520,10 +521,14 @@ Contribution policy:
520
521
 
521
522
  ## Publishing
522
523
 
524
+ Prefer using script `usr/bin/release.sh`, it will ensure that repository is synced and after publishing gem will create a tag.
525
+
523
526
  ```sh
527
+ GEM_VERSION=$(grep -Eo "VERSION\s*=\s*\".+\"" lib/slack_bot.rb | grep -Eo "[0-9.]{5,}")
524
528
  rm grape-slack-bot-*.gem
525
529
  gem build grape-slack-bot.gemspec
526
- gem push grape-slack-bot-*.gem
530
+ gem push grape-slack-bot-$GEM_VERSION.gem
531
+ git tag $GEM_VERSION && git push --tags
527
532
  ```
528
533
 
529
534
  ## License
@@ -1,11 +1,9 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
1
  Gem::Specification.new do |gem|
4
2
  gem.name = "grape-slack-bot"
5
- gem.version = File.read(File.expand_path('../lib/slack_bot.rb', __FILE__)).match(/VERSION\s*=\s*'(.*?)'/)[1]
3
+ gem.version = File.read(File.expand_path("../lib/slack_bot.rb", __FILE__)).match(/VERSION\s*=\s*"(.*?)"/)[1]
6
4
 
7
5
  repository_url = "https://github.com/amkisko/grape-slack-bot.rb"
8
- root_files = %w(CHANGELOG.md LICENSE.md README.md)
6
+ root_files = %w[CHANGELOG.md LICENSE.md README.md]
9
7
  root_files << "#{gem.name}.gemspec"
10
8
 
11
9
  gem.license = "MIT"
@@ -15,7 +13,7 @@ Gem::Specification.new do |gem|
15
13
  gem.authors = ["Andrei Makarov"]
16
14
  gem.email = ["andrei@kiskolabs.com"]
17
15
  gem.homepage = repository_url
18
- gem.summary = %q{Slack bot implementation for ruby-grape}
16
+ gem.summary = "Slack bot implementation for ruby-grape"
19
17
  gem.description = gem.summary
20
18
  gem.metadata = {
21
19
  "homepage" => repository_url,
@@ -25,22 +23,24 @@ Gem::Specification.new do |gem|
25
23
  "rubygems_mfa_required" => "true"
26
24
  }
27
25
 
28
- gem.executables = Dir.glob("bin/*").map{ |f| File.basename(f) }
26
+ gem.executables = Dir.glob("bin/*").map { |f| File.basename(f) }
29
27
  gem.files = Dir.glob("lib/**/*.rb") + Dir.glob("bin/**/*") + root_files
30
- gem.test_files = Dir.glob("spec/**/*_spec.rb")
31
28
 
32
- gem.required_ruby_version = ">= 2.5.0"
29
+ gem.required_ruby_version = ">= 3"
33
30
  gem.require_paths = ["lib"]
34
31
 
35
- gem.add_runtime_dependency 'rack', '> 2'
36
- gem.add_runtime_dependency 'grape', '> 1'
37
- gem.add_runtime_dependency 'faraday', '> 1'
38
- gem.add_runtime_dependency 'activesupport', '> 5'
39
-
40
- gem.add_development_dependency 'bundler', '~> 2'
41
- gem.add_development_dependency 'pry', '~> 0.14'
42
- gem.add_development_dependency 'rspec', '~> 3'
43
- gem.add_development_dependency 'webmock', '~> 3'
44
- gem.add_development_dependency 'simplecov', '~> 0.21'
45
- gem.add_development_dependency 'simplecov-cobertura', '~> 2'
32
+ gem.add_runtime_dependency "rack", "> 2"
33
+ gem.add_runtime_dependency "grape", "> 1"
34
+ gem.add_runtime_dependency "faraday", "> 1"
35
+ gem.add_runtime_dependency "activesupport", "> 5"
36
+
37
+ gem.add_development_dependency "bundler", "~> 2"
38
+ gem.add_development_dependency "pry", "~> 0.14"
39
+ gem.add_development_dependency "rspec", "~> 3"
40
+ gem.add_development_dependency "webmock", "~> 3"
41
+ gem.add_development_dependency "simplecov", "~> 0.21"
42
+ gem.add_development_dependency "simplecov-cobertura", "~> 2"
43
+ gem.add_development_dependency "standard", "~> 1"
44
+ gem.add_development_dependency "standard-performance", "~> 1"
45
+ gem.add_development_dependency "standard-rspec", "~> 0.2"
46
46
  end
@@ -1,4 +1,4 @@
1
- require 'faraday'
1
+ require "faraday"
2
2
 
3
3
  module SlackBot
4
4
  class ApiResponse
@@ -20,6 +20,7 @@ module SlackBot
20
20
  JSON.parse(response.body)
21
21
  end
22
22
  end
23
+
23
24
  class ApiClient
24
25
  attr_reader :client
25
26
  def initialize(authorization_token: ENV["SLACK_BOT_API_TOKEN"])
@@ -37,27 +38,53 @@ module SlackBot
37
38
  end
38
39
 
39
40
  def views_open(trigger_id:, view:)
40
- ApiResponse.new { client.post("views.open", { trigger_id: trigger_id, view: view }.to_json) }
41
+ ApiResponse.new { client.post("views.open", {trigger_id: trigger_id, view: view}.to_json) }
41
42
  end
42
43
 
43
44
  def views_update(view_id:, view:)
44
- ApiResponse.new { client.post("views.update", { view_id: view_id, view: view }.to_json) }
45
+ ApiResponse.new { client.post("views.update", {view_id: view_id, view: view}.to_json) }
45
46
  end
46
47
 
47
48
  def chat_post_message(channel:, text:, blocks:)
48
- ApiResponse.new { client.post("chat.postMessage", { channel: channel, text: text, blocks: blocks }.to_json) }
49
+ ApiResponse.new { client.post("chat.postMessage", {channel: channel, text: text, blocks: blocks}.to_json) }
49
50
  end
50
51
 
51
52
  def chat_update(channel:, ts:, text:, blocks:)
52
- ApiResponse.new { client.post("chat.update", { channel: channel, ts: ts, text: text, blocks: blocks }.to_json) }
53
+ ApiResponse.new { client.post("chat.update", {channel: channel, ts: ts, text: text, blocks: blocks}.to_json) }
53
54
  end
54
55
 
55
56
  def users_info(user_id:)
56
- ApiResponse.new { client.post("users.info", { user: user_id }.to_json) }
57
+ ApiResponse.new { client.post("users.info", {user: user_id}.to_json) }
57
58
  end
58
59
 
59
60
  def views_publish(user_id:, view:)
60
- ApiResponse.new { client.post("views.publish", { user_id: user_id, view: view }.to_json) }
61
+ ApiResponse.new { client.post("views.publish", {user_id: user_id, view: view}.to_json) }
62
+ end
63
+
64
+ def users_list(cursor: nil, limit: 200, include_locale: nil, team_id: nil)
65
+ args = {}
66
+ args[:cursor] = cursor if cursor
67
+ args[:limit] = limit if limit
68
+ args[:include_locale] = include_locale if include_locale
69
+ args[:team_id] = team_id if team_id
70
+ ApiResponse.new { client.post("users.list", args.to_json) }
71
+ end
72
+
73
+ def chat_post_ephemeral(channel:, user:, text:, as_user: nil, attachments: nil, blocks: nil, icon_emoji: nil, icon_url: nil, link_names: nil, parse: nil, thread_ts: nil, username: nil)
74
+ args = {}
75
+ args[:channel] = channel
76
+ args[:user] = user
77
+ args[:text] = text if text
78
+ args[:as_user] = as_user if as_user
79
+ args[:attachments] = attachments if attachments
80
+ args[:blocks] = blocks if blocks
81
+ args[:icon_emoji] = icon_emoji if icon_emoji
82
+ args[:icon_url] = icon_url if icon_url
83
+ args[:link_names] = link_names if link_names
84
+ args[:parse] = parse if parse
85
+ args[:thread_ts] = thread_ts if thread_ts
86
+ args[:username] = username if username
87
+ ApiResponse.new { client.post("chat.postEphemeral", args.to_json) }
61
88
  end
62
89
  end
63
90
  end
@@ -1,23 +1,28 @@
1
- require 'rack/utils'
2
- require 'active_support/core_ext/hash/indifferent_access'
1
+ require "rack/utils"
2
+ require "active_support"
3
+ require "active_support/core_ext/hash/indifferent_access"
3
4
 
4
5
  module SlackBot
5
6
  class ArgsParser
6
7
  def initialize(args)
7
8
  @args = args
8
9
  end
10
+
9
11
  def call
10
12
  Rack::Utils.parse_query(@args)
11
13
  end
12
14
  end
15
+
13
16
  class ArgsBuilder
14
17
  def initialize(args)
15
18
  @args = args
16
19
  end
20
+
17
21
  def call
18
22
  Rack::Utils.build_query(@args)
19
23
  end
20
24
  end
25
+
21
26
  class Args
22
27
  attr_accessor :args
23
28
  def initialize(builder: ArgsBuilder, parser: ArgsParser)
@@ -1,5 +1,5 @@
1
- require 'active_support/core_ext/object'
2
- require 'active_support/core_ext/numeric/time'
1
+ require "active_support/core_ext/object"
2
+ require "active_support/core_ext/numeric/time"
3
3
 
4
4
  module SlackBot
5
5
  class Callback
@@ -23,7 +23,7 @@ module SlackBot
23
23
  find(callback_id, user: user, config: config)
24
24
  end
25
25
 
26
- def self.create(id: nil, class_name:, user:, channel_id: nil, config: nil, payload: nil, expires_in: nil, user_scope: nil)
26
+ def self.create(class_name:, user:, id: nil, channel_id: nil, config: nil, payload: nil, expires_in: nil, user_scope: nil)
27
27
  callback =
28
28
  new(id: id, class_name: class_name, user: user, channel_id: channel_id, payload: payload, config: config, expires_in: expires_in, user_scope: user_scope)
29
29
  callback.save
@@ -75,10 +75,10 @@ module SlackBot
75
75
  return if id.blank?
76
76
  return if data.blank?
77
77
 
78
- if @data[:payload].is_a?(Hash)
79
- @data[:payload] = @data[:payload].merge(payload)
78
+ @data[:payload] = if @data[:payload].is_a?(Hash)
79
+ @data[:payload].merge(payload)
80
80
  else
81
- @data[:payload] = payload
81
+ payload
82
82
  end
83
83
 
84
84
  save
@@ -1,5 +1,5 @@
1
- require 'slack_bot/concerns/interaction_klass'
2
- require 'slack_bot/concerns/view_klass'
1
+ require "slack_bot/concerns/interaction_klass"
2
+ require "slack_bot/concerns/view_klass"
3
3
 
4
4
  module SlackBot
5
5
  class Command
@@ -1,14 +1,15 @@
1
- require 'active_support/core_ext/object'
1
+ require "active_support"
2
+ require "active_support/core_ext/object"
2
3
 
3
4
  module SlackBot
4
5
  class Config
5
6
  def self.current_instance
6
7
  @@current_instances ||= {}
7
- @@current_instances[self.name] ||= self.new
8
+ @@current_instances[name] ||= new
8
9
  end
9
10
 
10
- def self.configure(&block)
11
- current_instance.instance_eval(&block)
11
+ def self.configure(&)
12
+ current_instance.instance_eval(&)
12
13
  end
13
14
 
14
15
  attr_reader :callback_storage_instance
@@ -40,7 +41,7 @@ module SlackBot
40
41
  event_handlers[event_type.to_sym]
41
42
  end
42
43
 
43
- def slash_command_endpoint(url_token, command_klass = nil, handler_name: nil, &block)
44
+ def slash_command_endpoint(url_token, command_klass = nil, handler_name: nil, &)
44
45
  @slash_command_endpoints ||= {}
45
46
  @slash_command_endpoints[url_token.to_sym] ||=
46
47
  begin
@@ -51,7 +52,7 @@ module SlackBot
51
52
  config: self,
52
53
  handler_name: handler_name
53
54
  )
54
- endpoint.instance_eval(&block) if block_given?
55
+ endpoint.instance_eval(&) if block
55
56
  endpoint
56
57
  end
57
58
  end
@@ -104,7 +105,7 @@ module SlackBot
104
105
  end
105
106
  end
106
107
 
107
- def command(command_token, command_klass, handler_name: nil, &block)
108
+ def command(command_token, command_klass, handler_name: nil, &)
108
109
  @command_configs ||= {}
109
110
  @command_configs[command_token.to_sym] ||=
110
111
  begin
@@ -115,7 +116,7 @@ module SlackBot
115
116
  endpoint: self,
116
117
  handler_name: handler_name
117
118
  )
118
- command.instance_eval(&block) if block_given?
119
+ command.instance_eval(&) if block
119
120
  command
120
121
  end
121
122
  end
@@ -154,7 +155,7 @@ module SlackBot
154
155
  endpoint.config.handler_class(handler_name, command_klass)
155
156
  end
156
157
 
157
- def argument_command(argument_token, klass = nil, &block)
158
+ def argument_command(argument_token, klass = nil, &)
158
159
  @argument_command_configs ||= {}
159
160
  @argument_command_configs[argument_token.to_sym] ||=
160
161
  SlashCommandConfig.new(
@@ -165,7 +166,7 @@ module SlackBot
165
166
  )
166
167
 
167
168
  command_config = @argument_command_configs[argument_token.to_sym]
168
- command_config.instance_eval(&block) if block_given?
169
+ command_config.instance_eval(&) if block
169
170
 
170
171
  command_config
171
172
  end
@@ -19,22 +19,22 @@ module SlackBot
19
19
  def self.log(message = nil, &block)
20
20
  return unless enabled?
21
21
 
22
- message = yield if block_given?
22
+ message = yield if block
23
23
  logger.info(message)
24
24
  end
25
25
 
26
26
  def self.log_input(message = nil, &block)
27
- message = yield if block_given?
27
+ message = yield if block
28
28
  log(">>> #{message}")
29
29
  end
30
30
 
31
31
  def self.log_output(message = nil, &block)
32
- message = yield if block_given?
32
+ message = yield if block
33
33
  log("<<< #{message}")
34
34
  end
35
35
 
36
36
  def self.log_check(message = nil, &block)
37
- message = yield if block_given?
37
+ message = yield if block
38
38
  log("!!! #{message}")
39
39
  end
40
40
  end
@@ -1,5 +1,5 @@
1
- require 'slack_bot/concerns/interaction_klass'
2
- require 'slack_bot/concerns/view_klass'
1
+ require "slack_bot/concerns/interaction_klass"
2
+ require "slack_bot/concerns/view_klass"
3
3
 
4
4
  module SlackBot
5
5
  class Event
@@ -20,13 +20,9 @@ module SlackBot
20
20
 
21
21
  private
22
22
 
23
- def callback=(callback)
24
- @callback = callback
25
- end
23
+ attr_writer :callback
26
24
 
27
- def metadata=(metadata)
28
- @metadata = metadata
29
- end
25
+ attr_writer :metadata
30
26
 
31
27
  def event_type
32
28
  params["event"]["type"]
@@ -1,104 +1,107 @@
1
- require 'active_support/core_ext/object'
1
+ require "active_support"
2
+ require "active_support/core_ext/object"
2
3
 
3
4
  module SlackBot
4
- module GrapeExtension
5
- def self.included(base)
6
- base.format :json
7
- base.content_type :json, "application/json"
8
- base.use ActionDispatch::RemoteIp
9
- base.helpers do
10
- def fetch_team_id
11
- params.dig("team_id") || params.dig("team", "id")
12
- end
5
+ module GrapeHelpers
6
+ def fetch_team_id
7
+ params.dig("team_id") || params.dig("team", "id")
8
+ end
13
9
 
14
- def fetch_user_id
15
- params.dig("user_id") || params.dig("user", "id") || params.dig("event", "user")
16
- end
10
+ def fetch_user_id
11
+ params.dig("user_id") || params.dig("user", "id") || params.dig("event", "user")
12
+ end
17
13
 
18
- def verify_slack_signature!
19
- slack_signing_secret = ENV.fetch("SLACK_SIGNING_SECRET")
20
- timestamp = request.headers["X-Slack-Request-Timestamp"]
21
- request_body = request.body.read
22
- sig_basestring = "v0:#{timestamp}:#{request_body}"
23
- my_signature =
24
- "v0=" +
25
- OpenSSL::HMAC.hexdigest(
26
- OpenSSL::Digest.new("sha256"),
27
- slack_signing_secret,
28
- sig_basestring
29
- )
30
- slack_signature = request.headers["X-Slack-Signature"]
31
- if ActiveSupport::SecurityUtils.secure_compare(
32
- my_signature,
33
- slack_signature
34
- )
35
- true
36
- else
37
- raise SlackBot::SignatureAuthenticationError.new("Signature mismatch")
38
- end
39
- end
14
+ def verify_slack_signature!
15
+ slack_signing_secret = ENV.fetch("SLACK_SIGNING_SECRET")
16
+ timestamp = request.headers.fetch("x-slack-request-timestamp")
17
+ request_body = request.body.read
18
+ sig_basestring = "v0:#{timestamp}:#{request_body}"
19
+ my_signature =
20
+ "v0=" +
21
+ OpenSSL::HMAC.hexdigest(
22
+ OpenSSL::Digest.new("sha256"),
23
+ slack_signing_secret,
24
+ sig_basestring
25
+ )
26
+ slack_signature = request.headers.fetch("x-slack-signature")
27
+ if ActiveSupport::SecurityUtils.secure_compare(
28
+ my_signature,
29
+ slack_signature
30
+ )
31
+ true
32
+ else
33
+ raise SlackBot::Errors::SignatureAuthenticationError.new("Signature mismatch")
34
+ end
35
+ end
40
36
 
41
- def verify_slack_team!
42
- slack_team_id = ENV.fetch("SLACK_TEAM_ID")
43
- if slack_team_id == fetch_team_id
44
- true
45
- else
46
- raise SlackBot::TeamAuthenticationError.new("Team is not authorized")
47
- end
48
- end
37
+ def verify_slack_team!
38
+ slack_team_id = ENV.fetch("SLACK_TEAM_ID")
39
+ if slack_team_id == fetch_team_id
40
+ true
41
+ else
42
+ raise SlackBot::Errors::TeamAuthenticationError.new("Team is not authorized")
43
+ end
44
+ end
49
45
 
50
- def verify_direct_message_channel!
51
- if params[:channel_name] == "directmessage"
52
- true
53
- else
54
- raise SlackBot::ChannelAuthenticationError.new(
55
- "This command is only available in direct messages"
56
- )
57
- end
58
- end
46
+ def verify_direct_message_channel!
47
+ if params[:channel_name] == "directmessage"
48
+ true
49
+ else
50
+ raise SlackBot::Errors::ChannelAuthenticationError.new(
51
+ "This command is only available in direct messages"
52
+ )
53
+ end
54
+ end
59
55
 
60
- def verify_current_user!
61
- if current_user
62
- true
63
- else
64
- raise SlackBot::Errors::UserAuthenticationError.new("User is not authorized")
65
- end
66
- end
56
+ def verify_current_user!
57
+ if current_user
58
+ true
59
+ else
60
+ raise SlackBot::Errors::UserAuthenticationError.new("User is not authorized")
61
+ end
62
+ end
67
63
 
68
- def events_callback(params)
69
- verify_slack_team!
64
+ def events_callback(params)
65
+ verify_slack_team!
70
66
 
71
- SlackBot::DevConsole.log_input "SlackApi::Events#events_callback: #{params.inspect}"
72
- handler = config.find_event_handler(params[:event][:type].to_sym)
73
- return if handler.blank?
67
+ SlackBot::DevConsole.log_input "SlackApi::Events#events_callback: #{params.inspect}"
68
+ handler = config.find_event_handler(params[:event][:type].to_sym)
69
+ return if handler.blank?
74
70
 
75
- event = handler.new(params: params, current_user: current_user)
76
- event.call
77
- end
71
+ event = handler.new(params: params, current_user: current_user)
72
+ event.call
73
+ end
78
74
 
79
- def url_verification(params)
80
- SlackBot::DevConsole.log_input "SlackApi::Events#url_verification: #{params.inspect}"
81
- { challenge: params[:challenge] }
82
- end
75
+ def url_verification(params)
76
+ SlackBot::DevConsole.log_input "SlackApi::Events#url_verification: #{params.inspect}"
77
+ {challenge: params[:challenge]}
78
+ end
83
79
 
84
- def handle_block_actions_view(view:, user:, params:)
85
- callback_id = view&.dig("callback_id")
80
+ def handle_block_actions_view(view:, user:, params:)
81
+ callback_id = view&.dig("callback_id")
86
82
 
87
- callback = SlackBot::Callback.find(callback_id, user: user, config: config)
88
- raise SlackBot::Errors::CallbackNotFound.new if callback.blank?
83
+ callback = SlackBot::Callback.find(callback_id, user: user, config: config)
84
+ raise SlackBot::Errors::CallbackNotFound.new if callback.blank?
89
85
 
90
- SlackBot::DevConsole.log_check "SlackApi::Interactions##{__method__}: #{callback.id} #{callback.payload} #{callback.user_id} #{user&.id}"
86
+ SlackBot::DevConsole.log_check "SlackApi::Interactions##{__method__}: #{callback.id} #{callback.payload} #{callback.user_id} #{user&.id}"
91
87
 
92
- if callback.user_id != user.id
93
- raise "Callback user is not equal to action user"
94
- end
88
+ if callback.user_id != user.id
89
+ raise "Callback user is not equal to action user"
90
+ end
95
91
 
96
- interaction_klass = callback.handler_class&.interaction_klass
97
- return if interaction_klass.blank?
92
+ interaction_klass = callback.handler_class&.interaction_klass
93
+ return if interaction_klass.blank?
98
94
 
99
- interaction_klass.new(current_user: user, params: params, callback: callback, config: config).call
100
- end
101
- end
95
+ interaction_klass.new(current_user: user, params: params, callback: callback, config: config).call
96
+ end
97
+ end
98
+
99
+ module GrapeExtension
100
+ def self.included(base)
101
+ base.format :json
102
+ base.content_type :json, "application/json"
103
+ base.use ActionDispatch::RemoteIp
104
+ base.helpers SlackBot::GrapeHelpers
102
105
 
103
106
  base.before do
104
107
  verify_slack_signature!
@@ -1,6 +1,7 @@
1
- require 'active_support/core_ext/object'
1
+ require "active_support"
2
+ require "active_support/core_ext/object"
2
3
 
3
- require 'slack_bot/concerns/view_klass'
4
+ require "slack_bot/concerns/view_klass"
4
5
 
5
6
  module SlackBot
6
7
  class Interaction
@@ -9,7 +10,7 @@ module SlackBot
9
10
  include SlackBot::Concerns::ViewKlass
10
11
 
11
12
  def self.open_modal(callback:, trigger_id:, view:)
12
- view = view.merge({ type: "modal", callback_id: callback&.id })
13
+ view = view.merge({type: "modal", callback_id: callback&.id})
13
14
  response =
14
15
  SlackBot::ApiClient.new.views_open(trigger_id: trigger_id, view: view)
15
16
 
@@ -26,7 +27,7 @@ module SlackBot
26
27
  end
27
28
 
28
29
  def self.update_modal(callback:, view_id:, view:)
29
- view = view.merge({ type: "modal", callback_id: callback&.id })
30
+ view = view.merge({type: "modal", callback_id: callback&.id})
30
31
  response =
31
32
  SlackBot::ApiClient.new.views_update(view_id: view_id, view: view)
32
33
 
@@ -42,7 +43,7 @@ module SlackBot
42
43
  SlackViewsReply.new(callback&.id, view_id)
43
44
  end
44
45
 
45
- def self.publish_view(callback: nil, metadata: nil, user_id:, view:)
46
+ def self.publish_view(user_id:, view:, callback: nil, metadata: nil)
46
47
  view = view.merge(callback_id: callback.id) if callback.present?
47
48
  view = view.merge(private_metadata: metadata) if metadata.present?
48
49
  response =
@@ -138,7 +139,7 @@ module SlackBot
138
139
  return if callback.blank?
139
140
  return if actions.blank?
140
141
 
141
- if block_given?
142
+ if block
142
143
  actions.each { |action| instance_exec(action, &block) }
143
144
  else
144
145
  callback.args.raw_args = actions.first["value"]