stream-chat-ruby 2.20.0 → 2.22.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 +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +29 -0
- data/CONTRIBUTING.md +64 -0
- data/Gemfile +2 -0
- data/README.md +69 -117
- data/lib/stream-chat/channel.rb +111 -6
- data/lib/stream-chat/client.rb +355 -30
- data/lib/stream-chat/errors.rb +22 -9
- data/lib/stream-chat/stream_rate_limits.rb +16 -5
- data/lib/stream-chat/stream_response.rb +21 -8
- data/lib/stream-chat/types.rb +13 -0
- data/lib/stream-chat/util.rb +16 -6
- data/lib/stream-chat/version.rb +2 -3
- data/lib/stream-chat.rb +2 -1
- data/stream-chat.gemspec +3 -1
- metadata +32 -2
data/lib/stream-chat/channel.rb
CHANGED
@@ -1,49 +1,77 @@
|
|
1
|
+
# typed: strict
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
4
|
+
require 'stream-chat/client'
|
3
5
|
require 'stream-chat/errors'
|
4
6
|
require 'stream-chat/util'
|
7
|
+
require 'stream-chat/types'
|
5
8
|
|
6
9
|
module StreamChat
|
7
|
-
class Channel
|
10
|
+
class Channel
|
11
|
+
extend T::Sig
|
12
|
+
T::Configuration.default_checked_level = :never
|
13
|
+
# For now we disable runtime type checks.
|
14
|
+
# We will enable it with a major bump in the future,
|
15
|
+
# but for now, let's just run a static type check.
|
16
|
+
|
17
|
+
sig { returns(T.nilable(String)) }
|
8
18
|
attr_reader :id
|
19
|
+
|
20
|
+
sig { returns(String) }
|
9
21
|
attr_reader :channel_type
|
22
|
+
|
23
|
+
sig { returns(StringKeyHash) }
|
10
24
|
attr_reader :custom_data
|
25
|
+
|
26
|
+
sig { returns(T::Array[StringKeyHash]) }
|
11
27
|
attr_reader :members
|
12
28
|
|
29
|
+
sig { params(client: StreamChat::Client, channel_type: String, channel_id: T.nilable(String), custom_data: T.nilable(StringKeyHash)).void }
|
13
30
|
def initialize(client, channel_type, channel_id = nil, custom_data = nil)
|
14
31
|
@channel_type = channel_type
|
15
32
|
@id = channel_id
|
16
|
-
@cid = "#{@channel_type}:#{@id}"
|
33
|
+
@cid = T.let("#{@channel_type}:#{@id}", String)
|
17
34
|
@client = client
|
18
|
-
@custom_data = custom_data
|
19
|
-
@
|
35
|
+
@custom_data = T.let(custom_data || {}, StringKeyHash)
|
36
|
+
@members = T.let([], T::Array[StringKeyHash])
|
20
37
|
end
|
21
38
|
|
39
|
+
sig { returns(String) }
|
22
40
|
def url
|
23
41
|
raise StreamChannelException, 'channel does not have an id' if @id.nil?
|
24
42
|
|
25
43
|
"channels/#{@channel_type}/#{@id}"
|
26
44
|
end
|
27
45
|
|
46
|
+
# Gets multiple messages from the channel.
|
47
|
+
sig { params(message_ids: T::Array[String]).returns(StreamChat::StreamResponse) }
|
28
48
|
def get_messages(message_ids)
|
29
49
|
@client.get("#{url}/messages", params: { 'ids' => message_ids.join(',') })
|
30
50
|
end
|
31
51
|
|
52
|
+
# Sends a message to this channel.
|
53
|
+
sig { params(message: StringKeyHash, user_id: String).returns(StreamChat::StreamResponse) }
|
32
54
|
def send_message(message, user_id)
|
33
55
|
payload = { message: add_user_id(message, user_id) }
|
34
56
|
@client.post("#{url}/message", data: payload)
|
35
57
|
end
|
36
58
|
|
59
|
+
# Sends an event on this channel.
|
60
|
+
sig { params(event: StringKeyHash, user_id: String).returns(StreamChat::StreamResponse) }
|
37
61
|
def send_event(event, user_id)
|
38
62
|
payload = { 'event' => add_user_id(event, user_id) }
|
39
63
|
@client.post("#{url}/event", data: payload)
|
40
64
|
end
|
41
65
|
|
66
|
+
# Sends a new reaction to a given message.
|
67
|
+
sig { params(message_id: String, reaction: StringKeyHash, user_id: String).returns(StreamChat::StreamResponse) }
|
42
68
|
def send_reaction(message_id, reaction, user_id)
|
43
69
|
payload = { reaction: add_user_id(reaction, user_id) }
|
44
70
|
@client.post("messages/#{message_id}/reaction", data: payload)
|
45
71
|
end
|
46
72
|
|
73
|
+
# Delete a reaction from a message.
|
74
|
+
sig { params(message_id: String, reaction_type: String, user_id: String).returns(StreamChat::StreamResponse) }
|
47
75
|
def delete_reaction(message_id, reaction_type, user_id)
|
48
76
|
@client.delete(
|
49
77
|
"messages/#{message_id}/reaction/#{reaction_type}",
|
@@ -51,11 +79,15 @@ module StreamChat
|
|
51
79
|
)
|
52
80
|
end
|
53
81
|
|
82
|
+
# Creates a channel with the given creator user.
|
83
|
+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
|
54
84
|
def create(user_id)
|
55
85
|
@custom_data['created_by'] = { id: user_id }
|
56
86
|
query(watch: false, state: false, presence: false)
|
57
87
|
end
|
58
88
|
|
89
|
+
# Creates or returns a channel.
|
90
|
+
sig { params(options: T.untyped).returns(StreamChat::StreamResponse) }
|
59
91
|
def query(**options)
|
60
92
|
payload = { state: true, data: @custom_data }.merge(options)
|
61
93
|
url = "channels/#{@channel_type}"
|
@@ -66,17 +98,24 @@ module StreamChat
|
|
66
98
|
state
|
67
99
|
end
|
68
100
|
|
101
|
+
# Queries members of a channel.
|
102
|
+
#
|
103
|
+
# The queryMembers endpoint allows you to list and paginate members from a channel. The
|
104
|
+
# endpoint supports filtering on numerous criteria to efficiently return members information.
|
105
|
+
# This endpoint is useful for channels that have large lists of members and
|
106
|
+
# you want to search members or if you want to display the full list of members for a channel.
|
107
|
+
sig { params(filter_conditions: StringKeyHash, sort: T.nilable(T::Hash[String, Integer]), options: T.untyped).returns(StreamChat::StreamResponse) }
|
69
108
|
def query_members(filter_conditions = {}, sort: nil, **options)
|
70
109
|
params = {}.merge(options).merge({
|
71
110
|
id: @id,
|
72
111
|
type: @channel_type,
|
73
112
|
filter_conditions: filter_conditions,
|
74
|
-
sort: get_sort_fields(sort)
|
113
|
+
sort: StreamChat.get_sort_fields(sort)
|
75
114
|
})
|
76
115
|
|
77
116
|
if @id == '' && @members.length.positive?
|
78
117
|
params['members'] = []
|
79
|
-
@members
|
118
|
+
@members.each do |m|
|
80
119
|
params['members'] << m['user'].nil? ? m['user_id'] : m['user']['id']
|
81
120
|
end
|
82
121
|
end
|
@@ -84,11 +123,15 @@ module StreamChat
|
|
84
123
|
@client.get('members', params: { payload: params.to_json })
|
85
124
|
end
|
86
125
|
|
126
|
+
# Updates a channel.
|
127
|
+
sig { params(channel_data: T.nilable(StringKeyHash), update_message: T.nilable(StringKeyHash), options: T.untyped).returns(StreamChat::StreamResponse) }
|
87
128
|
def update(channel_data, update_message = nil, **options)
|
88
129
|
payload = { data: channel_data, message: update_message }.merge(options)
|
89
130
|
@client.post(url, data: payload)
|
90
131
|
end
|
91
132
|
|
133
|
+
# Updates a channel partially.
|
134
|
+
sig { params(set: T.nilable(StringKeyHash), unset: T.nilable(T::Array[String])).returns(StreamChat::StreamResponse) }
|
92
135
|
def update_partial(set = nil, unset = nil)
|
93
136
|
raise StreamChannelException, 'set or unset is needed' if set.nil? && unset.nil?
|
94
137
|
|
@@ -96,107 +139,169 @@ module StreamChat
|
|
96
139
|
@client.patch(url, data: payload)
|
97
140
|
end
|
98
141
|
|
142
|
+
# Deletes a channel.
|
143
|
+
sig { returns(StreamChat::StreamResponse) }
|
99
144
|
def delete
|
100
145
|
@client.delete(url)
|
101
146
|
end
|
102
147
|
|
148
|
+
# Removes all messages from the channel.
|
149
|
+
sig { params(options: T.untyped).returns(StreamChat::StreamResponse) }
|
103
150
|
def truncate(**options)
|
104
151
|
@client.post("#{url}/truncate", data: options)
|
105
152
|
end
|
106
153
|
|
154
|
+
# Mutes a channel.
|
155
|
+
#
|
156
|
+
# Messages added to a muted channel will not trigger push notifications, nor change the
|
157
|
+
# unread count for the users that muted it. By default, mutes stay in place indefinitely
|
158
|
+
# until the user removes it; however, you can optionally set an expiration time. The list
|
159
|
+
# of muted channels and their expiration time is returned when the user connects.
|
160
|
+
sig { params(user_id: String, expiration: T.nilable(Integer)).returns(StreamChat::StreamResponse) }
|
107
161
|
def mute(user_id, expiration = nil)
|
108
162
|
data = { user_id: user_id, channel_cid: @cid }
|
109
163
|
data['expiration'] = expiration if expiration
|
110
164
|
@client.post('moderation/mute/channel', data: data)
|
111
165
|
end
|
112
166
|
|
167
|
+
# Unmutes a channel.
|
168
|
+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
|
113
169
|
def unmute(user_id)
|
114
170
|
@client.post('moderation/unmute/channel', data: { 'user_id' => user_id, 'channel_cid' => @cid })
|
115
171
|
end
|
116
172
|
|
173
|
+
# Adds members to the channel.
|
174
|
+
sig { params(user_ids: T::Array[String], options: T.untyped).returns(StreamChat::StreamResponse) }
|
117
175
|
def add_members(user_ids, **options)
|
118
176
|
payload = options.merge({ add_members: user_ids })
|
119
177
|
update(nil, nil, **payload)
|
120
178
|
end
|
121
179
|
|
180
|
+
# Invites users to the channel.
|
181
|
+
sig { params(user_ids: T::Array[String], options: T.untyped).returns(StreamChat::StreamResponse) }
|
122
182
|
def invite_members(user_ids, **options)
|
123
183
|
payload = options.merge({ invites: user_ids })
|
124
184
|
update(nil, nil, **payload)
|
125
185
|
end
|
126
186
|
|
187
|
+
# Accepts an invitation to the channel.
|
188
|
+
sig { params(user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
127
189
|
def accept_invite(user_id, **options)
|
128
190
|
payload = options.merge({ user_id: user_id, accept_invite: true })
|
129
191
|
update(nil, nil, **payload)
|
130
192
|
end
|
131
193
|
|
194
|
+
# Rejects an invitation to the channel.
|
195
|
+
sig { params(user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
132
196
|
def reject_invite(user_id, **options)
|
133
197
|
payload = options.merge({ user_id: user_id, reject_invite: true })
|
134
198
|
update(nil, nil, **payload)
|
135
199
|
end
|
136
200
|
|
201
|
+
# Adds moderators to the channel.
|
202
|
+
sig { params(user_ids: T::Array[String]).returns(StreamChat::StreamResponse) }
|
137
203
|
def add_moderators(user_ids)
|
138
204
|
update(nil, nil, add_moderators: user_ids)
|
139
205
|
end
|
140
206
|
|
207
|
+
# Removes members from the channel.
|
208
|
+
sig { params(user_ids: T::Array[String]).returns(StreamChat::StreamResponse) }
|
141
209
|
def remove_members(user_ids)
|
142
210
|
update(nil, nil, remove_members: user_ids)
|
143
211
|
end
|
144
212
|
|
213
|
+
# Assigns roles to members in the channel.
|
214
|
+
sig { params(members: T::Array[StringKeyHash], message: T.nilable(StringKeyHash)).returns(StreamChat::StreamResponse) }
|
145
215
|
def assign_roles(members, message = nil)
|
146
216
|
update(nil, message, assign_roles: members)
|
147
217
|
end
|
148
218
|
|
219
|
+
# Demotes moderators in the channel.
|
220
|
+
sig { params(user_ids: T::Array[String]).returns(StreamChat::StreamResponse) }
|
149
221
|
def demote_moderators(user_ids)
|
150
222
|
update(nil, nil, demote_moderators: user_ids)
|
151
223
|
end
|
152
224
|
|
225
|
+
# Sends the mark read event for this user, only works if the `read_events` setting is enabled.
|
226
|
+
sig { params(user_id: String, options: StringKeyHash).returns(StreamChat::StreamResponse) }
|
153
227
|
def mark_read(user_id, **options)
|
154
228
|
payload = add_user_id(options, user_id)
|
155
229
|
@client.post("#{url}/read", data: payload)
|
156
230
|
end
|
157
231
|
|
232
|
+
# List the message replies for a parent message.
|
233
|
+
sig { params(parent_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
158
234
|
def get_replies(parent_id, **options)
|
159
235
|
@client.get("messages/#{parent_id}/replies", params: options)
|
160
236
|
end
|
161
237
|
|
238
|
+
# List the reactions, supports pagination.
|
239
|
+
sig { params(message_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
162
240
|
def get_reactions(message_id, **options)
|
163
241
|
@client.get("messages/#{message_id}/reactions", params: options)
|
164
242
|
end
|
165
243
|
|
244
|
+
# Bans a user from this channel.
|
245
|
+
sig { params(user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
166
246
|
def ban_user(user_id, **options)
|
167
247
|
@client.ban_user(user_id, type: @channel_type, id: @id, **options)
|
168
248
|
end
|
169
249
|
|
250
|
+
# Removes the ban for a user on this channel.
|
251
|
+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
|
170
252
|
def unban_user(user_id)
|
171
253
|
@client.unban_user(user_id, type: @channel_type, id: @id)
|
172
254
|
end
|
173
255
|
|
256
|
+
# Removes a channel from query channel requests for that user until a new message is added.
|
257
|
+
# Use `show` to cancel this operation.
|
258
|
+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
|
174
259
|
def hide(user_id)
|
175
260
|
@client.post("#{url}/hide", data: { user_id: user_id })
|
176
261
|
end
|
177
262
|
|
263
|
+
# Shows a previously hidden channel.
|
264
|
+
# Use `hide` to hide a channel.
|
265
|
+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
|
178
266
|
def show(user_id)
|
179
267
|
@client.post("#{url}/show", data: { user_id: user_id })
|
180
268
|
end
|
181
269
|
|
270
|
+
# Uploads a file.
|
271
|
+
#
|
272
|
+
# This functionality defaults to using the Stream CDN. If you would like, you can
|
273
|
+
# easily change the logic to upload to your own CDN of choice.
|
274
|
+
sig { params(url: String, user: StringKeyHash, content_type: T.nilable(String)).returns(StreamChat::StreamResponse) }
|
182
275
|
def send_file(url, user, content_type = nil)
|
183
276
|
@client.send_file("#{self.url}/file", url, user, content_type)
|
184
277
|
end
|
185
278
|
|
279
|
+
# Uploads an image.
|
280
|
+
#
|
281
|
+
# Stream supported image types are: image/bmp, image/gif, image/jpeg, image/png, image/webp,
|
282
|
+
# image/heic, image/heic-sequence, image/heif, image/heif-sequence, image/svg+xml.
|
283
|
+
# You can set a more restrictive list for your application if needed.
|
284
|
+
# The maximum file size is 100MB.
|
285
|
+
sig { params(url: String, user: StringKeyHash, content_type: T.nilable(String)).returns(StreamChat::StreamResponse) }
|
186
286
|
def send_image(url, user, content_type = nil)
|
187
287
|
@client.send_file("#{self.url}/image", url, user, content_type)
|
188
288
|
end
|
189
289
|
|
290
|
+
# Deletes a file by file url.
|
291
|
+
sig { params(url: String).returns(StreamChat::StreamResponse) }
|
190
292
|
def delete_file(url)
|
191
293
|
@client.delete("#{self.url}/file", params: { url: url })
|
192
294
|
end
|
193
295
|
|
296
|
+
# Deletes an image by image url.
|
297
|
+
sig { params(url: String).returns(StreamChat::StreamResponse) }
|
194
298
|
def delete_image(url)
|
195
299
|
@client.delete("#{self.url}/image", params: { url: url })
|
196
300
|
end
|
197
301
|
|
198
302
|
private
|
199
303
|
|
304
|
+
sig { params(payload: StringKeyHash, user_id: String).returns(StringKeyHash) }
|
200
305
|
def add_user_id(payload, user_id)
|
201
306
|
payload.merge({ user: { id: user_id } })
|
202
307
|
end
|