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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 368533ab7e4dae44ffbef5ccf8afef048def96d964a6af64c294c23ba617dfa3
4
- data.tar.gz: f9397472bbc5c5db81dd1c9d7715e5015f4ec455948e7a29afbb11ef8c8a3d01
3
+ metadata.gz: '008fdfc2e46435b3bb49aae67e30b3ef354ca0c923c935c918088ee25eec7bda'
4
+ data.tar.gz: 2fe7d85c853361d12f02f58d19e4bef43ffc81d3683ef5f8b3776657eb86c5ae
5
5
  SHA512:
6
- metadata.gz: 5cce143a95d508694221f1c667428f850ce7aa537e73f61c1869498b68a5751afe2ac386215b96702a1a27bcad3758c474ba09870a1cd7a31a7c33a17ebd4d53
7
- data.tar.gz: 7f81e1876f231899588b174c87c4a0a3ca3bcbc4057216092311b300cff7d23d6541083b5e481e811795042538e2e6713b1a9f5eb5f6eba345e79960335cad91
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 on how to make use of that API. For instance:
21
+ opinionated stances about usage to try to minimize the pain of integrating
22
+ with it. For example:
23
23
 
24
- * No dependencies. Your lockfile is enough of a mess already.
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 to
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
- user_email = 'hello@joemastey.com'
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 clickable email
265
- addresses. Additionally, Slack will automatically convert a number of channel
266
- names and tags you're probably already used to:
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 there's no coffee left!"
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 stop API calls for posting messages, and will allow you access to
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 fairly simple. Other gems have lots of config
344
- options and abilities, which is wonderful, but overall complicates usage. If
345
- you want to add a feature, open an issue on Github first to see if it's likely
346
- to be merged. This gem was built out of an existing need that _didn't_ include
347
- most of the block API, but I'd be inclined to merge features that sustainably
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
  ------------
@@ -2,18 +2,16 @@ require 'net/http'
2
2
  require 'net/https'
3
3
  require 'json'
4
4
 
5
- class SlackMessage::Api
6
- def self.user_id_for(email, profile)
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
- response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
14
- http.request(request)
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 self.post(payload, target, profile)
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
- # mostly test harness
84
- def self.post_message(profile, params)
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
@@ -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
 
@@ -30,7 +30,7 @@ module SlackMessage::RSpec
30
30
  FauxResponse = Struct.new(:code, :body)
31
31
 
32
32
  def self.included(_)
33
- SlackMessage::Api.singleton_class.undef_method(:post_message)
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 =~ /^\S{1,}@\S{2,}\.\S{2,}$/
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 =~ /^\S{1,}@\S{2,}\.\S{2,}$/
47
+ target = Api::user_id_for(target, profile) if target =~ EMAIL_PATTERN
45
48
 
46
49
  Api.post(payload, target, profile)
47
50
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = 'slack_message'
3
- gem.version = "2.2.0"
3
+ gem.version = "2.2.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'
@@ -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
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slack_message
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Mastey