slack_message 1.3.0 → 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: fb63c39ef18b4b6e6fb1d25e62300fcff41b759f3d59902c10423c306f892007
4
- data.tar.gz: 499f1d885b3a00e60af92ff9d0ba17c19f59ba3b1468d178498d08802c9429dd
3
+ metadata.gz: a2cd232d81a66a48c9543a5b910c335bca7a82474a60472d03f7cffab3fce0d0
4
+ data.tar.gz: c27312311ff02ee414f2882461fe5ea9b5c07d9d8e99847ae7af33faf4a31283
5
5
  SHA512:
6
- metadata.gz: b0bf20b89e6ce48e9accb2ccd475d5f999686804d3c952e6a8903958af2f7b1500011f6abd904abba5f2cf73d635498f8c1feae7e4d00aa021b3ab0b6c1a5baa
7
- data.tar.gz: 42a8e2ecc5b6ca51ec1ab534e2a91bb500e352e26636f1a5671bf81244a40b321162bed30e1e7e0a78e53490575fbb0052c9d39fb108951f73425269cfafbab5
6
+ metadata.gz: 69352d5eb8d4f6837f66ba042817bfe0a51c3483356bbc64ded0cbc60fc7e72c084ea39df542a93bf79a6c0a8c4ad860cdb9791f28d807edb5b1c859b13f129f
7
+ data.tar.gz: 740af84829c6b258b4788b5f83901f242a5732e98737781efb288ee426ed232726823d9fdde453da6c7d83eb55607733e1d4b55757580676921b37abba1c70ad
data/CHANGELOG.md CHANGED
@@ -2,19 +2,33 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.7.0] - 2021-10-06
6
+ - Added new error messages when API configuration is wrong / missing.
7
+ - Fixed issue with `instance_eval` and using methods within block.
8
+ - Fixed issue with sectionless `list_item`.
9
+
10
+ ## [1.6.0] - 2021-10-04
11
+ - Added `:default_channel` and `post_as` to deal with repetitive channel usage.
12
+
13
+ ## [1.5.0] - 2021-10-01
14
+ - Added `ol` and `ul` to sections w/ some formatting.
15
+
16
+ ## [1.4.0] - 2021-09-27
17
+ - Changed `image` to `accessory_image` to differentiate between the image block
18
+ and the accessory image within a block.
19
+
5
20
  ## [1.3.0] - 2021-09-27
6
21
  - Added ability to use custom names when posting.
7
22
  - Added ability to post images within sections.
8
23
  - Added warnings for potentially invalid URLs.
9
24
 
10
25
  ## [1.2.0] - 2021-09-26
11
- - Turns out gemspec was broken. Fixed that.
26
+ - Fixed gemspec, which was entirely broken.
12
27
 
13
28
  ## [1.1.0] - 2021-09-26
14
29
  - Expanded the README significantly w/ usage instructions.
15
30
  - Added lots of error handling to requests.
16
31
 
17
32
  ## [1.0.0] - 2021-09-25
18
-
19
33
  - Added the base gem w/ a DSL for constructing blocks using sections.
20
34
  - Added a changelog, apparently.
data/README.md CHANGED
@@ -55,6 +55,28 @@ SlackMessage.configure do |config|
55
55
  end
56
56
  ```
57
57
 
58
+ If you frequently ping the same channel with the same bot, and don't want to
59
+ continually specify the channel name, you can specify a default channel and
60
+ post using the `post_as` method. It is otherwise identical to `post_to`, but
61
+ allows you to omit the channel argument:
62
+
63
+ ```ruby
64
+ SlackMessage.configure do |config|
65
+ config.add_profile(:prod_alert_bot,
66
+ name: 'Prod Alert Bot',
67
+ url: ENV['SLACK_PROD_ALERT_WEBHOOK_URL'],
68
+ default_channel: '#red_alerts'
69
+ )
70
+ end
71
+
72
+ SlackMessage.post_as(:prod_alert_bot) do
73
+ text ":ambulance: weeooo weeooo something went wrong"
74
+ end
75
+ ```
76
+
77
+ Note that `post_as` does not allow you to choose a channel (because that's just
78
+ the same as using `post_to`), so you really do have to specify `default_channel`.
79
+
58
80
  #### Configuring User Search
59
81
 
60
82
  Slack's API no longer allows you to send DMs to users by username. You need to
@@ -69,7 +91,7 @@ SlackMessage.configure do |config|
69
91
  end
70
92
  ```
71
93
 
72
- ### Usage
94
+ ### Posting Messages
73
95
 
74
96
  As mentioned at the top, posting a message to Slack is dang easy:
75
97
 
@@ -192,6 +214,18 @@ SlackMessage.post_to('#general') do
192
214
  end
