slacks 0.4.3 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 47d70d2fd8637b680b0996c328a8bc4e904370a5
4
- data.tar.gz: 01e16f46e8f99eef67164cc69b7c80fd5d6be1e5
2
+ SHA256:
3
+ metadata.gz: ef0147c441c7d163618ff3273ff4110509acf5f4462589c74f3055bde0a8bc5b
4
+ data.tar.gz: 0afaff93535de9e0e68e0f958296e90a5f118761ecf2256632cdf239def152da
5
5
  SHA512:
6
- metadata.gz: b9ee9d64bafcade4b4d692e8364462c2217f5c4847761a565bb491ca8fbc3f05e65205969f10230fba9bc820e25f98cabffd4d1122d3eef30103902065cdaecc
7
- data.tar.gz: c73f2491c1af828ce7fa2071f620de5abda68528fe9d40949ae134bb8ee4ea6f79b44be55307b70690f9198d3e28774aea6e5ada296135f170b8daacafa9390f
6
+ metadata.gz: 7de1e45fe98ae222c312cf6202c6f9b9437bee7363f751280666644b43abb14931d74df2a6b0af31d4e468de408c6598fe278837db4e43399148ffb645f4cc74
7
+ data.tar.gz: 4462429444e6e8793718cd1beb291a9cab446dd0ee30d2e9ab2e17d58f0977f08d490681dadeebe3ec391012f6d89f21a34e69a9297e8f22447eda4a238d59a5
@@ -12,17 +12,12 @@ module Slacks
12
12
  end
13
13
 
14
14
  def reply(*messages)
15
- messages.flatten!
16
15
  return unless messages.any?
17
16
 
18
- first_message = messages.shift
19
- message_options = {}
20
- message_options = messages.shift if messages.length == 1 && messages[0].is_a?(Hash)
21
- slack.send_message(first_message, message_options.merge(channel: id))
22
-
23
- messages.each do |message|
24
- sleep message.length / slack.typing_speed
25
- slack.send_message(message, channel: id)
17
+ if messages.first.is_a?(Array)
18
+ reply_many(messages[0])
19
+ else
20
+ reply_one(*messages)
26
21
  end
27
22
  end
28
23
  alias :say :reply
@@ -61,6 +56,19 @@ module Slacks
61
56
  "##{name}"
62
57
  end
63
58
 
59
+ protected
60
+
61
+ def reply_one(message, options={})
62
+ slack.send_message(message, options.merge(channel: id))
63
+ end
64
+
65
+ def reply_many(messages)
66
+ messages.each_with_index.map do |message, i|
67
+ sleep message.length / slack.typing_speed if i > 0
68
+ slack.send_message(message, channel: id)
69
+ end
70
+ end
71
+
64
72
  private
65
73
  attr_reader :slack
66
74
  end
@@ -24,10 +24,8 @@ module Slacks
24
24
  @user_ids_dm_ids = {}
25
25
  @users_by_id = {}
26
26
  @user_id_by_name = {}
27
- @groups_by_id = {}
28
- @group_id_by_name = {}
29
- @channels_by_id = {}
30
- @channel_id_by_name = {}
27
+ @conversations_by_id = {}
28
+ @conversation_ids_by_name = {}
31
29
  end
32
30
 
33
31
 
@@ -41,11 +39,8 @@ module Slacks
41
39
  as_user: true, # post as the authenticated user (rather than as slackbot)
42
40
  link_names: 1} # find and link channel names and user names
43
41
  params.merge!(attachments: MultiJson.dump(attachments)) if attachments.any?
44
- params.merge!(options.select { |key, _| [:username, :as_user, :parse, :link_names,
45
- :unfurl_links, :unfurl_media, :icon_url, :icon_emoji].member?(key) })
46
- api("chat.postMessage", params)
47
- rescue Slacks::ResponseError
48
- $!.response
42
+ params.merge!(options.select { |key, _| SEND_MESSAGE_PARAMS.member?(key) })
43
+ api("chat.postMessage", **params)
49
44
  end
50
45
  alias :say :send_message
51
46
 
@@ -53,9 +48,7 @@ module Slacks
53
48
  params = {
54
49
  channel: to_channel_id(channel),
55
50
  timestamp: ts }
56
- api("reactions.get", params)
57
- rescue Slacks::ResponseError
58
- $!.response
51
+ api("reactions.get", **params)
59
52
  end
60
53
 
61
54
  def update_message(ts, message, options={})
@@ -70,34 +63,38 @@ module Slacks
70
63
  params.merge!(attachments: MultiJson.dump(attachments)) if attachments.any?
71
64
  params.merge!(options.select { |key, _| [:username, :as_user, :parse, :link_names,
72
65
  :unfurl_links, :unfurl_media, :icon_url, :icon_emoji].member?(key) })
73
- api("chat.update", params)
74
- rescue Slacks::ResponseError
75
- $!.response
66
+ api("chat.update", **params)
76
67
  end
77
68
 
78
69
  def add_reaction(emojis, message)
79
70
  Array(emojis).each do |emoji|
80
- api("reactions.add", {
71
+ api("reactions.add",
81
72
  name: emoji.gsub(/^:|:$/, ""),
82
73
  channel: message.channel.id,
83
- timestamp: message.timestamp })
74
+ timestamp: message.timestamp)
84
75
  end
85
- rescue Slacks::ResponseError
86
- $!.response
87
76
  end
88
77
 
78
+
79
+
89
80
  def typing_on(channel)
81
+ raise NotListeningError unless listening?
90
82
  websocket.write MultiJson.dump(type: "typing", channel: to_channel_id(channel))
91
83
  end
92
84
 
85
+ def ping
86
+ raise NotListeningError unless listening?
87
+ websocket.ping
88
+ end
89
+
90
+ def listening?
91
+ !websocket.nil?
92
+ end
93
+
93
94
 
94
95
 
95
96
  def listen!
96
97
  response = api("rtm.start")
97
- unless response["ok"]
98
- raise MigrationInProgress if response["error"] == "migration_in_progress"
99
- raise ResponseError.new(response, response["error"])
100
- end
101
98
  store_context!(response)
102
99
 
103
100
  @websocket = Slacks::Driver.new
@@ -117,21 +114,16 @@ module Slacks
117
114
  # one, we'll skill it.
118
115
  next
119
116
 
120
- when EVENT_GROUP_JOINED
121
- group = data["channel"]
122
- @groups_by_id[group["id"]] = group
123
- @group_id_by_name[group["name"]] = group["id"]
117
+ when EVENT_GROUP_JOINED, EVENT_CHANNEL_CREATED
118
+ conversation = data["channel"]
119
+ @conversations_by_id[conversation["id"]] = conversation
120
+ @conversation_ids_by_name[conversation["name"]] = conversation["id"]
124
121
 
125
122
  when EVENT_USER_JOINED
126
123
  user = data["user"]
127
124
  @users_by_id[user["id"]] = user
128
125
  @user_id_by_name[user["name"]] = user["id"]
129
126
 
130
- when EVENT_CHANNEL_CREATED
131
- channel = data["channel"]
132
- @channels_by_id[channel["id"]] = channel
133
- @channel_id_by_name[channel["name"]] = channel["id"]
134
-
135
127
  when EVENT_MESSAGE
136
128
  # Don't respond to things that this bot said
137
129
  next if data["user"] == bot.id
@@ -158,10 +150,9 @@ module Slacks
158
150
 
159
151
 
160
152
  def channels
161
- channels = user_id_by_name.keys + group_id_by_name.keys + channel_id_by_name.keys
153
+ channels = user_id_by_name.keys + conversation_ids_by_name.keys
162
154
  if channels.empty?
163
- fetch_channels!
164
- fetch_groups!
155
+ fetch_conversations!
165
156
  fetch_users!
166
157
  end
167
158
  channels
@@ -184,13 +175,9 @@ module Slacks
184
175
  "id" => id,
185
176
  "is_im" => true,
186
177
  "name" => user.username }
187
- when /^G/
188
- Slacks::Channel.new(self, groups_by_id.fetch(id) do
189
- raise ArgumentError, "Unable to find a group with the ID #{id.inspect}"
190
- end)
191
178
  else
192
- Slacks::Channel.new(self, channels_by_id.fetch(id) do
193
- raise ArgumentError, "Unable to find a channel with the ID #{id.inspect}"
179
+ Slacks::Channel.new(self, conversations_by_id.fetch(id) do
180
+ raise ArgumentError, "Unable to find a conversation with the ID #{id.inspect}"
194
181
  end)
195
182
  end
196
183
  end
@@ -225,10 +212,8 @@ module Slacks
225
212
  attr_reader :user_ids_dm_ids,
226
213
  :users_by_id,
227
214
  :user_id_by_name,
228
- :groups_by_id,
229
- :group_id_by_name,
230
- :channels_by_id,
231
- :channel_id_by_name,
215
+ :conversations_by_id,
216
+ :conversation_ids_by_name,
232
217
  :websocket_url,
233
218
  :websocket
234
219
 
@@ -239,16 +224,8 @@ module Slacks
239
224
  @bot = BotUser.new(response.fetch("self"))
240
225
  @team = Team.new(response.fetch("team"))
241
226
 
242
- @channels_by_id = Hash[response.fetch("channels").map { |attrs| [attrs.fetch("id"), attrs] }]
243
- @channel_id_by_name = Hash[response.fetch("channels").map { |attrs| ["##{attrs.fetch("name")}", attrs.fetch("id")] }]
244
-
245
- @users_by_id = Hash[response.fetch("users").map { |attrs| [attrs.fetch("id"), attrs] }]
246
- @user_id_by_name = Hash[response.fetch("users").map { |attrs| ["@#{attrs.fetch("name")}", attrs.fetch("id")] }]
247
-
248
- @groups_by_id = Hash[response.fetch("groups").map { |attrs| [attrs.fetch("id"), attrs] }]
249
- @group_id_by_name = Hash[response.fetch("groups").map { |attrs| [attrs.fetch("name"), attrs.fetch("id")] }]
250
- rescue KeyError
251
- raise ResponseError.new(response, $!.message)
227
+ @conversations_by_id = Hash[response.fetch("channels").map { |attrs| [ attrs.fetch("id"), attrs ] }]
228
+ @conversation_ids_by_name = Hash[response.fetch("channels").map { |attrs| [ attrs["name"], attrs["id"] ] }]
252
229
  end
253
230
 
254
231
 
@@ -257,13 +234,9 @@ module Slacks
257
234
  return name.id if name.is_a?(Slacks::Channel)
258
235
  return name if name =~ /^[DGC]/ # this already looks like a channel id
259
236
  return get_dm_for_username(name) if name.start_with?("@")
260
- return to_group_id(name) unless name.start_with?("#")
261
-
262
- channel_id_by_name[name] || fetch_channels![name] || missing_channel!(name)
263
- end
264
237
 
265
- def to_group_id(name)
266
- group_id_by_name[name] || fetch_groups![name] || missing_group!(name)
238
+ name = name.gsub(/^#/, "") # Leading hashes are no longer a thing in the conversations API
239
+ conversation_ids_by_name[name] || fetch_conversations![name] || missing_conversation!(name)
267
240
  end
268
241
 
269
242
  def to_user_id(name)
@@ -276,40 +249,29 @@ module Slacks
276
249
 
277
250
  def get_dm_for_user_id(user_id)
278
251
  user_ids_dm_ids[user_id] ||= begin
279
- response = api("im.open", user: user_id)
280
- raise UnableToDirectMessageError.new(response, user_id) unless response["ok"]
252
+ response = api("conversations.open", users: user_id)
281
253
  response["channel"]["id"]
282
254
  end
283
255
  end
284
256
 
285
257
 
286
-
287
- def fetch_channels!
288
- response = api("channels.list")
289
- @channels_by_id = response["channels"].index_by { |attrs| attrs["id"] }
290
- @channel_id_by_name = Hash[response["channels"].map { |attrs| ["##{attrs["name"]}", attrs["id"]] }]
291
- end
292
-
293
- def fetch_groups!
294
- response = api("groups.list")
295
- @groups_by_id = response["groups"].index_by { |attrs| attrs["id"] }
296
- @group_id_by_name = Hash[response["groups"].map { |attrs| [attrs["name"], attrs["id"]] }]
258
+ def fetch_conversations!
259
+ conversations, ims = api("conversations.list")["channels"].partition { |attrs| attrs["is_channel"] || attrs["is_group"] }
260
+ user_ids_dm_ids.merge! Hash[ims.map { |attrs| attrs.values_at("user", "id") }]
261
+ @conversations_by_id = Hash[conversations.map { |attrs| [ attrs.fetch("id"), attrs ] }]
262
+ @conversation_ids_by_name = Hash[conversations.map { |attrs| [ attrs["name"], attrs["id"] ] }]
297
263
  end
298
264
 
299
265
  def fetch_users!
300
266
  response = api("users.list")
301
- @users_by_id = response["members"].index_by { |attrs| attrs["id"] }
267
+ @users_by_id = response["members"].each_with_object({}) { |attrs, hash| hash[attrs["id"]] = attrs }
302
268
  @user_id_by_name = Hash[response["members"].map { |attrs| ["@#{attrs["name"]}", attrs["id"]] }]
303
269
  end
304
270
 
305
271
 
306
272
 
307
- def missing_channel!(name)
308
- raise ArgumentError, "Couldn't find a channel named #{name}"
309
- end
310
-
311
- def missing_group!(name)
312
- raise ArgumentError, "Couldn't find a private group named #{name}"
273
+ def missing_conversation!(name)
274
+ raise ArgumentError, "Couldn't find a conversation named #{name}"
313
275
  end
314
276
 
315
277
  def missing_user!(name)
@@ -321,8 +283,7 @@ module Slacks
321
283
  def get_user_id_for_dm(dm)
322
284
  user_id = user_ids_dm_ids.key(dm)
323
285
  unless user_id
324
- response = api("im.list")
325
- user_ids_dm_ids.merge! Hash[response["ims"].map { |attrs| attrs.values_at("user", "id") }]
286
+ fetch_conversations!
326
287
  user_id = user_ids_dm_ids.key(dm)
327
288
  end
328
289
  raise ArgumentError, "Unable to find a user for the direct message ID #{dm.inspect}" unless user_id
@@ -331,9 +292,36 @@ module Slacks
331
292
 
332
293
 
333
294
 
334
- def api(command, options={})
335
- response = http.post(command, options.merge(token: token))
336
- MultiJson.load(response.body)
295
+ def api(command, page_limit: MAX_PAGES, **params)
296
+ params_with_token = params.merge(token: token)
297
+ response = api_post command, params_with_token
298
+ fetched_pages = 1
299
+ cursor = response.dig("response_metadata", "next_cursor")
300
+ while cursor && !cursor.empty? && fetched_pages < page_limit do
301
+ api_post(command, params_with_token.merge(cursor: cursor)).each do |key, value|
302
+ if value.is_a?(Array)
303
+ response[key].concat value
304
+ elsif value.is_a?(Hash)
305
+ response[key].merge! value
306
+ else
307
+ response[key] = value
308
+ end
309
+ end
310
+ fetched_pages += 1
311
+ cursor = response.dig("response_metadata", "next_cursor")
312
+ end
313
+ response
314
+ end
315
+
316
+ def api_post(command, params)
317
+ response = http.post(command, params)
318
+ response = MultiJson.load(response.body)
319
+ unless response["ok"]
320
+ response["error"].split(/,\s*/).each do |error_code|
321
+ raise ::Slacks::Response.fetch(error_code).new(command, params, response)
322
+ end
323
+ end
324
+ response
337
325
 
338
326
  rescue MultiJson::ParseError
339
327
  $!.additional_information[:response_body] = response.body
@@ -347,5 +335,22 @@ module Slacks
347
335
  end
348
336
  end
349
337
 
338
+
339
+
340
+ SEND_MESSAGE_PARAMS = %i{
341
+ username
342
+ as_user
343
+ parse
344
+ link_names
345
+ unfurl_links
346
+ unfurl_media
347
+ icon_url
348
+ icon_emoji
349
+ thread_ts
350
+ reply_broadcast
351
+ }.freeze
352
+
353
+ MAX_PAGES = 9001
354
+
350
355
  end
351
356
  end
data/lib/slacks/driver.rb CHANGED
@@ -70,6 +70,10 @@ module Slacks
70
70
  @driver.text(message)
71
71
  end
72
72
 
73
+ def ping
74
+ @driver.ping
75
+ end
76
+
73
77
  def connected?
74
78
  @connected || false
75
79
  end
data/lib/slacks/errors.rb CHANGED
@@ -1,19 +1,79 @@
1
1
  require "slacks/core_ext/exception"
2
2
 
3
3
  module Slacks
4
- class MigrationInProgress < RuntimeError
5
- def initialize
6
- super "Team is being migrated between servers. Try the request again in a few seconds."
4
+ module Response
5
+ class Error < RuntimeError
6
+ attr_reader :command, :params, :response
7
+
8
+ def initialize(command, params, response, message)
9
+ super message
10
+ @command = command
11
+ @params = params
12
+ @response = response
13
+ additional_information[:command] = command
14
+ additional_information[:params] = params
15
+ additional_information[:response] = response
16
+ end
7
17
  end
8
- end
9
18
 
10
- class ResponseError < RuntimeError
11
- attr_reader :response
19
+ class UnspecifiedError < ::Slacks::Response::Error
20
+ def initialize(command, params, response)
21
+ super command, params, response, "Request failed with #{response["error"].inspect}"
22
+ end
23
+ end
24
+
25
+ @_errors = {}
26
+
27
+ def self.fetch(error_code)
28
+ @_errors.fetch(error_code, ::Slacks::Response::UnspecifiedError)
29
+ end
30
+
31
+ {
32
+ "account_inactive" => "Authentication token is for a deleted user or team.",
33
+ "already_reacted" => "The specified item already has the user/reaction combination.",
34
+ "bad_timestamp" => "Value passed for timestamp was invalid.",
35
+ "cant_update_message" => "Authenticated user does not have permission to update this message.",
36
+ "channel_not_found" => "Value passed for channel was invalid.",
37
+ "edit_window_closed" => "The message cannot be edited due to the team message edit settings",
38
+ "fatal_error" => "",
39
+ "file_comment_not_found" => "File comment specified by file_comment does not exist.",
40
+ "file_not_found" => "File specified by file does not exist.",
41
+ "invalid_arg_name" => "The method was passed an argument whose name falls outside the bounds of common decency. This includes very long names and names with non-alphanumeric characters other than _. If you get this error, it is typically an indication that you have made a very malformed API call.",
42
+ "invalid_array_arg" => "The method was passed a PHP-style array argument (e.g. with a name like foo[7]). These are never valid with the Slack API.",
43
+ "invalid_auth" => "Invalid authentication token.",
44
+ "invalid_charset" => "The method was called via a POST request, but the charset specified in the Content-Type header was invalid. Valid charset names are: utf-8 iso-8859-1.",
45
+ "invalid_form_data" => "The method was called via a POST request with Content-Type application/x-www-form-urlencoded or multipart/form-data, but the form data was either missing or syntactically invalid.",
46
+ "invalid_name" => "Value passed for name was invalid.",
47
+ "invalid_post_type" => "The method was called via a POST request, but the specified Content-Type was invalid. Valid types are: application/json application/x-www-form-urlencoded multipart/form-data text/plain.",
48
+ "is_archived" => "Channel has been archived.",
49
+ "message_not_found" => "Message specified by channel and timestamp does not exist.",
50
+ "migration_in_progress" => "Team is being migrated between servers. See the team_migration_started event documentation for details.",
51
+ "missing_post_type" => "The method was called via a POST request and included a data payload, but the request did not include a Content-Type header.",
52
+ "msg_too_long" => "Message text is too long",
53
+ "no_item_specified" => "file, file_comment, or combination of channel and timestamp was not specified.",
54
+ "no_text" => "No message text provided",
55
+ "not_authed" => "No authentication token provided.",
56
+ "not_in_channel" => "Cannot post user messages to a channel they are not in.",
57
+ "rate_limited" => "Application has posted too many messages, read the Rate Limit documentation for more information",
58
+ "request_timeout" => "The method was called via a POST request, but the POST data was either missing or truncated.",
59
+ "too_many_attachments" => "Too many attachments were provided with this message. A maximum of 100 attachments are allowed on a message.",
60
+ "too_many_emoji" => "The limit for distinct reactions (i.e emoji) on the item has been reached.",
61
+ "too_many_reactions" => "The limit for reactions a person may add to the item has been reached."
62
+ }.each do |error_code, message|
63
+ class_name = error_code.gsub(/(?:^|_)([a-z]+)/) { $1.capitalize }
64
+ class_name = {
65
+ "MsgTooLong" => "MessageTooLong"
66
+ }.fetch(class_name, class_name)
67
+
68
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
69
+ class #{class_name} < ::Slacks::Response::Error
70
+ def initialize(command, params, response)
71
+ super command, params, response, "#{message}"
72
+ end
73
+ end
12
74
 
13
- def initialize(response, message)
14
- super message
15
- @response = response
16
- additional_information[:response] = response
75
+ @_errors["#{error_code}"] = ::Slacks::Response::#{class_name}
76
+ RUBY
17
77
  end
18
78
  end
19
79
 
@@ -24,21 +84,21 @@ module Slacks
24
84
  end
25
85
  end
26
86
 
27
- class AlreadyRespondedError < RuntimeError
28
- def initialize(message=nil)
29
- super message || "You have already replied to this Slash Command; you can only reply once"
30
- end
31
- end
32
-
33
87
  class NotInChannelError < RuntimeError
34
88
  def initialize(channel)
35
89
  super "The bot is not in the channel #{channel} and cannot reply"
36
90
  end
37
91
  end
38
92
 
39
- class UnableToDirectMessageError < ResponseError
40
- def initialize(response, user_id)
41
- super response, "Unable to direct message the user #{user_id.inspect}: #{response["error"]}"
93
+ class MissingTokenError < ArgumentError
94
+ def initialize
95
+ super "Unable to connect to Slack; a token has no"
96
+ end
97
+ end
98
+
99
+ class NotListeningError < ArgumentError
100
+ def initialize
101
+ super "Not connected to the RTM API; call `listen!` first"
42
102
  end
43
103
  end
44
104
  end
@@ -1,3 +1,3 @@
1
1
  module Slacks
2
- VERSION = "0.4.3"
2
+ VERSION = "0.6.1"
3
3
  end
data/slacks.gemspec CHANGED
@@ -25,8 +25,8 @@ Gem::Specification.new do |spec|
25
25
  spec.add_dependency "faraday-raise-errors"
26
26
  spec.add_dependency "concurrent-ruby"
27
27
 
28
- spec.add_development_dependency "bundler", "~> 1.10"
29
- spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "bundler"
29
+ spec.add_development_dependency "rake"
30
30
  spec.add_development_dependency "minitest", "~> 5.0"
31
31
  spec.add_development_dependency "pry"
32
32
  spec.add_development_dependency "minitest-reporters"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slacks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bob Lail
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-10-14 00:00:00.000000000 Z
11
+ date: 2021-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: websocket-driver
@@ -84,30 +84,30 @@ dependencies:
84
84
  name: bundler
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: '1.10'
89
+ version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: '1.10'
96
+ version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rake
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '10.0'
103
+ version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: '10.0'
110
+ version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: minitest
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -164,7 +164,7 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
- description:
167
+ description:
168
168
  email:
169
169
  - bob.lailfamily@gmail.com
170
170
  executables: []
@@ -196,7 +196,7 @@ homepage: https://github.com/houston/slacks
196
196
  licenses:
197
197
  - MIT
198
198
  metadata: {}
199
- post_install_message:
199
+ post_install_message:
200
200
  rdoc_options: []
201
201
  require_paths:
202
202
  - lib
@@ -211,9 +211,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
211
211
  - !ruby/object:Gem::Version
212
212
  version: '0'
213
213
  requirements: []
214
- rubyforge_project:
215
- rubygems_version: 2.2.2
216
- signing_key:
214
+ rubygems_version: 3.1.2
215
+ signing_key:
217
216
  specification_version: 4
218
217
  summary: A library for communicating via Slack
219
218
  test_files: []