slack_message 1.2.0 → 1.6.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 +16 -1
- data/Gemfile.lock +1 -1
- data/README.md +60 -5
- data/lib/slack_message/configuration.rb +7 -5
- data/lib/slack_message/dsl.rb +80 -7
- data/lib/slack_message.rb +23 -4
- data/slack_message.gemspec +1 -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: e66bdedefd2ac86c6c49d974e5f5d0474cc9b3756ce3a64e52df66ccc6e39cf4
|
4
|
+
data.tar.gz: b085edf556d957516d1cbbc9b260b7aff0e5d34b4561d27ae0d5f6b2dda9c93b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea935db68ca4771e11b40828d5cbd2fef02cf10c248fab3ede05ea82aef6a3a6d7ad96953debdc9214833ee0f281222e5e09adefd923c70d21090c996dba31a0
|
7
|
+
data.tar.gz: 46d2163aa9ec0e9df582700575d0c8b47b389b808f93275129025bc277086eb02fbeb4caa0754408dbc6d6fba9f06b6d8720493280550e0d3664bc735059f7c1
|
data/CHANGELOG.md
CHANGED
@@ -2,11 +2,26 @@
|
|
2
2
|
|
3
3
|
## [Unreleased]
|
4
4
|
|
5
|
+
## [1.6.0] - 2021-10-04
|
6
|
+
- Added `:default_channel` and `post_as` to deal with repetitive channel usage.
|
7
|
+
|
8
|
+
## [1.5.0] - 2021-10-01
|
9
|
+
- Added `ol` and `ul` to sections w/ some formatting.
|
10
|
+
|
11
|
+
## [1.4.0] - 2021-09-27
|
12
|
+
- Moved image to accessory_image to differentiate between the image block
|
13
|
+
and the accessory image within a block.
|
14
|
+
|
15
|
+
## [1.3.0] - 2021-09-27
|
16
|
+
- Added ability to use custom names when posting.
|
17
|
+
- Added ability to post images within sections.
|
18
|
+
- Added warnings for potentially invalid URLs.
|
19
|
+
|
5
20
|
## [1.2.0] - 2021-09-26
|
6
21
|
- Turns out gemspec was broken. Fixed that.
|
7
22
|
|
8
23
|
## [1.1.0] - 2021-09-26
|
9
|
-
- Expanded the README significantly w/ usage instructions
|
24
|
+
- Expanded the README significantly w/ usage instructions.
|
10
25
|
- Added lots of error handling to requests.
|
11
26
|
|
12
27
|
## [1.0.0] - 2021-09-25
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -6,6 +6,14 @@ API](https://app.slack.com/block-kit-builder/) to make it easy to read and
|
|
6
6
|
write messages to slack in your ruby application. It has zero dependencies and
|
7
7
|
is built to be opinionated to keep your configuration needs low.
|
8
8
|
|
9
|
+
Posting a message to Slack should be this easy:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
SlackMessage.post_to('#general') do
|
13
|
+
text "We did it @here! :thumbsup:"
|
14
|
+
end
|
15
|
+
```
|
16
|
+
|
9
17
|
To install, just add `slack_message` to your bundle and you're ready to go.
|
10
18
|
|
11
19
|
|
@@ -47,6 +55,28 @@ SlackMessage.configure do |config|
|
|
47
55
|
end
|
48
56
|
```
|
49
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
|
+
|
50
80
|
#### Configuring User Search
|
51
81
|
|
52
82
|
Slack's API no longer allows you to send DMs to users by username. You need to
|
@@ -61,13 +91,13 @@ SlackMessage.configure do |config|
|
|
61
91
|
end
|
62
92
|
```
|
63
93
|
|
64
|
-
###
|
94
|
+
### Posting Messages
|
65
95
|
|
66
|
-
|
96
|
+
As mentioned at the top, posting a message to Slack is dang easy:
|
67
97
|
|
68
98
|
```ruby
|
69
99
|
SlackMessage.post_to('#general') do
|
70
|
-
text "We did it! :thumbsup:"
|
100
|
+
text "We did it @here! :thumbsup:"
|
71
101
|
end
|
72
102
|
```
|
73
103
|
|
@@ -130,7 +160,7 @@ SlackMessage is able to build all kinds of rich messages for you, and has been
|
|
130
160
|
a real joy to use for the author at least. To understand a bit more about the
|
131
161
|
possibilities of blocks, see Slack's [Block Kit
|
132
162
|
Builder](https://app.slack.com/block-kit-builder/) to understand the structure
|
133
|
-
better:
|
163
|
+
better. There are lots of options:
|
134
164
|
|
135
165
|
```ruby
|
136
166
|
SlackMessage.post_to('#general') do
|
@@ -174,6 +204,27 @@ SlackMessage.post_to('#general', as: :sidekiq_bot) do
|
|
174
204
|
end
|
175
205
|
```
|
176
206
|
|
207
|
+
You can also use a custom name when sending a message:
|
208
|
+
|
209
|
+
```ruby
|
210
|
+
SlackMessage.post_to('#general') do
|
211
|
+
bot_name "CoffeeBot"
|
212
|
+
|
213
|
+
text ":coffee::clock: Time to take a break!"
|
214
|
+
end
|
215
|
+
```
|
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.
|
177
228
|
|
178
229
|
What it Doesn't Do
|
179
230
|
------------
|
@@ -190,7 +241,11 @@ DSL to include more of the block API itself.
|
|
190
241
|
Also, some behaviors that are still planned but not yet added:
|
191
242
|
|
192
243
|
* allow custom http_options in configuration
|
193
|
-
*
|
244
|
+
* more of BlockKit's options
|
245
|
+
* any interactive elements at all (I don't understand them yet)
|
246
|
+
* more interesting return types for your message
|
247
|
+
* some way to specify default channel for a given profile (and omit param to post_to)
|
248
|
+
* richer text formatting (ul is currently a hack)
|
194
249
|
|
195
250
|
Contributing
|
196
251
|
------------
|
@@ -27,19 +27,21 @@ 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
|
-
warn
|
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
|
-
def self.profile(handle)
|
38
|
+
def self.profile(handle, custom_name: nil)
|
39
39
|
unless @@profiles.include?(handle)
|
40
40
|
raise ArgumentError, "Unknown SlackMessage profile '#{handle}'."
|
41
41
|
end
|
42
42
|
|
43
|
-
@@profiles[handle]
|
43
|
+
@@profiles[handle].tap do |profile|
|
44
|
+
profile[:name] = custom_name if !custom_name.nil?
|
45
|
+
end
|
44
46
|
end
|
45
47
|
end
|
data/lib/slack_message/dsl.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
class SlackMessage::Dsl
|
2
|
-
attr_reader :body, :default_section
|
2
|
+
attr_reader :body, :default_section, :custom_bot_name
|
3
|
+
|
4
|
+
EMSPACE = " " # unicode emspace
|
3
5
|
|
4
6
|
def initialize
|
5
7
|
@body = []
|
6
8
|
@default_section = Section.new
|
9
|
+
@custom_bot_name = nil
|
7
10
|
end
|
8
11
|
|
9
12
|
# allowable top-level entities within a block
|
@@ -24,6 +27,24 @@ class SlackMessage::Dsl
|
|
24
27
|
@body.push({ type: "divider" })
|
25
28
|
end
|
26
29
|
|
30
|
+
def image(url, alt_text:, title: nil)
|
31
|
+
finalize_default_section
|
32
|
+
|
33
|
+
config = {
|
34
|
+
type: "image",
|
35
|
+
image_url: url,
|
36
|
+
alt_text: alt_text,
|
37
|
+
}
|
38
|
+
|
39
|
+
if !title.nil?
|
40
|
+
config[:title] = {
|
41
|
+
type: "plain_text", text: title, emoji: true
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
@body.push(config)
|
46
|
+
end
|
47
|
+
|
27
48
|
def context(text)
|
28
49
|
finalize_default_section
|
29
50
|
|
@@ -38,12 +59,28 @@ class SlackMessage::Dsl
|
|
38
59
|
|
39
60
|
def text(*args); default_section.text(*args); end
|
40
61
|
def link_button(*args); default_section.link_button(*args); end
|
62
|
+
def accessory_image(*args); default_section.accessory_image(*args); end
|
41
63
|
def blank_line(*args); default_section.blank_line(*args); end
|
42
64
|
def link(*args); default_section.link(*args); end
|
43
65
|
def list_item(*args); default_section.list_item(*args); end
|
66
|
+
def ul(*args); default_section.ul(*args); end
|
67
|
+
def ol(*args); default_section.ol(*args); end
|
44
68
|
|
45
69
|
# end delegation
|
46
70
|
|
71
|
+
# custom bot name
|
72
|
+
|
73
|
+
def bot_name(name)
|
74
|
+
@custom_bot_name = name
|
75
|
+
end
|
76
|
+
|
77
|
+
# end bot name
|
78
|
+
|
79
|
+
def render
|
80
|
+
finalize_default_section
|
81
|
+
@body
|
82
|
+
end
|
83
|
+
|
47
84
|
private
|
48
85
|
|
49
86
|
# when doing things that would generate new top-levels, first try
|
@@ -56,11 +93,6 @@ class SlackMessage::Dsl
|
|
56
93
|
@default_section = Section.new
|
57
94
|
end
|
58
95
|
|
59
|
-
def render
|
60
|
-
finalize_default_section
|
61
|
-
@body
|
62
|
-
end
|
63
|
-
|
64
96
|
class Section
|
65
97
|
attr_reader :body
|
66
98
|
|
@@ -78,8 +110,31 @@ class SlackMessage::Dsl
|
|
78
110
|
end
|
79
111
|
end
|
80
112
|
|
113
|
+
def ul(elements)
|
114
|
+
raise Arguments, "please pass an array" unless elements.respond_to?(:map)
|
115
|
+
text(
|
116
|
+
elements.map { |text| "#{EMSPACE}• #{text}" }.join("\n")
|
117
|
+
)
|
118
|
+
end
|
119
|
+
|
120
|
+
def ol(elements)
|
121
|
+
raise Arguments, "please pass an array" unless elements.respond_to?(:map)
|
122
|
+
text(
|
123
|
+
elements.map.with_index(1) { |text, idx| "#{EMSPACE}#{idx}. #{text}" }.join("\n")
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
81
127
|
# styles: default, primary, danger
|
82
128
|
def link_button(label, target, style: :primary)
|
129
|
+
if !@body[:accessory].nil?
|
130
|
+
previous_type = @body[:accessory][:type]
|
131
|
+
warn "WARNING: Overriding previous #{previous_type} in section to use link_button instead: #{label}"
|
132
|
+
end
|
133
|
+
|
134
|
+
unless /(^|\s)((https?:\/\/)?[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?)/i =~ target
|
135
|
+
warn "WARNING: Passing a probably-invalid URL to link button #{label} (url: '#{target}')"
|
136
|
+
end
|
137
|
+
|
83
138
|
config = {
|
84
139
|
accessory: {
|
85
140
|
type: "button",
|
@@ -99,6 +154,24 @@ class SlackMessage::Dsl
|
|
99
154
|
@body.merge!(config)
|
100
155
|
end
|
101
156
|
|
157
|
+
def accessory_image(url, alt_text: nil)
|
158
|
+
if !@body[:accessory].nil?
|
159
|
+
previous_type = @body[:accessory][:type]
|
160
|
+
warn "WARNING: Overriding previous #{previous_type} in section to use accessory image instead: #{url}"
|
161
|
+
end
|
162
|
+
|
163
|
+
config = {
|
164
|
+
accessory: {
|
165
|
+
type: "image",
|
166
|
+
image_url: url
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
config[:accessory][:alt_text] = alt_text if !alt_text.nil?
|
171
|
+
|
172
|
+
@body.merge!(config)
|
173
|
+
end
|
174
|
+
|
102
175
|
# for markdown links
|
103
176
|
def link(label, target)
|
104
177
|
"<#{target}|#{label}>"
|
@@ -109,7 +182,7 @@ class SlackMessage::Dsl
|
|
109
182
|
end
|
110
183
|
|
111
184
|
def blank_line
|
112
|
-
text
|
185
|
+
text EMSPACE
|
113
186
|
end
|
114
187
|
|
115
188
|
def has_content?
|
data/lib/slack_message.rb
CHANGED
@@ -11,16 +11,35 @@ 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 =
|
20
|
-
|
19
|
+
payload = Dsl.new.tap do |instance|
|
20
|
+
instance.instance_eval(&block)
|
21
|
+
end
|
22
|
+
|
23
|
+
profile = Configuration.profile(as, custom_name: payload.custom_bot_name)
|
24
|
+
target = user_id_for(target) if target =~ /^\S{1,}@\S{2,}\.\S{2,}$/
|
25
|
+
|
26
|
+
Api.post(payload.render, target, profile)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.post_as(profile_name, &block)
|
30
|
+
payload = Dsl.new.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]
|
21
40
|
target = user_id_for(target) if target =~ /^\S{1,}@\S{2,}\.\S{2,}$/
|
22
41
|
|
23
|
-
Api.post(payload, target, profile)
|
42
|
+
Api.post(payload.render, target, profile)
|
24
43
|
end
|
25
44
|
|
26
45
|
def self.build(&block)
|
data/slack_message.gemspec
CHANGED
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.6.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-
|
11
|
+
date: 2021-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|