slack_message 2.4.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +7 -0
- data/docs/01_configuration.md +116 -0
- data/docs/02_posting_a_message.md +134 -0
- data/docs/03_message_dsl.md +283 -0
- data/docs/04_editing_messages.md +88 -0
- data/docs/05_deleting_messages.md +45 -0
- data/docs/06_notifying_users.md +62 -0
- data/docs/07_testing.md +49 -0
- data/docs/index.md +7 -0
- data/lib/slack_message/api.rb +81 -2
- data/lib/slack_message/response.rb +42 -0
- data/lib/slack_message/rspec.rb +2 -0
- data/lib/slack_message.rb +32 -1
- data/slack_message.gemspec +1 -1
- data/spec/slack_message_spec.rb +2 -0
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62f8b7feb3289a37b79cb887dc4e7846c037a8c72290138afe611682a066a884
|
4
|
+
data.tar.gz: 73e391d721ace67ad31ae69b7a17eae3578d4f85a2bcd111a5cb1966b68c85cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb28febfda107047351955825d1cd84dafdf553147b9f0101573944f3d5290c6d3e84a4d1190e63888f6c8ba851ac70da9eb774f1a01a04372d19520b7df8779
|
7
|
+
data.tar.gz: 3438883916204aec8a16a8dfa80b52506d4f640fc69161ad6e8efea1b5a136e97fc15f8b990c2529f3bbfb1f4380a989a0827cbe8f810af08a42bf3a2b6df382
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [3.0.0] - 2021-12-19
|
4
|
+
- Return a more structured object from successful message sends.
|
5
|
+
- Add the ability to edit or delete a message.
|
6
|
+
- Complete overhaul of docs because they were too large.
|
7
|
+
|
3
8
|
## [2.4.0] - 2021-12-13
|
4
9
|
- Add ability to schedule messages, plus some guard rails around that.
|
5
10
|
- Add ability to debug by logging out the total set of params sent to the API.
|
data/README.md
CHANGED
@@ -48,6 +48,11 @@ SlackMessage.post_to('#general') do
|
|
48
48
|
end
|
49
49
|
```
|
50
50
|
|
51
|
+
### The Docs
|
52
|
+
|
53
|
+
You'll find much more information about how to use SlackMessage by visiting
|
54
|
+
[the docs](https://jmmastey.github.io/slack_message).
|
55
|
+
|
51
56
|
#### Opinionated Stances
|
52
57
|
|
53
58
|
This gem is intended to stay simple. Other Slack gems have lots of config
|
@@ -75,8 +80,10 @@ Some behaviors that are still planned but not yet added:
|
|
75
80
|
* multiple recipients: https://api.slack.com/methods/conversations.open
|
76
81
|
* more interesting return types for your message
|
77
82
|
* richer text formatting (for instance, `ul` is currently a hack)
|
83
|
+
* more mrkdwn syntax, like quotes or code blocks
|
78
84
|
* more and better organized testing capability
|
79
85
|
* posting ephemeral messages: https://api.slack.com/methods/chat.postEphemeral
|
86
|
+
* some Rspec test harness for scheduled messages, editing, deleting (probably going to need a test overhaul)
|
80
87
|
|
81
88
|
Contributing
|
82
89
|
------------
|
@@ -0,0 +1,116 @@
|
|
1
|
+
## Getting Started / Configuration
|
2
|
+
|
3
|
+
To get started sending messages, you'll first need to create a Slack App with
|
4
|
+
some appropriate permissions. It used to be possible to use the Webhook API,
|
5
|
+
but that's long since been deprecated, and apps are pretty [straightforward to
|
6
|
+
create](https://api.slack.com/tutorials/tracks/getting-a-token).
|
7
|
+
|
8
|
+
Generally, make sure your token has permissions for _at least_ `users:read` and
|
9
|
+
`chat:write`. Then, define a default profile for SlackMessage to use for
|
10
|
+
posting.
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
SlackMessage.configure do |config|
|
14
|
+
api_token = 'xoxb-11111111111-2222222222-33333333333333333'
|
15
|
+
|
16
|
+
config.add_profile(api_token: api_token)
|
17
|
+
end
|
18
|
+
```
|
19
|
+
|
20
|
+
You should keep your token in a safe place like `ENV`. If using this gem with
|
21
|
+
Rails, place this code in somewhere like
|
22
|
+
`config/initializers/slack_message.rb`.
|
23
|
+
|
24
|
+
### Additional Profiles
|
25
|
+
|
26
|
+
If your app uses slack messages for several different purposes, it's common to
|
27
|
+
want to post to different channels as different names / icons / etc. To do that
|
28
|
+
more easily and consistently, you can specify multiple profiles.
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
SlackMessage.configure do |config|
|
32
|
+
api_token = 'xoxb-11111111111-2222222222-33333333333333333'
|
33
|
+
|
34
|
+
# default profile
|
35
|
+
config.add_profile(api_token: api_token, name: 'Slack Notifier')
|
36
|
+
|
37
|
+
# additional profiles (see below for usage)
|
38
|
+
config.add_profile(:prod_alert_bot,
|
39
|
+
name: 'Prod Alert Bot'
|
40
|
+
icon: ':mooseandsquirrel:'
|
41
|
+
)
|
42
|
+
config.add_profile(:sidekiq_bot,
|
43
|
+
api_token: ENV.fetch('SIDEKIQ_SLACK_APP_API_TOKEN'),
|
44
|
+
name: 'Sidekiq Bot',
|
45
|
+
)
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
A number of parameters are available to make it simpler to use a profile
|
50
|
+
without specifying repetitive information. You can generally also specify this
|
51
|
+
information on a per-message basis.
|
52
|
+
|
53
|
+
| Config | Default | Value |
|
54
|
+
|-----------------|-----------------|-----------------------------------------------------------------|
|
55
|
+
| api_token | None | Your Slack App API Key. |
|
56
|
+
| name | From Slack App | The bot name for your message. |
|
57
|
+
| icon | From Slack App | Profile icon for your message. Specify as :emoji: or image URL. |
|
58
|
+
| default_channel | None (optional) | Channel / user to post to by default. |
|
59
|
+
|
60
|
+
|
61
|
+
Setting a `default_channel` specifically will allow you to use `post_as`, which
|
62
|
+
is a convenient shortcut for bots that repeatedly post to one channel as a
|
63
|
+
consistent identity.
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
SlackMessage.configure do |config|
|
67
|
+
config.add_profile(:red_alert_bot,
|
68
|
+
api_token: ENV.fetch('SLACK_API_TOKEN'),
|
69
|
+
name: 'Red Alerts',
|
70
|
+
icon: ':klaxon:',
|
71
|
+
default_channel: '#red_alerts'
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
SlackMessage.post_as(:red_alert_bot) do
|
76
|
+
text ":ambulance: weeooo weeooo something went wrong"
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
There's no reason you can't use the same API key for several profiles. Profiles
|
81
|
+
are most useful to create consistent name / icon setups for apps with many
|
82
|
+
bots.
|
83
|
+
|
84
|
+
### Debug Mode
|
85
|
+
|
86
|
+
If you'd like to get more information about the messages you send, you can set
|
87
|
+
SlackMessage to debug mode.
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
SlackMessage.configure do |config|
|
91
|
+
config.debug
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
You will now see warnings detailing all params sent to the API.
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
{
|
99
|
+
:channel=>"#general",
|
100
|
+
:username=>"Builds",
|
101
|
+
:blocks=>[
|
102
|
+
{:type=>"section", :text=>{
|
103
|
+
:type=>"mrkdwn",
|
104
|
+
:text=>"Build Stability is Looking Ruff :dog:"
|
105
|
+
}}
|
106
|
+
],
|
107
|
+
:text=>"Build Issues",
|
108
|
+
:post_at=>1639421171,
|
109
|
+
}
|
110
|
+
```
|
111
|
+
|
112
|
+
Note this includes data that is not included in `SlackMessage.build`.
|
113
|
+
|
114
|
+
---
|
115
|
+
|
116
|
+
Next: [Posting a Message](https://jmmastey.github.io/slack_message/02_posting_a_message)
|
@@ -0,0 +1,134 @@
|
|
1
|
+
## Posting Messages
|
2
|
+
|
3
|
+
As mentioned at the outset, posting a message to Slack is dang easy.
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
SlackMessage.post_to('#general') do
|
7
|
+
text "We did it @here! :thumbsup:"
|
8
|
+
end
|
9
|
+
```
|
10
|
+
|
11
|
+
That's it! SlackMessage will automatically serialize for the API.
|
12
|
+
|
13
|
+
```json
|
14
|
+
[{"type":"section","text":{"type":"mrkdwn","text":"We did it @here! :thumbsup:"}}]
|
15
|
+
```
|
16
|
+
|
17
|
+
Details like remembering that Slack made a mystifying decision to force you to
|
18
|
+
request "mrkdwn", or requiring your text to be wrapped into a section are
|
19
|
+
handled for you. Building up messages is meant to be as user-friendly as
|
20
|
+
possible.
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
SlackMessage.build do
|
24
|
+
text "haiku are easy"
|
25
|
+
text "but sometimes they don't make sense"
|
26
|
+
text "refrigerator"
|
27
|
+
|
28
|
+
context "- unknown author"
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
SlackMessage will combine your text declarations and add any necessary wrappers
|
33
|
+
automatically.
|
34
|
+
|
35
|
+
```json
|
36
|
+
[
|
37
|
+
{
|
38
|
+
"type": "section",
|
39
|
+
"text": {
|
40
|
+
"type": "mrkdwn",
|
41
|
+
"text": "haiku are easy\nbut sometimes they don't make sense\nrefrigerator"
|
42
|
+
}
|
43
|
+
},
|
44
|
+
{
|
45
|
+
"type": "context",
|
46
|
+
"elements": [
|
47
|
+
{
|
48
|
+
"type": "mrkdwn",
|
49
|
+
"text": "- unknown author"
|
50
|
+
}
|
51
|
+
]
|
52
|
+
}
|
53
|
+
]
|
54
|
+
```
|
55
|
+
|
56
|
+
### Direct Messages
|
57
|
+
|
58
|
+
It's just as easy to send messages directly to users. SlackMessage will look
|
59
|
+
for targets that are email-addressish, and look them up for you automatically.
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
SlackMessage.post_to('hello@joemastey.com') do
|
63
|
+
text "You specifically did it! :thumbsup:"
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
SlackMessage will compose this into Block Kit syntax and send it on its way!
|
68
|
+
|
69
|
+
### Multiple Profiles
|
70
|
+
|
71
|
+
If you've defined multiple profiles in configuration, you can specify which to
|
72
|
+
use for your message by specifying its name.
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
SlackMessage.post_to('#general', as: :sidekiq_bot) do
|
76
|
+
text ":octagonal_sign: A job has failed permanently and needs to be rescued."
|
77
|
+
|
78
|
+
link_button "Sidekiq Dashboard", sidekiq_dashboard_url, style: :danger
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
You can also override profile bot details when sending a message.
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
SlackMessage.post_to('#general') do
|
86
|
+
bot_name "CoffeeBot"
|
87
|
+
bot_icon ":coffee:"
|
88
|
+
|
89
|
+
text ":coffee::clock: Time to take a break!"
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
Finally, if your profile specifies a `default_channel`, you can also post with
|
94
|
+
the `post_as` shorthand.
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
SlackMessage.post_as(:coffeebot) do
|
98
|
+
text ":coffee::clock: Time to take a break!"
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
### Scheduling a Message
|
103
|
+
|
104
|
+
To schedule a message, simply provide a `at` parameter to your post. Provide
|
105
|
+
either a time object that responds to `to_i`, or an integer that represents a
|
106
|
+
[unix timestamp](https://en.wikipedia.org/wiki/Unix_time) for the time at which
|
107
|
+
you want your message posted.
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
SlackMessage.post_to('hello@joemastey.com', at: 20.seconds.from_now) do
|
111
|
+
text "From the top of the key. :basketball:"
|
112
|
+
end
|
113
|
+
|
114
|
+
SlackMessage.post_as(:basketball_bot, at: 20.seconds.from_now) do
|
115
|
+
text "Boom shakalaka! :explosion:"
|
116
|
+
end
|
117
|
+
```
|
118
|
+
|
119
|
+
Please note that scheduled messages can't specify a `bot_name` or `bot_icon`,
|
120
|
+
nor can they be scheduled more than 120 days into the future.
|
121
|
+
|
122
|
+
### Best Practices
|
123
|
+
|
124
|
+
Talk about having coherent methods that post a message, rather than a block
|
125
|
+
that includes lots of indirection or ternaries.
|
126
|
+
|
127
|
+
See the [API documentation for
|
128
|
+
chat.postMessage](https://api.slack.com/methods/chat.postMessage) or
|
129
|
+
[chat.scheduleMessage](https://api.slack.com/methods/chat.scheduleMessage) for
|
130
|
+
more information on posting messages.
|
131
|
+
|
132
|
+
---
|
133
|
+
|
134
|
+
Next: [The SlackMessage DSL](https://jmmastey.github.io/slack_message/03_message_dsl)
|
@@ -0,0 +1,283 @@
|
|
1
|
+
### The Message DSL
|
2
|
+
|
3
|
+
A pretty good number of the elements available in BlockKit are usable in SlackMessage. There are also a few elements that haven't been implemented in the official API, but are too useful to be missing.
|
4
|
+
|
5
|
+
#### Basic Text
|
6
|
+
|
7
|
+
While BlockKit officially requires that any elements are contained within a section element, that requirement is relaxed in SlackMessage. If you don't specify a section, one will silently be created to encapsulate your code. That's the secret behind the most basic messages in these docs.
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
SlackMessage.build do
|
11
|
+
text "couldn't be easier"
|
12
|
+
end
|
13
|
+
|
14
|
+
# => [{:type=>"section",
|
15
|
+
# :text=>{:type=>"mrkdwn", :text=>"couldn't be easier"}
|
16
|
+
# }]
|
17
|
+
```
|
18
|
+
|
19
|
+
This is equivalent to the more verbose version with a declared section.
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
SlackMessage.build do
|
23
|
+
section do
|
24
|
+
text "could be easier"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# => [{:type=>"section",
|
29
|
+
# :text=>{:type=>"mrkdwn", :text=>"could be easier"}
|
30
|
+
# }]
|
31
|
+
```
|
32
|
+
|
33
|
+
Text elements are the most basic type of element. Adding multiple text calls
|
34
|
+
will add a newline between text calls, which will cause a line break
|
35
|
+
appropriately.
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
SlackMessage.build do
|
39
|
+
text "one fish, two fish"
|
40
|
+
text "red fish, blue fish"
|
41
|
+
end
|
42
|
+
|
43
|
+
# => [{:type=>"section",
|
44
|
+
# :text=>{:type=>"mrkdwn", :text=>"one fish, two fish\nred fish, blue fish"}
|
45
|
+
# }]
|
46
|
+
```
|
47
|
+
|
48
|
+
Slack uses a [faux-markdown syntax called
|
49
|
+
mrkdwn](https://api.slack.com/reference/surfaces/formatting#basics), which you
|
50
|
+
may be familiar with by typing in the Slack app itself. The API will
|
51
|
+
automatically render mrkdwn appropriately.
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
SlackMessage.build do
|
55
|
+
text "*Favorite Colors*"
|
56
|
+
text "_John_: ~red~ actually blue."
|
57
|
+
end
|
58
|
+
|
59
|
+
# => [{:type=>"section",
|
60
|
+
# :text=>{:type=>"mrkdwn", :text=>"*Favorite Colors*\n_John_: ~red~ actually blue."}}]
|
61
|
+
```
|
62
|
+
|
63
|
+
Rendering emoji in messages is possible using either a) real unicode emoji in
|
64
|
+
your message, or b) using the `:emojiname:` syntax, which supports any emoji
|
65
|
+
that would work in your Slack app itself, including custom emoji.
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
SlackMessage.build do
|
69
|
+
text ":shipit_squirrel:🚀 time to gooo :tada:"
|
70
|
+
end
|
71
|
+
|
72
|
+
# => [{:type=>"section",
|
73
|
+
# :text=>{:type=>"mrkdwn", :text=>":shipit_squirrel:🚀 time to gooo :tada:"}
|
74
|
+
# }]
|
75
|
+
```
|
76
|
+
|
77
|
+
To add a link using Slack's non-markdown link syntax, use the `link` helper
|
78
|
+
method interpolated into a text element. Using the `link` helper as its own
|
79
|
+
element won't work, as the method simply returns a string that has to be
|
80
|
+
included into a text element specifically.
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
SlackMessage.build do
|
84
|
+
text "Your #{link('build', 'https://google.com')} is ready."
|
85
|
+
end
|
86
|
+
|
87
|
+
# => [{:type=>"section",
|
88
|
+
# :text=>{:type=>"mrkdwn", :text=>"Your <https://google.com|build> is ready."}
|
89
|
+
# }]
|
90
|
+
```
|
91
|
+
|
92
|
+
While the API squishes whitespace (much in the same way HTML does), it may
|
93
|
+
sometimes be useful to add a blank line between text _without_ adding a new
|
94
|
+
section to your message. To do so, use the pseudo-element `blank_line`.
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
SlackMessage.build do
|
98
|
+
text "don't let this line"
|
99
|
+
blank_line
|
100
|
+
text "touch this line."
|
101
|
+
end
|
102
|
+
|
103
|
+
# => => [{:type=>"section",
|
104
|
+
# :text=>{:type=>"mrkdwn", :text=>"don't let this line\n \ntouch this line."}
|
105
|
+
# }]
|
106
|
+
```
|
107
|
+
|
108
|
+
Note that between the two newlines in the above example is a unicode emspace,
|
109
|
+
which the API will respect as a line worth rendering.
|
110
|
+
|
111
|
+
#### Buttons
|
112
|
+
|
113
|
+
BlockKit allows you to specify a button to the right of a section / block. That
|
114
|
+
button will be aligned outside the normal space for a section, and is meant to
|
115
|
+
link out of the app. To create one of these, use the `link_button` helper.
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
SlackMessage.build do
|
119
|
+
text "Your daily stats are ready @here"
|
120
|
+
link_button "Stats Dashboard", stats_dashboard_url
|
121
|
+
end
|
122
|
+
|
123
|
+
# => [{:type=>"section",
|
124
|
+
# :text=>{:type=>"mrkdwn", :text=>"Your daily stats are ready @here"},
|
125
|
+
# :accessory=>
|
126
|
+
# {:type=>"button",
|
127
|
+
# :url=>"http://yoursite.com/stats_dashboard",
|
128
|
+
# :text=>{:type=>"plain_text", :text=>"Stats Dashboard", :emoji=>true},
|
129
|
+
# :style=>:primary}}]
|
130
|
+
```
|
131
|
+
|
132
|
+
Slack allows three styles for buttons: `default`, `primary`, and `danger`.
|
133
|
+
These correspond to gray, green and red buttons respectively. If not specified,
|
134
|
+
SlackMessage will use the `primary` style for buttons. I get that this could be
|
135
|
+
confusing when there is a default style, but in my experience, a colorful button
|
136
|
+
is way more common.
|
137
|
+
|
138
|
+
You can override the button style by specifying the style with your link button.
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
SlackMessage.build do
|
142
|
+
text "A job has failed catastrophically!"
|
143
|
+
link_button "Sidekiq Dashboard", sidekiq_dashboard_url, style: :danger
|
144
|
+
end
|
145
|
+
|
146
|
+
# => [{:type=>"section",
|
147
|
+
# :text=>{:type=>"mrkdwn", :text=>"A job has failed catastrophically!"},
|
148
|
+
# :accessory=>
|
149
|
+
# {:type=>"button",
|
150
|
+
# :url=>"https://yoursite.com/sidekiq",
|
151
|
+
# :text=>{:type=>"plain_text", :text=>"Sidekiq Dashboard", :emoji=>true},
|
152
|
+
# :style=>:danger}}]
|
153
|
+
```
|
154
|
+
|
155
|
+
#### Lists and List Items
|
156
|
+
|
157
|
+
- list_item, ul, ol
|
158
|
+
|
159
|
+
### Including Multiple Sections
|
160
|
+
|
161
|
+
Adding more sections is trivial. Simply declare each section and it will be
|
162
|
+
separated in the rendered message. This can often occur when looping.
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
SlackMessage.build do
|
166
|
+
pet_types.each do |type, breeds|
|
167
|
+
section do
|
168
|
+
text "*#{type}:* #{breeds.join(", ")}"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
```
|
173
|
+
|
174
|
+
It can also be useful to add a visual divider (similar to a `hr` in HTML)
|
175
|
+
between sections. To add one of these, use the `divider` helper. You can also
|
176
|
+
add a divider at the end of all the sections, but it often looks silly.
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
SlackMessage.build do
|
180
|
+
section do
|
181
|
+
text "*Topsiders:* Emily, Elsie, Derick"
|
182
|
+
end
|
183
|
+
|
184
|
+
divider
|
185
|
+
|
186
|
+
section do
|
187
|
+
text "*Undergrounders:* Kristina, Lauren, Different Emily"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
# => [
|
192
|
+
# {:type=>"section", :text=>{:type=>"mrkdwn", :text=>"*Topsiders:* Emily, Elsie, Derick"}},
|
193
|
+
# {:type=>"divider"},
|
194
|
+
# {:type=>"section", :text=>{:type=>"mrkdwn", :text=>"*Undergrounders:* Kristina, Lauren, Different Emily"}}
|
195
|
+
# ]
|
196
|
+
```
|
197
|
+
|
198
|
+
Note that a divider can only occur between sections, not within a single
|
199
|
+
section. Because of how implicit sections are built, it may look like this works
|
200
|
+
for simple messages. You may have troubles when you start adding more
|
201
|
+
complicated elements to your messages.
|
202
|
+
|
203
|
+
### Images
|
204
|
+
- image, accessory_image
|
205
|
+
|
206
|
+
### Footers (Context)
|
207
|
+
|
208
|
+
Slack allows you to add a small additional piece of text to your message, which
|
209
|
+
will be rendered in italics and small text. It can support both links and emoji,
|
210
|
+
and is useful for providing minor details for your message.
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
SlackMessage.build do
|
214
|
+
text "New coffee complaints have been added."
|
215
|
+
context "this complaint added by #{link('Joe Mastey', 'hello@joemastey.com')}."
|
216
|
+
end
|
217
|
+
|
218
|
+
# => [{:type=>"section",
|
219
|
+
# :text=>{:type=>"mrkdwn", :text=>"New coffee complaints have been added."}
|
220
|
+
# },
|
221
|
+
# {:type=>"context", :elements=>
|
222
|
+
# [{:type=>"mrkdwn",
|
223
|
+
# :text=>"this complaint added by <hello@joemastey.com|Joe Mastey>."
|
224
|
+
# }]
|
225
|
+
# }]
|
226
|
+
```
|
227
|
+
|
228
|
+
Context does not belong to a section, and is per-message, not per-section.
|
229
|
+
Specifying more than one context will simply overwrite previous calls.
|
230
|
+
|
231
|
+
### Bot Customization
|
232
|
+
|
233
|
+
By default - and with scheduled messages - Slack will use the name and icon of
|
234
|
+
the Slack app whose API key you configured. As seen before, it's
|
235
|
+
possible to override those default names and icons in configuration. However, it
|
236
|
+
can also be customized per-message.
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
SlackMessage.build do
|
240
|
+
bot_icon ":sad_robot:"
|
241
|
+
bot_name "BadNewsBuildBot"
|
242
|
+
|
243
|
+
text "The build is broken. @here"
|
244
|
+
end
|
245
|
+
|
246
|
+
# => [{:type=>"section", :text=>{:type=>"mrkdwn", :text=>"The build is broken. @here"}}]
|
247
|
+
```
|
248
|
+
|
249
|
+
Notice that the bot details aren't shown in the output of the `build` command.
|
250
|
+
To view the changes these methods cause, use `debug` mode.
|
251
|
+
|
252
|
+
The `bot_icon` can be specified as either an emoji (`:example:`), or a URL
|
253
|
+
pointing to an image (`http://mysite.com/shipit.png`). Any other value seems to
|
254
|
+
cause an error.
|
255
|
+
|
256
|
+
### Custom Notification Text
|
257
|
+
|
258
|
+
For users who have notifications turned on, Slack will provide a small message
|
259
|
+
preview when you send them a message. By default, this preview will take the
|
260
|
+
first several words from your message.
|
261
|
+
|
262
|
+
However, you can specify some custom notification text to be shown to the user.
|
263
|
+
This text supports basic emoji and formatting, but nothing complicated.
|
264
|
+
|
265
|
+
```ruby
|
266
|
+
SlackMessage.build do
|
267
|
+
notification_text "Having issues with the build. :ohnoes:"
|
268
|
+
|
269
|
+
text "The build is broken. The error message was 'undefined method round for NilClass'"
|
270
|
+
|
271
|
+
# => [{:type=>"section",
|
272
|
+
# :text=>
|
273
|
+
# {:type=>"mrkdwn",
|
274
|
+
# :text=>"The build is broken. The error message was 'undefined method round for NilClass'"}}]
|
275
|
+
end
|
276
|
+
```
|
277
|
+
|
278
|
+
Again notice that notification text is not set within the blocks themselves, so
|
279
|
+
you will need to enable debugging to see how it changes what is sent to the API.
|
280
|
+
|
281
|
+
---
|
282
|
+
|
283
|
+
Next: [Editing Messages](https://jmmastey.github.io/slack_message/04_editing_messages)
|
@@ -0,0 +1,88 @@
|
|
1
|
+
### Updating a Previous Message
|
2
|
+
|
3
|
+
After you've posted a message, you may want to edit it later. Interactive bots,
|
4
|
+
for instance, may want to repeatedly update a message.
|
5
|
+
|
6
|
+
Posting will always return an object representing your posted message.
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
message = SlackMessage.post_to('#general') do
|
10
|
+
text "Getting ready..."
|
11
|
+
end
|
12
|
+
```
|
13
|
+
|
14
|
+
Then, you can use that response object to go back and rewrite the message a
|
15
|
+
little or a lot.
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
SlackMessage.update(message) do
|
19
|
+
text "Done!"
|
20
|
+
end
|
21
|
+
```
|
22
|
+
|
23
|
+
The new message contents will be built and updated via the API. To give an
|
24
|
+
example, you could alert slack to a job status by updating your original
|
25
|
+
message.
|
26
|
+
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
class SomeWorker < ApplicationWorker
|
30
|
+
def perform
|
31
|
+
post_started_status
|
32
|
+
|
33
|
+
# ... perform work here
|
34
|
+
|
35
|
+
post_finished_status
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def post_started_status
|
41
|
+
@message = SlackMessage.post_as(:job_worker) do
|
42
|
+
text "Beginning upload."
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def post_finished_status
|
47
|
+
SlackMessage.update(@message) do
|
48
|
+
text "Finished upload! @here come and get it."
|
49
|
+
link_button "See Results", uploaded_data_url
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
#### Storing Response Objects for Later
|
56
|
+
|
57
|
+
Since updates are likely to occur after you've long since finished posting the
|
58
|
+
original message, you'll need to persist the message response somehow until you
|
59
|
+
need to update it later. As one option, you could serialize the response object
|
60
|
+
for later.
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
# initially
|
64
|
+
message = SlackMessage.post_to('#general') do
|
65
|
+
text "Starting..."
|
66
|
+
end
|
67
|
+
redis_connection.set(self.message_cache_key, Marshal.dump(message))
|
68
|
+
|
69
|
+
|
70
|
+
# later
|
71
|
+
message = Marshal.load(redis_connection.get(self.message_cache_key))
|
72
|
+
SlackMessage.update(message) do
|
73
|
+
text "Finished!"
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
#### Updating Scheduled Messages
|
78
|
+
|
79
|
+
Sadly, there's currently no way to edit a scheduled message. You'll receive an
|
80
|
+
error if you attempt to call `update` on a scheduled message.
|
81
|
+
|
82
|
+
See the [API documentation for
|
83
|
+
chat.update](https://api.slack.com/methods/chat.update) for more information on
|
84
|
+
updating messages.
|
85
|
+
|
86
|
+
---
|
87
|
+
|
88
|
+
Next: [Deleting Messages](https://jmmastey.github.io/slack_message/05_deleting_messages)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
### Deleting Messages
|
2
|
+
|
3
|
+
Deleting a message is much like editing a message, only simpler. Just like when
|
4
|
+
you edit a message, you'll need a reference to the message you posted.
|
5
|
+
|
6
|
+
*Important Note: It's not possible to delete a message sent directly to a user.
|
7
|
+
It's also not possible to delete a scheduled message once it's already posted.
|
8
|
+
Don't send anything you don't want your boss to read.*
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
message = SlackMessage.post_to('#general') do
|
12
|
+
text "Testing: #{SLACK_SECRET_KEY}"
|
13
|
+
end
|
14
|
+
```
|
15
|
+
|
16
|
+
Now you can simply call the `delete` method to make up for your mistakes.
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
SlackMessage.delete(message)
|
20
|
+
```
|
21
|
+
|
22
|
+
As with editing a message, it's possible to persist messages to redis / your
|
23
|
+
database and remove them using the timestamp and channel of your message.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
# initially
|
27
|
+
message = SlackMessage.post_to('#general') do
|
28
|
+
text "Testing: #{SLACK_SECRET_KEY}"
|
29
|
+
end
|
30
|
+
redis_connection.set(self.message_cache_key, Marshal.dump(message))
|
31
|
+
|
32
|
+
|
33
|
+
# later
|
34
|
+
message = Marshal.load(redis_connection.get(self.message_cache_key))
|
35
|
+
SlackMessage.delete(message)
|
36
|
+
```
|
37
|
+
|
38
|
+
See the [API documentation for
|
39
|
+
chat.delete](https://api.slack.com/methods/chat.delete) or
|
40
|
+
[chat.deleteScheduledMessage](https://api.slack.com/methods/chat.deleteScheduledMessage)
|
41
|
+
for more information on deleting messages.
|
42
|
+
|
43
|
+
---
|
44
|
+
|
45
|
+
Next: [Mentions / Notifying Users](https://jmmastey.github.io/slack_message/06_notifying_users)
|
@@ -0,0 +1,62 @@
|
|
1
|
+
## Mentions / Notifying Users
|
2
|
+
|
3
|
+
There are several supported ways to tag and notify users. As mentioned
|
4
|
+
initially, it's possible to DM a user by their account email.
|
5
|
+
|
6
|
+
```ruby
|
7
|
+
SlackMessage.post_to('hello@joemastey.com') do
|
8
|
+
text "Hi there!"
|
9
|
+
end
|
10
|
+
```
|
11
|
+
|
12
|
+
You can also mention a user by email within a channel by wrapping their name in
|
13
|
+
tags.
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
SlackMessage.post_to('#general') do
|
17
|
+
bot_name "CoffeeBot"
|
18
|
+
bot_icon ":coffee:"
|
19
|
+
|
20
|
+
text ":coffee: It's your turn to make coffee <hello@joemastey.com>."
|
21
|
+
end
|
22
|
+
```
|
23
|
+
|
24
|
+
Emails that are not wrapped in tags will be rendered as normal email addresses.
|
25
|
+
Additionally, Slack will automatically convert a number of channel names and
|
26
|
+
tags you're probably already used to.
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
SlackMessage.post_to('#general') do
|
30
|
+
bot_name "CoffeeBot"
|
31
|
+
bot_icon ":coffee:"
|
32
|
+
|
33
|
+
text "@here There's no coffee left! Let #general know when you fix it."
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
By default, the desktop notification for a message will be the text of the
|
38
|
+
message itself. However, you can customize desktop notifications if you prefer.
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
SlackMessage.post_to('hello@joemastey.com') do
|
42
|
+
bot_name "CoffeeBot"
|
43
|
+
bot_icon ":coffee:"
|
44
|
+
|
45
|
+
notification_text "It's a coffee emergency!"
|
46
|
+
text "There's no coffee left!"
|
47
|
+
end
|
48
|
+
```
|
49
|
+
|
50
|
+
#### Using @channel or @here
|
51
|
+
|
52
|
+
Not really a feature, but Slack will respect usage of `@here` and `@channel`.
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
SlackMessage.post_to('#general') do
|
56
|
+
text "Hey @channel, don't forget to submit your drink requests."
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
---
|
61
|
+
|
62
|
+
Next: [Testing](https://jmmastey.github.io/slack_message/07_testing)
|
data/docs/07_testing.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
## Testing
|
2
|
+
|
3
|
+
You can do some basic testing against SlackMessage, at least if you use RSpec!
|
4
|
+
You'll need to require and include the testing behavior in your spec_helper
|
5
|
+
file.
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
require 'slack_message/rspec'
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
include SlackMessage::RSpec
|
12
|
+
|
13
|
+
# your other spec_helper config
|
14
|
+
end
|
15
|
+
```
|
16
|
+
|
17
|
+
This will prevent API calls from leaking in your tests, and will allow you
|
18
|
+
access to some custom matchers.
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
expect {
|
22
|
+
SlackMessage.post_to('#general') { text "foo" }
|
23
|
+
}.to post_slack_message_to('#general').with_content_matching(/foo/)
|
24
|
+
|
25
|
+
expect {
|
26
|
+
SlackMessage.post_as(:schmoebot) { text "foo" }
|
27
|
+
}.to post_slack_message_as(:schmoebot)
|
28
|
+
|
29
|
+
expect {
|
30
|
+
SlackMessage.post_as(:schmoebot) { text "foo" }
|
31
|
+
}.to post_slack_message_as('Schmoe Bot')
|
32
|
+
|
33
|
+
expect {
|
34
|
+
SlackMessage.post_as(:schmoebot) { text "foo" }
|
35
|
+
}.to post_slack_message_with_icon(':schmoebot:')
|
36
|
+
|
37
|
+
expect {
|
38
|
+
SlackMessage.post_as(:schmoebot) { text "foo" }
|
39
|
+
}.to post_slack_message_with_icon_matching(/gravatar/)
|
40
|
+
|
41
|
+
expect {
|
42
|
+
SlackMessage.post_to('#general') { text "foo" }
|
43
|
+
}.to post_to_slack
|
44
|
+
```
|
45
|
+
|
46
|
+
Be forewarned, I'm frankly not that great at more complicated RSpec matchers,
|
47
|
+
so I'm guessing there are some bugs. Also, because the content of a message
|
48
|
+
gets turned into a complex JSON object, matching against content isn't capable
|
49
|
+
of very complicated regexes.
|
data/docs/index.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
* [Configuration](https://jmmastey.github.io/slack_message/01_configuration)
|
2
|
+
* [Posting a Message](https://jmmastey.github.io/slack_message/02_posting_a_message)
|
3
|
+
* [The SlackMessage DSL](https://jmmastey.github.io/slack_message/03_message_dsl)
|
4
|
+
* [Editing Messages](https://jmmastey.github.io/slack_message/04_editing_messages)
|
5
|
+
* [Deleting Messages](https://jmmastey.github.io/slack_message/05_deleting_messages)
|
6
|
+
* [Mentions / Notifying Users](https://jmmastey.github.io/slack_message/06_notifying_users)
|
7
|
+
* [Testing](https://jmmastey.github.io/slack_message/07_testing)
|
data/lib/slack_message/api.rb
CHANGED
@@ -59,7 +59,7 @@ module SlackMessage::Api
|
|
59
59
|
if !time.nil?
|
60
60
|
params[:post_at] = time.to_i
|
61
61
|
|
62
|
-
if
|
62
|
+
if payload.custom_bot_name || payload.custom_bot_icon
|
63
63
|
raise ArgumentError, "Sorry, setting an image / emoji icon for scheduled messages isn't supported."
|
64
64
|
end
|
65
65
|
end
|
@@ -72,6 +72,8 @@ module SlackMessage::Api
|
|
72
72
|
body = JSON.parse(response.body)
|
73
73
|
error = body.fetch("error", "")
|
74
74
|
|
75
|
+
# TODO: if a scheduled message w/ a short timer is "time_in_past", warn the user?
|
76
|
+
|
75
77
|
# let's try to be helpful about error messages
|
76
78
|
if ["token_revoked", "token_expired", "invalid_auth", "not_authed"].include?(error)
|
77
79
|
raise SlackMessage::ApiError, "Couldn't send slack message because the API key for profile '#{profile[:handle]}' is wrong."
|
@@ -87,6 +89,51 @@ module SlackMessage::Api
|
|
87
89
|
raise SlackMessage::ApiError, "Got an error back from the Slack API (HTTP #{response.code}):\n#{response.body}"
|
88
90
|
end
|
89
91
|
|
92
|
+
SlackMessage::Response.new(response, profile[:handle])
|
93
|
+
end
|
94
|
+
|
95
|
+
def update(payload, message, profile)
|
96
|
+
params = {
|
97
|
+
channel: message.channel,
|
98
|
+
ts: message.timestamp,
|
99
|
+
blocks: payload.render,
|
100
|
+
text: payload.custom_notification # TODO: ???
|
101
|
+
}
|
102
|
+
|
103
|
+
if params[:blocks].length == 0
|
104
|
+
raise ArgumentError, "Tried to send an entirely empty message."
|
105
|
+
end
|
106
|
+
|
107
|
+
if SlackMessage::Configuration.debugging?
|
108
|
+
warn params.inspect
|
109
|
+
end
|
110
|
+
|
111
|
+
response = update_message(profile, params)
|
112
|
+
body = JSON.parse(response.body)
|
113
|
+
error = body.fetch("error", "")
|
114
|
+
|
115
|
+
# TODO: error messaging
|
116
|
+
|
117
|
+
SlackMessage::Response.new(response, profile[:handle])
|
118
|
+
end
|
119
|
+
|
120
|
+
def delete(message, profile)
|
121
|
+
params = if message.scheduled?
|
122
|
+
{
|
123
|
+
channel: message.channel,
|
124
|
+
scheduled_message_id: message.scheduled_message_id,
|
125
|
+
}
|
126
|
+
else
|
127
|
+
{
|
128
|
+
channel: message.channel,
|
129
|
+
ts: message.timestamp,
|
130
|
+
}
|
131
|
+
end
|
132
|
+
|
133
|
+
response = delete_message(profile, params)
|
134
|
+
|
135
|
+
# TODO error handling (incl for already scheduled-and-sent messages)
|
136
|
+
|
90
137
|
response
|
91
138
|
end
|
92
139
|
|
@@ -108,7 +155,7 @@ module SlackMessage::Api
|
|
108
155
|
end
|
109
156
|
|
110
157
|
def post_message(profile, params)
|
111
|
-
uri = if params
|
158
|
+
uri = if params.has_key?(:post_at)
|
112
159
|
URI("https://slack.com/api/chat.scheduleMessage")
|
113
160
|
else
|
114
161
|
URI("https://slack.com/api/chat.postMessage")
|
@@ -124,4 +171,36 @@ module SlackMessage::Api
|
|
124
171
|
http.request(request)
|
125
172
|
end
|
126
173
|
end
|
174
|
+
|
175
|
+
def update_message(profile, params)
|
176
|
+
uri = URI("https://slack.com/api/chat.update")
|
177
|
+
|
178
|
+
request = Net::HTTP::Post.new(uri).tap do |req|
|
179
|
+
req['Authorization'] = "Bearer #{profile[:api_token]}"
|
180
|
+
req['Content-type'] = "application/json; charset=utf-8"
|
181
|
+
req.body = params.to_json
|
182
|
+
end
|
183
|
+
|
184
|
+
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
185
|
+
http.request(request)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def delete_message(profile, params)
|
190
|
+
uri = if params.has_key?(:scheduled_message_id)
|
191
|
+
URI("https://slack.com/api/chat.deleteScheduledMessage")
|
192
|
+
else
|
193
|
+
URI("https://slack.com/api/chat.delete")
|
194
|
+
end
|
195
|
+
|
196
|
+
request = Net::HTTP::Post.new(uri).tap do |req|
|
197
|
+
req['Authorization'] = "Bearer #{profile[:api_token]}"
|
198
|
+
req['Content-type'] = "application/json; charset=utf-8"
|
199
|
+
req.body = params.to_json
|
200
|
+
end
|
201
|
+
|
202
|
+
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
203
|
+
http.request(request)
|
204
|
+
end
|
205
|
+
end
|
127
206
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class SlackMessage::Response
|
2
|
+
attr_reader :channel, :timestamp, :profile_handle, :scheduled_message_id, :original_response
|
3
|
+
|
4
|
+
def initialize(api_response, profile_handle)
|
5
|
+
@original_response = JSON.parse(api_response.body)
|
6
|
+
@ok = @original_response["ok"]
|
7
|
+
@channel = @original_response["channel"]
|
8
|
+
|
9
|
+
@timestamp = @original_response["ts"]
|
10
|
+
@scheduled_message_id = @original_response["scheduled_message_id"]
|
11
|
+
|
12
|
+
@profile_handle = profile_handle
|
13
|
+
end
|
14
|
+
|
15
|
+
def marshal_dump
|
16
|
+
[ @profile_handle, @channel, @timestamp, @original_response, @ok, @original_response ]
|
17
|
+
end
|
18
|
+
|
19
|
+
def marshal_load(data)
|
20
|
+
@profile_handle, @channel, @timestamp, @original_response, @ok, @original_response = data
|
21
|
+
end
|
22
|
+
|
23
|
+
def sent_to_user?
|
24
|
+
channel =~ /^D.*/ # users are D for DM, channels start w/ C
|
25
|
+
end
|
26
|
+
|
27
|
+
def scheduled?
|
28
|
+
!!scheduled_message_id
|
29
|
+
end
|
30
|
+
|
31
|
+
def inspect
|
32
|
+
identifier = if scheduled?
|
33
|
+
"scheduled_message_id=#{scheduled_message_id}"
|
34
|
+
else
|
35
|
+
"timestamp=#{timestamp}"
|
36
|
+
end
|
37
|
+
|
38
|
+
ok_msg = @ok ? "ok" : "error"
|
39
|
+
|
40
|
+
"<SlackMessage::Response #{ok_msg} profile_handle=:#{profile_handle} channel=#{channel} #{identifier}>"
|
41
|
+
end
|
42
|
+
end
|
data/lib/slack_message/rspec.rb
CHANGED
data/lib/slack_message.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
module SlackMessage
|
2
|
+
require 'slack_message/response'
|
2
3
|
require 'slack_message/dsl'
|
3
4
|
require 'slack_message/api'
|
4
5
|
require 'slack_message/configuration'
|
@@ -39,16 +40,46 @@ module SlackMessage
|
|
39
40
|
raise ArgumentError, "Sorry, you need to specify a default_channel for profile #{profile_name} to use post_as"
|
40
41
|
end
|
41
42
|
|
43
|
+
target = profile[:default_channel]
|
42
44
|
payload = Dsl.new(block, profile).tap do |instance|
|
43
45
|
instance.instance_eval(&block)
|
44
46
|
end
|
45
47
|
|
46
|
-
target = profile[:default_channel]
|
47
48
|
target = Api::user_id_for(target, profile) if target =~ EMAIL_PATTERN
|
48
49
|
|
49
50
|
Api.post(payload, target, profile, at)
|
50
51
|
end
|
51
52
|
|
53
|
+
def self.update(message, &block)
|
54
|
+
unless message.is_a?(SlackMessage::Response)
|
55
|
+
raise ArgumentError, "You must pass in a SlackMessage::Response to update a message"
|
56
|
+
end
|
57
|
+
|
58
|
+
if message.scheduled?
|
59
|
+
raise ArgumentError, "Sorry, scheduled messages cannot be updated. You will need to delete the message and schedule a new one."
|
60
|
+
end
|
61
|
+
|
62
|
+
profile = Configuration.profile(message.profile_handle)
|
63
|
+
payload = Dsl.new(block, profile).tap do |instance|
|
64
|
+
instance.instance_eval(&block)
|
65
|
+
end
|
66
|
+
|
67
|
+
Api.update(payload, message, profile)
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.delete(message)
|
71
|
+
unless message.is_a?(SlackMessage::Response)
|
72
|
+
raise ArgumentError, "You must pass in a SlackMessage::Response to delete a message"
|
73
|
+
end
|
74
|
+
|
75
|
+
if message.sent_to_user?
|
76
|
+
raise ArgumentError, "It's not possible to delete messages sent directly to users."
|
77
|
+
end
|
78
|
+
|
79
|
+
profile = Configuration.profile(message.profile_handle)
|
80
|
+
Api.delete(message, profile)
|
81
|
+
end
|
82
|
+
|
52
83
|
def self.build(profile_name = :default, &block)
|
53
84
|
profile = Configuration.profile(profile_name)
|
54
85
|
|
data/slack_message.gemspec
CHANGED
data/spec/slack_message_spec.rb
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:
|
4
|
+
version: 3.0.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-12-
|
11
|
+
date: 2021-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -66,10 +66,19 @@ files:
|
|
66
66
|
- Gemfile
|
67
67
|
- MIT-LICENSE
|
68
68
|
- README.md
|
69
|
+
- docs/01_configuration.md
|
70
|
+
- docs/02_posting_a_message.md
|
71
|
+
- docs/03_message_dsl.md
|
72
|
+
- docs/04_editing_messages.md
|
73
|
+
- docs/05_deleting_messages.md
|
74
|
+
- docs/06_notifying_users.md
|
75
|
+
- docs/07_testing.md
|
76
|
+
- docs/index.md
|
69
77
|
- lib/slack_message.rb
|
70
78
|
- lib/slack_message/api.rb
|
71
79
|
- lib/slack_message/configuration.rb
|
72
80
|
- lib/slack_message/dsl.rb
|
81
|
+
- lib/slack_message/response.rb
|
73
82
|
- lib/slack_message/rspec.rb
|
74
83
|
- slack_message.gemspec
|
75
84
|
- spec/slack_message_spec.rb
|