slack_message 1.4.0 → 1.7.1
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 +19 -3
- data/Gemfile.lock +1 -1
- data/README.md +38 -0
- data/lib/slack_message/api.rb +11 -1
- data/lib/slack_message/configuration.rb +2 -2
- data/lib/slack_message/dsl.rb +29 -3
- data/lib/slack_message.rb +19 -3
- data/slack_message.gemspec +1 -1
- data/spec/slack_message_spec.rb +4 -4
- 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: f3438c93abd1488bafc0ee9f33df94674290b68bd94110e8f2e601d95d3254bc
|
4
|
+
data.tar.gz: 5eee7e715e66042ab6c3ccbc47eedba3e2ddddacd327e1096e3a2d3476b076b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
-
|
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
|
-
-
|
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
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
|
------------
|
data/lib/slack_message/api.rb
CHANGED
@@ -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)
|
data/lib/slack_message/dsl.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
class SlackMessage::Dsl
|
2
2
|
attr_reader :body, :default_section, :custom_bot_name
|
3
3
|
|
4
|
-
|
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.
|
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
|
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
|
data/slack_message.gemspec
CHANGED
data/spec/slack_message_spec.rb
CHANGED
@@ -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
|
-
|
11
|
-
|
12
|
-
|
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
|
+
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-
|
11
|
+
date: 2021-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|