slack_message 2.2.0 → 2.2.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 +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
|
|