slack_message 1.4.0 → 1.7.1

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: 858633fd4b83922e886bbec641c0075aab65aa9551d0a268cab9b51e3f3722fc
4
- data.tar.gz: 3bc79397b71344abe4b535424d9913ca8a7f37259b4904da43acc0149674a6c6
3
+ metadata.gz: f3438c93abd1488bafc0ee9f33df94674290b68bd94110e8f2e601d95d3254bc
4
+ data.tar.gz: 5eee7e715e66042ab6c3ccbc47eedba3e2ddddacd327e1096e3a2d3476b076b0
5
5
  SHA512:
6
- metadata.gz: d8cb6fcfaeeade894cba87671231d49de003917069e597906d53a166a8d2e74a25a1e2f55aaadefbe606b940106f8123afe02b9d820191210bfccd3e8962ce95
7
- data.tar.gz: fa49ddfecbd19538bfe91d62f0e7decc88cc52ef42e6d0c880138820671b27d23334dd90fd7a970e080a85221bdbf5b40929e3ee3d6e73db0e039efc1d17acd9
6
+ metadata.gz: ddc5ace3b66e6977b164accfeec16c67450ed8fbd182939e85aa1d56c251319f203c4527d75d410c2858bbfa7540889a83ed08aed12890488944077edf1867ed
7
+ data.tar.gz: 16601f240ee826b8cadbd03429b5fd431ba21a5b159c1ca3c70932da362b54388c32115544bf782c45f9e2b1c603801d82e2fd6827e7020abfcaed18669601ee
data/CHANGELOG.md CHANGED
@@ -2,8 +2,25 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.7.1] - 2021-10-06
6
+ - Fixed literally a syntax issue.
7
+ - Fixed specs.
8
+ - Fixed API to include JSON since consumers may not have loaded it.
9
+
10
+ ## [1.7.0] - 2021-10-06
11
+ - THIS RELEASE IS BADLY BROKEN.
12
+ - Added new error messages when API configuration is wrong / missing.
13
+ - Fixed issue with `instance_eval` and using methods within block.
14
+ - Fixed issue with sectionless `list_item`.
15
+
16
+ ## [1.6.0] - 2021-10-04
17
+ - Added `:default_channel` and `post_as` to deal with repetitive channel usage.
18
+
19
+ ## [1.5.0] - 2021-10-01
20
+ - Added `ol` and `ul` to sections w/ some formatting.
21
+
5
22
  ## [1.4.0] - 2021-09-27
6
- - Moved image to accessory_image to differentiate between the image block
23
+ - Changed `image` to `accessory_image` to differentiate between the image block
7
24
  and the accessory image within a block.
8
25
 
9
26
  ## [1.3.0] - 2021-09-27
@@ -12,13 +29,12 @@
12
29
  - Added warnings for potentially invalid URLs.
13
30
 
14
31
  ## [1.2.0] - 2021-09-26
15
- - Turns out gemspec was broken. Fixed that.
32
+ - Fixed gemspec, which was entirely broken.
16
33
 
17
34
  ## [1.1.0] - 2021-09-26
18
35
  - Expanded the README significantly w/ usage instructions.
19
36
  - Added lots of error handling to requests.
20
37
 
21
38
  ## [1.0.0] - 2021-09-25
22
-
23
39
  - Added the base gem w/ a DSL for constructing blocks using sections.
24
40
  - Added a changelog, apparently.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- slack_message (1.2.0)
