slack_message 2.2.1 → 2.4.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/.github/workflows/main.yml +27 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +17 -0
- data/README.md +22 -302
- data/lib/slack_message/api.rb +20 -2
- data/lib/slack_message/configuration.rb +11 -1
- data/lib/slack_message/dsl.rb +7 -5
- data/lib/slack_message/rspec.rb +5 -5
- data/lib/slack_message.rb +4 -4
- data/slack_message.gemspec +3 -1
- data/spec/slack_message_spec.rb +8 -2
- metadata +4 -4
- data/Gemfile.lock +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b97efc9f2b80be4ee01c89d4c82aab83bb79983077ec8bfa87f0026ea5387f37
|
4
|
+
data.tar.gz: ae251f82220f9c15e45d3065f4e8cd84f5ad913c630a48d6cf9713df33b41b34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2e5a3f499fe2e73f245ff2163284f73825f3d051c4cc06aee03c39184eb01e22d6ce5d426f1dde77a0f89e6eacd1764b3a49b1f0548a368490588a7dc0bd757
|
7
|
+
data.tar.gz: d2417ed29a6b0e3b88133e9e679a965104d2b9030945d7241af106b54dabc471190d73902f4a4bceae02a469f24eeeeb6e95d91f1b8c9817dc0f69ee41a6524d
|
@@ -0,0 +1,27 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
strategy:
|
12
|
+
matrix:
|
13
|
+
os: [ubuntu-latest, macos-latest]
|
14
|
+
ruby-version: [3.0, 2.7, 2.6, 2.5]
|
15
|
+
runs-on: ${{ matrix.os }}
|
16
|
+
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v2
|
19
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
20
|
+
uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby-version }}
|
23
|
+
bundler-cache: true
|
24
|
+
- name: Install dependencies
|
25
|
+
run: bundle install
|
26
|
+
- name: Run tests
|
27
|
+
run: bundle exec rspec
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [2.4.0] - 2021-12-13
|
4
|
+
- Add ability to schedule messages, plus some guard rails around that.
|
5
|
+
- Add ability to debug by logging out the total set of params sent to the API.
|
6
|
+
|
7
|
+
## [2.3.1] - 2021-11-30
|
8
|
+
- Adjust that minimum version by changing some syntax to older styles. Given
|
9
|
+
support for ruby 2.4 ended almost 2 years ago, going to go ahead and leave
|
10
|
+
it behind.
|
11
|
+
- Remove lockfile from repo
|
12
|
+
|
13
|
+
## [2.3.0] - 2021-11-30
|
14
|
+
- Formally require minimum version of ruby. It wouldn't have worked anyway,
|
15
|
+
but worth actually specifying.
|
16
|
+
|
17
|
+
## [2.2.2] - 2021-11-30
|
18
|
+
- Add github workflow for automatic CI runs. Stolen from another project.
|
19
|
+
|
3
20
|
## [2.2.1] - 2021-11-20
|
4
21
|
- Trying to fetch user ID for a string that isn't email-like raises an error.
|
5
22
|
- In tests, fetching user IDs is mocked out to prevent network requests.
|
data/README.md
CHANGED
@@ -13,172 +13,7 @@ SlackMessage.post_to('#general') do
|
|
13
13
|
end
|
14
14
|
```
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
#### Opinionated Stances
|
19
|
-
|
20
|
-
Slack's API has a lot of options available to you! But this gem takes some
|
21
|
-
opinionated stances about usage to try to minimize the pain of integrating
|
22
|
-
with it. For example:
|
23
|
-
|
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.
|
27
|
-
* Webhooks are passé. Only Slack Apps are supported now.
|
28
|
-
* Unless you request otherwise, text is always rendered using `mrkdwn`. If you
|
29
|
-
want plaintext, you'll need to ask for it. Same for the `emoji` flag.
|
30
|
-
* As many API semantics as possible are hidden. For instance, if you post to
|
31
|
-
something that looks like an email address, `slack_message` is going to try
|
32
|
-
to look it up as an email address.
|
33
|
-
* A few little hacks on the block syntax, such as adding a `blank_line` (which
|
34
|
-
doesn't exist in the API), or leading spaces.
|
35
|
-
* Configuration is kept as simple as possible. But, as much heavy lifting as
|
36
|
-
possible should occur just once via configuration and not on every call.
|
37
|
-
|
38
|
-
Usage
|
39
|
-
------------
|
40
|
-
|
41
|
-
### Configuration
|
42
|
-
|
43
|
-
To get started, you'll need to create a Slack App with some appropriate
|
44
|
-
permissions. It used to be possible to use the Webhook API, but that's long
|
45
|
-
since been deprecated, and apps are pretty [straightforward to
|
46
|
-
create](https://api.slack.com/tutorials/tracks/getting-a-token).
|
47
|
-
|
48
|
-
Generally, make sure your token has permissions for `users:read` and `chat:write`.
|
49
|
-
|
50
|
-
```ruby
|
51
|
-
SlackMessage.configure do |config|
|
52
|
-
api_token = 'xoxb-11111111111-2222222222-33333333333333333'
|
53
|
-
|
54
|
-
config.add_profile(api_token: api_token)
|
55
|
-
end
|
56
|
-
```
|
57
|
-
|
58
|
-
You should keep your token in a safe place like `ENV`. If using this gem with
|
59
|
-
Rails, place this code in somewhere like `config/initializers/slack_message.rb`.
|
60
|
-
|
61
|
-
#### Additional Profiles
|
62
|
-
|
63
|
-
If your app uses slack messages for several different purposes, it's common to
|
64
|
-
want to post to different channels as different names / icons / etc. To do that
|
65
|
-
more easily and consistently, you can specify multiple profiles:
|
66
|
-
|
67
|
-
```ruby
|
68
|
-
SlackMessage.configure do |config|
|
69
|
-
api_token = 'xoxb-11111111111-2222222222-33333333333333333'
|
70
|
-
|
71
|
-
# default profile
|
72
|
-
config.add_profile(api_token: api_token, name: 'Slack Notifier')
|
73
|
-
|
74
|
-
# additional profiles (see below for usage)
|
75
|
-
config.add_profile(:prod_alert_bot,
|
76
|
-
name: 'Prod Alert Bot'
|
77
|
-
icon: ':mooseandsquirrel:'
|
78
|
-
)
|
79
|
-
config.add_profile(:sidekiq_bot,
|
80
|
-
api_token: ENV.fetch('SIDEKIQ_SLACK_APP_API_TOKEN'),
|
81
|
-
name: 'Sidekiq Bot',
|
82
|
-
)
|
83
|
-
end
|
84
|
-
```
|
85
|
-
|
86
|
-
A number of parameters are available to make it simpler to use a profile without
|
87
|
-
specifying repetitive information. Most all have corresponding options when
|
88
|
-
composing a message:
|
89
|
-
|
90
|
-
| Config | Default | Value |
|
91
|
-
|-----------------|-----------------|-----------------------------------------------------------------|
|
92
|
-
| api_token | None | Your Slack App API Key. |
|
93
|
-
| name | From Slack App | The bot name for your message. |
|
94
|
-
| icon | From Slack App | Profile icon for your message. Specify as :emoji: or image URL. |
|
95
|
-
| default_channel | None (optional) | Channel / user to post to by default. |
|
96
|
-
|
97
|
-
|
98
|
-
Setting a `default_channel` specifically will allow you to use `post_as`, which
|
99
|
-
is a convenient shortcut for bots that repeatedly post to one channel as a
|
100
|
-
consistent identity:
|
101
|
-
|
102
|
-
```ruby
|
103
|
-
SlackMessage.configure do |config|
|
104
|
-
config.add_profile(:red_alert_bot,
|
105
|
-
api_token: ENV.fetch('SLACK_API_TOKEN'),
|
106
|
-
name: 'Red Alerts',
|
107
|
-
icon: ':klaxon:',
|
108
|
-
default_channel: '#red_alerts'
|
109
|
-
)
|
110
|
-
end
|
111
|
-
|
112
|
-
SlackMessage.post_as(:red_alert_bot) do
|
113
|
-
text ":ambulance: weeooo weeooo something went wrong"
|
114
|
-
end
|
115
|
-
```
|
116
|
-
|
117
|
-
There's no reason you can't use the same API key for several profiles. Profiles
|
118
|
-
are most useful to create consistent name / icon setups for apps with many bots.
|
119
|
-
|
120
|
-
### Posting Messages
|
121
|
-
|
122
|
-
As mentioned at the top, posting a message to Slack is dang easy:
|
123
|
-
|
124
|
-
```ruby
|
125
|
-
SlackMessage.post_to('#general') do
|
126
|
-
text "We did it @here! :thumbsup:"
|
127
|
-
end
|
128
|
-
```
|
129
|
-
|
130
|
-
That's it! SlackMessage will automatically serialize for the API like this:
|
131
|
-
|
132
|
-
```json
|
133
|
-
[{"type":"section","text":{"type":"mrkdwn","text":"We did it @here! :thumbsup:"}}]
|
134
|
-
```
|
135
|
-
|
136
|
-
Details like remembering that Slack made a mystifying decision to force you to
|
137
|
-
request "mrkdwn", or requiring your text to be wrapped into a section are handled
|
138
|
-
for you. Building up messages is meant to be as user-friendly as possible:
|
139
|
-
|
140
|
-
```ruby
|
141
|
-
SlackMessage.build do
|
142
|
-
text "haiku are easy"
|
143
|
-
text "but sometimes they don't make sense"
|
144
|
-
text "refrigerator"
|
145
|
-
|
146
|
-
context "- unknown author"
|
147
|
-
end
|
148
|
-
```
|
149
|
-
|
150
|
-
SlackMessage will combine your text declarations and add any necessary wrappers
|
151
|
-
automatically:
|
152
|
-
|
153
|
-
```json
|
154
|
-
[
|
155
|
-
{
|
156
|
-
"type": "section",
|
157
|
-
"text": {
|
158
|
-
"type": "mrkdwn",
|
159
|
-
"text": "haiku are easy\nbut sometimes they don't make sense\nrefrigerator"
|
160
|
-
}
|
161
|
-
},
|
162
|
-
{
|
163
|
-
"type": "context",
|
164
|
-
"elements": [
|
165
|
-
{
|
166
|
-
"type": "mrkdwn",
|
167
|
-
"text": "- unknown author"
|
168
|
-
}
|
169
|
-
]
|
170
|
-
}
|
171
|
-
]
|
172
|
-
```
|
173
|
-
|
174
|
-
It's just as easy to send messages directly to users. SlackMessage will look for
|
175
|
-
targets that are email-addressish, and look them up for you automatically:
|
176
|
-
|
177
|
-
```ruby
|
178
|
-
SlackMessage.post_to('hello@joemastey.com') do
|
179
|
-
text "You specifically did it! :thumbsup:"
|
180
|
-
end
|
181
|
-
```
|
16
|
+
#### Posting
|
182
17
|
|
183
18
|
SlackMessage is able to build all kinds of rich messages for you, and has been
|
184
19
|
a real joy to use for the author at least. To understand a bit more about the
|
@@ -213,155 +48,40 @@ SlackMessage.post_to('#general') do
|
|
213
48
|
end
|
214
49
|
```
|
215
50
|
|
216
|
-
|
217
|
-
|
218
|
-
If you've defined multiple profiles in configuration, you can specify which to
|
219
|
-
use for your message by specifying its name:
|
220
|
-
|
221
|
-
```ruby
|
222
|
-
SlackMessage.post_to('#general', as: :sidekiq_bot) do
|
223
|
-
text ":octagonal_sign: A job has failed permanently and needs to be rescued."
|
224
|
-
|
225
|
-
link_button "Sidekiq Dashboard", sidekiq_dashboard_url, style: :danger
|
226
|
-
end
|
227
|
-
```
|
228
|
-
|
229
|
-
You can also override profile bot details when sending a message:
|
230
|
-
|
231
|
-
```ruby
|
232
|
-
SlackMessage.post_to('#general') do
|
233
|
-
bot_name "CoffeeBot"
|
234
|
-
bot_icon ":coffee:"
|
235
|
-
|
236
|
-
text ":coffee::clock: Time to take a break!"
|
237
|
-
end
|
238
|
-
```
|
239
|
-
|
240
|
-
#### Notifying Users
|
241
|
-
|
242
|
-
There are several supported ways to tag and notify users. Mentioned above, it's
|
243
|
-
possible to DM a user by email:
|
244
|
-
|
245
|
-
```ruby
|
246
|
-
SlackMessage.post_to('hello@joemastey.com') do
|
247
|
-
text "Hi there!"
|
248
|
-
end
|
249
|
-
```
|
250
|
-
|
251
|
-
You can also mention a user by email within a channel by wrapping their name
|
252
|
-
in tags:
|
253
|
-
|
254
|
-
```ruby
|
255
|
-
SlackMessage.post_to('#general') do
|
256
|
-
bot_name "CoffeeBot"
|
257
|
-
bot_icon ":coffee:"
|
258
|
-
|
259
|
-
text ":coffee: It's your turn to make coffee <hello@joemastey.com>."
|
260
|
-
end
|
261
|
-
```
|
262
|
-
|
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:
|
266
|
-
|
267
|
-
```ruby
|
268
|
-
SlackMessage.post_to('#general') do
|
269
|
-
bot_name "CoffeeBot"
|
270
|
-
bot_icon ":coffee:"
|
271
|
-
|
272
|
-
text "@here There's no coffee left! Let #general know when you fix it."
|
273
|
-
end
|
274
|
-
```
|
275
|
-
|
276
|
-
By default, the desktop notification for a message will be the text of the
|
277
|
-
message itself. However, you can customize desktop notifications if you prefer:
|
278
|
-
|
279
|
-
```ruby
|
280
|
-
SlackMessage.post_to('hello@joemastey.com') do
|
281
|
-
bot_name "CoffeeBot"
|
282
|
-
bot_icon ":coffee:"
|
283
|
-
|
284
|
-
notification_text "It's a coffee emergency!"
|
285
|
-
text "There's no coffee left!"
|
286
|
-
end
|
287
|
-
```
|
288
|
-
|
289
|
-
### Testing
|
290
|
-
|
291
|
-
You can do some basic testing against SlackMessage, at least if you use RSpec!
|
292
|
-
You'll need to require and include the testing behavior like this, in your
|
293
|
-
spec_helper file:
|
294
|
-
|
295
|
-
```ruby
|
296
|
-
require 'slack_message/rspec'
|
297
|
-
|
298
|
-
RSpec.configure do |config|
|
299
|
-
include SlackMessage::RSpec
|
300
|
-
|
301
|
-
# your other config
|
302
|
-
end
|
303
|
-
```
|
304
|
-
|
305
|
-
This will prevent API calls from leaking in your tests, and will allow you
|
306
|
-
access to some custom matchers:
|
307
|
-
|
308
|
-
```ruby
|
309
|
-
expect {
|
310
|
-
SlackMessage.post_to('#general') { text "foo" }
|
311
|
-
}.to post_slack_message_to('#general').with_content_matching(/foo/)
|
312
|
-
|
313
|
-
expect {
|
314
|
-
SlackMessage.post_as(:schmoebot) { text "foo" }
|
315
|
-
}.to post_slack_message_as(:schmoebot)
|
316
|
-
|
317
|
-
expect {
|
318
|
-
SlackMessage.post_as(:schmoebot) { text "foo" }
|
319
|
-
}.to post_slack_message_as('Schmoe Bot')
|
320
|
-
|
321
|
-
expect {
|
322
|
-
SlackMessage.post_as(:schmoebot) { text "foo" }
|
323
|
-
}.to post_slack_message_with_icon(':schmoebot:')
|
324
|
-
|
325
|
-
expect {
|
326
|
-
SlackMessage.post_as(:schmoebot) { text "foo" }
|
327
|
-
}.to post_slack_message_with_icon_matching(/gravatar/)
|
328
|
-
|
329
|
-
expect {
|
330
|
-
SlackMessage.post_to('#general') { text "foo" }
|
331
|
-
}.to post_to_slack
|
332
|
-
```
|
333
|
-
|
334
|
-
Be forewarned, I'm frankly not that great at more complicated RSpec matchers,
|
335
|
-
so I'm guessing there are some bugs. Also, because the content of a message
|
336
|
-
gets turned into a complex JSON object, matching against content isn't capable
|
337
|
-
of very complicated regexes.
|
338
|
-
|
339
|
-
What it Doesn't Do
|
340
|
-
------------
|
51
|
+
#### Opinionated Stances
|
341
52
|
|
342
53
|
This gem is intended to stay simple. Other Slack gems have lots of config
|
343
54
|
options and abilities, which makes them powerful, but makes them a pain to use.
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
55
|
+
|
56
|
+
Accordingly, SlackMessage is developed with some strong opinions in mind:
|
57
|
+
|
58
|
+
* SlackMessage has no dependencies. Your lockfile is enough of a mess already.
|
59
|
+
* The code to build a message should look a lot like the message itself. Code
|
60
|
+
that is simple to read and understand is a priority.
|
61
|
+
* Webhooks are passé. Only Slack Apps are supported now.
|
62
|
+
* Unless you request otherwise, text is always rendered using `mrkdwn`. If you
|
63
|
+
want plaintext, you'll need to ask for it. Same for the `emoji` flag.
|
64
|
+
* As many API semantics as possible are hidden. For instance, if you post to
|
65
|
+
something that looks like an email address, `slack_message` is going to try
|
66
|
+
to look it up as an email address.
|
67
|
+
* A few little hacks on the block syntax, such as adding a `blank_line` (which
|
68
|
+
doesn't exist in the API), or leading spaces.
|
69
|
+
* Configuration is kept as simple as possible. But, as much heavy lifting as
|
70
|
+
possible should occur just once via configuration and not on every call.
|
348
71
|
|
349
72
|
Some behaviors that are still planned but not yet added:
|
350
73
|
|
351
|
-
*
|
352
|
-
*
|
353
|
-
* more of BlockKit's options
|
354
|
-
* any interactive elements at all
|
355
|
-
* editing / updating messages
|
356
|
-
* multiple recipients
|
74
|
+
* any interactive elements at all: https://api.slack.com/interactivity/handling
|
75
|
+
* multiple recipients: https://api.slack.com/methods/conversations.open
|
357
76
|
* more interesting return types for your message
|
358
77
|
* richer text formatting (for instance, `ul` is currently a hack)
|
359
78
|
* more and better organized testing capability
|
79
|
+
* posting ephemeral messages: https://api.slack.com/methods/chat.postEphemeral
|
360
80
|
|
361
81
|
Contributing
|
362
82
|
------------
|
363
83
|
|
364
|
-
Contributions are very welcome. Fork, fix, submit pull.
|
84
|
+
Contributions are very welcome. Fork, fix, submit pull. Since simplicity of API is a strong priority, so opening an issue to discuss possible interface changes would be wise.
|
365
85
|
|
366
86
|
Contribution is expected to conform to the [Contributor Covenant](https://github.com/jmmastey/slack_message/blob/master/CODE_OF_CONDUCT.md).
|
367
87
|
|
data/lib/slack_message/api.rb
CHANGED
@@ -35,7 +35,7 @@ module SlackMessage::Api
|
|
35
35
|
payload["user"]["id"]
|
36
36
|
end
|
37
37
|
|
38
|
-
def post(payload, target, profile)
|
38
|
+
def post(payload, target, profile, time)
|
39
39
|
params = {
|
40
40
|
channel: target,
|
41
41
|
username: payload.custom_bot_name || profile[:name],
|
@@ -56,6 +56,18 @@ module SlackMessage::Api
|
|
56
56
|
raise ArgumentError, "Couldn't figure out icon '#{icon}'. Try :emoji: or a URL."
|
57
57
|
end
|
58
58
|
|
59
|
+
if !time.nil?
|
60
|
+
params[:post_at] = time.to_i
|
61
|
+
|
62
|
+
if params[:icon_url] || params[:icon_emoji]
|
63
|
+
raise ArgumentError, "Sorry, setting an image / emoji icon for scheduled messages isn't supported."
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
if SlackMessage::Configuration.debugging?
|
68
|
+
warn params.inspect
|
69
|
+
end
|
70
|
+
|
59
71
|
response = post_message(profile, params)
|
60
72
|
body = JSON.parse(response.body)
|
61
73
|
error = body.fetch("error", "")
|
@@ -84,6 +96,7 @@ module SlackMessage::Api
|
|
84
96
|
|
85
97
|
def look_up_user_by_email(email, profile)
|
86
98
|
uri = URI("https://slack.com/api/users.lookupByEmail?email=#{email}")
|
99
|
+
|
87
100
|
request = Net::HTTP::Get.new(uri).tap do |req|
|
88
101
|
req['Authorization'] = "Bearer #{profile[:api_token]}"
|
89
102
|
req['Content-type'] = "application/json; charset=utf-8"
|
@@ -95,7 +108,12 @@ module SlackMessage::Api
|
|
95
108
|
end
|
96
109
|
|
97
110
|
def post_message(profile, params)
|
98
|
-
uri =
|
111
|
+
uri = if params[:post_at]
|
112
|
+
URI("https://slack.com/api/chat.scheduleMessage")
|
113
|
+
else
|
114
|
+
URI("https://slack.com/api/chat.postMessage")
|
115
|
+
end
|
116
|
+
|
99
117
|
request = Net::HTTP::Post.new(uri).tap do |req|
|
100
118
|
req['Authorization'] = "Bearer #{profile[:api_token]}"
|
101
119
|
req['Content-type'] = "application/json; charset=utf-8"
|
@@ -1,8 +1,10 @@
|
|
1
1
|
module SlackMessage::Configuration
|
2
2
|
@@profiles = {}
|
3
|
+
@@debug = false
|
3
4
|
|
4
5
|
def self.reset
|
5
|
-
@@profiles
|
6
|
+
@@profiles = {}
|
7
|
+
@@debug = false
|
6
8
|
end
|
7
9
|
|
8
10
|
def self.configure
|
@@ -36,4 +38,12 @@ module SlackMessage::Configuration
|
|
36
38
|
|
37
39
|
@@profiles[handle]
|
38
40
|
end
|
41
|
+
|
42
|
+
def self.debug
|
43
|
+
@@debug = true
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.debugging?
|
47
|
+
@@debug
|
48
|
+
end
|
39
49
|
end
|
data/lib/slack_message/dsl.rb
CHANGED
@@ -111,12 +111,14 @@ class SlackMessage::Dsl
|
|
111
111
|
# replace emails w/ real user IDs
|
112
112
|
def enrich_text(text_body)
|
113
113
|
text_body.scan(SlackMessage::EMAIL_TAG_PATTERN).each do |email_tag|
|
114
|
-
|
115
|
-
|
114
|
+
begin
|
115
|
+
raw_email = email_tag.gsub(/[><]/, '')
|
116
|
+
user_id = SlackMessage::Api::user_id_for(raw_email, profile)
|
116
117
|
|
117
|
-
|
118
|
-
|
119
|
-
|
118
|
+
text_body.gsub!(email_tag, "<@#{user_id}>") if user_id
|
119
|
+
rescue SlackMessage::ApiError => e
|
120
|
+
# swallow errors for not-found users
|
121
|
+
end
|
120
122
|
end
|
121
123
|
|
122
124
|
text_body
|
data/lib/slack_message/rspec.rb
CHANGED
@@ -206,11 +206,11 @@ module SlackMessage::RSpec
|
|
206
206
|
SlackMessage::RSpec.unregister_expectation_listener(self)
|
207
207
|
|
208
208
|
@captured_calls
|
209
|
-
.
|
210
|
-
.
|
211
|
-
.
|
212
|
-
.
|
213
|
-
.
|
209
|
+
.select { |call| !@channel || call[:channel] == @channel }
|
210
|
+
.select { |call| !@profile || [call[:profile][:handle], call[:username]].include?(@profile) }
|
211
|
+
.select { |call| !@content || call.fetch(:blocks).to_s =~ @content }
|
212
|
+
.select { |call| !@icon || call.fetch(:icon_emoji, call.fetch(:icon_url, '')) == @icon }
|
213
|
+
.select { |call| !@icon_matching || call.fetch(:icon_emoji, call.fetch(:icon_url, '')) =~ @icon_matching }
|
214
214
|
.any?
|
215
215
|
end
|
216
216
|
|
data/lib/slack_message.rb
CHANGED
@@ -21,7 +21,7 @@ module SlackMessage
|
|
21
21
|
Api.user_id_for(email, profile)
|
22
22
|
end
|
23
23
|
|
24
|
-
def self.post_to(target, as: :default, &block)
|
24
|
+
def self.post_to(target, as: :default, at: nil, &block)
|
25
25
|
profile = Configuration.profile(as)
|
26
26
|
|
27
27
|
payload = Dsl.new(block, profile).tap do |instance|
|
@@ -30,10 +30,10 @@ module SlackMessage
|
|
30
30
|
|
31
31
|
target = Api::user_id_for(target, profile) if target =~ EMAIL_PATTERN
|
32
32
|
|
33
|
-
Api.post(payload, target, profile)
|
33
|
+
Api.post(payload, target, profile, at)
|
34
34
|
end
|
35
35
|
|
36
|
-
def self.post_as(profile_name, &block)
|
36
|
+
def self.post_as(profile_name, at: nil, &block)
|
37
37
|
profile = Configuration.profile(profile_name)
|
38
38
|
if profile[:default_channel].nil?
|
39
39
|
raise ArgumentError, "Sorry, you need to specify a default_channel for profile #{profile_name} to use post_as"
|
@@ -46,7 +46,7 @@ module SlackMessage
|
|
46
46
|
target = profile[:default_channel]
|
47
47
|
target = Api::user_id_for(target, profile) if target =~ EMAIL_PATTERN
|
48
48
|
|
49
|
-
Api.post(payload, target, profile)
|
49
|
+
Api.post(payload, target, profile, at)
|
50
50
|
end
|
51
51
|
|
52
52
|
def self.build(profile_name = :default, &block)
|
data/slack_message.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |gem|
|
2
2
|
gem.name = 'slack_message'
|
3
|
-
gem.version = "2.
|
3
|
+
gem.version = "2.4.0"
|
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'
|
@@ -18,6 +18,8 @@ Gem::Specification.new do |gem|
|
|
18
18
|
"source_code_uri" => "http://github.com/jmmastey/slack_message",
|
19
19
|
}
|
20
20
|
|
21
|
+
gem.required_ruby_version = '>= 2.5.0'
|
22
|
+
|
21
23
|
gem.add_development_dependency "rspec", "3.10.0"
|
22
24
|
gem.add_development_dependency "pry", "0.14.1"
|
23
25
|
gem.add_development_dependency "rb-readline", "0.5.5"
|
data/spec/slack_message_spec.rb
CHANGED
@@ -142,13 +142,19 @@ RSpec.describe SlackMessage do
|
|
142
142
|
expect {
|
143
143
|
SlackMessage.post_to('#general') { text("Not Tagged: hello@joemastey.com ") }
|
144
144
|
}.to post_to_slack.with_content_matching(/hello@joemastey.com/)
|
145
|
+
end
|
145
146
|
|
146
|
-
|
147
|
-
allow(SlackMessage::Api).to receive(:user_id_for).and_raise(SlackMessage::ApiError)
|
147
|
+
it "is graceful about those failures" do
|
148
|
+
allow(SlackMessage::Api).to receive(:user_id_for).with('nuffin@nuffin.nuffin', any_args).and_raise(SlackMessage::ApiError)
|
149
|
+
allow(SlackMessage::Api).to receive(:user_id_for).with('hello@joemastey.com', any_args).and_return('ABC123')
|
148
150
|
|
149
151
|
expect {
|
150
152
|
SlackMessage.post_to('#general') { text("Not User: <nuffin@nuffin.nuffin>") }
|
151
153
|
}.to post_to_slack.with_content_matching(/\<nuffin@nuffin.nuffin\>/)
|
154
|
+
|
155
|
+
expect {
|
156
|
+
SlackMessage.post_to('#general') { text("Not User: <nuffin@nuffin.nuffin>, User: <hello@joemastey.com>") }
|
157
|
+
}.to post_to_slack.with_content_matching(/ABC123/)
|
152
158
|
end
|
153
159
|
end
|
154
160
|
end
|
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: 2.
|
4
|
+
version: 2.4.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-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -58,12 +58,12 @@ executables: []
|
|
58
58
|
extensions: []
|
59
59
|
extra_rdoc_files: []
|
60
60
|
files:
|
61
|
+
- ".github/workflows/main.yml"
|
61
62
|
- ".gitignore"
|
62
63
|
- ".ruby-version"
|
63
64
|
- CHANGELOG.md
|
64
65
|
- CODE_OF_CONDUCT.md
|
65
66
|
- Gemfile
|
66
|
-
- Gemfile.lock
|
67
67
|
- MIT-LICENSE
|
68
68
|
- README.md
|
69
69
|
- lib/slack_message.rb
|
@@ -89,7 +89,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
89
89
|
requirements:
|
90
90
|
- - ">="
|
91
91
|
- !ruby/object:Gem::Version
|
92
|
-
version:
|
92
|
+
version: 2.5.0
|
93
93
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
95
|
- - ">="
|
data/Gemfile.lock
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
slack_message (2.2.0)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: https://rubygems.org/
|
8
|
-
specs:
|
9
|
-
coderay (1.1.3)
|
10
|
-
diff-lcs (1.4.4)
|
11
|
-
method_source (1.0.0)
|
12
|
-
pry (0.14.1)
|
13
|
-
coderay (~> 1.1)
|
14
|
-
method_source (~> 1.0)
|
15
|
-
rb-readline (0.5.5)
|
16
|
-
rspec (3.10.0)
|
17
|
-
rspec-core (~> 3.10.0)
|
18
|
-
rspec-expectations (~> 3.10.0)
|
19
|
-
rspec-mocks (~> 3.10.0)
|
20
|
-
rspec-core (3.10.1)
|
21
|
-
rspec-support (~> 3.10.0)
|
22
|
-
rspec-expectations (3.10.1)
|
23
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
24
|
-
rspec-support (~> 3.10.0)
|
25
|
-
rspec-mocks (3.10.2)
|
26
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
27
|
-
rspec-support (~> 3.10.0)
|
28
|
-
rspec-support (3.10.2)
|
29
|
-
|
30
|
-
PLATFORMS
|
31
|
-
ruby
|
32
|
-
|
33
|
-
DEPENDENCIES
|
34
|
-
pry (= 0.14.1)
|
35
|
-
rb-readline (= 0.5.5)
|
36
|
-
rspec (= 3.10.0)
|
37
|
-
slack_message!
|
38
|
-
|
39
|
-
BUNDLED WITH
|
40
|
-
2.1.4
|