slack_message 3.2.0 → 3.3.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 +4 -4
- data/CHANGELOG.md +7 -1
- data/lib/slack_message/api.rb +9 -3
- data/lib/slack_message/error_handling.rb +22 -10
- data/lib/slack_message/rspec.rb +25 -23
- data/slack_message.gemspec +1 -1
- data/spec/slack_message_spec.rb +67 -20
- data/spec/spec_helper.rb +5 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0b35e974e04457e2d9e3b55af0c5c7562d0381c76477e9a85143c66e8d605071
|
|
4
|
+
data.tar.gz: 21892df8e52b365ade154424d2c98a55434efb541e144d046d208fe8b1243f24
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 720e5bcf8d91f355939474b09f9d2a9830178037dca5c067ecfc4c6585631673e2ea13d888338ff1fb7a3d25ae1009b5f1a97f7a8244f1f06696b437227f6260
|
|
7
|
+
data.tar.gz: b7fa2c16e3d5a31ac18605bda1e1eacdd367c6e94f34779c50964a92c679b8edcdc1168d3fa808392401669f55bbeae30aec607ec44a2cfd55b916d0ad0fe70d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.3.0] - 2022-07-21
|
|
4
|
+
- Differentiate errors for bad JSON versus invalid block data.
|
|
5
|
+
- Expand tests to cover many more cases.
|
|
6
|
+
- Add validation for block size limit in Slack API.
|
|
7
|
+
- Add CI check to prevent checkin of `fit`, `fcontext` etc.
|
|
8
|
+
|
|
3
9
|
## [3.2.0] - 2022-06-23
|
|
4
|
-
- Fix bugs introduced by accidental checkin of incomplete refactor
|
|
10
|
+
- Fix bugs introduced by accidental checkin of incomplete refactor.
|
|
5
11
|
|
|
6
12
|
## [3.1.0] - 2022-04-18
|
|
7
13
|
- Methods from the calling context can now be called within a section block.
|
data/lib/slack_message/api.rb
CHANGED
|
@@ -41,6 +41,10 @@ module SlackMessage::Api
|
|
|
41
41
|
raise ArgumentError, "Tried to send an entirely empty message."
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
if params[:blocks].length > 50
|
|
45
|
+
raise ArgumentError, "Message cannot contain more than 50 blocks."
|
|
46
|
+
end
|
|
47
|
+
|
|
44
48
|
icon = payload.custom_bot_icon || profile[:icon]
|
|
45
49
|
if icon =~ /^:\w+:$/
|
|
46
50
|
params[:icon_emoji] = icon
|
|
@@ -80,15 +84,17 @@ module SlackMessage::Api
|
|
|
80
84
|
raise ArgumentError, "Tried to send an entirely empty message."
|
|
81
85
|
end
|
|
82
86
|
|
|
87
|
+
if params[:blocks].length > 50
|
|
88
|
+
raise ArgumentError, "Message cannot contain more than 50 blocks."
|
|
89
|
+
end
|
|
90
|
+
|
|
83
91
|
if SlackMessage::Configuration.debugging?
|
|
84
92
|
warn params.inspect
|
|
85
93
|
end
|
|
86
94
|
|
|
87
95
|
response = update_message(profile, params)
|
|
88
|
-
body = JSON.parse(response.body)
|
|
89
|
-
error = body.fetch("error", "")
|
|
90
96
|
|
|
91
|
-
SlackMessage::ErrorHandling.
|
|
97
|
+
SlackMessage::ErrorHandling.raise_update_response_errors(response, params, profile)
|
|
92
98
|
SlackMessage::Response.new(response, profile[:handle])
|
|
93
99
|
end
|
|
94
100
|
|
|
@@ -7,8 +7,10 @@ class SlackMessage::ErrorHandling
|
|
|
7
7
|
body = JSON.parse(response.body)
|
|
8
8
|
error = body.fetch("error", "")
|
|
9
9
|
|
|
10
|
-
if
|
|
11
|
-
raise SlackMessage::ApiError, "Couldn't send Slack message because the
|
|
10
|
+
if error == "invalid_blocks"
|
|
11
|
+
raise SlackMessage::ApiError, "Couldn't send Slack message because the request contained invalid blocks:\n#{blocks_message(params[:blocks])}"
|
|
12
|
+
elsif error == "invalid_blocks_format"
|
|
13
|
+
raise SlackMessage::ApiError, "Couldn't send Slack message because blocks is not a valid JSON object or doesn't match the Block Kit syntax:\n#{blocks_message(params[:blocks])}"
|
|
12
14
|
elsif error == "channel_not_found"
|
|
13
15
|
raise SlackMessage::ApiError, "Tried to send Slack message to non-existent channel or user '#{params[:channel]}'"
|
|
14
16
|
|
|
@@ -34,21 +36,23 @@ class SlackMessage::ErrorHandling
|
|
|
34
36
|
elsif response.code != "200"
|
|
35
37
|
raise SlackMessage::ApiError, "Got an error back from the Slack API (HTTP #{response.code}):\n#{response.body}"
|
|
36
38
|
elsif !(error.nil? || error == "")
|
|
37
|
-
raise SlackMessage::ApiError, "Received error response from Slack during message posting:\n#{response.body}"
|
|
39
|
+
raise SlackMessage::ApiError, "Received error response '#{error}' from Slack during message posting:\n#{response.body}"
|
|
38
40
|
end
|
|
39
41
|
end
|
|
40
42
|
|
|
41
|
-
def self.raise_update_response_errors(response,
|
|
43
|
+
def self.raise_update_response_errors(response, params, profile)
|
|
42
44
|
body = JSON.parse(response.body)
|
|
43
45
|
error = body.fetch("error", "")
|
|
44
46
|
|
|
45
|
-
if
|
|
46
|
-
raise SlackMessage::ApiError, "Couldn't update Slack message because the
|
|
47
|
+
if error == "invalid_blocks"
|
|
48
|
+
raise SlackMessage::ApiError, "Couldn't update Slack message because the request contained invalid blocks:\n#{blocks_message(params[:blocks])}"
|
|
49
|
+
elsif error == "invalid_blocks_format"
|
|
50
|
+
raise SlackMessage::ApiError, "Couldn't update Slack message because blocks is not a valid JSON object or doesn't match the Block Kit syntax:\n#{blocks_message(params[:blocks])}"
|
|
47
51
|
elsif error == "channel_not_found"
|
|
48
|
-
raise SlackMessage::ApiError, "Tried to update Slack message to non-existent channel or user '#{
|
|
52
|
+
raise SlackMessage::ApiError, "Tried to update Slack message to non-existent channel or user '#{params[:channel]}'"
|
|
49
53
|
|
|
50
54
|
elsif error == "message_not_found"
|
|
51
|
-
raise SlackMessage::ApiError, "Tried to update Slack message, but the message wasn't found (timestamp '#{
|
|
55
|
+
raise SlackMessage::ApiError, "Tried to update Slack message, but the message wasn't found (timestamp '#{params[:ts]}' for channel '#{params[:channel]}'"
|
|
52
56
|
elsif error == "cant_update_message"
|
|
53
57
|
raise SlackMessage::ApiError, "Couldn't update message because the message type isn't able to be updated, or #{profile[:handle]} isn't allowed to update it"
|
|
54
58
|
elsif error == "edit_window_closed"
|
|
@@ -68,7 +72,7 @@ class SlackMessage::ErrorHandling
|
|
|
68
72
|
elsif response.code != "200"
|
|
69
73
|
raise SlackMessage::ApiError, "Got an error back from the Slack API (HTTP #{response.code}):\n#{response.body}"
|
|
70
74
|
elsif !(error.nil? || error == "")
|
|
71
|
-
raise SlackMessage::ApiError, "Received error response from Slack during message update:\n#{response.body}"
|
|
75
|
+
raise SlackMessage::ApiError, "Received error response '#{error}' from Slack during message update:\n#{response.body}"
|
|
72
76
|
end
|
|
73
77
|
end
|
|
74
78
|
|
|
@@ -98,7 +102,7 @@ class SlackMessage::ErrorHandling
|
|
|
98
102
|
elsif response.code != "200"
|
|
99
103
|
raise SlackMessage::ApiError, "Got an error back from the Slack API (HTTP #{response.code}):\n#{response.body}"
|
|
100
104
|
elsif !(error.nil? || error == "")
|
|
101
|
-
raise SlackMessage::ApiError, "Received error response from Slack during message delete:\n#{response.body}"
|
|
105
|
+
raise SlackMessage::ApiError, "Received error response '#{error}' from Slack during message delete:\n#{response.body}"
|
|
102
106
|
end
|
|
103
107
|
end
|
|
104
108
|
|
|
@@ -127,4 +131,12 @@ class SlackMessage::ErrorHandling
|
|
|
127
131
|
raise SlackMessage::ApiError, "Received error response from Slack during user lookup:\n#{response.body}"
|
|
128
132
|
end
|
|
129
133
|
end
|
|
134
|
+
|
|
135
|
+
def self.blocks_message(blocks)
|
|
136
|
+
if SlackMessage::Configuration.debugging?
|
|
137
|
+
JSON.pretty_generate(blocks)
|
|
138
|
+
else
|
|
139
|
+
"[Enable debugging in configuration to view block data.]"
|
|
140
|
+
end
|
|
141
|
+
end
|
|
130
142
|
end
|
data/lib/slack_message/rspec.rb
CHANGED
|
@@ -40,30 +40,32 @@ module SlackMessage::RSpec
|
|
|
40
40
|
FauxResponse = Struct.new(:code, :body)
|
|
41
41
|
|
|
42
42
|
def self.included(_)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
[:post_message, :update_message, :delete_message].each do |method|
|
|
44
|
+
SlackMessage::Api.undef_method(method)
|
|
45
|
+
SlackMessage::Api.define_singleton_method(method) do |profile, params|
|
|
46
|
+
@@listeners.each do |listener|
|
|
47
|
+
listener.record_call(params.merge(profile: profile))
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
response = {
|
|
51
|
+
"ok" => true,
|
|
52
|
+
"channel" => "C12345678",
|
|
53
|
+
"ts" => "1635863996.002300",
|
|
54
|
+
"message" => { "type"=>"message", "subtype"=>"bot_message",
|
|
55
|
+
"text"=>"foo",
|
|
56
|
+
"ts"=>"1635863996.002300",
|
|
57
|
+
"username"=>"SlackMessage",
|
|
58
|
+
"icons"=>{"emoji"=>":successkid:"},
|
|
59
|
+
"bot_id"=>"B1234567890",
|
|
60
|
+
"blocks"=> [{"type"=>"section",
|
|
61
|
+
"block_id"=>"hAh7",
|
|
62
|
+
"text"=>{"type"=>"mrkdwn", "text"=>"foo", "verbatim"=>false}}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
}.merge(@@custom_response).to_json
|
|
66
|
+
|
|
67
|
+
return FauxResponse.new(@@response_code, response)
|
|
47
68
|
end
|
|
48
|
-
|
|
49
|
-
response = {
|
|
50
|
-
"ok" => true,
|
|
51
|
-
"channel" => "C12345678",
|
|
52
|
-
"ts" => "1635863996.002300",
|
|
53
|
-
"message" => { "type"=>"message", "subtype"=>"bot_message",
|
|
54
|
-
"text"=>"foo",
|
|
55
|
-
"ts"=>"1635863996.002300",
|
|
56
|
-
"username"=>"SlackMessage",
|
|
57
|
-
"icons"=>{"emoji"=>":successkid:"},
|
|
58
|
-
"bot_id"=>"B1234567890",
|
|
59
|
-
"blocks"=> [{"type"=>"section",
|
|
60
|
-
"block_id"=>"hAh7",
|
|
61
|
-
"text"=>{"type"=>"mrkdwn", "text"=>"foo", "verbatim"=>false}}
|
|
62
|
-
]
|
|
63
|
-
}
|
|
64
|
-
}.merge(@@custom_response).to_json
|
|
65
|
-
|
|
66
|
-
return FauxResponse.new(@@response_code, response)
|
|
67
69
|
end
|
|
68
70
|
|
|
69
71
|
SlackMessage::Api.undef_method(:look_up_user_by_email)
|
data/slack_message.gemspec
CHANGED
data/spec/slack_message_spec.rb
CHANGED
|
@@ -176,18 +176,6 @@ RSpec.describe SlackMessage do
|
|
|
176
176
|
SlackMessage::RSpec.reset_mock_response
|
|
177
177
|
end
|
|
178
178
|
|
|
179
|
-
it "raises nice error messages when API methods return errors" do
|
|
180
|
-
SlackMessage::RSpec.respond_with({'error' => 'nuffin'})
|
|
181
|
-
|
|
182
|
-
expect {
|
|
183
|
-
SlackMessage.post_to('#general') { text 'nuh uh' }
|
|
184
|
-
}.to raise_error(SlackMessage::ApiError)
|
|
185
|
-
|
|
186
|
-
expect {
|
|
187
|
-
SlackMessage.post_as(:schmoebot) { text 'nuh uh' }
|
|
188
|
-
}.to raise_error(SlackMessage::ApiError)
|
|
189
|
-
end
|
|
190
|
-
|
|
191
179
|
it "raises for redirects" do
|
|
192
180
|
SlackMessage::RSpec.respond_with(code: '302')
|
|
193
181
|
|
|
@@ -196,24 +184,83 @@ RSpec.describe SlackMessage do
|
|
|
196
184
|
}.to raise_error(SlackMessage::ApiError)
|
|
197
185
|
end
|
|
198
186
|
|
|
199
|
-
it "raises errors
|
|
187
|
+
it "even raises errors during deletes" do
|
|
200
188
|
message = SlackMessage.post_to('#general') { text 'nuh uh' }
|
|
201
189
|
|
|
202
190
|
SlackMessage::RSpec.respond_with({'error' => 'bad choice'})
|
|
203
191
|
|
|
204
192
|
expect {
|
|
205
|
-
SlackMessage.
|
|
193
|
+
SlackMessage.delete(message)
|
|
206
194
|
}.to raise_error(SlackMessage::ApiError)
|
|
207
195
|
end
|
|
208
196
|
|
|
209
|
-
|
|
210
|
-
|
|
197
|
+
shared_examples 'post api error message' do |error, error_message|
|
|
198
|
+
it "responds to posts with error code '#{error}' with the expected message" do
|
|
199
|
+
SlackMessage::RSpec.respond_with({'error' => error})
|
|
211
200
|
|
|
212
|
-
|
|
201
|
+
expect {
|
|
202
|
+
SlackMessage.post_to('#general') { text 'nuh uh' }
|
|
203
|
+
}.to raise_error(SlackMessage::ApiError).with_message(error_message)
|
|
213
204
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
205
|
+
expect {
|
|
206
|
+
SlackMessage.post_as(:schmoebot) { text 'nuh uh' }
|
|
207
|
+
}.to raise_error(SlackMessage::ApiError).with_message(error_message)
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
shared_examples 'update api error message' do |error, error_message|
|
|
212
|
+
it "responds to updates with error code '#{error}' with the expected message" do
|
|
213
|
+
message = SlackMessage.post_to('#general') { text 'nuh uh' }
|
|
214
|
+
|
|
215
|
+
SlackMessage::RSpec.respond_with({'error' => error})
|
|
216
|
+
|
|
217
|
+
expect {
|
|
218
|
+
SlackMessage.update(message) { text 'nuh uh' }
|
|
219
|
+
}.to raise_error(SlackMessage::ApiError).with_message(error_message)
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
shared_examples 'delete api error message' do |error, error_message|
|
|
224
|
+
it "responds to updates with error code '#{error}' with the expected message" do
|
|
225
|
+
message = SlackMessage.post_to('#general') { text 'nuh uh' }
|
|
226
|
+
|
|
227
|
+
SlackMessage::RSpec.respond_with({'error' => error})
|
|
228
|
+
|
|
229
|
+
expect {
|
|
230
|
+
SlackMessage.delete(message)
|
|
231
|
+
}.to raise_error(SlackMessage::ApiError).with_message(error_message)
|
|
232
|
+
end
|
|
217
233
|
end
|
|
234
|
+
|
|
235
|
+
shared_examples 'block api error message' do |error, error_message|
|
|
236
|
+
include_examples 'post api error message', error, error_message
|
|
237
|
+
include_examples 'update api error message', error, error_message
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
include_examples 'block api error message', 'nuffin', /Received error response 'nuffin' from Slack/
|
|
241
|
+
include_examples 'block api error message', 'invalid_blocks', /because the request contained invalid blocks:\n\[Enable debugging in configuration to view block data\.\]/
|
|
242
|
+
include_examples 'block api error message', 'invalid_blocks_format', /because blocks is not a valid JSON object or doesn't match the Block Kit syntax:\n\[Enable debugging in configuration to view block data\.\]/
|
|
243
|
+
include_examples 'block api error message', 'channel_not_found', /Slack message to non-existent channel or user/
|
|
244
|
+
include_examples 'block api error message', 'invalid_auth', /because the API key for profile '.*' is wrong, or the app has insufficient permissions \(invalid_auth\)/
|
|
245
|
+
include_examples 'block api error message', 'message_too_long', /but the message was too long/
|
|
246
|
+
include_examples 'block api error message', 'invalid_arguments', /with invalid payload/
|
|
247
|
+
include_examples 'block api error message', 'rate_limited', /because you've reached your rate limit/
|
|
248
|
+
|
|
249
|
+
# Scheduling messages
|
|
250
|
+
include_examples 'post api error message', 'invalid_time', /because you requested an invalid time/
|
|
251
|
+
include_examples 'post api error message', 'time_in_past', /because you requested a time in the past \(or too close to now\)/
|
|
252
|
+
include_examples 'post api error message', 'time_too_far', /because you requested a time more than 120 days in the future/
|
|
253
|
+
|
|
254
|
+
# Updating messages
|
|
255
|
+
include_examples 'update api error message', 'message_not_found', /but the message wasn't found/
|
|
256
|
+
|
|
257
|
+
# Deleting messages
|
|
258
|
+
include_examples 'delete api error message', 'nuffin', /Received error response 'nuffin' from Slack/
|
|
259
|
+
include_examples 'delete api error message', 'invalid_scheduled_message_id', /Can't delete message because the ID was invalid, or the message has already posted/
|
|
260
|
+
include_examples 'delete api error message', 'message_not_found', /but the message wasn't found/
|
|
261
|
+
include_examples 'delete api error message', 'cant_delete_message', /Can't delete message because 'default' doesn't have permission to/
|
|
262
|
+
include_examples 'delete api error message', 'compliance_exports_prevent_deletion', /Can't delete message because team compliance settings prevent it/
|
|
263
|
+
include_examples 'delete api error message', 'invalid_auth', /because the API key for profile '.*' is wrong, or the app has insufficient permissions \(invalid_auth\)/
|
|
264
|
+
include_examples 'delete api error message', 'rate_limited', /because you've reached your rate limit/
|
|
218
265
|
end
|
|
219
266
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -26,7 +26,11 @@ RSpec.configure do |config|
|
|
|
26
26
|
# is tagged with `:focus`, all examples get run. RSpec also provides
|
|
27
27
|
# aliases for `it`, `describe`, and `context` that include `:focus`
|
|
28
28
|
# metadata: `fit`, `fdescribe` and `fcontext`, respectively.
|
|
29
|
-
|
|
29
|
+
if ENV['CI'] == "true"
|
|
30
|
+
config.filter_run_when_matching :focus => lambda { raise ArgumentError, "Don't filter tests on checked in code." }
|
|
31
|
+
else
|
|
32
|
+
config.filter_run_when_matching :focus
|
|
33
|
+
end
|
|
30
34
|
|
|
31
35
|
# Limits the available syntax to the non-monkey patched syntax that is
|
|
32
36
|
# recommended. For more details, see:
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: slack_message
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joe Mastey
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-07-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rspec
|