4
+ slack_message (1.7.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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
@@ -192,6 +214,20 @@ 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
+ * It's easy to configure a bot for consistent name / channel use. My previous
229
+ use of SlackNotifier led to frequently inconsistent names.
230
+
195
231
  What it Doesn't Do
196
232
  ------------
197
233
 
@@ -206,10 +242,12 @@ DSL to include more of the block API itself.
206
242
 
207
243
  Also, some behaviors that are still planned but not yet added:
208
244
 
245
+ * some API documentation amirite?
209
246
  * allow custom http_options in configuration
210
247
  * more of BlockKit's options
211
248
  * any interactive elements at all (I don't understand them yet)
212
249
  * more interesting return types for your message
250
+ * richer text formatting (ul is currently a hack)
213
251
 
214
252
  Contributing
215
253
  ------------
@@ -1,5 +1,6 @@
1
1
  require 'net/http'
2
2
  require 'net/https'
3
+ require 'json'
3
4
 
4
5
  class SlackMessage::Api
5
6
  def self.user_id_for(email)
@@ -17,9 +18,16 @@ class SlackMessage::Api
17
18
 
18
19
  if response.code != "200"
19
20
  raise "Got an error back from the Slack API (HTTP #{response.code}):\n#{response.body}"
21
+ elsif response.body == ""
22
+ raise "Received empty 200 response from Slack when looking up user info. Check your API key."
23
+ end
24
+
25
+ begin
26
+ payload = JSON.parse(response.body)
27
+ rescue
28
+ raise "Unable to parse JSON response from Slack API\n#{response.body}"
20
29
  end
21
30
 
22
- payload = JSON.parse(response.body)
23
31
  if payload.include?("error") && payload["error"] == "invalid_auth"
24
32
  raise "Received an error because your authentication token isn't properly configured:\n#{response.body}"
25
33
  elsif payload.include?("error")
@@ -48,6 +56,8 @@ class SlackMessage::Api
48
56
  raise "Tried to send Slack message to non-existent channel or user '#{target}'"
49
57
  elsif response.body == "missing_text_or_fallback_or_attachments"
50
58
  raise "Tried to send Slack message with invalid payload."
59
+ elsif response.code == "302"
60
+ raise "Got 302 response while posting to Slack. Check your webhook URL for '#{profile[:handle]}'."
51
61
  elsif response.code != "200"
52
62
  raise "Got an error back from the Slack API (HTTP #{response.code}):\n#{response.body}"
53
63
  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
@@ -61,6 +67,8 @@ class SlackMessage::Dsl
61
67
  def blank_line(*args); default_section.blank_line(*args); end
62
68
  def link(*args); default_section.link(*args); end
63
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
64
72
 
65
73
  # end delegation
66
74
 
@@ -77,13 +85,17 @@ class SlackMessage::Dsl
77
85
  @body
78
86
  end
79
87
 
88
+ def method_missing(meth, *args, &blk)
89
+ @caller_self.send meth, *args, &blk
90
+ end
91
+
80
92
  private
81
93
 
82
94
  # when doing things that would generate new top-levels, first try
83
95
  # to finish the implicit section.
84
96
  def finalize_default_section
85
97
  if default_section.has_content?
86
- @body.push(default_section.body)
98
+ @body.push(default_section.render)
87
99
  end
88
100
 
89
101
  @default_section = Section.new
@@ -106,6 +118,20 @@ class SlackMessage::Dsl
106
118
  end
107
119
  end
108
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
+
109
135
  # styles: default, primary, danger
110
136
  def link_button(label, target, style: :primary)
111
137
  if !@body[:accessory].nil?
@@ -164,7 +190,7 @@ class SlackMessage::Dsl
164
190
  end
165
191
 
166
192
  def blank_line
167
- text " " # unicode emspace
193
+ text EMSPACE
168
194
  end
169
195
 
170
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.4.0"
3
+ gem.version = "1.7.1"
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'
@@ -7,9 +7,10 @@ RSpec.describe SlackMessage do
7
7
 
8
8
  describe "API convenience" do
9
9
  it "can grab user IDs" do
10
- allow(SlackMessage::Api).to receive(:api_request)
11
- .with(/hello@joemastey.com/)
12
- .and_return({ "user" => { "id" => "ABC123" }})
10
+ SlackMessage.configure { |c| c.api_token = "asdf" }
11
+ allow(Net::HTTP).to receive(:start).and_return(
12
+ double(code: "200", body: '{ "user": { "id": "ABC123" }}')
13
+ )
13
14
 
14
15
  result = SlackMessage.user_id_for("hello@joemastey.com")
15
16
  expect(result).to eq("ABC123")
@@ -63,7 +64,6 @@ RSpec.describe SlackMessage do
63
64
  config.add_profile(:nonstandard, name: 'another profile', url: 'http://hooks.slack.com/1234/')
64
65
  end
65
66
 
66
-
67
67
  expect(SlackMessage.configuration.profile(:default)[:name]).to eq('default profile')
68
68
  expect(SlackMessage.configuration.profile(:nonstandard)[:name]).to eq('another profile')
69
69
 
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.4.0
4
+ version: 1.7.1
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