slacks 0.5.0 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +14 -0
- data/lib/slacks/connection.rb +76 -76
- data/lib/slacks/version.rb +1 -1
- data/slacks.gemspec +2 -3
- metadata +15 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ffbca3af38608a41841c035811bd052e30a2a2acd39bf58fbef037a1b4ab8bd1
|
4
|
+
data.tar.gz: 29e54298f59bbbca5b1eb25d90e7d7496bd7d77535a8b03c50afee5fbbaee43a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39d1b8223ac325f57bde88ab86134f0705a3d0ca28da6e88e5f0b3cf8f6e9853e361fb11b8bde50b4bb51d6c4d84a66df685f8b8a129f290cf9a69d09c61ad02
|
7
|
+
data.tar.gz: 2eab93bf02fcf7fef3a5c8844ac42a9a992fd1fd991f6ac708d1ec1d91cf001d5ebb0dfe42a7dec80d7640b624acaa3138431e445d3e63c6d0f4d19c795168f7
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
### v0.6.4
|
2
|
+
- Removed reliance on faraday-raise-errors in favor of using built-in Faraday::RaiseError middleware
|
3
|
+
|
4
|
+
### v0.6.3
|
5
|
+
- Removed remaining calls to `.present?`, since we're not actually dependent on ActiveSupport
|
6
|
+
|
7
|
+
### v0.6.2
|
8
|
+
- Fixed a regression where groups, DMs, and private channels were not fetched
|
9
|
+
|
10
|
+
### v0.6.1
|
11
|
+
- Fixed a typo with creating a DM associated with a user
|
12
|
+
|
13
|
+
### v0.6.0
|
14
|
+
- Switched to using the Slack Conversations API
|
data/lib/slacks/connection.rb
CHANGED
@@ -7,7 +7,6 @@ require "slacks/guest_channel"
|
|
7
7
|
require "slacks/team"
|
8
8
|
require "slacks/user"
|
9
9
|
require "faraday"
|
10
|
-
require "faraday/raise_errors"
|
11
10
|
|
12
11
|
module Slacks
|
13
12
|
class Connection
|
@@ -24,10 +23,8 @@ module Slacks
|
|
24
23
|
@user_ids_dm_ids = {}
|
25
24
|
@users_by_id = {}
|
26
25
|
@user_id_by_name = {}
|
27
|
-
@
|
28
|
-
@
|
29
|
-
@channels_by_id = {}
|
30
|
-
@channel_id_by_name = {}
|
26
|
+
@conversations_by_id = {}
|
27
|
+
@conversation_ids_by_name = {}
|
31
28
|
end
|
32
29
|
|
33
30
|
|
@@ -42,7 +39,7 @@ module Slacks
|
|
42
39
|
link_names: 1} # find and link channel names and user names
|
43
40
|
params.merge!(attachments: MultiJson.dump(attachments)) if attachments.any?
|
44
41
|
params.merge!(options.select { |key, _| SEND_MESSAGE_PARAMS.member?(key) })
|
45
|
-
api("chat.postMessage", params)
|
42
|
+
api("chat.postMessage", **params)
|
46
43
|
end
|
47
44
|
alias :say :send_message
|
48
45
|
|
@@ -50,7 +47,7 @@ module Slacks
|
|
50
47
|
params = {
|
51
48
|
channel: to_channel_id(channel),
|
52
49
|
timestamp: ts }
|
53
|
-
api("reactions.get", params)
|
50
|
+
api("reactions.get", **params)
|
54
51
|
end
|
55
52
|
|
56
53
|
def update_message(ts, message, options={})
|
@@ -65,15 +62,15 @@ module Slacks
|
|
65
62
|
params.merge!(attachments: MultiJson.dump(attachments)) if attachments.any?
|
66
63
|
params.merge!(options.select { |key, _| [:username, :as_user, :parse, :link_names,
|
67
64
|
:unfurl_links, :unfurl_media, :icon_url, :icon_emoji].member?(key) })
|
68
|
-
api("chat.update", params)
|
65
|
+
api("chat.update", **params)
|
69
66
|
end
|
70
67
|
|
71
68
|
def add_reaction(emojis, message)
|
72
69
|
Array(emojis).each do |emoji|
|
73
|
-
api("reactions.add",
|
70
|
+
api("reactions.add",
|
74
71
|
name: emoji.gsub(/^:|:$/, ""),
|
75
72
|
channel: message.channel.id,
|
76
|
-
timestamp: message.timestamp
|
73
|
+
timestamp: message.timestamp)
|
77
74
|
end
|
78
75
|
end
|
79
76
|
|
@@ -116,21 +113,16 @@ module Slacks
|
|
116
113
|
# one, we'll skill it.
|
117
114
|
next
|
118
115
|
|
119
|
-
when EVENT_GROUP_JOINED
|
120
|
-
|
121
|
-
@
|
122
|
-
@
|
116
|
+
when EVENT_GROUP_JOINED, EVENT_CHANNEL_CREATED
|
117
|
+
conversation = data["channel"]
|
118
|
+
@conversations_by_id[conversation["id"]] = conversation
|
119
|
+
@conversation_ids_by_name[conversation["name"]] = conversation["id"]
|
123
120
|
|
124
121
|
when EVENT_USER_JOINED
|
125
122
|
user = data["user"]
|
126
123
|
@users_by_id[user["id"]] = user
|
127
124
|
@user_id_by_name[user["name"]] = user["id"]
|
128
125
|
|
129
|
-
when EVENT_CHANNEL_CREATED
|
130
|
-
channel = data["channel"]
|
131
|
-
@channels_by_id[channel["id"]] = channel
|
132
|
-
@channel_id_by_name[channel["name"]] = channel["id"]
|
133
|
-
|
134
126
|
when EVENT_MESSAGE
|
135
127
|
# Don't respond to things that this bot said
|
136
128
|
next if data["user"] == bot.id
|
@@ -157,17 +149,17 @@ module Slacks
|
|
157
149
|
|
158
150
|
|
159
151
|
def channels
|
160
|
-
channels = user_id_by_name.keys +
|
152
|
+
channels = user_id_by_name.keys + conversation_ids_by_name.keys
|
161
153
|
if channels.empty?
|
162
|
-
|
163
|
-
fetch_groups!
|
154
|
+
fetch_conversations!
|
164
155
|
fetch_users!
|
165
156
|
end
|
166
157
|
channels
|
167
158
|
end
|
168
159
|
|
169
160
|
def can_see?(channel)
|
170
|
-
to_channel_id(channel)
|
161
|
+
channel_id = to_channel_id(channel)
|
162
|
+
channel_id && !channel_id.empty?
|
171
163
|
rescue ArgumentError
|
172
164
|
false
|
173
165
|
end
|
@@ -183,21 +175,28 @@ module Slacks
|
|
183
175
|
"id" => id,
|
184
176
|
"is_im" => true,
|
185
177
|
"name" => user.username }
|
186
|
-
when /^G/
|
187
|
-
Slacks::Channel.new(self, groups_by_id.fetch(id) do
|
188
|
-
raise ArgumentError, "Unable to find a group with the ID #{id.inspect}"
|
189
|
-
end)
|
190
178
|
else
|
191
|
-
Slacks::Channel.new(self,
|
192
|
-
|
193
|
-
|
179
|
+
Slacks::Channel.new(self, find_conversation(id))
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def find_conversation(id)
|
184
|
+
conversations_by_id.fetch(id) do
|
185
|
+
fetch_conversations!
|
186
|
+
conversations_by_id.fetch(id) do
|
187
|
+
raise ArgumentError, "Unable to find a conversation with the ID #{id.inspect}"
|
188
|
+
end
|
194
189
|
end
|
195
190
|
end
|
196
191
|
|
197
192
|
def find_user(id)
|
198
|
-
|
199
|
-
|
200
|
-
|
193
|
+
user = users_by_id.fetch(id) do
|
194
|
+
fetch_users!
|
195
|
+
users_by_id.fetch(id) do
|
196
|
+
raise ArgumentError, "Unable to find a user with the ID #{id.inspect}"
|
197
|
+
end
|
198
|
+
end
|
199
|
+
Slacks::User.new(self, user)
|
201
200
|
end
|
202
201
|
|
203
202
|
def find_user_by_nickname(nickname)
|
@@ -208,7 +207,8 @@ module Slacks
|
|
208
207
|
|
209
208
|
def user_exists?(username)
|
210
209
|
return false if username.nil?
|
211
|
-
to_user_id(username)
|
210
|
+
user_id = to_user_id(username)
|
211
|
+
user_id && !user_id.empty?
|
212
212
|
rescue ArgumentError
|
213
213
|
false
|
214
214
|
end
|
@@ -224,10 +224,8 @@ module Slacks
|
|
224
224
|
attr_reader :user_ids_dm_ids,
|
225
225
|
:users_by_id,
|
226
226
|
:user_id_by_name,
|
227
|
-
:
|
228
|
-
:
|
229
|
-
:channels_by_id,
|
230
|
-
:channel_id_by_name,
|
227
|
+
:conversations_by_id,
|
228
|
+
:conversation_ids_by_name,
|
231
229
|
:websocket_url,
|
232
230
|
:websocket
|
233
231
|
|
@@ -238,14 +236,8 @@ module Slacks
|
|
238
236
|
@bot = BotUser.new(response.fetch("self"))
|
239
237
|
@team = Team.new(response.fetch("team"))
|
240
238
|
|
241
|
-
@
|
242
|
-
@
|
243
|
-
|
244
|
-
@users_by_id = Hash[response.fetch("users").map { |attrs| [attrs.fetch("id"), attrs] }]
|
245
|
-
@user_id_by_name = Hash[response.fetch("users").map { |attrs| ["@#{attrs.fetch("name")}", attrs.fetch("id")] }]
|
246
|
-
|
247
|
-
@groups_by_id = Hash[response.fetch("groups").map { |attrs| [attrs.fetch("id"), attrs] }]
|
248
|
-
@group_id_by_name = Hash[response.fetch("groups").map { |attrs| [attrs.fetch("name"), attrs.fetch("id")] }]
|
239
|
+
@conversations_by_id = Hash[response.fetch("channels").map { |attrs| [ attrs.fetch("id"), attrs ] }]
|
240
|
+
@conversation_ids_by_name = Hash[response.fetch("channels").map { |attrs| [ attrs["name"], attrs["id"] ] }]
|
249
241
|
end
|
250
242
|
|
251
243
|
|
@@ -254,13 +246,9 @@ module Slacks
|
|
254
246
|
return name.id if name.is_a?(Slacks::Channel)
|
255
247
|
return name if name =~ /^[DGC]/ # this already looks like a channel id
|
256
248
|
return get_dm_for_username(name) if name.start_with?("@")
|
257
|
-
return to_group_id(name) unless name.start_with?("#")
|
258
|
-
|
259
|
-
channel_id_by_name[name] || fetch_channels![name] || missing_channel!(name)
|
260
|
-
end
|
261
249
|
|
262
|
-
|
263
|
-
|
250
|
+
name = name.gsub(/^#/, "") # Leading hashes are no longer a thing in the conversations API
|
251
|
+
conversation_ids_by_name[name] || fetch_conversations![name] || missing_conversation!(name)
|
264
252
|
end
|
265
253
|
|
266
254
|
def to_user_id(name)
|
@@ -273,39 +261,29 @@ module Slacks
|
|
273
261
|
|
274
262
|
def get_dm_for_user_id(user_id)
|
275
263
|
user_ids_dm_ids[user_id] ||= begin
|
276
|
-
response = api("
|
264
|
+
response = api("conversations.open", users: user_id)
|
277
265
|
response["channel"]["id"]
|
278
266
|
end
|
279
267
|
end
|
280
268
|
|
281
269
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
@
|
286
|
-
@
|
287
|
-
end
|
288
|
-
|
289
|
-
def fetch_groups!
|
290
|
-
response = api("groups.list")
|
291
|
-
@groups_by_id = response["groups"].index_by { |attrs| attrs["id"] }
|
292
|
-
@group_id_by_name = Hash[response["groups"].map { |attrs| [attrs["name"], attrs["id"]] }]
|
270
|
+
def fetch_conversations!
|
271
|
+
conversations, ims = api("conversations.list", types: "public_channel,private_channel,mpim,im")["channels"].partition { |attrs| attrs["is_channel"] || attrs["is_group"] }
|
272
|
+
user_ids_dm_ids.merge! Hash[ims.map { |attrs| attrs.values_at("user", "id") }]
|
273
|
+
@conversations_by_id = Hash[conversations.map { |attrs| [ attrs.fetch("id"), attrs ] }]
|
274
|
+
@conversation_ids_by_name = Hash[conversations.map { |attrs| [ attrs["name"], attrs["id"] ] }]
|
293
275
|
end
|
294
276
|
|
295
277
|
def fetch_users!
|
296
278
|
response = api("users.list")
|
297
|
-
@users_by_id = response["members"].
|
279
|
+
@users_by_id = response["members"].each_with_object({}) { |attrs, hash| hash[attrs["id"]] = attrs }
|
298
280
|
@user_id_by_name = Hash[response["members"].map { |attrs| ["@#{attrs["name"]}", attrs["id"]] }]
|
299
281
|
end
|
300
282
|
|
301
283
|
|
302
284
|
|
303
|
-
def
|
304
|
-
raise ArgumentError, "Couldn't find a
|
305
|
-
end
|
306
|
-
|
307
|
-
def missing_group!(name)
|
308
|
-
raise ArgumentError, "Couldn't find a private group named #{name}"
|
285
|
+
def missing_conversation!(name)
|
286
|
+
raise ArgumentError, "Couldn't find a conversation named #{name}"
|
309
287
|
end
|
310
288
|
|
311
289
|
def missing_user!(name)
|
@@ -317,8 +295,7 @@ module Slacks
|
|
317
295
|
def get_user_id_for_dm(dm)
|
318
296
|
user_id = user_ids_dm_ids.key(dm)
|
319
297
|
unless user_id
|
320
|
-
|
321
|
-
user_ids_dm_ids.merge! Hash[response["ims"].map { |attrs| attrs.values_at("user", "id") }]
|
298
|
+
fetch_conversations!
|
322
299
|
user_id = user_ids_dm_ids.key(dm)
|
323
300
|
end
|
324
301
|
raise ArgumentError, "Unable to find a user for the direct message ID #{dm.inspect}" unless user_id
|
@@ -327,8 +304,29 @@ module Slacks
|
|
327
304
|
|
328
305
|
|
329
306
|
|
330
|
-
def api(command, params
|
331
|
-
|
307
|
+
def api(command, page_limit: MAX_PAGES, **params)
|
308
|
+
params_with_token = params.merge(token: token)
|
309
|
+
response = api_post command, params_with_token
|
310
|
+
fetched_pages = 1
|
311
|
+
cursor = response.dig("response_metadata", "next_cursor")
|
312
|
+
while cursor && !cursor.empty? && fetched_pages < page_limit do
|
313
|
+
api_post(command, params_with_token.merge(cursor: cursor)).each do |key, value|
|
314
|
+
if value.is_a?(Array)
|
315
|
+
response[key].concat value
|
316
|
+
elsif value.is_a?(Hash)
|
317
|
+
response[key].merge! value
|
318
|
+
else
|
319
|
+
response[key] = value
|
320
|
+
end
|
321
|
+
end
|
322
|
+
fetched_pages += 1
|
323
|
+
cursor = response.dig("response_metadata", "next_cursor")
|
324
|
+
end
|
325
|
+
response
|
326
|
+
end
|
327
|
+
|
328
|
+
def api_post(command, params)
|
329
|
+
response = http.post(command, params)
|
332
330
|
response = MultiJson.load(response.body)
|
333
331
|
unless response["ok"]
|
334
332
|
response["error"].split(/,\s*/).each do |error_code|
|
@@ -345,7 +343,7 @@ module Slacks
|
|
345
343
|
|
346
344
|
def http
|
347
345
|
@http ||= Faraday.new(url: "https://slack.com/api").tap do |connection|
|
348
|
-
connection.
|
346
|
+
connection.response :raise_error
|
349
347
|
end
|
350
348
|
end
|
351
349
|
|
@@ -364,5 +362,7 @@ module Slacks
|
|
364
362
|
reply_broadcast
|
365
363
|
}.freeze
|
366
364
|
|
365
|
+
MAX_PAGES = 9001
|
366
|
+
|
367
367
|
end
|
368
368
|
end
|
data/lib/slacks/version.rb
CHANGED
data/slacks.gemspec
CHANGED
@@ -22,11 +22,10 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_dependency "websocket-driver"
|
23
23
|
spec.add_dependency "multi_json"
|
24
24
|
spec.add_dependency "faraday"
|
25
|
-
spec.add_dependency "faraday-raise-errors"
|
26
25
|
spec.add_dependency "concurrent-ruby"
|
27
26
|
|
28
|
-
spec.add_development_dependency "bundler"
|
29
|
-
spec.add_development_dependency "rake"
|
27
|
+
spec.add_development_dependency "bundler"
|
28
|
+
spec.add_development_dependency "rake"
|
30
29
|
spec.add_development_dependency "minitest", "~> 5.0"
|
31
30
|
spec.add_development_dependency "pry"
|
32
31
|
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
|
+
version: 0.6.4
|
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:
|
11
|
+
date: 2021-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: websocket-driver
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: concurrent-ruby
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,47 +67,33 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
|
-
type: :
|
76
|
+
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: bundler
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '1.10'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '1.10'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: rake
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
|
-
- - "
|
87
|
+
- - ">="
|
102
88
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
89
|
+
version: '0'
|
104
90
|
type: :development
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
|
-
- - "
|
94
|
+
- - ">="
|
109
95
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
96
|
+
version: '0'
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
98
|
name: minitest
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,7 +150,7 @@ dependencies:
|
|
164
150
|
- - ">="
|
165
151
|
- !ruby/object:Gem::Version
|
166
152
|
version: '0'
|
167
|
-
description:
|
153
|
+
description:
|
168
154
|
email:
|
169
155
|
- bob.lailfamily@gmail.com
|
170
156
|
executables: []
|
@@ -173,6 +159,7 @@ extra_rdoc_files: []
|
|
173
159
|
files:
|
174
160
|
- ".gitignore"
|
175
161
|
- ".travis.yml"
|
162
|
+
- CHANGELOG.md
|
176
163
|
- Gemfile
|
177
164
|
- LICENSE.txt
|
178
165
|
- README.md
|
@@ -196,7 +183,7 @@ homepage: https://github.com/houston/slacks
|
|
196
183
|
licenses:
|
197
184
|
- MIT
|
198
185
|
metadata: {}
|
199
|
-
post_install_message:
|
186
|
+
post_install_message:
|
200
187
|
rdoc_options: []
|
201
188
|
require_paths:
|
202
189
|
- lib
|
@@ -211,9 +198,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
211
198
|
- !ruby/object:Gem::Version
|
212
199
|
version: '0'
|
213
200
|
requirements: []
|
214
|
-
|
215
|
-
|
216
|
-
signing_key:
|
201
|
+
rubygems_version: 3.1.2
|
202
|
+
signing_key:
|
217
203
|
specification_version: 4
|
218
204
|
summary: A library for communicating via Slack
|
219
205
|
test_files: []
|