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/client.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
|
+
# typed: strict
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
|
-
# lib/client.rb
|
4
4
|
require 'open-uri'
|
5
5
|
require 'faraday'
|
6
6
|
require 'faraday/multipart'
|
7
7
|
require 'faraday/net_http_persistent'
|
8
8
|
require 'jwt'
|
9
9
|
require 'time'
|
10
|
+
require 'sorbet-runtime'
|
10
11
|
require 'stream-chat/channel'
|
11
12
|
require 'stream-chat/errors'
|
12
13
|
require 'stream-chat/stream_response'
|
13
14
|
require 'stream-chat/version'
|
14
15
|
require 'stream-chat/util'
|
16
|
+
require 'stream-chat/types'
|
15
17
|
|
16
18
|
module StreamChat
|
17
19
|
DEFAULT_BLOCKLIST = 'profanity_en_2020_v1'
|
@@ -19,34 +21,44 @@ module StreamChat
|
|
19
21
|
HARD_DELETE = 'hard'
|
20
22
|
|
21
23
|
class Client
|
24
|
+
extend T::Sig
|
25
|
+
T::Configuration.default_checked_level = :never
|
26
|
+
# For now we disable runtime type checks.
|
27
|
+
# We will enable it with a major bump in the future,
|
28
|
+
# but for now, let's just run a static type check.
|
29
|
+
|
22
30
|
DEFAULT_BASE_URL = 'https://chat.stream-io-api.com'
|
23
31
|
DEFAULT_TIMEOUT = 6.0
|
24
32
|
|
33
|
+
sig { returns(String) }
|
25
34
|
attr_reader :api_key
|
35
|
+
|
36
|
+
sig { returns(String) }
|
26
37
|
attr_reader :api_secret
|
38
|
+
|
39
|
+
sig { returns(Faraday::Connection) }
|
27
40
|
attr_reader :conn
|
28
|
-
attr_reader :options
|
29
41
|
|
30
42
|
# initializes a Stream Chat API Client
|
31
43
|
#
|
32
44
|
# @param [string] api_key your application api_key
|
33
45
|
# @param [string] api_secret your application secret
|
34
46
|
# @param [float] timeout the timeout for the http requests
|
35
|
-
# @param [
|
47
|
+
# @param [Hash] options extra options such as base_url
|
36
48
|
#
|
37
49
|
# @example initialized the client with a timeout setting
|
38
50
|
# StreamChat::Client.new('my_key', 'my_secret', 3.0)
|
39
51
|
#
|
52
|
+
sig { params(api_key: String, api_secret: String, timeout: T.nilable(T.any(Float, String)), options: T.untyped).void }
|
40
53
|
def initialize(api_key, api_secret, timeout = nil, **options)
|
41
54
|
raise ArgumentError, 'api_key and api_secret are required' if api_key.to_s.empty? || api_secret.to_s.empty?
|
42
55
|
|
43
56
|
@api_key = api_key
|
44
57
|
@api_secret = api_secret
|
45
|
-
@timeout = timeout || DEFAULT_TIMEOUT
|
46
|
-
@
|
47
|
-
@
|
48
|
-
|
49
|
-
@conn = Faraday.new(url: @base_url) do |faraday|
|
58
|
+
@timeout = T.let(timeout&.to_f || DEFAULT_TIMEOUT, Float)
|
59
|
+
@auth_token = T.let(JWT.encode({ server: true }, @api_secret, 'HS256'), String)
|
60
|
+
@base_url = T.let(options[:base_url] || DEFAULT_BASE_URL, String)
|
61
|
+
conn = Faraday.new(@base_url) do |faraday|
|
50
62
|
faraday.options[:open_timeout] = @timeout
|
51
63
|
faraday.options[:timeout] = @timeout
|
52
64
|
faraday.request :multipart
|
@@ -55,15 +67,17 @@ module StreamChat
|
|
55
67
|
http.idle_timeout = 59
|
56
68
|
end
|
57
69
|
end
|
70
|
+
@conn = T.let(conn, Faraday::Connection)
|
58
71
|
end
|
59
72
|
|
60
73
|
# initializes a Stream Chat API Client from STREAM_KEY and STREAM_SECRET
|
61
74
|
# environmental variables. STREAM_CHAT_TIMEOUT and STREAM_CHAT_URL
|
62
75
|
# variables are optional.
|
63
|
-
# @param [
|
76
|
+
# @param [StringKeyHash] options extra options
|
77
|
+
sig { params(options: T.untyped).returns(Client) }
|
64
78
|
def self.from_env(**options)
|
65
|
-
Client.new(ENV['STREAM_KEY'],
|
66
|
-
ENV['STREAM_SECRET'],
|
79
|
+
Client.new(T.must(ENV['STREAM_KEY']),
|
80
|
+
T.must(ENV['STREAM_SECRET']),
|
67
81
|
ENV['STREAM_CHAT_TIMEOUT'],
|
68
82
|
**{ base_url: ENV['STREAM_CHAT_URL'] }.merge(options))
|
69
83
|
end
|
@@ -71,10 +85,18 @@ module StreamChat
|
|
71
85
|
# Sets the underlying Faraday http client.
|
72
86
|
#
|
73
87
|
# @param [client] an instance of Faraday::Connection
|
88
|
+
sig { params(client: Faraday::Connection).void }
|
74
89
|
def set_http_client(client)
|
75
90
|
@conn = client
|
76
91
|
end
|
77
92
|
|
93
|
+
# Creates a JWT for a user.
|
94
|
+
#
|
95
|
+
# Stream uses JWT (JSON Web Tokens) to authenticate chat users, enabling them to login.
|
96
|
+
# Knowing whether a user is authorized to perform certain actions is managed
|
97
|
+
# separately via a role based permissions system.
|
98
|
+
# You can set an `exp` (expires at) or `iat` (issued at) claim as well.
|
99
|
+
sig { params(user_id: String, exp: T.nilable(Integer), iat: T.nilable(Integer)).returns(String) }
|
78
100
|
def create_token(user_id, exp = nil, iat = nil)
|
79
101
|
payload = { user_id: user_id }
|
80
102
|
payload['exp'] = exp unless exp.nil?
|
@@ -82,24 +104,42 @@ module StreamChat
|
|
82
104
|
JWT.encode(payload, @api_secret, 'HS256')
|
83
105
|
end
|
84
106
|
|
107
|
+
# Updates application settings.
|
108
|
+
sig { params(settings: T.untyped).returns(StreamChat::StreamResponse) }
|
85
109
|
def update_app_settings(**settings)
|
86
|
-
patch('app',
|
110
|
+
patch('app', data: settings)
|
87
111
|
end
|
88
112
|
|
113
|
+
# Returns application settings.
|
114
|
+
sig { returns(StreamChat::StreamResponse) }
|
89
115
|
def get_app_settings
|
90
116
|
get('app')
|
91
117
|
end
|
92
118
|
|
119
|
+
# Flags a message.
|
120
|
+
#
|
121
|
+
# Any user is allowed to flag a message. This triggers the message.flagged
|
122
|
+
# webhook event and adds the message to the inbox of your
|
123
|
+
# Stream Dashboard Chat Moderation view.
|
124
|
+
sig { params(id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
93
125
|
def flag_message(id, **options)
|
94
126
|
payload = { target_message_id: id }.merge(options)
|
95
127
|
post('moderation/flag', data: payload)
|
96
128
|
end
|
97
129
|
|
130
|
+
# Unflags a message.
|
131
|
+
sig { params(id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
98
132
|
def unflag_message(id, **options)
|
99
133
|
payload = { target_message_id: id }.merge(options)
|
100
134
|
post('moderation/unflag', data: payload)
|
101
135
|
end
|
102
136
|
|
137
|
+
# Queries message flags.
|
138
|
+
#
|
139
|
+
# If you prefer to build your own in app moderation dashboard, rather than use the Stream
|
140
|
+
# dashboard, then the query message flags endpoint lets you get flagged messages. Similar
|
141
|
+
# to other queries in Stream Chat, you can filter the flags using query operators.
|
142
|
+
sig { params(filter_conditions: StringKeyHash, options: T.untyped).returns(StreamChat::StreamResponse) }
|
103
143
|
def query_message_flags(filter_conditions, **options)
|
104
144
|
params = options.merge({
|
105
145
|
filter_conditions: filter_conditions
|
@@ -107,28 +147,57 @@ module StreamChat
|
|
107
147
|
get('moderation/flags/message', params: { payload: params.to_json })
|
108
148
|
end
|
109
149
|
|
150
|
+
# Flags a user.
|
151
|
+
sig { params(id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
110
152
|
def flag_user(id, **options)
|
111
153
|
payload = { target_user_id: id }.merge(options)
|
112
154
|
post('moderation/flag', data: payload)
|
113
155
|
end
|
114
156
|
|
157
|
+
# Unflags a user.
|
158
|
+
sig { params(id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
115
159
|
def unflag_user(id, **options)
|
116
160
|
payload = { target_user_id: id }.merge(options)
|
117
161
|
post('moderation/unflag', data: payload)
|
118
162
|
end
|
119
163
|
|
164
|
+
# Queries flag reports.
|
165
|
+
sig { params(options: T.untyped).returns(StreamChat::StreamResponse) }
|
166
|
+
def query_flag_reports(**options)
|
167
|
+
data = { filter_conditions: options }
|
168
|
+
post('moderation/reports', data: data)
|
169
|
+
end
|
170
|
+
|
171
|
+
# Sends a flag report review.
|
172
|
+
sig { params(report_id: String, review_result: String, user_id: String, details: T.untyped).returns(StreamChat::StreamResponse) }
|
173
|
+
def review_flag_report(report_id, review_result, user_id, **details)
|
174
|
+
data = {
|
175
|
+
review_result: review_result,
|
176
|
+
user_id: user_id,
|
177
|
+
review_details: details
|
178
|
+
}
|
179
|
+
patch("moderation/reports/#{report_id}", data: data)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns a message.
|
183
|
+
sig { params(id: String).returns(StreamChat::StreamResponse) }
|
120
184
|
def get_message(id)
|
121
185
|
get("messages/#{id}")
|
122
186
|
end
|
123
187
|
|
188
|
+
# Searches for messages.
|
189
|
+
#
|
190
|
+
# You can enable and/or disable the search indexing on a per channel basis
|
191
|
+
# type through the Stream Dashboard.
|
192
|
+
sig { params(filter_conditions: StringKeyHash, query: T.any(String, StringKeyHash), sort: T.nilable(T::Hash[String, Integer]), options: T.untyped).returns(StreamChat::StreamResponse) }
|
124
193
|
def search(filter_conditions, query, sort: nil, **options)
|
125
|
-
offset = options[:offset]
|
194
|
+
offset = T.cast(options[:offset], T.nilable(Integer))
|
126
195
|
next_value = options[:next]
|
127
196
|
raise ArgumentError, 'cannot use offset with next or sort parameters' if offset&.positive? && (next_value || (!sort.nil? && !sort.empty?))
|
128
197
|
|
129
198
|
to_merge = {
|
130
199
|
filter_conditions: filter_conditions,
|
131
|
-
sort: get_sort_fields(sort)
|
200
|
+
sort: StreamChat.get_sort_fields(sort)
|
132
201
|
}
|
133
202
|
if query.is_a? String
|
134
203
|
to_merge[:query] = query
|
@@ -138,7 +207,23 @@ module StreamChat
|
|
138
207
|
get('search', params: { payload: options.merge(to_merge).to_json })
|
139
208
|
end
|
140
209
|
|
210
|
+
# <b>DEPRECATED:</b> Please use <tt>upsert_users</tt> instead.
|
211
|
+
sig { params(users: T::Array[StringKeyHash]).returns(StreamChat::StreamResponse) }
|
141
212
|
def update_users(users)
|
213
|
+
warn '[DEPRECATION] `update_users` is deprecated. Please use `upsert_users` instead.'
|
214
|
+
upsert_users(users)
|
215
|
+
end
|
216
|
+
|
217
|
+
# <b>DEPRECATED:</b> Please use <tt>upsert_user</tt> instead.
|
218
|
+
sig { params(user: StringKeyHash).returns(StreamChat::StreamResponse) }
|
219
|
+
def update_user(user)
|
220
|
+
warn '[DEPRECATION] `update_user` is deprecated. Please use `upsert_user` instead.'
|
221
|
+
upsert_user(user)
|
222
|
+
end
|
223
|
+
|
224
|
+
# Creates or updates users.
|
225
|
+
sig { params(users: T::Array[StringKeyHash]).returns(StreamChat::StreamResponse) }
|
226
|
+
def upsert_users(users)
|
142
227
|
payload = {}
|
143
228
|
users.each do |user|
|
144
229
|
id = user[:id] || user['id']
|
@@ -149,69 +234,116 @@ module StreamChat
|
|
149
234
|
post('users', data: { users: payload })
|
150
235
|
end
|
151
236
|
|
152
|
-
|
153
|
-
|
237
|
+
# Creates or updates a user.
|
238
|
+
sig { params(user: StringKeyHash).returns(StreamChat::StreamResponse) }
|
239
|
+
def upsert_user(user)
|
240
|
+
upsert_users([user])
|
154
241
|
end
|
155
242
|
|
243
|
+
# Updates multiple users partially.
|
244
|
+
sig { params(updates: T::Array[StringKeyHash]).returns(StreamChat::StreamResponse) }
|
156
245
|
def update_users_partial(updates)
|
157
246
|
patch('users', data: { users: updates })
|
158
247
|
end
|
159
248
|
|
249
|
+
# Updates a single user partially.
|
250
|
+
sig { params(update: StringKeyHash).returns(StreamChat::StreamResponse) }
|
160
251
|
def update_user_partial(update)
|
161
252
|
update_users_partial([update])
|
162
253
|
end
|
163
254
|
|
255
|
+
# Deletes a user synchronously.
|
256
|
+
sig { params(user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
164
257
|
def delete_user(user_id, **options)
|
165
258
|
delete("users/#{user_id}", params: options)
|
166
259
|
end
|
167
260
|
|
261
|
+
# Deactivates a user.
|
262
|
+
# Deactivated users cannot connect to Stream Chat, and can't send or receive messages.
|
263
|
+
# To reactivate a user, use `reactivate_user` method.
|
264
|
+
sig { params(user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
168
265
|
def deactivate_user(user_id, **options)
|
169
|
-
post("users/#{user_id}/deactivate",
|
266
|
+
post("users/#{user_id}/deactivate", params: options)
|
170
267
|
end
|
171
268
|
|
269
|
+
# Reactivates a deactivated user. Use deactivate_user to deactivate a user.
|
270
|
+
sig { params(user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
172
271
|
def reactivate_user(user_id, **options)
|
173
|
-
post("users/#{user_id}/reactivate",
|
272
|
+
post("users/#{user_id}/reactivate", params: options)
|
174
273
|
end
|
175
274
|
|
275
|
+
# Exports a user. It exports a user and returns an object
|
276
|
+
# containing all of it's data.
|
277
|
+
sig { params(user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
176
278
|
def export_user(user_id, **options)
|
177
279
|
get("users/#{user_id}/export", params: options)
|
178
280
|
end
|
179
281
|
|
282
|
+
# Bans a user. Users can be banned from an app entirely or from a channel.
|
283
|
+
# When a user is banned, they will not be allowed to post messages until the
|
284
|
+
# ban is removed or expired but will be able to connect to Chat and to channels as before.
|
285
|
+
# To unban a user, use `unban_user` method.
|
286
|
+
sig { params(target_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
180
287
|
def ban_user(target_id, **options)
|
181
288
|
payload = { target_user_id: target_id }.merge(options)
|
182
289
|
post('moderation/ban', data: payload)
|
183
290
|
end
|
184
291
|
|
292
|
+
# Unbans a user.
|
293
|
+
# To ban a user, use `ban_user` method.
|
294
|
+
sig { params(target_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
185
295
|
def unban_user(target_id, **options)
|
186
296
|
params = { target_user_id: target_id }.merge(options)
|
187
297
|
delete('moderation/ban', params: params)
|
188
298
|
end
|
189
299
|
|
300
|
+
# Shadow ban a user.
|
301
|
+
# When a user is shadow banned, they will still be allowed to post messages,
|
302
|
+
# but any message sent during the will only be visible to the messages author
|
303
|
+
# and invisible to other users of the App.
|
304
|
+
# To remove a shadow ban, use `remove_shadow_ban` method.
|
305
|
+
sig { params(target_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
190
306
|
def shadow_ban(target_id, **options)
|
191
307
|
payload = { target_user_id: target_id, shadow: true }.merge(options)
|
192
308
|
post('moderation/ban', data: payload)
|
193
309
|
end
|
194
310
|
|
311
|
+
# Removes a shadow ban of a user.
|
312
|
+
# To shadow ban a user, use `shadow_ban` method.
|
313
|
+
sig { params(target_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
195
314
|
def remove_shadow_ban(target_id, **options)
|
196
315
|
params = { target_user_id: target_id, shadow: true }.merge(options)
|
197
316
|
delete('moderation/ban', params: params)
|
198
317
|
end
|
199
318
|
|
319
|
+
# Mutes a user.
|
320
|
+
sig { params(target_id: String, user_id: String).returns(StreamChat::StreamResponse) }
|
200
321
|
def mute_user(target_id, user_id)
|
201
322
|
payload = { target_id: target_id, user_id: user_id }
|
202
323
|
post('moderation/mute', data: payload)
|
203
324
|
end
|
204
325
|
|
326
|
+
# Unmutes a user.
|
327
|
+
sig { params(target_id: String, user_id: String).returns(StreamChat::StreamResponse) }
|
205
328
|
def unmute_user(target_id, user_id)
|
206
329
|
payload = { target_id: target_id, user_id: user_id }
|
207
330
|
post('moderation/unmute', data: payload)
|
208
331
|
end
|
209
332
|
|
333
|
+
# Marks all messages as read for a user.
|
334
|
+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
|
210
335
|
def mark_all_read(user_id)
|
211
336
|
payload = { user: { id: user_id } }
|
212
337
|
post('channels/read', data: payload)
|
213
338
|
end
|
214
339
|
|
340
|
+
# Pins a message.
|
341
|
+
#
|
342
|
+
# Pinned messages allow users to highlight important messages, make announcements, or temporarily
|
343
|
+
# promote content. Pinning a message is, by default, restricted to certain user roles,
|
344
|
+
# but this is flexible. Each channel can have multiple pinned messages and these can be created
|
345
|
+
# or updated with or without an expiration.
|
346
|
+
sig { params(message_id: String, user_id: String, expiration: T.nilable(String)).returns(StreamChat::StreamResponse) }
|
215
347
|
def pin_message(message_id, user_id, expiration: nil)
|
216
348
|
updates = {
|
217
349
|
set: {
|
@@ -222,6 +354,8 @@ module StreamChat
|
|
222
354
|
update_message_partial(message_id, updates, user_id: user_id)
|
223
355
|
end
|
224
356
|
|
357
|
+
# Unpins a message.
|
358
|
+
sig { params(message_id: String, user_id: String).returns(StreamChat::StreamResponse) }
|
225
359
|
def unpin_message(message_id, user_id)
|
226
360
|
updates = {
|
227
361
|
set: {
|
@@ -231,64 +365,101 @@ module StreamChat
|
|
231
365
|
update_message_partial(message_id, updates, user_id: user_id)
|
232
366
|
end
|
233
367
|
|
368
|
+
# Updates a message. Fully overwrites a message.
|
369
|
+
# For partial update, use `update_message_partial` method.
|
370
|
+
sig { params(message: StringKeyHash).returns(StreamChat::StreamResponse) }
|
234
371
|
def update_message(message)
|
235
|
-
raise ArgumentError 'message must have an id' unless message.key? 'id'
|
372
|
+
raise ArgumentError, 'message must have an id' unless message.key? 'id'
|
236
373
|
|
237
374
|
post("messages/#{message['id']}", data: { message: message })
|
238
375
|
end
|
239
376
|
|
377
|
+
# Updates a message partially.
|
378
|
+
# A partial update can be used to set and unset specific fields when
|
379
|
+
# it is necessary to retain additional data fields on the object. AKA a patch style update.
|
380
|
+
sig { params(message_id: String, updates: StringKeyHash, user_id: T.nilable(String), options: T.untyped).returns(StreamChat::StreamResponse) }
|
240
381
|
def update_message_partial(message_id, updates, user_id: nil, **options)
|
241
382
|
params = updates.merge(options)
|
242
383
|
params['user'] = { id: user_id } if user_id
|
243
384
|
put("messages/#{message_id}", data: params)
|
244
385
|
end
|
245
386
|
|
246
|
-
|
247
|
-
|
387
|
+
# Deletes a message.
|
388
|
+
sig { params(message_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
389
|
+
def delete_message(message_id, **options)
|
390
|
+
delete("messages/#{message_id}", params: options)
|
248
391
|
end
|
249
392
|
|
393
|
+
# Queries banned users.
|
394
|
+
#
|
395
|
+
# Banned users can be retrieved in different ways:
|
396
|
+
# 1) Using the dedicated query bans endpoint
|
397
|
+
# 2) User Search: you can add the banned:true condition to your search. Please note that
|
398
|
+
# this will only return users that were banned at the app-level and not the ones
|
399
|
+
# that were banned only on channels.
|
400
|
+
sig { params(filter_conditions: StringKeyHash, sort: T.nilable(T::Hash[String, Integer]), options: T.untyped).returns(StreamChat::StreamResponse) }
|
250
401
|
def query_banned_users(filter_conditions, sort: nil, **options)
|
251
402
|
params = options.merge({
|
252
403
|
filter_conditions: filter_conditions,
|
253
|
-
sort: get_sort_fields(sort)
|
404
|
+
sort: StreamChat.get_sort_fields(sort)
|
254
405
|
})
|
255
406
|
get('query_banned_users', params: { payload: params.to_json })
|
256
407
|
end
|
257
408
|
|
409
|
+
# Allows you to search for users and see if they are online/offline.
|
410
|
+
# You can filter and sort on the custom fields you've set for your user, the user id, and when the user was last active.
|
411
|
+
sig { params(filter_conditions: StringKeyHash, sort: T.nilable(T::Hash[String, Integer]), options: T.untyped).returns(StreamChat::StreamResponse) }
|
258
412
|
def query_users(filter_conditions, sort: nil, **options)
|
259
413
|
params = options.merge({
|
260
414
|
filter_conditions: filter_conditions,
|
261
|
-
sort: get_sort_fields(sort)
|
415
|
+
sort: StreamChat.get_sort_fields(sort)
|
262
416
|
})
|
263
417
|
get('users', params: { payload: params.to_json })
|
264
418
|
end
|
265
419
|
|
420
|
+
# Queries channels.
|
421
|
+
#
|
422
|
+
# You can query channels based on built-in fields as well as any custom field you add to channels.
|
423
|
+
# Multiple filters can be combined using AND, OR logical operators, each filter can use its
|
424
|
+
# comparison (equality, inequality, greater than, greater or equal, etc.).
|
425
|
+
# You can find the complete list of supported operators in the query syntax section of the docs.
|
426
|
+
sig { params(filter_conditions: StringKeyHash, sort: T.nilable(T::Hash[String, Integer]), options: T.untyped).returns(StreamChat::StreamResponse) }
|
266
427
|
def query_channels(filter_conditions, sort: nil, **options)
|
267
428
|
data = { state: true, watch: false, presence: false }
|
268
429
|
data = data.merge(options).merge({
|
269
430
|
filter_conditions: filter_conditions,
|
270
|
-
sort: get_sort_fields(sort)
|
431
|
+
sort: StreamChat.get_sort_fields(sort)
|
271
432
|
})
|
272
433
|
post('channels', data: data)
|
273
434
|
end
|
274
435
|
|
436
|
+
# Creates a new channel type.
|
437
|
+
sig { params(data: StringKeyHash).returns(StreamChat::StreamResponse) }
|
275
438
|
def create_channel_type(data)
|
276
439
|
data['commands'] = ['all'] unless data.key?('commands') || data['commands'].nil? || data['commands'].empty?
|
277
440
|
post('channeltypes', data: data)
|
278
441
|
end
|
279
442
|
|
443
|
+
# Returns a channel types.
|
444
|
+
sig { params(channel_type: String).returns(StreamChat::StreamResponse) }
|
280
445
|
def get_channel_type(channel_type)
|
281
446
|
get("channeltypes/#{channel_type}")
|
282
447
|
end
|
283
448
|
|
449
|
+
# Returns a list of channel types.
|
450
|
+
sig { returns(StreamChat::StreamResponse) }
|
284
451
|
def list_channel_types
|
285
452
|
get('channeltypes')
|
286
453
|
end
|
287
454
|
|
455
|
+
# Updates a channel type.
|
456
|
+
sig { params(channel_type: String, options: T.untyped).returns(StreamChat::StreamResponse) }
|
288
457
|
def update_channel_type(channel_type, **options)
|
289
458
|
put("channeltypes/#{channel_type}", data: options)
|
290
459
|
end
|
291
460
|
|
461
|
+
# Deletes a channel type.
|
462
|
+
sig { params(channel_type: String).returns(StreamChat::StreamResponse) }
|
292
463
|
def delete_channel_type(channel_type)
|
293
464
|
delete("channeltypes/#{channel_type}")
|
294
465
|
end
|
@@ -297,30 +468,41 @@ module StreamChat
|
|
297
468
|
#
|
298
469
|
# @param [string] channel_type the channel type
|
299
470
|
# @param [string] channel_id the channel identifier
|
300
|
-
# @param [
|
471
|
+
# @param [StringKeyHash] data additional channel data
|
301
472
|
#
|
302
473
|
# @return [StreamChat::Channel]
|
303
474
|
#
|
475
|
+
sig { params(channel_type: String, channel_id: T.nilable(String), data: T.nilable(StringKeyHash)).returns(StreamChat::Channel) }
|
304
476
|
def channel(channel_type, channel_id: nil, data: nil)
|
305
477
|
StreamChat::Channel.new(self, channel_type, channel_id, data)
|
306
478
|
end
|
307
479
|
|
308
|
-
|
480
|
+
# Adds a device to a user.
|
481
|
+
sig { params(device_id: String, push_provider: String, user_id: String, push_provider_name: T.nilable(String)).returns(StreamChat::StreamResponse) }
|
482
|
+
def add_device(device_id, push_provider, user_id, push_provider_name = nil)
|
309
483
|
post('devices', data: {
|
310
484
|
id: device_id,
|
311
485
|
push_provider: push_provider,
|
486
|
+
push_provider_name: push_provider_name,
|
312
487
|
user_id: user_id
|
313
488
|
})
|
314
489
|
end
|
315
490
|
|
491
|
+
# Delete a device.
|
492
|
+
sig { params(device_id: String, user_id: String).returns(StreamChat::StreamResponse) }
|
316
493
|
def delete_device(device_id, user_id)
|
317
494
|
delete('devices', params: { id: device_id, user_id: user_id })
|
318
495
|
end
|
319
496
|
|
497
|
+
# Returns a list of devices.
|
498
|
+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
|
320
499
|
def get_devices(user_id)
|
321
500
|
get('devices', params: { user_id: user_id })
|
322
501
|
end
|
323
502
|
|
503
|
+
# Get rate limit quotas and usage.
|
504
|
+
# If no params are toggled, all limits for all endpoints are returned.
|
505
|
+
sig { params(server_side: T::Boolean, android: T::Boolean, ios: T::Boolean, web: T::Boolean, endpoints: T::Array[String]).returns(StreamChat::StreamResponse) }
|
324
506
|
def get_rate_limits(server_side: false, android: false, ios: false, web: false, endpoints: [])
|
325
507
|
params = {}
|
326
508
|
params['server_side'] = server_side if server_side
|
@@ -332,78 +514,156 @@ module StreamChat
|
|
332
514
|
get('rate_limits', params: params)
|
333
515
|
end
|
334
516
|
|
517
|
+
# Verify the signature added to a webhook event.
|
518
|
+
sig { params(request_body: String, x_signature: String).returns(T::Boolean) }
|
335
519
|
def verify_webhook(request_body, x_signature)
|
336
520
|
signature = OpenSSL::HMAC.hexdigest('SHA256', @api_secret, request_body)
|
337
521
|
signature == x_signature
|
338
522
|
end
|
339
523
|
|
524
|
+
# Allows you to send custom events to a connected user.
|
525
|
+
sig { params(user_id: String, event: StringKeyHash).returns(StreamChat::StreamResponse) }
|
340
526
|
def send_user_event(user_id, event)
|
341
527
|
post("users/#{user_id}/event", data: event)
|
342
528
|
end
|
343
529
|
|
530
|
+
# Translates an existing message to another language. The source language
|
531
|
+
# is inferred from the user language or detected automatically by analyzing its text.
|
532
|
+
# If possible it is recommended to store the user language. See the documentation.
|
533
|
+
sig { params(message_id: String, language: String).returns(StreamChat::StreamResponse) }
|
344
534
|
def translate_message(message_id, language)
|
345
535
|
post("messages/#{message_id}/translate", data: { language: language })
|
346
536
|
end
|
347
537
|
|
538
|
+
# Runs a message command action.
|
539
|
+
sig { params(message_id: String, data: StringKeyHash).returns(StreamChat::StreamResponse) }
|
348
540
|
def run_message_action(message_id, data)
|
349
541
|
post("messages/#{message_id}/action", data: data)
|
350
542
|
end
|
351
543
|
|
544
|
+
# Creates a guest user.
|
545
|
+
#
|
546
|
+
# Guest sessions can be created client-side and do not require any server-side authentication.
|
547
|
+
# Support and livestreams are common use cases for guests users because really
|
548
|
+
# often you want a visitor to be able to use chat on your application without (or before)
|
549
|
+
# they have a regular user account.
|
550
|
+
sig { params(user: StringKeyHash).returns(StreamChat::StreamResponse) }
|
352
551
|
def create_guest(user)
|
353
552
|
post('guests', data: user)
|
354
553
|
end
|
355
554
|
|
555
|
+
# Returns all blocklists.
|
556
|
+
#
|
557
|
+
# A Block List is a list of words that you can use to moderate chat messages. Stream Chat
|
558
|
+
# comes with a built-in Block List called profanity_en_2020_v1 which contains over a thousand
|
559
|
+
# of the most common profane words.
|
560
|
+
# You can manage your own block lists via the Stream dashboard or APIs to a manage
|
561
|
+
# blocklists and configure your channel types to use them.
|
562
|
+
sig { returns(StreamChat::StreamResponse) }
|
356
563
|
def list_blocklists
|
357
564
|
get('blocklists')
|
358
565
|
end
|
359
566
|
|
567
|
+
# Returns a blocklist.
|
568
|
+
#
|
569
|
+
# A Block List is a list of words that you can use to moderate chat messages. Stream Chat
|
570
|
+
# comes with a built-in Block List called profanity_en_2020_v1 which contains over a thousand
|
571
|
+
# of the most common profane words.
|
572
|
+
# You can manage your own block lists via the Stream dashboard or APIs to a manage
|
573
|
+
# blocklists and configure your channel types to use them.
|
574
|
+
sig { params(name: String).returns(StreamChat::StreamResponse) }
|
360
575
|
def get_blocklist(name)
|
361
576
|
get("blocklists/#{name}")
|
362
577
|
end
|
363
578
|
|
579
|
+
# Creates a blocklist.
|
580
|
+
#
|
581
|
+
# A Block List is a list of words that you can use to moderate chat messages. Stream Chat
|
582
|
+
# comes with a built-in Block List called profanity_en_2020_v1 which contains over a thousand
|
583
|
+
# of the most common profane words.
|
584
|
+
# You can manage your own block lists via the Stream dashboard or APIs to a manage
|
585
|
+
# blocklists and configure your channel types to use them.
|
586
|
+
sig { params(name: String, words: StringKeyHash).returns(StreamChat::StreamResponse) }
|
364
587
|
def create_blocklist(name, words)
|
365
588
|
post('blocklists', data: { name: name, words: words })
|
366
589
|
end
|
367
590
|
|
591
|
+
# Updates a blocklist.
|
592
|
+
#
|
593
|
+
# A Block List is a list of words that you can use to moderate chat messages. Stream Chat
|
594
|
+
# comes with a built-in Block List called profanity_en_2020_v1 which contains over a thousand
|
595
|
+
# of the most common profane words.
|
596
|
+
# You can manage your own block lists via the Stream dashboard or APIs to a manage
|
597
|
+
# blocklists and configure your channel types to use them.
|
598
|
+
sig { params(name: String, words: StringKeyHash).returns(StreamChat::StreamResponse) }
|
368
599
|
def update_blocklist(name, words)
|
369
600
|
put("blocklists/#{name}", data: { words: words })
|
370
601
|
end
|
371
602
|
|
603
|
+
# Deletes a blocklist.
|
604
|
+
#
|
605
|
+
# A Block List is a list of words that you can use to moderate chat messages. Stream Chat
|
606
|
+
# comes with a built-in Block List called profanity_en_2020_v1 which contains over a thousand
|
607
|
+
# of the most common profane words.
|
608
|
+
# You can manage your own block lists via the Stream dashboard or APIs to a manage
|
609
|
+
# blocklists and configure your channel types to use them.
|
610
|
+
sig { params(name: String).returns(StreamChat::StreamResponse) }
|
372
611
|
def delete_blocklist(name)
|
373
612
|
delete("blocklists/#{name}")
|
374
613
|
end
|
375
614
|
|
615
|
+
# Requests a channel export.
|
616
|
+
#
|
617
|
+
# Channel exports are created asynchronously, you can use the Task ID returned by
|
618
|
+
# the APIs to keep track of the status and to download the final result when it is ready.
|
619
|
+
# Use `get_task` to check the status of the export.
|
620
|
+
sig { params(channels: StringKeyHash, options: T.untyped).returns(StreamChat::StreamResponse) }
|
376
621
|
def export_channels(*channels, **options)
|
377
622
|
post('export_channels', data: { channels: channels, **options })
|
378
623
|
end
|
379
624
|
|
625
|
+
# Returns the status of a channel export. It contains the URL to the JSON file.
|
626
|
+
sig { params(task_id: String).returns(StreamChat::StreamResponse) }
|
380
627
|
def get_export_channel_status(task_id)
|
381
628
|
get("export_channels/#{task_id}")
|
382
629
|
end
|
383
630
|
|
631
|
+
# Returns the status of a task.
|
632
|
+
sig { params(task_id: String).returns(StreamChat::StreamResponse) }
|
384
633
|
def get_task(task_id)
|
385
634
|
get("tasks/#{task_id}")
|
386
635
|
end
|
387
636
|
|
637
|
+
# Delete users asynchronously. Use `get_task` to check the status of the task.
|
638
|
+
sig { params(user_ids: T::Array[String], user: String, messages: T.nilable(StringKeyHash), conversations: T.nilable(String)).returns(StreamChat::StreamResponse) }
|
388
639
|
def delete_users(user_ids, user: SOFT_DELETE, messages: nil, conversations: nil)
|
389
640
|
post('users/delete', data: { user_ids: user_ids, user: user, messages: messages, conversations: conversations })
|
390
641
|
end
|
391
642
|
|
643
|
+
# Deletes multiple channels. This is an asynchronous operation and the returned value is a task Id.
|
644
|
+
# You can use `get_task` method to check the status of the task.
|
645
|
+
sig { params(cids: T::Array[String], hard_delete: T::Boolean).returns(StreamChat::StreamResponse) }
|
392
646
|
def delete_channels(cids, hard_delete: false)
|
393
647
|
post('channels/delete', data: { cids: cids, hard_delete: hard_delete })
|
394
648
|
end
|
395
649
|
|
650
|
+
# Revoke tokens for an application issued since the given date.
|
651
|
+
sig { params(before: T.any(DateTime, String)).returns(StreamChat::StreamResponse) }
|
396
652
|
def revoke_tokens(before)
|
397
|
-
before = before.rfc3339 if before.instance_of?(DateTime)
|
653
|
+
before = T.cast(before, DateTime).rfc3339 if before.instance_of?(DateTime)
|
398
654
|
update_app_settings({ 'revoke_tokens_issued_before' => before })
|
399
655
|
end
|
400
656
|
|
657
|
+
# Revoke tokens for a user issued since the given date.
|
658
|
+
sig { params(user_id: String, before: T.any(DateTime, String)).returns(StreamChat::StreamResponse) }
|
401
659
|
def revoke_user_token(user_id, before)
|
402
660
|
revoke_users_token([user_id], before)
|
403
661
|
end
|
404
662
|
|
663
|
+
# Revoke tokens for users issued since.
|
664
|
+
sig { params(user_ids: T::Array[String], before: T.any(DateTime, String)).returns(StreamChat::StreamResponse) }
|
405
665
|
def revoke_users_token(user_ids, before)
|
406
|
-
before = before.rfc3339 if before.instance_of?(DateTime)
|
666
|
+
before = T.cast(before, DateTime).rfc3339 if before.instance_of?(DateTime)
|
407
667
|
|
408
668
|
updates = []
|
409
669
|
user_ids.each do |user_id|
|
@@ -417,32 +677,42 @@ module StreamChat
|
|
417
677
|
update_users_partial(updates)
|
418
678
|
end
|
419
679
|
|
680
|
+
sig { params(relative_url: String, params: T.nilable(StringKeyHash), data: T.nilable(StringKeyHash)).returns(StreamChat::StreamResponse) }
|
420
681
|
def put(relative_url, params: nil, data: nil)
|
421
682
|
make_http_request(:put, relative_url, params: params, data: data)
|
422
683
|
end
|
423
684
|
|
685
|
+
sig { params(relative_url: String, params: T.nilable(StringKeyHash), data: T.nilable(StringKeyHash)).returns(StreamChat::StreamResponse) }
|
424
686
|
def post(relative_url, params: nil, data: nil)
|
425
687
|
make_http_request(:post, relative_url, params: params, data: data)
|
426
688
|
end
|
427
689
|
|
690
|
+
sig { params(relative_url: String, params: T.nilable(StringKeyHash)).returns(StreamChat::StreamResponse) }
|
428
691
|
def get(relative_url, params: nil)
|
429
692
|
make_http_request(:get, relative_url, params: params)
|
430
693
|
end
|
431
694
|
|
695
|
+
sig { params(relative_url: String, params: T.nilable(StringKeyHash)).returns(StreamChat::StreamResponse) }
|
432
696
|
def delete(relative_url, params: nil)
|
433
697
|
make_http_request(:delete, relative_url, params: params)
|
434
698
|
end
|
435
699
|
|
700
|
+
sig { params(relative_url: String, params: T.nilable(StringKeyHash), data: T.nilable(StringKeyHash)).returns(StreamChat::StreamResponse) }
|
436
701
|
def patch(relative_url, params: nil, data: nil)
|
437
702
|
make_http_request(:patch, relative_url, params: params, data: data)
|
438
703
|
end
|
439
704
|
|
440
|
-
|
705
|
+
# Uploads a file.
|
706
|
+
#
|
707
|
+
# This functionality defaults to using the Stream CDN. If you would like, you can
|
708
|
+
# easily change the logic to upload to your own CDN of choice.
|
709
|
+
sig { params(relative_url: String, file_url: String, user: StringKeyHash, content_type: T.nilable(String)).returns(StreamChat::StreamResponse) }
|
710
|
+
def send_file(relative_url, file_url, user, content_type = nil)
|
441
711
|
url = [@base_url, relative_url].join('/')
|
442
712
|
|
443
713
|
body = { user: user.to_json }
|
444
714
|
|
445
|
-
body[:file] = Faraday::UploadIO.new(file_url, content_type)
|
715
|
+
body[:file] = Faraday::UploadIO.new(file_url, content_type || 'application/octet-stream')
|
446
716
|
|
447
717
|
response = @conn.post url do |req|
|
448
718
|
req.headers['X-Stream-Client'] = get_user_agent
|
@@ -455,76 +725,129 @@ module StreamChat
|
|
455
725
|
parse_response(response)
|
456
726
|
end
|
457
727
|
|
728
|
+
# Check push notification settings.
|
729
|
+
sig { params(push_data: StringKeyHash).returns(StreamChat::StreamResponse) }
|
458
730
|
def check_push(push_data)
|
459
731
|
post('check_push', data: push_data)
|
460
732
|
end
|
461
733
|
|
734
|
+
# Check SQS Push settings
|
735
|
+
#
|
736
|
+
# When no parameters are given, the current SQS app settings are used.
|
737
|
+
sig { params(sqs_key: T.nilable(String), sqs_secret: T.nilable(String), sqs_url: T.nilable(String)).returns(StreamChat::StreamResponse) }
|
462
738
|
def check_sqs(sqs_key = nil, sqs_secret = nil, sqs_url = nil)
|
463
739
|
post('check_sqs', data: { sqs_key: sqs_key, sqs_secret: sqs_secret, sqs_url: sqs_url })
|
464
740
|
end
|
465
741
|
|
742
|
+
# Creates a new command.
|
743
|
+
sig { params(command: StringKeyHash).returns(StreamChat::StreamResponse) }
|
466
744
|
def create_command(command)
|
467
745
|
post('commands', data: command)
|
468
746
|
end
|
469
747
|
|
748
|
+
# Gets a comamnd.
|
749
|
+
sig { params(name: String).returns(StreamChat::StreamResponse) }
|
470
750
|
def get_command(name)
|
471
751
|
get("commands/#{name}")
|
472
752
|
end
|
473
753
|
|
754
|
+
# Updates a command.
|
755
|
+
sig { params(name: String, command: StringKeyHash).returns(StreamChat::StreamResponse) }
|
474
756
|
def update_command(name, command)
|
475
757
|
put("commands/#{name}", data: command)
|
476
758
|
end
|
477
759
|
|
760
|
+
# Deletes a command.
|
761
|
+
sig { params(name: String).returns(StreamChat::StreamResponse) }
|
478
762
|
def delete_command(name)
|
479
763
|
delete("commands/#{name}")
|
480
764
|
end
|
481
765
|
|
766
|
+
# Lists all commands.
|
767
|
+
sig { returns(StreamChat::StreamResponse) }
|
482
768
|
def list_commands
|
483
769
|
get('commands')
|
484
770
|
end
|
485
771
|
|
772
|
+
# Lists all permissions.
|
773
|
+
sig { returns(StreamChat::StreamResponse) }
|
486
774
|
def list_permissions
|
487
775
|
get('permissions')
|
488
776
|
end
|
489
777
|
|
778
|
+
# Gets a permission.
|
779
|
+
sig { params(id: String).returns(StreamChat::StreamResponse) }
|
490
780
|
def get_permission(id)
|
491
781
|
get("permissions/#{id}")
|
492
782
|
end
|
493
783
|
|
784
|
+
# Creates a new permission.
|
785
|
+
sig { params(permission: StringKeyHash).returns(StreamChat::StreamResponse) }
|
494
786
|
def create_permission(permission)
|
495
787
|
post('permissions', data: permission)
|
496
788
|
end
|
497
789
|
|
790
|
+
# Updates a permission.
|
791
|
+
sig { params(id: String, permission: StringKeyHash).returns(StreamChat::StreamResponse) }
|
498
792
|
def update_permission(id, permission)
|
499
793
|
put("permissions/#{id}", data: permission)
|
500
794
|
end
|
501
795
|
|
796
|
+
# Deletes a permission by id.
|
797
|
+
sig { params(id: String).returns(StreamChat::StreamResponse) }
|
502
798
|
def delete_permission(id)
|
503
799
|
delete("permissions/#{id}")
|
504
800
|
end
|
505
801
|
|
802
|
+
# Create a new role.
|
803
|
+
sig { params(name: String).returns(StreamChat::StreamResponse) }
|
506
804
|
def create_role(name)
|
507
805
|
post('roles', data: { name: name })
|
508
806
|
end
|
509
807
|
|
808
|
+
# Delete a role by name.
|
809
|
+
sig { params(name: String).returns(StreamChat::StreamResponse) }
|
510
810
|
def delete_role(name)
|
511
811
|
delete("roles/#{name}")
|
512
812
|
end
|
513
813
|
|
814
|
+
# List all roles.
|
815
|
+
sig { returns(StreamChat::StreamResponse) }
|
514
816
|
def list_roles
|
515
817
|
get('roles')
|
516
818
|
end
|
517
819
|
|
820
|
+
# Create or update a push provider.
|
821
|
+
sig { params(push_provider: StringKeyHash).returns(StreamChat::StreamResponse) }
|
822
|
+
def upsert_push_provider(push_provider)
|
823
|
+
post('push_providers', data: { push_provider: push_provider })
|
824
|
+
end
|
825
|
+
|
826
|
+
# Delete a push provider by type and name.
|
827
|
+
sig { params(type: String, name: String).returns(StreamChat::StreamResponse) }
|
828
|
+
def delete_push_provider(type, name)
|
829
|
+
delete("push_providers/#{type}/#{name}")
|
830
|
+
end
|
831
|
+
|
832
|
+
# Lists all push providers.
|
833
|
+
sig { returns(StreamChat::StreamResponse) }
|
834
|
+
def list_push_providers
|
835
|
+
get('push_providers')
|
836
|
+
end
|
837
|
+
|
518
838
|
private
|
519
839
|
|
840
|
+
sig { returns(T::Hash[String, String]) }
|
520
841
|
def get_default_params
|
521
842
|
{ api_key: @api_key }
|
522
843
|
end
|
523
844
|
|
845
|
+
sig { returns(String) }
|
524
846
|
def get_user_agent
|
525
847
|
"stream-ruby-client-#{StreamChat::VERSION}"
|
526
848
|
end
|
527
849
|
|
850
|
+
sig { returns(T::Hash[String, String]) }
|
528
851
|
def get_default_headers
|
529
852
|
{
|
530
853
|
'Content-Type': 'application/json',
|
@@ -532,6 +855,7 @@ module StreamChat
|
|
532
855
|
}
|
533
856
|
end
|
534
857
|
|
858
|
+
sig { params(response: Faraday::Response).returns(StreamChat::StreamResponse) }
|
535
859
|
def parse_response(response)
|
536
860
|
begin
|
537
861
|
parsed_result = JSON.parse(response.body)
|
@@ -543,6 +867,7 @@ module StreamChat
|
|
543
867
|
StreamResponse.new(parsed_result, response)
|
544
868
|
end
|
545
869
|
|
870
|
+
sig { params(method: Symbol, relative_url: String, params: T.nilable(StringKeyHash), data: T.nilable(StringKeyHash)).returns(StreamChat::StreamResponse) }
|
546
871
|
def make_http_request(method, relative_url, params: nil, data: nil)
|
547
872
|
headers = get_default_headers
|
548
873
|
headers['Authorization'] = @auth_token
|