grape-slack-bot 1.6.11 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 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"]