slack_message 2.2.0 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +24 -24
- data/lib/slack_message/api.rb +25 -14
- data/lib/slack_message/dsl.rb +2 -4
- data/lib/slack_message/rspec.rb +7 -1
- data/lib/slack_message.rb +5 -2
- data/slack_message.gemspec +1 -1
- data/spec/slack_message_spec.rb +0 -9
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '008fdfc2e46435b3bb49aae67e30b3ef354ca0c923c935c918088ee25eec7bda'
|
4
|
+
data.tar.gz: 2fe7d85c853361d12f02f58d19e4bef43ffc81d3683ef5f8b3776657eb86c5ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c5cc5b43f1813b55b6d1433da88ca661bc692a21785ffad1c2e13c459f0d2b4cb6bbf6251f5e774924a73e8e60f8c2517deaf71a0a1f74f57b2094e822e82ac
|
7
|
+
data.tar.gz: 0bb8d97ef6338703e601bd964405c090823ceded7cfa3045d42618a575397ca057591f6aad1cad6d1a74a7f4b877de11bced2d566424c75b53d80d2ce018cda0
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [2.2.1] - 2021-11-20
|
4
|
+
- Trying to fetch user ID for a string that isn't email-like raises an error.
|
5
|
+
- In tests, fetching user IDs is mocked out to prevent network requests.
|
6
|
+
- Tightened up and clarified README.
|
7
|
+
- Some internal cleanup and restructuring of modules.
|
8
|
+
|
3
9
|
## [2.2.0] - 2021-11-20
|
4
10
|
- When sending text, it is now possible to mention users and have their user
|
5
11
|
IDs automatically converted using `<email@email.com>` within text nodes.
|
data/README.md
CHANGED
@@ -15,19 +15,21 @@ end
|
|
15
15
|
|
16
16
|
To install, just add `slack_message` to your bundle and you're ready to go.
|
17
17
|
|
18
|
-
Opinionated Stances
|
19
|
-
------------
|
18
|
+
#### Opinionated Stances
|
20
19
|
|
21
20
|
Slack's API has a lot of options available to you! But this gem takes some
|
22
|
-
opinionated stances
|
21
|
+
opinionated stances about usage to try to minimize the pain of integrating
|
22
|
+
with it. For example:
|
23
23
|
|
24
|
-
*
|
24
|
+
* SlackMessage has no dependencies. Your lockfile is enough of a mess already.
|
25
|
+
* The code to build a message should look a lot like the message itself. Code
|
26
|
+
that is simple to read and understand is a priority.
|
25
27
|
* Webhooks are passé. Only Slack Apps are supported now.
|
26
28
|
* Unless you request otherwise, text is always rendered using `mrkdwn`. If you
|
27
29
|
want plaintext, you'll need to ask for it. Same for the `emoji` flag.
|
28
30
|
* As many API semantics as possible are hidden. For instance, if you post to
|
29
|
-
something that looks like an email address, `slack_message` is going to try
|
30
|
-
look it up as an email address.
|
31
|
+
something that looks like an email address, `slack_message` is going to try
|
32
|
+
to look it up as an email address.
|
31
33
|
* A few little hacks on the block syntax, such as adding a `blank_line` (which
|
32
34
|
doesn't exist in the API), or leading spaces.
|
33
35
|
* Configuration is kept as simple as possible. But, as much heavy lifting as
|
@@ -173,9 +175,7 @@ It's just as easy to send messages directly to users. SlackMessage will look for
|
|
173
175
|
targets that are email-addressish, and look them up for you automatically:
|
174
176
|
|
175
177
|
```ruby
|
176
|
-
|
177
|
-
|
178
|
-
SlackMessage.post_to(user_email) do
|
178
|
+
SlackMessage.post_to('hello@joemastey.com') do
|
179
179
|
text "You specifically did it! :thumbsup:"
|
180
180
|
end
|
181
181
|
```
|
@@ -207,15 +207,13 @@ SlackMessage.post_to('#general') do
|
|
207
207
|
text "See more here: #{link('result', 'https://google.com')}"
|
208
208
|
end
|
209
209
|
|
210
|
-
text ":rocketship: hello@joemastey.com"
|
210
|
+
text ":rocketship: <hello@joemastey.com>"
|
211
211
|
|
212
212
|
context ":custom_slack_emoji: An example footer *with some markdown*."
|
213
213
|
end
|
214
214
|
```
|
215
215
|
|
216
216
|
SlackMessage will compose this into Block Kit syntax and send it on its way!
|
217
|
-
For now you'll need to read a bit of the source code to get the entire API. Sorry,
|
218
|
-
working on it.
|
219
217
|
|
220
218
|
If you've defined multiple profiles in configuration, you can specify which to
|
221
219
|
use for your message by specifying its name:
|
@@ -223,6 +221,7 @@ use for your message by specifying its name:
|
|
223
221
|
```ruby
|
224
222
|
SlackMessage.post_to('#general', as: :sidekiq_bot) do
|
225
223
|
text ":octagonal_sign: A job has failed permanently and needs to be rescued."
|
224
|
+
|
226
225
|
link_button "Sidekiq Dashboard", sidekiq_dashboard_url, style: :danger
|
227
226
|
end
|
228
227
|
```
|
@@ -261,16 +260,16 @@ SlackMessage.post_to('#general') do
|
|
261
260
|
end
|
262
261
|
```
|
263
262
|
|
264
|
-
Emails that are not wrapped in tags will be rendered as normal
|
265
|
-
|
266
|
-
|
263
|
+
Emails that are not wrapped in tags will be rendered as normal email addresses.
|
264
|
+
Additionally, Slack will automatically convert a number of channel names and
|
265
|
+
tags you're probably already used to:
|
267
266
|
|
268
267
|
```ruby
|
269
268
|
SlackMessage.post_to('#general') do
|
270
269
|
bot_name "CoffeeBot"
|
271
270
|
bot_icon ":coffee:"
|
272
271
|
|
273
|
-
text "@here
|
272
|
+
text "@here There's no coffee left! Let #general know when you fix it."
|
274
273
|
end
|
275
274
|
```
|
276
275
|
|
@@ -303,8 +302,8 @@ RSpec.configure do |config|
|
|
303
302
|
end
|
304
303
|
```
|
305
304
|
|
306
|
-
This will
|
307
|
-
some custom matchers:
|
305
|
+
This will prevent API calls from leaking in your tests, and will allow you
|
306
|
+
access to some custom matchers:
|
308
307
|
|
309
308
|
```ruby
|
310
309
|
expect {
|
@@ -340,12 +339,12 @@ of very complicated regexes.
|
|
340
339
|
What it Doesn't Do
|
341
340
|
------------
|
342
341
|
|
343
|
-
This gem is intended to stay
|
344
|
-
options and abilities, which
|
345
|
-
you want to add a feature, open an issue on Github first to see if it's
|
346
|
-
to be merged. This gem was built out of an existing need that _didn't_
|
347
|
-
|
348
|
-
expand the DSL to include more useful features.
|
342
|
+
This gem is intended to stay simple. Other Slack gems have lots of config
|
343
|
+
options and abilities, which makes them powerful, but makes them a pain to use.
|
344
|
+
If you want to add a feature, open an issue on Github first to see if it's
|
345
|
+
likely to be merged. This gem was built out of an existing need that _didn't_
|
346
|
+
include all of the block API, but I'd be inclined to merge features that
|
347
|
+
sustainably expand the DSL to include more useful features.
|
349
348
|
|
350
349
|
Some behaviors that are still planned but not yet added:
|
351
350
|
|
@@ -357,6 +356,7 @@ Some behaviors that are still planned but not yet added:
|
|
357
356
|
* multiple recipients
|
358
357
|
* more interesting return types for your message
|
359
358
|
* richer text formatting (for instance, `ul` is currently a hack)
|
359
|
+
* more and better organized testing capability
|
360
360
|
|
361
361
|
Contributing
|
362
362
|
------------
|
data/lib/slack_message/api.rb
CHANGED
@@ -2,18 +2,16 @@ require 'net/http'
|
|
2
2
|
require 'net/https'
|
3
3
|
require 'json'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
uri = URI("https://slack.com/api/users.lookupByEmail?email=#{email}")
|
8
|
-
request = Net::HTTP::Get.new(uri).tap do |req|
|
9
|
-
req['Authorization'] = "Bearer #{profile[:api_token]}"
|
10
|
-
req['Content-type'] = "application/json; charset=utf-8"
|
11
|
-
end
|
5
|
+
module SlackMessage::Api
|
6
|
+
extend self
|
12
7
|
|
13
|
-
|
14
|
-
|
8
|
+
def user_id_for(email, profile)
|
9
|
+
unless email =~ SlackMessage::EMAIL_PATTERN
|
10
|
+
raise ArgumentError, "Tried to find profile by invalid email address '#{email}'"
|
15
11
|
end
|
16
12
|
|
13
|
+
response = look_up_user_by_email(email, profile)
|
14
|
+
|
17
15
|
if response.code != "200"
|
18
16
|
raise SlackMessage::ApiError, "Got an error back from the Slack API (HTTP #{response.code}):\n#{response.body}"
|
19
17
|
elsif response.body == ""
|
@@ -37,7 +35,7 @@ class SlackMessage::Api
|
|
37
35
|
payload["user"]["id"]
|
38
36
|
end
|
39
37
|
|
40
|
-
def
|
38
|
+
def post(payload, target, profile)
|
41
39
|
params = {
|
42
40
|
channel: target,
|
43
41
|
username: payload.custom_bot_name || profile[:name],
|
@@ -80,8 +78,23 @@ class SlackMessage::Api
|
|
80
78
|
response
|
81
79
|
end
|
82
80
|
|
83
|
-
|
84
|
-
|
81
|
+
private
|
82
|
+
|
83
|
+
# mostly for test harnesses
|
84
|
+
|
85
|
+
def look_up_user_by_email(email, profile)
|
86
|
+
uri = URI("https://slack.com/api/users.lookupByEmail?email=#{email}")
|
87
|
+
request = Net::HTTP::Get.new(uri).tap do |req|
|
88
|
+
req['Authorization'] = "Bearer #{profile[:api_token]}"
|
89
|
+
req['Content-type'] = "application/json; charset=utf-8"
|
90
|
+
end
|
91
|
+
|
92
|
+
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
93
|
+
http.request(request)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def post_message(profile, params)
|
85
98
|
uri = URI("https://slack.com/api/chat.postMessage")
|
86
99
|
request = Net::HTTP::Post.new(uri).tap do |req|
|
87
100
|
req['Authorization'] = "Bearer #{profile[:api_token]}"
|
@@ -93,6 +106,4 @@ class SlackMessage::Api
|
|
93
106
|
http.request(request)
|
94
107
|
end
|
95
108
|
end
|
96
|
-
|
97
|
-
private_class_method :post_message
|
98
109
|
end
|
data/lib/slack_message/dsl.rb
CHANGED
@@ -2,7 +2,7 @@ class SlackMessage::Dsl
|
|
2
2
|
attr_reader :body, :default_section, :custom_bot_name, :custom_bot_icon, :profile
|
3
3
|
attr_accessor :custom_notification
|
4
4
|
|
5
|
-
EMSPACE = " " # unicode emspace
|
5
|
+
EMSPACE = " " # unicode emspace, Slack won't compress this
|
6
6
|
|
7
7
|
def initialize(block, profile)
|
8
8
|
# Delegate missing methods to caller scope. Thanks 2008:
|
@@ -108,11 +108,9 @@ class SlackMessage::Dsl
|
|
108
108
|
@caller_self.send meth, *args, &blk
|
109
109
|
end
|
110
110
|
|
111
|
-
EMAIL_TAG_PATTERN = /<[^@ \t\r\n\<]+@[^@ \t\r\n]+\.[^@ \t\r\n]+>/
|
112
|
-
|
113
111
|
# replace emails w/ real user IDs
|
114
112
|
def enrich_text(text_body)
|
115
|
-
text_body.scan(EMAIL_TAG_PATTERN).each do |email_tag|
|
113
|
+
text_body.scan(SlackMessage::EMAIL_TAG_PATTERN).each do |email_tag|
|
116
114
|
raw_email = email_tag.gsub(/[><]/, '')
|
117
115
|
user_id = SlackMessage::Api::user_id_for(raw_email, profile)
|
118
116
|
|
data/lib/slack_message/rspec.rb
CHANGED
@@ -30,7 +30,7 @@ module SlackMessage::RSpec
|
|
30
30
|
FauxResponse = Struct.new(:code, :body)
|
31
31
|
|
32
32
|
def self.included(_)
|
33
|
-
SlackMessage::Api.
|
33
|
+
SlackMessage::Api.undef_method(:post_message)
|
34
34
|
SlackMessage::Api.define_singleton_method(:post_message) do |profile, params|
|
35
35
|
@@listeners.each do |listener|
|
36
36
|
listener.record_call(params.merge(profile: profile))
|
@@ -53,6 +53,12 @@ module SlackMessage::RSpec
|
|
53
53
|
|
54
54
|
return FauxResponse.new('200', response.to_json)
|
55
55
|
end
|
56
|
+
|
57
|
+
SlackMessage::Api.undef_method(:look_up_user_by_email)
|
58
|
+
SlackMessage::Api.define_singleton_method(:look_up_user_by_email) do |email, profile|
|
59
|
+
response = {"ok"=>true, "user"=>{"id"=>"U5432CBA"}}
|
60
|
+
return FauxResponse.new('200', response.to_json)
|
61
|
+
end
|
56
62
|
end
|
57
63
|
|
58
64
|
# w/ channel
|
data/lib/slack_message.rb
CHANGED
@@ -3,6 +3,9 @@ module SlackMessage
|
|
3
3
|
require 'slack_message/api'
|
4
4
|
require 'slack_message/configuration'
|
5
5
|
|
6
|
+
EMAIL_TAG_PATTERN = /<[^@ \t\r\n\<]+@[^@ \t\r\n]+\.[^@ \t\r\n]+>/
|
7
|
+
EMAIL_PATTERN = /^\S{1,}@\S{2,}\.\S{2,}$/
|
8
|
+
|
6
9
|
class ApiError < RuntimeError; end
|
7
10
|
|
8
11
|
def self.configuration
|
@@ -25,7 +28,7 @@ module SlackMessage
|
|
25
28
|
instance.instance_eval(&block)
|
26
29
|
end
|
27
30
|
|
28
|
-
target = Api::user_id_for(target, profile) if target =~
|
31
|
+
target = Api::user_id_for(target, profile) if target =~ EMAIL_PATTERN
|
29
32
|
|
30
33
|
Api.post(payload, target, profile)
|
31
34
|
end
|
@@ -41,7 +44,7 @@ module SlackMessage
|
|
41
44
|
end
|
42
45
|
|
43
46
|
target = profile[:default_channel]
|
44
|
-
target = Api::user_id_for(target, profile) if target =~
|
47
|
+
target = Api::user_id_for(target, profile) if target =~ EMAIL_PATTERN
|
45
48
|
|
46
49
|
Api.post(payload, target, profile)
|
47
50
|
end
|
data/slack_message.gemspec
CHANGED
data/spec/slack_message_spec.rb
CHANGED
@@ -132,15 +132,6 @@ RSpec.describe SlackMessage do
|
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
|
-
it "can grab user IDs" do
|
136
|
-
allow(Net::HTTP).to receive(:start).and_return(
|
137
|
-
double(code: "200", body: '{ "user": { "id": "ABC123" }}')
|
138
|
-
)
|
139
|
-
|
140
|
-
result = SlackMessage::Api.user_id_for("hello@joemastey.com", profile)
|
141
|
-
expect(result).to eq("ABC123")
|
142
|
-
end
|
143
|
-
|
144
135
|
it "converts user IDs within text when tagged properly" do
|
145
136
|
allow(SlackMessage::Api).to receive(:user_id_for).and_return('ABC123')
|
146
137
|
|