slack_message 2.2.2 ā†’ 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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)
@@ -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)
@@ -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,10 +56,24 @@ 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 payload.custom_bot_name || payload.custom_bot_icon
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", "")
62
74
 
75
+ # TODO: if a scheduled message w/ a short timer is "time_in_past", warn the user?
76
+
63
77
  # let's try to be helpful about error messages
64
78
  if ["token_revoked", "token_expired", "invalid_auth", "not_authed"].include?(error)
65
79
  raise SlackMessage::ApiError, "Couldn't send slack message because the API key for profile '#{profile[:handle]}' is wrong."
@@ -75,6 +89,51 @@ module SlackMessage::Api
75
89
  raise SlackMessage::ApiError, "Got an error back from the Slack API (HTTP #{response.code}):\n#{response.body}"
76
90
  end
77
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
+
78
137
  response
79
138
  end
80
139
 
@@ -84,6 +143,7 @@ module SlackMessage::Api
84
143
 
85
144
  def look_up_user_by_email(email, profile)
86
145
  uri = URI("https://slack.com/api/users.lookupByEmail?email=#{email}")
146
+
87
147
  request = Net::HTTP::Get.new(uri).tap do |req|
88
148
  req['Authorization'] = "Bearer #{profile[:api_token]}"
89
149
  req['Content-type'] = "application/json; charset=utf-8"
@@ -95,7 +155,44 @@ module SlackMessage::Api
95
155
  end
96
156
 
97
157
  def post_message(profile, params)
98
- uri = URI("https://slack.com/api/chat.postMessage")
158
+ uri = if params.has_key?(:post_at)
159
+ URI("https://slack.com/api/chat.scheduleMessage")
160
+ else
161
+ URI("https://slack.com/api/chat.postMessage")
162
+ end
163
+
164
+ request = Net::HTTP::Post.new(uri).tap do |req|
165
+ req['Authorization'] = "Bearer #{profile[:api_token]}"
166
+ req['Content-type'] = "application/json; charset=utf-8"
167
+ req.body = params.to_json
168
+ end
169
+
170
+ Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
171
+ http.request(request)
172
+ end
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
+
99
196
  request = Net::HTTP::Post.new(uri).tap do |req|
100
197
  req['Authorization'] = "Bearer #{profile[:api_token]}"
101
198
  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