193
215
  ```
194
216
 
217
+ Opinionated Stances
218
+ ------------
219
+
220
+ Slack's API has a lot of options available to you! But this gem takes some
221
+ opinionated stances on how to make use of that API. For instance:
222
+
223
+ * Unless you request otherwise, text is always rendered using `mrkdwn`. If you
224
+ want plaintext, you'll need to ask for it.
225
+ * Generally, same goes for the `emoji` flag on almost every text element.
226
+ * It's possible to ask for a `blank_line` in sections, even though that concept
227
+ isn't real. In this case, a text line containing only an emspace is rendered.
228
+
195
229
  What it Doesn't Do
196
230
  ------------
197
231
 
@@ -206,9 +240,12 @@ DSL to include more of the block API itself.
206
240
 
207
241
  Also, some behaviors that are still planned but not yet added:
208
242
 
243
+ * some API documentation amirite?
209
244
  * allow custom http_options in configuration
210
245
  * more of BlockKit's options
211
246
  * any interactive elements at all (I don't understand them yet)
247
+ * more interesting return types for your message
248
+ * richer text formatting (ul is currently a hack)
212
249
 
213
250
  Contributing
214
251
  ------------
@@ -17,9 +17,16 @@ class SlackMessage::Api
17
17
 
18
18
  if response.code != "200"
19
19
  raise "Got an error back from the Slack API (HTTP #{response.code}):\n#{response.body}"
20
+ elsif response.body == ""
21
+ raise "Received empty 200 response from Slack when looking up user info. Check your API key."
22
+ end
23
+
24
+ begin
25
+ payload = JSON.parse(response.body)
26
+ rescue
27
+ raise "Unable to parse JSON response from Slack API\n#{response.body}"
20
28
  end
21
29
 
22
- payload = JSON.parse(response.body)
23
30
  if payload.include?("error") && payload["error"] == "invalid_auth"
24
31
  raise "Received an error because your authentication token isn't properly configured:\n#{response.body}"
25
32
  elsif payload.include?("error")
@@ -48,6 +55,8 @@ class SlackMessage::Api
48
55
  raise "Tried to send Slack message to non-existent channel or user '#{target}'"
49
56
  elsif response.body == "missing_text_or_fallback_or_attachments"
50
57
  raise "Tried to send Slack message with invalid payload."
58
+ elsif response.code == "302"
59
+ raise "Got 302 response while posting to Slack. Check your webhook URL for '#{profile[:handle]}'."
51
60
  elsif response.code != "200"
52
61
  raise "Got an error back from the Slack API (HTTP #{response.code}):\n#{response.body}"
53
62
  end
@@ -27,12 +27,12 @@ module SlackMessage::Configuration
27
27
 
28
28
  ###
29
29
 
30
- def self.add_profile(handle = :default, name:, url:)
30
+ def self.add_profile(handle = :default, name:, url:, default_channel: nil)
31
31
  if @@profiles.include?(handle)
32
32
  warn "WARNING: Overriding profile '#{handle}' in SlackMessage config"
33
33
  end
34
34
 
35
- @@profiles[handle] = { name: name, url: url, handle: handle }
35
+ @@profiles[handle] = { name: name, url: url, handle: handle, default_channel: default_channel }
36
36
  end
37
37
 
38
38
  def self.profile(handle, custom_name: nil)
@@ -1,7 +1,13 @@
1
1
  class SlackMessage::Dsl
2
2
  attr_reader :body, :default_section, :custom_bot_name
3
3
 
4
- def initialize
4
+ EMSPACE = " " # unicode emspace
5
+
6
+ def initialize(block)
7
+ # Delegate missing methods to caller scope. Thanks 2008:
8
+ # https://www.dan-manges.com/blog/ruby-dsls-instance-eval-with-delegation
9
+ @caller_self = eval("self", block.binding
10
+
5
11
  @body = []
6
12
  @default_section = Section.new
7
13
  @custom_bot_name = nil
@@ -25,6 +31,24 @@ class SlackMessage::Dsl
25
31
  @body.push({ type: "divider" })
26
32
  end
27
33
 
34
+ def image(url, alt_text:, title: nil)
35
+ finalize_default_section
36
+
37
+ config = {
38
+ type: "image",
39
+ image_url: url,
40
+ alt_text: alt_text,
41
+ }
42
+
43
+ if !title.nil?
44
+ config[:title] = {
45
+ type: "plain_text", text: title, emoji: true
46
+ }
47
+ end
48
+
49
+ @body.push(config)
50
+ end
51
+
28
52
  def context(text)
29
53
  finalize_default_section
30
54
 
@@ -39,10 +63,12 @@ class SlackMessage::Dsl
39
63
 
40
64
  def text(*args); default_section.text(*args); end
41
65
  def link_button(*args); default_section.link_button(*args); end
42
- def image(*args); default_section.image(*args); end
66
+ def accessory_image(*args); default_section.accessory_image(*args); end
43
67
  def blank_line(*args); default_section.blank_line(*args); end
44
68
  def link(*args); default_section.link(*args); end
45
69
  def list_item(*args); default_section.list_item(*args); end
70
+ def ul(*args); default_section.ul(*args); end
71
+ def ol(*args); default_section.ol(*args); end
46
72
 
47
73
  # end delegation
48
74
 
@@ -59,13 +85,17 @@ class SlackMessage::Dsl
59
85
  @body
60
86
  end
61
87
 
88
+ def method_missing(meth, *args, &blk)
89
+ @caller_self.send meth, *args, &blk
90
+ end
91
+
62
92
  private
63
93
 
64
94
  # when doing things that would generate new top-levels, first try
65
95
  # to finish the implicit section.
66
96
  def finalize_default_section
67
97
  if default_section.has_content?
68
- @body.push(default_section.body)
98
+ @body.push(default_section.render)
69
99
  end
70
100
 
71
101
  @default_section = Section.new
@@ -88,6 +118,20 @@ class SlackMessage::Dsl
88
118
  end
89
119
  end
90
120
 
121
+ def ul(elements)
122
+ raise Arguments, "please pass an array" unless elements.respond_to?(:map)
123
+ text(
124
+ elements.map { |text| "#{EMSPACE}• #{text}" }.join("\n")
125
+ )
126
+ end
127
+
128
+ def ol(elements)
129
+ raise Arguments, "please pass an array" unless elements.respond_to?(:map)
130
+ text(
131
+ elements.map.with_index(1) { |text, idx| "#{EMSPACE}#{idx}. #{text}" }.join("\n")
132
+ )
133
+ end
134
+
91
135
  # styles: default, primary, danger
92
136
  def link_button(label, target, style: :primary)
93
137
  if !@body[:accessory].nil?
@@ -118,10 +162,10 @@ class SlackMessage::Dsl
118
162
  @body.merge!(config)
119
163
  end
120
164
 
121
- def image(url, alt_text: nil)
165
+ def accessory_image(url, alt_text: nil)
122
166
  if !@body[:accessory].nil?
123
167
  previous_type = @body[:accessory][:type]
124
- warn "WARNING: Overriding previous #{previous_type} in section to use image instead: #{url}"
168
+ warn "WARNING: Overriding previous #{previous_type} in section to use accessory image instead: #{url}"
125
169
  end
126
170
 
127
171
  config = {
@@ -146,7 +190,7 @@ class SlackMessage::Dsl
146
190
  end
147
191
 
148
192
  def blank_line
149
- text " " # unicode emspace
193
+ text EMSPACE
150
194
  end
151
195
 
152
196
  def has_content?
data/lib/slack_message.rb CHANGED
@@ -11,12 +11,12 @@ module SlackMessage
11
11
  configuration.configure(&block)
12
12
  end
13
13
 
14
- def self.user_id_for(email)
14
+ def self.user_id_for(email) # spooky undocumented public method 👻
15
15
  Api::user_id_for(email)
16
16
  end
17
17
 
18
18
  def self.post_to(target, as: :default, &block)
19
- payload = Dsl.new.tap do |instance|
19
+ payload = Dsl.new(block).tap do |instance|
20
20
  instance.instance_eval(&block)
21
21
  end
22
22
 
@@ -26,8 +26,24 @@ module SlackMessage
26
26
  Api.post(payload.render, target, profile)
27
27
  end
28
28
 
29
+ def self.post_as(profile_name, &block)
30
+ payload = Dsl.new(block).tap do |instance|
31
+ instance.instance_eval(&block)
32
+ end
33
+
34
+ profile = Configuration.profile(profile_name, custom_name: payload.custom_bot_name)
35
+ if profile[:default_channel].nil?
36
+ raise ArgumentError, "Sorry, you need to specify a default_channel for profile #{profile_name} to use post_as"
37
+ end
38
+
39
+ target = profile[:default_channel]
40
+ target = user_id_for(target) if target =~ /^\S{1,}@\S{2,}\.\S{2,}$/
41
+
42
+ Api.post(payload.render, target, profile)
43
+ end
44
+
29
45
  def self.build(&block)
30
- Dsl.new.tap do |instance|
46
+ Dsl.new(block).tap do |instance|
31
47
  instance.instance_eval(&block)
32
48
  end.send(:render)
33
49
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = 'slack_message'
3
- gem.version = "1.3.0"
3
+ gem.version = "1.7.0"
4
4
  gem.summary = "A nice DSL for composing rich messages in Slack"
5
5
  gem.authors = ["Joe Mastey"]
6
6
  gem.email = 'hello@joemastey.com'
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: 1.3.0
4
+ version: 1.7.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: 2021-09-27 00:00:00.000000000 Z
11
+ date: 2021-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec