slacks 0.4.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4655b64b95738df424e627dd671d219ee46c55e3
4
- data.tar.gz: d5f1d21638a975aeb802d17a2b00d814b14579f3
2
+ SHA256:
3
+ metadata.gz: 3042bf152b61c2caa8a3b4fe792b49822d46915712a8573f6bcafc86132ae2b8
4
+ data.tar.gz: 116df1499c672f6d72c23894c4b9abe0133cbe855766175488384509845c5ec0
5
5
  SHA512:
6
- metadata.gz: 5742d45eb577916616ddba1bbe6b2b231ddb501a0795320aa4de58049a037f2f3b16101f4199093c068c4deebcb970f732a752ed050a2213926b422b3eaf5804
7
- data.tar.gz: a1df56de686279475cb65b2fb7b14afe49afe01b407f654eeafa48f3efb109c928d55289ce0e0aacab4e030590ea8241eab1d48d8bc950719704fe1a847ecdc2
6
+ metadata.gz: c1f5d964031547e6d9160d465a4b894f76aa7bbe3174c98dc7bb36964c52eddbb5a5d527c9bcfbd67f7aad93b5fe0869acc8ea0faa07fa97217f129bd537ad27
7
+ data.tar.gz: 03b84265b6fe59c1d2858fc12a8274fdb1301575b142f224ea6dd8d6f811c81b94dd9cab6918548e4c7249b57dd695b39bead9a5d0173af964edd334689b2a26
@@ -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,7 +150,18 @@ module Slacks
158
150
 
159
151
 
160
152
  def channels
161
- 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
154
+ if channels.empty?
155
+ fetch_conversations!
156
+ fetch_users!
157
+ end
158
+ channels
159
+ end
160
+
161
+ def can_see?(channel)
162
+ to_channel_id(channel).present?
163
+ rescue ArgumentError
164
+ false
162
165
  end
163
166
 
164
167
 
@@ -172,13 +175,9 @@ module Slacks
172
175
  "id" => id,
173
176
  "is_im" => true,
174
177
  "name" => user.username }
175
- when /^G/
176
- Slacks::Channel.new(self, groups_by_id.fetch(id) do
177
- raise ArgumentError, "Unable to find a group with the ID #{id.inspect}"
178
- end)
179
178
  else
180
- Slacks::Channel.new(self, channels_by_id.fetch(id) do
181
- 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}"
182
181
  end)
183
182
  end
184
183
  end
@@ -213,10 +212,8 @@ module Slacks
213
212
  attr_reader :user_ids_dm_ids,
214
213
  :users_by_id,
215
214
  :user_id_by_name,
216
- :groups_by_id,
217
- :group_id_by_name,
218
- :channels_by_id,
219
- :channel_id_by_name,
215
+ :conversations_by_id,
216
+ :conversation_ids_by_name,
220
217
  :websocket_url,
221
218
  :websocket
222
219
 
@@ -227,16 +224,8 @@ module Slacks
227
224
  @bot = BotUser.new(response.fetch("self"))
228
225
  @team = Team.new(response.fetch("team"))
229
226
 
230
- @channels_by_id = Hash[response.fetch("channels").map { |attrs| [attrs.fetch("id"), attrs] }]
231
- @channel_id_by_name = Hash[response.fetch("channels").map { |attrs| ["##{attrs.fetch("name")}", attrs.fetch("id")] }]
232
-
233
- @users_by_id = Hash[response.fetch("users").map { |attrs| [attrs.fetch("id"), attrs] }]
234
- @user_id_by_name = Hash[response.fetch("users").map { |attrs| ["@#{attrs.fetch("name")}", attrs.fetch("id")] }]
235
-
236
- @groups_by_id = Hash[response.fetch("groups").map { |attrs| [attrs.fetch("id"), attrs] }]
237
- @group_id_by_name = Hash[response.fetch("groups").map { |attrs| [attrs.fetch("name"), attrs.fetch("id")] }]
238
- rescue KeyError
239
- 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"] ] }]
240
229
  end
241
230
 
242
231
 
@@ -245,13 +234,9 @@ module Slacks
245
234
  return name.id if name.is_a?(Slacks::Channel)
246
235
  return name if name =~ /^[DGC]/ # this already looks like a channel id
247
236
  return get_dm_for_username(name) if name.start_with?("@")
248
- return to_group_id(name) unless name.start_with?("#")
249
237
 
250
- channel_id_by_name[name] || fetch_channels![name] || missing_channel!(name)
251
- end
252
-
253
- def to_group_id(name)
254
- 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)
255
240
  end
256
241
 
257
242
  def to_user_id(name)
@@ -264,40 +249,29 @@ module Slacks
264
249
 
265
250
  def get_dm_for_user_id(user_id)
266
251
  user_ids_dm_ids[user_id] ||= begin
267
- response = api("im.open", user: user_id)
268
- raise UnableToDirectMessageError.new(response, user_id) unless response["ok"]
252
+ response = api("conversations.open", user: user_id)
269
253
  response["channel"]["id"]
270
254
  end
271
255
  end
272
256
 
273
257
 
274
-
275
- def fetch_channels!
276
- response = api("channels.list")
277
- @channels_by_id = response["channels"].index_by { |attrs| attrs["id"] }
278
- @channel_id_by_name = Hash[response["channels"].map { |attrs| ["##{attrs["name"]}", attrs["id"]] }]
279
- end
280
-
281
- def fetch_groups!
282
- response = api("groups.list")
283
- @groups_by_id = response["groups"].index_by { |attrs| attrs["id"] }
284
- @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"] ] }]
285
263
  end
286
264
 
287
265
  def fetch_users!
288
266
  response = api("users.list")
289
- @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 }
290
268
  @user_id_by_name = Hash[response["members"].map { |attrs| ["@#{attrs["name"]}", attrs["id"]] }]
291
269
  end
292
270
 
293
271
 
294
272
 
295
- def missing_channel!(name)
296
- raise ArgumentError, "Couldn't find a channel named #{name}"
297
- end
298
-
299
- def missing_group!(name)
300
- 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}"
301
275
  end
302
276
 
303
277
  def missing_user!(name)
@@ -309,8 +283,7 @@ module Slacks
309
283
  def get_user_id_for_dm(dm)
310
284
  user_id = user_ids_dm_ids.key(dm)
311
285
  unless user_id
312
- response = api("im.list")
313
- user_ids_dm_ids.merge! Hash[response["ims"].map { |attrs| attrs.values_at("user", "id") }]
286
+ fetch_conversations!
314
287
  user_id = user_ids_dm_ids.key(dm)
315
288
  end
316
289
  raise ArgumentError, "Unable to find a user for the direct message ID #{dm.inspect}" unless user_id
@@ -319,9 +292,36 @@ module Slacks
319
292
 
320
293
 
321
294
 
322
- def api(command, options={})
323
- response = http.post(command, options.merge(token: token))
324
- 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
325
325
 
326
326
  rescue MultiJson::ParseError
327
327
  $!.additional_information[:response_body] = response.body
@@ -335,5 +335,22 @@ module Slacks
335
335
  end
336
336
  end
337
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
+
338
355
  end
339
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.2"
2
+ VERSION = "0.6.0"
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.2
4
+ version: 0.6.0
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-09-02 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: []