activematrix 0.0.0

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.
@@ -0,0 +1,1982 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Metrics/ModuleLength
4
+ module MatrixSdk::Protocols::CS
5
+ # Gets the available client API versions
6
+ # @return [Array]
7
+ #
8
+ # @example Getting API versions
9
+ # api.client_api_versions
10
+ # # => [ 'r0.1.0', 'r0.2.0', ...
11
+ # api.client_api_versions.latest
12
+ # # => 'latest'
13
+ def client_api_versions
14
+ (@client_api_versions ||= request(:get, :client, '/versions')).versions.tap do |vers|
15
+ vers.instance_eval <<-'CODE', __FILE__, __LINE__ + 1
16
+ if !respond_to? :latest
17
+ def latest
18
+ last
19
+ end
20
+ end
21
+ CODE
22
+ end
23
+ end
24
+
25
+ # Gets the list of available unstable client API features
26
+ # @return [Hash]
27
+ #
28
+ # @example Checking for unstable features
29
+ # api.client_api_unstable_features
30
+ # # => { :"m.lazy_load_members" => true }
31
+ # api.client_api_unstable_features.has? 'm.lazy_load_members'
32
+ # # => true
33
+ def client_api_unstable_features
34
+ (@client_api_versions ||= request(:get, :client, '/versions')).unstable_features.tap do |vers|
35
+ vers.instance_eval <<-'CODE', __FILE__, __LINE__ + 1
36
+ def has?(feature)
37
+ feature = feature.to_s.to_sym unless feature.is_a? Symbol
38
+ fetch(feature, nil)
39
+ end
40
+ CODE
41
+ end
42
+ end
43
+
44
+ # Gets the latest version of the client API
45
+ # @return [Symbol] :client_r0 / :client_v3 / etc
46
+ def client_api_latest
47
+ @client_api_latest ||= :client_v3 if client_api_versions.any? { |v| v.start_with? 'v1.1' }
48
+ @client_api_latest ||= :client_r0
49
+ rescue StandardError => e
50
+ logger.warn "Failed to look up supported client API, defaulting to r0. The error was #{e.class}: #{e}"
51
+ @client_api_latest ||= :client_r0
52
+ end
53
+
54
+ # Gets the list of available methods for logging in
55
+ # @return [Response]
56
+ def allowed_login_methods
57
+ request(:get, client_api_latest, '/login')
58
+ end
59
+
60
+ # Runs the client API /sync method
61
+ # @param timeout [Numeric] (30.0) The timeout in seconds for the sync
62
+ # @param params [Hash] The sync options to use
63
+ # @option params [String] :since The value of the batch token to base the sync from
64
+ # @option params [String,Hash] :filter The filter to use on the sync
65
+ # @option params [Boolean] :full_state Should the sync include the full state
66
+ # @option params [Boolean] :set_presence Should the sync set the user status to online
67
+ # @return [Response]
68
+ # @see https://matrix.org/docs/spec/client_server/latest.html#get-matrix-client-r0-sync
69
+ # For more information on the parameters and what they mean
70
+ def sync(timeout: 30.0, **params)
71
+ query = params.select do |k, _v|
72
+ %i[since filter full_state set_presence].include? k
73
+ end
74
+
75
+ query[:timeout] = (timeout * 1000).to_i if timeout
76
+ query[:timeout] = params.delete(:timeout_ms).to_i if params.key? :timeout_ms
77
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
78
+
79
+ request(:get, client_api_latest, '/sync', query: query)
80
+ end
81
+
82
+ # Registers a user using the client API /register endpoint
83
+ #
84
+ # @example Regular user registration and login
85
+ # api.register(username: 'example', password: 'NotARealPass')
86
+ # # => { user_id: '@example:matrix.org', access_token: '...', home_server: 'matrix.org', device_id: 'ABCD123' }
87
+ # api.whoami?
88
+ # # => { user_id: '@example:matrix.org' }
89
+ #
90
+ # @param kind [String,Symbol] ('user') The kind of registration to use
91
+ # @param params [Hash] The registration information, all not handled by Ruby will be passed as JSON in the body
92
+ # @option params [Boolean] :store_token (true) Should the resulting access token be stored for the API
93
+ # @option params [Boolean] :store_device_id (store_token value) Should the resulting device ID be stored for the API
94
+ # @return [Response]
95
+ # @see https://matrix.org/docs/spec/client_server/latest.html#post-matrix-client-r0-register
96
+ # For options that are permitted in this call
97
+ def register(kind: 'user', **params)
98
+ query = {}
99
+ query[:kind] = kind
100
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
101
+
102
+ store_token = params.delete(:store_token) { !protocol?(:AS) }
103
+ store_device_id = params.delete(:store_device_id) { store_token }
104
+
105
+ request(:post, client_api_latest, '/register', body: params, query: query).tap do |resp|
106
+ @access_token = resp.token if resp.key?(:token) && store_token
107
+ @device_id = resp.device_id if resp.key?(:device_id) && store_device_id
108
+ end
109
+ end
110
+
111
+ # Requests to register an email address to the current account
112
+ #
113
+ # @param secret [String] A random string containing only the characters `[0-9a-zA-Z.=_-]`
114
+ # @param email [String] The email address to register
115
+ # @param attempt [Integer] The current attempt count to register the email+secret combo, increase to send another verification email
116
+ # @param next_link [String,URI] An URL to redirect to after verification is finished
117
+ # @return [Response] A hash containing the :sid id for the current request
118
+ # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-register-email-requesttoken
119
+ # For options that are permitted in this call
120
+ def register_email_request(secret, email, attempt: 1, next_link: nil)
121
+ body = {
122
+ client_secret: secret,
123
+ email: email,
124
+ send_attempt: attempt,
125
+ next_link: next_link
126
+ }.compact
127
+
128
+ request(:post, client_api_latest, '/register/email/requestToken', body: body)
129
+ end
130
+
131
+ # Requests to register a phone number to the current account
132
+ #
133
+ # @param secret [String] A random string containing only the characters `[0-9a-zA-Z.=_-]`
134
+ # @param country [String] The two-letter ISO-3166-1 country identifier of the destination country of the number
135
+ # @param number [String] The phone number itself
136
+ # @param attempt [Integer] The current attempt count to register the email+secret combo, increase to send another verification email
137
+ # @param next_link [String,URI] An URL to redirect to after verification is finished
138
+ # @return [Response] A hash containing the :sid id for the current request
139
+ # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-register-email-requesttoken
140
+ # For options that are permitted in this call
141
+ def register_msisdn_request(secret, country, number, attempt: 1, next_link: nil)
142
+ body = {
143
+ client_secret: secret,
144
+ country: country,
145
+ phone_number: number,
146
+ send_attempt: attempt,
147
+ next_link: next_link
148
+ }.compact
149
+
150
+ request(:post, client_api_latest, '/register/msisdn/requestToken', body: body)
151
+ end
152
+
153
+ # Checks if a given username is available and valid for registering
154
+ #
155
+ # @example Verifying a username
156
+ # api.username_available?('example')
157
+ # # => { available: true }
158
+ #
159
+ # @param username [String] The username to check
160
+ # @return [Response]
161
+ # @see https://matrix.org/docs/spec/client_server/latest.html#get-matrix-client-r0-register-available
162
+ def username_available?(username)
163
+ request(:get, client_api_latest, '/register/available', query: { username: username })
164
+ end
165
+
166
+ # Logs in using the client API /login endpoint, and optionally stores the resulting access for API usage
167
+ #
168
+ # @example Logging in with username and password
169
+ # api.login(user: 'example', password: 'NotARealPass')
170
+ # # => { user_id: '@example:matrix.org', access_token: '...', home_server: 'matrix.org', device_id: 'ABCD123' }
171
+ # api.whoami?
172
+ # # => { user_id: '@example:matrix.org' }
173
+ #
174
+ # @example Advanced login, without storing details
175
+ # api.whoami?
176
+ # # => { user_id: '@example:matrix.org' }
177
+ # api.login(medium: 'email', address: 'someone@somewhere.net', password: '...', store_token: false)
178
+ # # => { user_id: '@someone:matrix.org', access_token: ...
179
+ # api.whoami?.user_id
180
+ # # => '@example:matrix.org'
181
+ #
182
+ # @param login_type [String] ('m.login.password') The type of login to attempt
183
+ # @param params [Hash] The login information to use, along with options for said log in
184
+ # @option params [Boolean] :store_token (true) Should the resulting access token be stored for the API
185
+ # @option params [Boolean] :store_device_id (store_token value) Should the resulting device ID be stored for the API
186
+ # @option params [String] :initial_device_display_name (USER_AGENT) The device display name to specify for this login attempt
187
+ # @option params [String] :device_id The device ID to set on the login
188
+ # @return [Response] A response hash with the parameters :user_id, :access_token, :home_server, and :device_id.
189
+ # @see https://matrix.org/docs/spec/client_server/latest.html#post-matrix-client-r0-login
190
+ # The Matrix Spec, for more information about the call and response
191
+ def login(login_type: 'm.login.password', **params)
192
+ query = {}
193
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
194
+
195
+ options = {}
196
+ options[:store_token] = params.delete(:store_token) { true }
197
+ options[:store_device_id] = params.delete(:store_device_id) { options[:store_token] }
198
+
199
+ data = {
200
+ type: login_type,
201
+ initial_device_display_name: params.delete(:initial_device_display_name) { MatrixSdk::Api::USER_AGENT }
202
+ }.merge params
203
+ data[:device_id] = device_id if device_id
204
+
205
+ request(:post, client_api_latest, '/login', body: data, query: query).tap do |resp|
206
+ @access_token = resp.access_token if resp.key?(:access_token) && options[:store_token]
207
+ @device_id = resp.device_id if resp.key?(:device_id) && options[:store_device_id]
208
+ end
209
+ end
210
+
211
+ # Logs out the currently logged in device for the current user
212
+ # @return [Response] An empty response if the logout was successful
213
+ # @see https://matrix.org/docs/spec/client_server/latest.html#post-matrix-client-r0-logout
214
+ # The Matrix Spec, for more information about the call and response
215
+ def logout(**params)
216
+ query = {}
217
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
218
+
219
+ request(:post, client_api_latest, '/logout', query: query)
220
+ end
221
+
222
+ # Logs out the currently logged in user
223
+ # @return [Response] An empty response if the logout was successful
224
+ # @see https://matrix.org/docs/spec/client_server/latest.html#post-matrix-client-r0-logout-all
225
+ # The Matrix Spec, for more information about the call and response
226
+ def logout_all(**params)
227
+ query = {}
228
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
229
+
230
+ request(:post, client_api_latest, '/logout/all', query: query)
231
+ end
232
+
233
+ # Changes the users password
234
+ # @param new_password [String] The new password
235
+ # @param auth [Hash] An auth object returned from an interactive auth query
236
+ # @return [Response] An empty response if the password change was successful
237
+ # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-account-password
238
+ # The Matrix Spec, for more information about the call and response
239
+ def change_password(new_password, auth:, **params)
240
+ query = {}
241
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
242
+
243
+ # raise Error unless auth.is_a?(Hash) && auth.key? :type
244
+
245
+ body = {
246
+ new_password: new_password,
247
+ auth: auth
248
+ }
249
+
250
+ request(:post, client_api_latest, '/account/password', body: body, query: query)
251
+ end
252
+
253
+ # Requests an authentication token based on an email address
254
+ #
255
+ # @param secret [String] A random string containing only the characters `[0-9a-zA-Z.=_-]`
256
+ # @param email [String] The email address to register
257
+ # @param attempt [Integer] The current attempt count to register the email+secret combo, increase to send another verification email
258
+ # @param next_link [String,URI] An URL to redirect to after verification is finished
259
+ # @return [Response] A hash containing the :sid id for the current request
260
+ # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-account-password-email-requesttoken
261
+ # For options that are permitted in this call
262
+ def request_email_login_token(secret, email, attempt: 1, next_link: nil)
263
+ body = {
264
+ client_secret: secret,
265
+ email: email,
266
+ send_attempt: attempt,
267
+ next_link: next_link
268
+ }.compact
269
+
270
+ request(:post, client_api_latest, '/account/password/email/requestToken', body: body)
271
+ end
272
+
273
+ # Requests an authentication token based on a phone number
274
+ #
275
+ # @param secret [String] A random string containing only the characters `[0-9a-zA-Z.=_-]`
276
+ # @param country [String] The two-letter ISO-3166-1 country identifier of the destination country of the number
277
+ # @param number [String] The phone number itself
278
+ # @param attempt [Integer] The current attempt count to register the email+secret combo, increase to send another verification email
279
+ # @param next_link [String,URI] An URL to redirect to after verification is finished
280
+ # @return [Response] A hash containing the :sid id for the current request
281
+ # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-account-password-msisdn-requesttoken
282
+ # For options that are permitted in this call
283
+ def request_msisdn_login_token(secret, country, number, attempt: 1, next_link: nil)
284
+ body = {
285
+ client_secret: secret,
286
+ country: country,
287
+ phone_number: number,
288
+ send_attempt: attempt,
289
+ next_link: next_link
290
+ }.compact
291
+
292
+ request(:post, client_api_latest, '/account/password/msisdn/requestToken', body: body)
293
+ end
294
+
295
+ # Deactivates the current account, logging out all connected devices and preventing future logins
296
+ #
297
+ # @param auth_data [Hash] Interactive authentication data to verify the request
298
+ # @param id_server [String] Override the ID server to unbind all 3PIDs from
299
+ # @return [Response]
300
+ # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-account-deactivate
301
+ # For options that are permitted in this call
302
+ def deactivate_account(auth_data, id_server: nil)
303
+ body = {
304
+ auth: auth_data,
305
+ id_server: id_server
306
+ }.compact
307
+
308
+ request(:post, client_api_latest, '/account/deactivate', body: body)
309
+ end
310
+
311
+ def get_3pids(**params)
312
+ query = {}
313
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
314
+
315
+ request(:get, client_api_latest, '/account/3pid', query: query)
316
+ end
317
+
318
+ # Finishes a 3PID addition to the current user
319
+ #
320
+ # @param secret [String] The shared secret with the HS
321
+ # @param session [String] The session ID to finish the request for
322
+ # @param auth_data [Hash] Interactive authentication data to verify the request
323
+ # @return [Response]
324
+ # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-account-3pid-add
325
+ # For options that are permitted in this call
326
+ def complete_3pid_add(secret:, session:, auth_data: nil)
327
+ body = {
328
+ sid: session,
329
+ client_secret: secret,
330
+ auth: auth_data
331
+ }.compact
332
+
333
+ request(:post, client_api_latest, '/account/3pid/add', body: body)
334
+ end
335
+
336
+ # Finishes binding a 3PID to the current user
337
+ #
338
+ # @param secret [String] The shared secret with the identity server
339
+ # @param id_server [String] The identity server being acted against
340
+ # @param id_server_token [String] A previous identity server token
341
+ # @param session [String] The session ID to finish the bind for
342
+ # @return [Response]
343
+ # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-account-3pid-bind
344
+ # For options that are permitted in this call
345
+ def bind_3pid(secret:, id_server:, id_server_token:, session:)
346
+ body = {
347
+ client_secret: secret,
348
+ id_server: id_server,
349
+ id_server_token: id_server_token,
350
+ sid: session
351
+ }
352
+
353
+ request(:post, client_api_latest, '/account/3pid/bind', body: body)
354
+ end
355
+
356
+ # Deletes a 3PID from the current user, this method might not unbind it from the identity server
357
+ #
358
+ # @param medium [:email,:msisdn] The medium of 3PID being removed
359
+ # @param address [String] The address that is to be removed
360
+ # @param id_server [String] The identity server being acted against
361
+ # @return [Response]
362
+ # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-account-3pid-delete
363
+ # For options that are permitted in this call
364
+ def delete_3pid(medium, address, id_server:)
365
+ body = {
366
+ address: address,
367
+ id_server: id_server,
368
+ medium: medium
369
+ }
370
+
371
+ request(:post, client_api_latest, '/account/3pid/delete', body: body)
372
+ end
373
+
374
+ # Unbinds a 3PID from the current user
375
+ #
376
+ # @param medium [:email,:msisdn] The medium of 3PID being removed
377
+ # @param address [String] The address that is to be removed
378
+ # @param id_server [String] The identity server being acted against
379
+ # @return [Response]
380
+ # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-account-3pid-unbind
381
+ # For options that are permitted in this call
382
+ def unbind_3pid(medium, address, id_server:)
383
+ body = {
384
+ address: address,
385
+ id_server: id_server,
386
+ medium: medium
387
+ }
388
+
389
+ request(:post, client_api_latest, '/account/3pid/unbind', body: body)
390
+ end
391
+
392
+ # Gets the list of rooms joined by the current user
393
+ #
394
+ # @return [Response] An array of room IDs under the key :joined_rooms
395
+ # @see https://matrix.org/docs/spec/client_server/latest.html#get-matrix-client-r0-joined-rooms
396
+ def get_joined_rooms(**params)
397
+ query = {}
398
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
399
+
400
+ request(:get, client_api_latest, '/joined_rooms', query: query)
401
+ end
402
+
403
+ # Gets the list of public rooms on a Matrix server
404
+ #
405
+ # @param limit [Integer] Limits the number of results returned
406
+ # @param since [String] A pagination token received from an earlier call
407
+ # @param server [String] The Matrix server to request public rooms from
408
+ # @return [Response] An array of public rooms in the :chunk key, along with
409
+ # :next_batch, :prev_batch, and :total_room_count_estimate
410
+ # for pagination
411
+ # @see https://matrix.org/docs/spec/client_server/latest.html#get-matrix-client-r0-publicrooms
412
+ # https://matrix.org/docs/spec/client_server/latest.html#post-matrix-client-r0-publicrooms
413
+ def get_public_rooms(server: nil, **params)
414
+ query = {
415
+ server: server
416
+ }.compact
417
+ body = nil
418
+ method = :get
419
+
420
+ if !params[:filter].nil? || !params[:include_all_networks].nil? || !params[:third_party_instance_id].nil?
421
+ body = {
422
+ limit: params[:limit],
423
+ since: params[:since],
424
+ filter: params[:filter],
425
+ include_all_networks: params[:include_all_networks],
426
+ third_party_instance_id: params[:third_party_instance_id]
427
+ }.merge(params).compact
428
+ method = :post
429
+ else
430
+ query = query.merge(params).compact
431
+ end
432
+
433
+ request(method, client_api_latest, '/publicRooms', query: query, body: body)
434
+ end
435
+
436
+ # Creates a new room
437
+ # @param params [Hash] The room creation details
438
+ # @option params [Symbol] :visibility (:public) The room visibility
439
+ # @option params [String] :room_alias A room alias to apply on creation
440
+ # @option params [Boolean] :invite Should the room be created invite-only
441
+ # @return [Response] A response hash with ...
442
+ # @see https://matrix.org/docs/spec/client_server/latest.html#post-matrix-client-r0-createroom
443
+ # The Matrix Spec, for more information about the call and response
444
+ def create_room(visibility: :public, **params)
445
+ query = {}
446
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
447
+
448
+ content = {
449
+ visibility: visibility
450
+ }
451
+ content[:room_alias_name] = params.delete(:room_alias) if params[:room_alias]
452
+ content[:invite] = [params.delete(:invite)].flatten if params[:invite]
453
+ content.merge! params
454
+
455
+ request(:post, client_api_latest, '/createRoom', body: content, query: query)
456
+ end
457
+
458
+ # Knock on a room
459
+ #
460
+ # @param id_or_alias [MXID,String] The room ID or Alias to knock
461
+ # @param reason [String] A reason for the knock, will be attached to the membership data
462
+ # @param server_name [String[]] A list of servers to perform the join through
463
+ # @param params [Hash] Extra room knock options
464
+ # @return [Response] A response hash with at least the parameter :room_id
465
+ # @see https://spec.matrix.org/v1.1/client-server-api/#knocking-on-rooms
466
+ # The Matrix Spec, for more information about the call and response
467
+ def knock_room(id_or_alias, reason: nil, server_name: nil, **params)
468
+ query = {}
469
+ query[:server_name] = server_name if server_name
470
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
471
+
472
+ content = {}
473
+ content[:reason] = reason if reason
474
+
475
+ id_or_alias = ERB::Util.url_encode id_or_alias.to_s
476
+
477
+ request(:post, client_api_latest, "/knock/#{id_or_alias}", body: content, query: query)
478
+ end
479
+
480
+ # Joins a room
481
+ # @param id_or_alias [MXID,String] The room ID or Alias to join
482
+ # @param params [Hash] Extra room join options
483
+ # @option params [String[]] :server_name A list of servers to perform the join through
484
+ # @return [Response] A response hash with the parameter :room_id
485
+ # @see https://matrix.org/docs/spec/client_server/latest.html#post-matrix-client-r0-join-roomidoralias
486
+ # The Matrix Spec, for more information about the call and response
487
+ # @todo Add support for 3rd-party signed objects
488
+ def join_room(id_or_alias, reason: nil, **params)
489
+ query = {}
490
+ query[:server_name] = params[:server_name] if params[:server_name]
491
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
492
+
493
+ content = {}
494
+ content[:reason] = reason if reason
495
+
496
+ id_or_alias = ERB::Util.url_encode id_or_alias.to_s
497
+
498
+ request(:post, client_api_latest, "/join/#{id_or_alias}", body: content, query: query)
499
+ end
500
+
501
+ # Sends a state event to a room
502
+ # @param room_id [MXID,String] The room ID to send the state event to
503
+ # @param event_type [String] The event type to send
504
+ # @param content [Hash] The contents of the state event
505
+ # @param params [Hash] Options for the request
506
+ # @option params [String] :state_key The state key of the event, if there is one
507
+ # @return [Response] A response hash with the parameter :event_id
508
+ # @see https://matrix.org/docs/spec/client_server/latest.html#put-matrix-client-r0-rooms-roomid-state-eventtype-statekey
509
+ # https://matrix.org/docs/spec/client_server/latest.html#put-matrix-client-r0-rooms-roomid-state-eventtype
510
+ # The Matrix Spec, for more information about the call and response
511
+ def send_state_event(room_id, event_type, content, **params)
512
+ query = {}
513
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
514
+
515
+ room_id = ERB::Util.url_encode room_id.to_s
516
+ event_type = ERB::Util.url_encode event_type.to_s
517
+ state_key = ERB::Util.url_encode params[:state_key].to_s if params.key? :state_key
518
+
519
+ request(:put, client_api_latest, "/rooms/#{room_id}/state/#{event_type}#{"/#{state_key}" unless state_key.nil?}", body: content, query: query)
520
+ end
521
+
522
+ alias set_room_state send_state_event
523
+
524
+ # Sends a message event to a room
525
+ # @param room_id [MXID,String] The room ID to send the message event to
526
+ # @param event_type [String] The event type of the message
527
+ # @param content [Hash] The contents of the message
528
+ # @param params [Hash] Options for the request
529
+ # @option params [Integer] :txn_id The ID of the transaction, or automatically generated
530
+ # @return [Response] A response hash with the parameter :event_id
531
+ # @see https://matrix.org/docs/spec/client_server/latest.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid
532
+ # The Matrix Spec, for more information about the call and response
533
+ def send_message_event(room_id, event_type, content, **params)
534
+ query = {}
535
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
536
+
537
+ txn_id = transaction_id
538
+ txn_id = params.fetch(:txn_id, "#{txn_id}#{Time.now.to_i}")
539
+
540
+ room_id = ERB::Util.url_encode room_id.to_s
541
+ event_type = ERB::Util.url_encode event_type.to_s
542
+ txn_id = ERB::Util.url_encode txn_id.to_s
543
+
544
+ request(:put, client_api_latest, "/rooms/#{room_id}/send/#{event_type}/#{txn_id}", body: content, query: query)
545
+ end
546
+
547
+ # Redact an event in a room
548
+ # @param room_id [MXID,String] The room ID to send the message event to
549
+ # @param event_id [String] The event ID of the event to redact
550
+ # @param params [Hash] Options for the request
551
+ # @option params [String] :reason The reason for the redaction
552
+ # @option params [Integer] :txn_id The ID of the transaction, or automatically generated
553
+ # @return [Response] A response hash with the parameter :event_id
554
+ # @see https://matrix.org/docs/spec/client_server/latest.html#put-matrix-client-r0-rooms-roomid-redact-eventid-txnid
555
+ # The Matrix Spec, for more information about the call and response
556
+ def redact_event(room_id, event_id, **params)
557
+ query = {}
558
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
559
+
560
+ content = {}
561
+ content[:reason] = params[:reason] if params[:reason]
562
+
563
+ txn_id = transaction_id
564
+ txn_id = params.fetch(:txn_id, "#{txn_id}#{Time.now.to_i}")
565
+
566
+ room_id = ERB::Util.url_encode room_id.to_s
567
+ event_id = ERB::Util.url_encode event_id.to_s
568
+ txn_id = ERB::Util.url_encode txn_id.to_s
569
+
570
+ request(:put, client_api_latest, "/rooms/#{room_id}/redact/#{event_id}/#{txn_id}", body: content, query: query)
571
+ end
572
+
573
+ # Send a content message to a room
574
+ #
575
+ # @example Sending an image to a room
576
+ # send_content('!abcd123:localhost',
577
+ # 'mxc://localhost/1234567',
578
+ # 'An image of a cat',
579
+ # 'm.image',
580
+ # extra_information: {
581
+ # h: 128,
582
+ # w: 128,
583
+ # mimetype: 'image/png',
584
+ # size: 1024
585
+ # })
586
+ #
587
+ # @example Sending a file to a room
588
+ # send_content('!example:localhost',
589
+ # 'mxc://localhost/fileurl',
590
+ # 'Contract.pdf',
591
+ # 'm.file',
592
+ # extra_content: {
593
+ # filename: 'contract.pdf'
594
+ # },
595
+ # extra_information: {
596
+ # mimetype: 'application/pdf',
597
+ # size: 96674
598
+ # })
599
+ #
600
+ # @param room_id [MXID,String] The room ID to send the content to
601
+ # @param url [URI,String] The URL to the content
602
+ # @param name [String] The name of the content
603
+ # @param msg_type [String] The message type of the content
604
+ # @param params [Hash] Options for the request
605
+ # @option params [Hash] :extra_information ({}) Extra information for the content
606
+ # @option params [Hash] :extra_content Extra data to insert into the content hash
607
+ # @return [Response] A response hash with the parameter :event_id
608
+ # @see send_message_event For more information on the underlying call
609
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-image
610
+ # https://matrix.org/docs/spec/client_server/latest.html#m-file
611
+ # https://matrix.org/docs/spec/client_server/latest.html#m-video
612
+ # https://matrix.org/docs/spec/client_server/latest.html#m-audio
613
+ # The Matrix Spec, for more information about the call and response
614
+ def send_content(room_id, url, name, msg_type, **params)
615
+ content = {
616
+ url: url,
617
+ msgtype: msg_type,
618
+ body: name,
619
+ info: params.delete(:extra_information) { {} }
620
+ }
621
+ content.merge!(params.fetch(:extra_content)) if params.key? :extra_content
622
+
623
+ send_message_event(room_id, 'm.room.message', content, **params)
624
+ end
625
+
626
+ # Send a geographic location to a room
627
+ #
628
+ # @param room_id [MXID,String] The room ID to send the location to
629
+ # @param geo_uri [URI,String] The geographical URI to send
630
+ # @param name [String] The name of the location
631
+ # @param params [Hash] Options for the request
632
+ # @option params [Hash] :extra_information ({}) Extra information for the location
633
+ # @option params [URI,String] :thumbnail_url The URL to a thumbnail of the location
634
+ # @option params [Hash] :thumbnail_info Image information about the location thumbnail
635
+ # @return [Response] A response hash with the parameter :event_id
636
+ # @see send_message_event For more information on the underlying call
637
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-location
638
+ # The Matrix Spec, for more information about the call and response
639
+ def send_location(room_id, geo_uri, name, **params)
640
+ content = {
641
+ geo_uri: geo_uri,
642
+ msgtype: 'm.location',
643
+ body: name,
644
+ info: params.delete(:extra_information) { {} }
645
+ }
646
+ content[:info][:thumbnail_url] = params.delete(:thumbnail_url) if params.key? :thumbnail_url
647
+ content[:info][:thumbnail_info] = params.delete(:thumbnail_info) if params.key? :thumbnail_info
648
+
649
+ send_message_event(room_id, 'm.room.message', content, **params)
650
+ end
651
+
652
+ # Send a plaintext message to a room
653
+ #
654
+ # @param room_id [MXID,String] The room ID to send the message to
655
+ # @param message [String] The message to send
656
+ # @param params [Hash] Options for the request
657
+ # @option params [String] :msg_type ('m.text') The message type to send
658
+ # @return [Response] A response hash with the parameter :event_id
659
+ # @see send_message_event For more information on the underlying call
660
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-text
661
+ # The Matrix Spec, for more information about the call and response
662
+ def send_message(room_id, message, **params)
663
+ content = {
664
+ msgtype: params.delete(:msg_type) { 'm.text' },
665
+ body: message
666
+ }
667
+ send_message_event(room_id, 'm.room.message', content, **params)
668
+ end
669
+
670
+ # Send a plaintext emote to a room
671
+ #
672
+ # @param room_id [MXID,String] The room ID to send the message to
673
+ # @param emote [String] The emote to send
674
+ # @param params [Hash] Options for the request
675
+ # @option params [String] :msg_type ('m.emote') The message type to send
676
+ # @return [Response] A response hash with the parameter :event_id
677
+ # @see send_message_event For more information on the underlying call
678
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-emote
679
+ # The Matrix Spec, for more information about the call and response
680
+ def send_emote(room_id, emote, **params)
681
+ content = {
682
+ msgtype: params.delete(:msg_type) { 'm.emote' },
683
+ body: emote
684
+ }
685
+ send_message_event(room_id, 'm.room.message', content, **params)
686
+ end
687
+
688
+ # Send a plaintext notice to a room
689
+ #
690
+ # @param room_id [MXID,String] The room ID to send the message to
691
+ # @param notice [String] The notice to send
692
+ # @param params [Hash] Options for the request
693
+ # @option params [String] :msg_type ('m.notice') The message type to send
694
+ # @return [Response] A response hash with the parameter :event_id
695
+ # @see send_message_event For more information on the underlying call
696
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-notice
697
+ # The Matrix Spec, for more information about the call and response
698
+ def send_notice(room_id, notice, **params)
699
+ content = {
700
+ msgtype: params.delete(:msg_type) { 'm.notice' },
701
+ body: notice
702
+ }
703
+ send_message_event(room_id, 'm.room.message', content, **params)
704
+ end
705
+
706
+ # Report an event in a room
707
+ #
708
+ # @param room_id [MXID,String] The room ID in which the event occurred
709
+ # @param room_id [MXID,String] The event ID to report
710
+ # @param score [Integer] The severity of the report, range between -100 - 0
711
+ # @param reason [String] The reason for the report
712
+ # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-rooms-roomid-report-eventid
713
+ # The Matrix Spec, for more information about the call and response
714
+ def report_event(room_id, event_id, score:, reason:, **params)
715
+ query = {}
716
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
717
+
718
+ body = {
719
+ score: score,
720
+ reason: reason
721
+ }
722
+
723
+ room_id = ERB::Util.url_encode room_id.to_s
724
+ event_id = ERB::Util.url_encode event_id.to_s
725
+
726
+ request(:post, client_api_latest, "/rooms/#{room_id}/report/#{event_id}", body: body, query: query)
727
+ end
728
+
729
+ # Retrieve additional messages in a room
730
+ #
731
+ # @param room_id [MXID,String] The room ID to retrieve messages for
732
+ # @param token [String] The token to start retrieving from, can be from a sync or from an earlier get_room_messages call
733
+ # @param direction [:b,:f] The direction to retrieve messages
734
+ # @param limit [Integer] (10) The limit of messages to retrieve
735
+ # @param params [Hash] Additional options for the request
736
+ # @option params [String] :to A token to limit retrieval to
737
+ # @option params [String] :filter A filter to limit the retrieval to
738
+ # @return [Response] A response hash with the message information containing :start, :end, and :chunk fields
739
+ # @see https://matrix.org/docs/spec/client_server/latest.html#get-matrix-client-r0-rooms-roomid-messages
740
+ # The Matrix Spec, for more information about the call and response
741
+ def get_room_messages(room_id, token, direction:, limit: 10, **params)
742
+ query = {
743
+ from: token,
744
+ dir: direction,
745
+ limit: limit
746
+ }
747
+ query[:to] = params[:to] if params.key? :to
748
+ query[:filter] = params.fetch(:filter) if params.key? :filter
749
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
750
+
751
+ room_id = ERB::Util.url_encode room_id.to_s
752
+
753
+ request(:get, client_api_latest, "/rooms/#{room_id}/messages", query: query)
754
+ end
755
+
756
+ # Gets a specific event from a room
757
+ #
758
+ # @param room_id [MXID,String] The room ID to read from
759
+ # @param event_id [MXID,String] The event ID to retrieve
760
+ # @return [Response] A response hash with the contents of the event
761
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-rooms-roomid-event-eventid
762
+ # The Matrix Spec, for more information about the call and response
763
+ def get_room_event(room_id, event_id, **params)
764
+ query = {}
765
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
766
+
767
+ room_id = ERB::Util.url_encode room_id.to_s
768
+ event_id = ERB::Util.url_encode event_id.to_s
769
+
770
+ request(:get, client_api_latest, "/rooms/#{room_id}/event/#{event_id}", query: query)
771
+ end
772
+
773
+ # Reads the latest instance of a room state event
774
+ #
775
+ # @param room_id [MXID,String] The room ID to read from
776
+ # @param state_type [String] The state type to read
777
+ # @return [Response] A response hash with the contents of the state event
778
+ # @see https://matrix.org/docs/spec/client_server/latest.html#get-matrix-client-r0-rooms-roomid-state-eventtype
779
+ # The Matrix Spec, for more information about the call and response
780
+ def get_room_state(room_id, state_type, key: nil, **params)
781
+ query = {}
782
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
783
+
784
+ room_id = ERB::Util.url_encode room_id.to_s
785
+ state_type = ERB::Util.url_encode state_type.to_s
786
+ key = ERB::Util.url_encode key.to_s
787
+
788
+ request(:get, client_api_latest, "/rooms/#{room_id}/state/#{state_type}#{key.empty? ? nil : "/#{key}"}", query: query)
789
+ end
790
+
791
+ # Retrieves all current state objects from a room
792
+ #
793
+ # @param room_id [MXID,String] The room ID to read from
794
+ # @return [Response] A response hash with the contents of all state events
795
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-rooms-roomid-event-eventid
796
+ # The Matrix Spec, for more information about the call and response
797
+ def get_room_state_all(room_id, **params)
798
+ query = {}
799
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
800
+
801
+ room_id = ERB::Util.url_encode room_id.to_s
802
+
803
+ request(:get, client_api_latest, "/rooms/#{room_id}/state", query: query)
804
+ end
805
+
806
+ # Retrieves number of events that happened just before and after the specified event
807
+ #
808
+ # @param room_id [MXID,String] The room to get events from.
809
+ # @param event_id [MXID,String] The event to get context around.
810
+ # @option params [Integer] :limit (10) The limit of messages to retrieve
811
+ # @option params [String] :filter A filter to limit the retrieval to
812
+ # @return [Response] A response hash with contextual event information
813
+ # @see https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-rooms-roomid-context-eventid
814
+ # The Matrix Spec, for more information about the call and response
815
+ # @example Find event context with filter and limit specified
816
+ # api.get_room_event_context('#room:example.com', '$event_id:example.com', filter: { types: ['m.room.message'] }.to_json, limit: 20)
817
+ def get_room_event_context(room_id, event_id, **params)
818
+ query = {}
819
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
820
+
821
+ query[:limit] = params.fetch(:limit) if params.key? :limit
822
+ query[:filter] = params.fetch(:filter) if params.key? :filter
823
+
824
+ room_id = ERB::Util.url_encode room_id.to_s
825
+ event_id = ERB::Util.url_encode event_id.to_s
826
+
827
+ request(:get, client_api_latest, "/rooms/#{room_id}/context/#{event_id}", query: query)
828
+ end
829
+
830
+ ## Specialized getters for specced state
831
+ #
832
+
833
+ # Gets the current display name of a room
834
+ #
835
+ # @param room_id [MXID,String] The room ID to look up
836
+ # @param [Hash] params Extra options to provide to the request, see #get_room_state
837
+ # @return [Response] A response hash with the parameter :name
838
+ # @raise [MatrixNotFoundError] Raised if no name has been set on the room
839
+ # @see get_room_state
840
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-name
841
+ # The Matrix Spec, for more information about the event and data
842
+ def get_room_name(room_id, **params)
843
+ get_room_state(room_id, 'm.room.name', **params)
844
+ end
845
+
846
+ # Sets the display name of a room
847
+ #
848
+ # @param [MXID,String] room_id The room ID to work on
849
+ # @param [String] name The new name of the room
850
+ # @param [Hash] params Extra options to set on the request, see #send_state_event
851
+ # @return [Response] The resulting state event
852
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-name
853
+ # The Matrix Spec, for more information about the event and data
854
+ def set_room_name(room_id, name, **params)
855
+ content = {
856
+ name: name
857
+ }
858
+ send_state_event(room_id, 'm.room.name', content, **params)
859
+ end
860
+
861
+ # Gets the current topic of a room
862
+ #
863
+ # @param [MXID,String] room_id The room ID to look up
864
+ # @param [Hash] params Extra options to provide to the request, see #get_room_state
865
+ # @return [Response] A response hash with the parameter :topic
866
+ # @raise [MatrixNotFoundError] Raised if no topic has been set on the room
867
+ # @see get_room_state
868
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-topic
869
+ # The Matrix Spec, for more information about the event and data
870
+ def get_room_topic(room_id, **params)
871
+ get_room_state(room_id, 'm.room.topic', **params)
872
+ end
873
+
874
+ # Sets the topic of a room
875
+ #
876
+ # @param [MXID,String] room_id The room ID to work on
877
+ # @param [String] topic The new topic of the room
878
+ # @param [Hash] params Extra options to set on the request, see #send_state_event
879
+ # @return [Response] The resulting state event
880
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-topic
881
+ # The Matrix Spec, for more information about the event and data
882
+ def set_room_topic(room_id, topic, **params)
883
+ content = {
884
+ topic: topic
885
+ }
886
+ send_state_event(room_id, 'm.room.topic', content, **params)
887
+ end
888
+
889
+ # Gets the current avatar URL of a room
890
+ #
891
+ # @param [MXID,String] room_id The room ID to look up
892
+ # @param [Hash] params Extra options to provide to the request, see #get_room_state
893
+ # @return [Response] A response hash with the parameters :url and (optionally) :info
894
+ # @raise [MatrixNotFoundError] Raised if no avatar has been set on the room
895
+ # @see get_room_state
896
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-avatar
897
+ # The Matrix Spec, for more information about the event and data
898
+ def get_room_avatar(room_id, **params)
899
+ get_room_state(room_id, 'm.room.avatar', **params)
900
+ end
901
+
902
+ # Sets the avatar URL for a room
903
+ #
904
+ # @param [MXID,String] room_id The room ID to work on
905
+ # @param [String,URI] url The new avatar URL for the room
906
+ # @param [Hash] params Extra options to set on the request, see #send_state_event
907
+ # @return [Response] The resulting state event
908
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-avatar
909
+ # The Matrix Spec, for more information about the event and data
910
+ def set_room_avatar(room_id, url, **params)
911
+ content = {
912
+ url: url
913
+ }
914
+ send_state_event(room_id, 'm.room.avatar', content, **params)
915
+ end
916
+
917
+ # Gets a list of currently known aliases of a room
918
+ #
919
+ # @param [MXID,String] room_id The room ID to look up
920
+ # @return [Response] A response hash with the array :aliases
921
+ # @raise [MatrixForbiddenError] Raised if the user doesn't have the right to read aliases
922
+ # @see https://spec.matrix.org/v1.1/client-server-api/#get_matrixclientv3roomsroomidaliases
923
+ # The Matrix Spec, for more information about the event and data
924
+ # @example Looking up aliases for a room
925
+ # api.get_room_aliases('!QtykxKocfZaZOUrTwp:matrix.org')
926
+ # # => {:aliases=>["#matrix:matrix.org"]}
927
+ def get_room_aliases(room_id, **params)
928
+ query = {}
929
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
930
+
931
+ room_id = ERB::Util.url_encode room_id.to_s
932
+
933
+ request(:get, client_api_latest, "/rooms/#{room_id}/aliases", query: query)
934
+ end
935
+
936
+ # Gets a list of pinned events in a room
937
+ #
938
+ # @param [MXID,String] room_id The room ID to look up
939
+ # @param [Hash] params Extra options to provide to the request, see #get_room_state
940
+ # @return [Response] A response hash with the array :pinned
941
+ # @raise [MatrixNotFoundError] Raised if no aliases has been set on the room by the specified HS
942
+ # @see get_room_state
943
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-pinned-events
944
+ # The Matrix Spec, for more information about the event and data
945
+ def get_room_pinned_events(room_id, **params)
946
+ get_room_state(room_id, 'm.room.pinned_events', **params)
947
+ end
948
+
949
+ # Sets the list of pinned events in a room
950
+ #
951
+ # @param [MXID,String] room_id The room ID to work on
952
+ # @param [Array[String]] events The new list of events to set as pinned
953
+ # @param [Hash] params Extra options to set on the request, see #send_state_event
954
+ # @return [Response] The resulting state event
955
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-pinned-events
956
+ # The Matrix Spec, for more information about the event and data
957
+ def set_room_pinned_events(room_id, events, **params)
958
+ content = {
959
+ pinned: events
960
+ }
961
+ send_state_event(room_id, 'm.room.pinned_events', content, **params)
962
+ end
963
+
964
+ # Gets the configured power levels for a room
965
+ #
966
+ # @param [MXID,String] room_id The room ID to look up
967
+ # @param [Hash] params Extra options to provide to the request, see #get_room_state
968
+ # @return [Response] A response hash with power level information
969
+ # @see get_room_state
970
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-power-levels
971
+ # The Matrix Spec, for more information about the event and data
972
+ def get_room_power_levels(room_id, **params)
973
+ get_room_state(room_id, 'm.room.power_levels', **params)
974
+ end
975
+ alias get_power_levels get_room_power_levels
976
+
977
+ # Sets the configuration for power levels in a room
978
+ #
979
+ # @param [MXID,String] room_id The room ID to work on
980
+ # @param [Hash] content The new power level configuration
981
+ # @param [Hash] params Extra options to set on the request, see #send_state_event
982
+ # @return [Response] The resulting state event
983
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-power-levels
984
+ # The Matrix Spec, for more information about the event and data
985
+ def set_room_power_levels(room_id, content, **params)
986
+ content[:events] = {} unless content.key? :events
987
+ send_state_event(room_id, 'm.room.power_levels', content, **params)
988
+ end
989
+ alias set_power_levels set_room_power_levels
990
+
991
+ # Gets the join rules for a room
992
+ #
993
+ # @param [MXID,String] room_id The room ID to look up
994
+ # @param [Hash] params Extra options to provide to the request, see #get_room_state
995
+ # @return [Response] A response hash with the key :join_rule
996
+ # @see get_room_state
997
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-join-rules
998
+ # The Matrix Spec, for more information about the event and data
999
+ def get_room_join_rules(room_id, **params)
1000
+ get_room_state(room_id, 'm.room.join_rules', **params)
1001
+ end
1002
+
1003
+ # Sets the join rules for a room
1004
+ #
1005
+ # @param [MXID,String] room_id The room ID to work on
1006
+ # @param [String,Symbol] join_rule The new join rule setting (Currently only public and invite are implemented)
1007
+ # @param [Hash] params Extra options to set on the request, see #send_state_event
1008
+ # @return [Response] The resulting state event
1009
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-join-rules
1010
+ # The Matrix Spec, for more information about the event and data
1011
+ def set_room_join_rules(room_id, join_rule, **params)
1012
+ content = {
1013
+ join_rule: join_rule
1014
+ }
1015
+
1016
+ send_state_event(room_id, 'm.room.join_rules', content, **params)
1017
+ end
1018
+
1019
+ # Gets the guest access settings for a room
1020
+ #
1021
+ # @param [MXID,String] room_id The room ID to look up
1022
+ # @param [Hash] params Extra options to provide to the request, see #get_room_state
1023
+ # @return [Response] A response hash with the key :guest_acces, either :can_join or :forbidden
1024
+ # @see get_room_state
1025
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-guest-access
1026
+ # The Matrix Spec, for more information about the event and data
1027
+ def get_room_guest_access(room_id, **params)
1028
+ get_room_state(room_id, 'm.room.guest_access', **params)
1029
+ end
1030
+
1031
+ # Sets the guest access settings for a room
1032
+ #
1033
+ # @param [MXID,String] room_id The room ID to work on
1034
+ # @param [:can_join, :forbidden] guest_access The new guest access setting for the room
1035
+ # @param [Hash] params Extra options to set on the request, see #send_state_event
1036
+ # @return [Response] The resulting state event
1037
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-guest-access
1038
+ # The Matrix Spec, for more information about the event and data
1039
+ def set_room_guest_access(room_id, guest_access, **params)
1040
+ content = {
1041
+ guest_access: guest_access
1042
+ }
1043
+
1044
+ send_state_event(room_id, 'm.room.guest_access', content, **params)
1045
+ end
1046
+
1047
+ # Gets the creation configuration object for a room
1048
+ #
1049
+ # @param [MXID,String] room_id The room ID to look up
1050
+ # @param [Hash] params Extra options to provide to the request, see #get_room_state
1051
+ # @return [Response] A response hash with the configuration the room was created for
1052
+ # @see get_room_state
1053
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-create
1054
+ # The Matrix Spec, for more information about the event and data
1055
+ def get_room_creation_info(room_id, **params)
1056
+ get_room_state(room_id, 'm.room.create', **params)
1057
+ end
1058
+
1059
+ # Gets the encryption configuration for a room
1060
+ #
1061
+ # @param [MXID,String] room_id The room ID to look up
1062
+ # @param [Hash] params Extra options to provide to the request, see #get_room_state
1063
+ # @return [Response] A response hash with the configuration the room was created for
1064
+ # @see get_room_state
1065
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-encryption
1066
+ # The Matrix Spec, for more information about the event and data
1067
+ def get_room_encryption_settings(room_id, **params)
1068
+ get_room_state(room_id, 'm.room.encryption', **params)
1069
+ end
1070
+
1071
+ # Sets the encryption configuration for a room
1072
+ #
1073
+ # @param [MXID,String] room_id The room ID to work on
1074
+ # @param ['m.megolm.v1.aes-sha2'] algorithm The encryption algorithm to use
1075
+ # @param [Integer] rotation_period_ms The interval between key rotation in milliseconds
1076
+ # @param [Integer] rotation_period_msgs The interval between key rotation in messages
1077
+ # @param [Hash] params Extra options to set on the request, see #send_state_event
1078
+ # @return [Response] The resulting state event
1079
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-guest-encryption
1080
+ # The Matrix Spec, for more information about the event and data
1081
+ def set_room_encryption_settings(room_id, algorithm: 'm.megolm.v1.aes-sha2', rotation_period_ms: 1 * 7 * 24 * 60 * 60 * 1000, rotation_period_msgs: 100, **params)
1082
+ content = {
1083
+ algorithm: algorithm,
1084
+ rotation_period_ms: rotation_period_ms,
1085
+ rotation_period_msgs: rotation_period_msgs
1086
+ }
1087
+ send_state_event(room_id, 'm.room.encryption', content, **params)
1088
+ end
1089
+
1090
+ # Gets the history availabiilty for a room
1091
+ #
1092
+ # @param [MXID,String] room_id The room ID to look up
1093
+ # @param [Hash] params Extra options to provide to the request, see #get_room_state
1094
+ # @return [Response] A response hash with the key :history_visibility
1095
+ # @see get_room_state
1096
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-history-visibility
1097
+ # The Matrix Spec, for more information about the event and data
1098
+ def get_room_history_visibility(room_id, **params)
1099
+ get_room_state(room_id, 'm.room.history_visibility', **params)
1100
+ end
1101
+
1102
+ # Sets the history availability for a room
1103
+ #
1104
+ # @param [MXID,String] room_id The room ID to work on
1105
+ # @param [:invited, :joined, :shared, :world_readable] visibility The new history visibility level
1106
+ # @param [Hash] params Extra options to set on the request, see #send_state_event
1107
+ # @return [Response] The resulting state event
1108
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-guest-history-visibility
1109
+ # The Matrix Spec, for more information about the event and data
1110
+ def set_room_history_visibility(room_id, visibility, **params)
1111
+ content = {
1112
+ history_visibility: visibility
1113
+ }
1114
+
1115
+ send_state_event(room_id, 'm.room.history_visibility', content, **params)
1116
+ end
1117
+
1118
+ # Gets the server ACLs for a room
1119
+ #
1120
+ # @param [MXID,String] room_id The room ID to look up
1121
+ # @param [Hash] params Extra options to provide to the request, see #get_room_state
1122
+ # @return [Response] A response hash with server ACL information
1123
+ # @see get_room_state
1124
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-server-acl
1125
+ # The Matrix Spec, for more information about the event and data
1126
+ def get_room_server_acl(room_id, **params)
1127
+ get_room_state(room_id, 'm.room.server_acl', **params)
1128
+ end
1129
+
1130
+ # Sets the server ACL configuration for a room
1131
+ #
1132
+ # @param [MXID,String] room_id The room ID to work on
1133
+ # @param [Boolean] allow_ip_literals If HSes with literal IP domains should be allowed
1134
+ # @param [Array[String]] allow A list of HS wildcards that are allowed to communicate with the room
1135
+ # @param [Array[String]] deny A list of HS wildcards that are denied from communicating with the room
1136
+ # @param [Hash] params Extra options to set on the request, see #send_state_event
1137
+ # @return [Response] The resulting state event
1138
+ # @see https://matrix.org/docs/spec/client_server/latest.html#m-room-guest-server-acl
1139
+ # The Matrix Spec, for more information about the event and data
1140
+ def set_room_server_acl(room_id, allow:, deny:, allow_ip_literals: false, **params)
1141
+ content = {
1142
+ allow_ip_literals: allow_ip_literals,
1143
+ allow: allow,
1144
+ deny: deny
1145
+ }
1146
+
1147
+ send_state_event(room_id, 'm.room.server_acl', content, **params)
1148
+ end
1149
+
1150
+ def leave_room(room_id, **params)
1151
+ query = {}
1152
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1153
+
1154
+ room_id = ERB::Util.url_encode room_id.to_s
1155
+
1156
+ request(:post, client_api_latest, "/rooms/#{room_id}/leave", query: query)
1157
+ end
1158
+
1159
+ def forget_room(room_id, **params)
1160
+ query = {}
1161
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1162
+
1163
+ room_id = ERB::Util.url_encode room_id.to_s
1164
+
1165
+ request(:post, client_api_latest, "/rooms/#{room_id}/forget", query: query)
1166
+ end
1167
+
1168
+ # Directly joins a room by ID
1169
+ #
1170
+ # @param room_id [MXID,String] The room ID to join
1171
+ # @param third_party_signed [Hash] The 3PID signature allowing the user to join
1172
+ # @return [Response] A response hash with the parameter :room_id
1173
+ # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-rooms-roomid-join
1174
+ # The Matrix Spec, for more information about the call and response
1175
+ def join_room_id(room_id, third_party_signed: nil, **params)
1176
+ query = {}
1177
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1178
+
1179
+ body = {
1180
+ third_party_signed: third_party_signed
1181
+ }.compact
1182
+
1183
+ room_id = ERB::Util.url_encode room_id.to_s
1184
+
1185
+ request(:post, client_api_latest, "/rooms/#{room_id}/join", body: body, query: query)
1186
+ end
1187
+
1188
+ def invite_user(room_id, user_id, **params)
1189
+ query = {}
1190
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1191
+
1192
+ content = {
1193
+ user_id: user_id
1194
+ }
1195
+
1196
+ room_id = ERB::Util.url_encode room_id.to_s
1197
+
1198
+ request(:post, client_api_latest, "/rooms/#{room_id}/invite", body: content, query: query)
1199
+ end
1200
+
1201
+ def kick_user(room_id, user_id, reason: '', **params)
1202
+ query = {}
1203
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1204
+
1205
+ content = {
1206
+ user_id: user_id,
1207
+ reason: reason
1208
+ }
1209
+ room_id = ERB::Util.url_encode room_id.to_s
1210
+
1211
+ request(:post, client_api_latest, "/rooms/#{room_id}/kick", body: content, query: query)
1212
+ end
1213
+
1214
+ def get_membership(room_id, user_id, **params)
1215
+ query = {}
1216
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1217
+
1218
+ room_id = ERB::Util.url_encode room_id.to_s
1219
+ user_id = ERB::Util.url_encode user_id.to_s
1220
+
1221
+ request(:get, client_api_latest, "/rooms/#{room_id}/state/m.room.member/#{user_id}", query: query)
1222
+ end
1223
+
1224
+ def set_membership(room_id, user_id, membership, reason: '', **params)
1225
+ content = {
1226
+ membership: membership,
1227
+ reason: reason
1228
+ }
1229
+ content[:displayname] = params.delete(:displayname) if params.key? :displayname
1230
+ content[:avatar_url] = params.delete(:avatar_url) if params.key? :avatar_url
1231
+
1232
+ send_state_event(room_id, 'm.room.member', content, params.merge(state_key: user_id))
1233
+ end
1234
+
1235
+ def ban_user(room_id, user_id, reason: '', **params)
1236
+ query = {}
1237
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1238
+
1239
+ content = {
1240
+ user_id: user_id,
1241
+ reason: reason
1242
+ }
1243
+ room_id = ERB::Util.url_encode room_id.to_s
1244
+
1245
+ request(:post, client_api_latest, "/rooms/#{room_id}/ban", body: content, query: query)
1246
+ end
1247
+
1248
+ def unban_user(room_id, user_id, **params)
1249
+ query = {}
1250
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1251
+
1252
+ content = {
1253
+ user_id: user_id
1254
+ }
1255
+ room_id = ERB::Util.url_encode room_id.to_s
1256
+
1257
+ request(:post, client_api_latest, "/rooms/#{room_id}/unban", body: content, query: query)
1258
+ end
1259
+
1260
+ # Gets the room directory visibility status for a room
1261
+ #
1262
+ # @param [MXID,String] room_id The room ID to look up
1263
+ # @return [Response] A response hash with a :visibility key
1264
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-directory-list-room-roomid
1265
+ # The Matrix Spec, for more information about the event and data
1266
+ def get_room_directory_visibility(room_id, **params)
1267
+ query = {}
1268
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1269
+
1270
+ room_id = ERB::Util.url_encode room_id.to_s
1271
+
1272
+ request(:get, client_api_latest, "/directory/list/room/#{room_id}", query: query)
1273
+ end
1274
+
1275
+ # Sets the room directory visibility status for a room
1276
+ #
1277
+ # @param [MXID,String] room_id The room ID to change visibility for
1278
+ # @param [:public,:private] visibility The new visibility status
1279
+ # @return [Response] An empty response hash if the visibilty change succeeded
1280
+ # @see https://matrix.org/docs/spec/client_server/latest#put-matrix-client-r0-directory-list-room-roomid
1281
+ # The Matrix Spec, for more information about the event and data
1282
+ def set_room_directory_visibility(room_id, visibility, **params)
1283
+ query = {}
1284
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1285
+
1286
+ body = {
1287
+ visibility: visibility
1288
+ }
1289
+
1290
+ room_id = ERB::Util.url_encode room_id.to_s
1291
+
1292
+ request(:put, client_api_latest, "/directory/list/room/#{room_id}", body: body, query: query)
1293
+ end
1294
+
1295
+ def get_user_tags(user_id, room_id, **params)
1296
+ query = {}
1297
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1298
+
1299
+ room_id = ERB::Util.url_encode room_id.to_s
1300
+ user_id = ERB::Util.url_encode user_id.to_s
1301
+
1302
+ request(:get, client_api_latest, "/user/#{user_id}/rooms/#{room_id}/tags", query: query)
1303
+ end
1304
+
1305
+ def remove_user_tag(user_id, room_id, tag, **params)
1306
+ query = {}
1307
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1308
+
1309
+ room_id = ERB::Util.url_encode room_id.to_s
1310
+ user_id = ERB::Util.url_encode user_id.to_s
1311
+ tag = ERB::Util.url_encode tag.to_s
1312
+
1313
+ request(:delete, client_api_latest, "/user/#{user_id}/rooms/#{room_id}/tags/#{tag}", query: query)
1314
+ end
1315
+
1316
+ def add_user_tag(user_id, room_id, tag, **params)
1317
+ query = {}
1318
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1319
+
1320
+ if params[:body]
1321
+ content = params[:body]
1322
+ else
1323
+ content = {}
1324
+ content[:order] = params[:order] if params.key? :order
1325
+ end
1326
+
1327
+ room_id = ERB::Util.url_encode room_id.to_s
1328
+ user_id = ERB::Util.url_encode user_id.to_s
1329
+ tag = ERB::Util.url_encode tag.to_s
1330
+
1331
+ request(:put, client_api_latest, "/user/#{user_id}/rooms/#{room_id}/tags/#{tag}", body: content, query: query)
1332
+ end
1333
+
1334
+ def get_account_data(user_id, type_key, **params)
1335
+ query = {}
1336
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1337
+
1338
+ user_id = ERB::Util.url_encode user_id.to_s
1339
+ type_key = ERB::Util.url_encode type_key.to_s
1340
+
1341
+ request(:get, client_api_latest, "/user/#{user_id}/account_data/#{type_key}", query: query)
1342
+ end
1343
+
1344
+ def set_account_data(user_id, type_key, account_data, **params)
1345
+ query = {}
1346
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1347
+
1348
+ user_id = ERB::Util.url_encode user_id.to_s
1349
+ type_key = ERB::Util.url_encode type_key.to_s
1350
+
1351
+ request(:put, client_api_latest, "/user/#{user_id}/account_data/#{type_key}", body: account_data, query: query)
1352
+ end
1353
+
1354
+ def get_room_account_data(user_id, room_id, type_key, **params)
1355
+ query = {}
1356
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1357
+
1358
+ user_id = ERB::Util.url_encode user_id.to_s
1359
+ room_id = ERB::Util.url_encode room_id.to_s
1360
+ type_key = ERB::Util.url_encode type_key.to_s
1361
+
1362
+ request(:get, client_api_latest, "/user/#{user_id}/rooms/#{room_id}/account_data/#{type_key}", query: query)
1363
+ end
1364
+
1365
+ def set_room_account_data(user_id, room_id, type_key, account_data, **params)
1366
+ query = {}
1367
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1368
+
1369
+ user_id = ERB::Util.url_encode user_id.to_s
1370
+ room_id = ERB::Util.url_encode room_id.to_s
1371
+ type_key = ERB::Util.url_encode type_key.to_s
1372
+
1373
+ request(:put, client_api_latest, "/user/#{user_id}/rooms/#{room_id}/account_data/#{type_key}", body: account_data, query: query)
1374
+ end
1375
+
1376
+ # Retrieve user information
1377
+ #
1378
+ # @param [String] user_id The MXID to look up
1379
+ # @return [Response] A response hash containing the requested user's information
1380
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-admin-whois-userid
1381
+ # The Matrix Spec, for more information about the parameters and data
1382
+ def whois(user_id)
1383
+ user_id = ERB::Util.url_encode user_id.to_s
1384
+
1385
+ request(:get, client_api_latest, "/admin/whois/#{user_id}")
1386
+ end
1387
+
1388
+ def get_filter(user_id, filter_id, **params)
1389
+ query = {}
1390
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1391
+
1392
+ user_id = ERB::Util.url_encode user_id.to_s
1393
+ filter_id = ERB::Util.url_encode filter_id.to_s
1394
+
1395
+ request(:get, client_api_latest, "/user/#{user_id}/filter/#{filter_id}", query: query)
1396
+ end
1397
+
1398
+ # Creates a filter for future use
1399
+ #
1400
+ # @param [String,MXID] user_id The user to create the filter for
1401
+ # @param [Hash] filter_params The filter to create
1402
+ def create_filter(user_id, filter_params, **params)
1403
+ query = {}
1404
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1405
+
1406
+ user_id = ERB::Util.url_encode user_id.to_s
1407
+
1408
+ request(:post, client_api_latest, "/user/#{user_id}/filter", body: filter_params, query: query)
1409
+ end
1410
+
1411
+ def media_upload(content, content_type, **params)
1412
+ query = {}
1413
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1414
+
1415
+ request(:post, :media_r0, '/upload', body: content, headers: { 'content-type' => content_type }, query: query)
1416
+ end
1417
+
1418
+ def get_display_name(user_id, **params)
1419
+ query = {}
1420
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1421
+
1422
+ user_id = ERB::Util.url_encode user_id.to_s
1423
+
1424
+ request(:get, client_api_latest, "/profile/#{user_id}/displayname", query: query)
1425
+ end
1426
+
1427
+ def set_display_name(user_id, display_name, **params)
1428
+ query = {}
1429
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1430
+
1431
+ content = {
1432
+ displayname: display_name
1433
+ }
1434
+
1435
+ user_id = ERB::Util.url_encode user_id.to_s
1436
+
1437
+ request(:put, client_api_latest, "/profile/#{user_id}/displayname", body: content, query: query)
1438
+ end
1439
+
1440
+ def get_avatar_url(user_id, **params)
1441
+ query = {}
1442
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1443
+
1444
+ user_id = ERB::Util.url_encode user_id.to_s
1445
+
1446
+ request(:get, client_api_latest, "/profile/#{user_id}/avatar_url", query: query)
1447
+ end
1448
+
1449
+ # Sets the avatar URL for a user
1450
+ #
1451
+ # @example Reuploading a gravatar as an avatar
1452
+ # require 'digest/md5'
1453
+ #
1454
+ # # Get a 256x256 gravatar of user@example.com, returning 404 if one doesn't exist
1455
+ # email = 'user@example.com'
1456
+ # url = "https://www.gravatar.com/avatar/#{Digest::MD5.hexdigest email.striprim.downcase}?d=404&s=256"
1457
+ #
1458
+ # data = Net::HTTP.get_response(URI(url))
1459
+ # data.value
1460
+ #
1461
+ # # Reupload the gravatar to your connected HS before setting the resulting MXC URL as the new avatar
1462
+ # mxc = api.media_upload(data.body, data.content_type)[:content_uri]
1463
+ # api.set_avatar_url(api.whoami?[:user_id], mxc)
1464
+ #
1465
+ # @param [String,MXID] user_id The ID of the user to set the avatar for
1466
+ # @param [String,URI::MXC] url The new avatar URL, should be a mxc:// URL
1467
+ # @return [Response] An empty response hash if the change was successful
1468
+ # @see https://matrix.org/docs/spec/client_server/latest#put-matrix-client-r0-profile-userid-avatar-url
1469
+ # The Matrix Spec, for more information about the event and data
1470
+ def set_avatar_url(user_id, url, **params)
1471
+ query = {}
1472
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1473
+
1474
+ content = {
1475
+ avatar_url: url
1476
+ }
1477
+
1478
+ user_id = ERB::Util.url_encode user_id.to_s
1479
+
1480
+ request(:put, client_api_latest, "/profile/#{user_id}/avatar_url", body: content, query: query)
1481
+ end
1482
+
1483
+ # Gets the combined profile object of a user.
1484
+ #
1485
+ # This includes their display name and avatar
1486
+ #
1487
+ # @param [String,MXID] user_id The User ID to read the profile for
1488
+ # @return [Response] The user profile object
1489
+ # @see #get_display_name
1490
+ # @see #get_avatar_url
1491
+ def get_profile(user_id, **params)
1492
+ query = {}
1493
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1494
+
1495
+ user_id = ERB::Util.url_encode user_id.to_s
1496
+
1497
+ request(:get, client_api_latest, "/profile/#{user_id}", query: query)
1498
+ end
1499
+
1500
+ # Gets TURN server connection information and credentials
1501
+ #
1502
+ # @return [Response] A response hash according to the spec
1503
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-voip-turnserver
1504
+ # The Matrix Spec, for more information about the event and data
1505
+ def get_turn_server
1506
+ request(:get, client_api_latest, '/voip/turnServer')
1507
+ end
1508
+
1509
+ # Sets the typing status for a user
1510
+ #
1511
+ # @param [String,MXID] room_id The ID of the room to set the typing status in
1512
+ # @param [String,MXID] user_id The ID of the user to set the typing status for
1513
+ # @param [Boolean] typing Is the user typing or not
1514
+ # @param [Numeric] timeout The timeout in seconds for how long the typing status should be valid
1515
+ # @return [Response] An empty response hash if the typing change was successful
1516
+ # @see https://matrix.org/docs/spec/client_server/latest#put-matrix-client-r0-rooms-roomid-typing-userid
1517
+ # The Matrix Spec, for more information about the event and data
1518
+ def set_typing(room_id, user_id, typing: true, timeout: nil)
1519
+ room_id = ERB::Util.url_encode room_id.to_s
1520
+ user_id = ERB::Util.url_encode user_id.to_s
1521
+
1522
+ body = {
1523
+ typing: typing,
1524
+ timeout: timeout ? timeout * 1000 : nil
1525
+ }.compact
1526
+
1527
+ request(:put, client_api_latest, "/rooms/#{room_id}/typing/#{user_id}", body: body)
1528
+ end
1529
+
1530
+ # Gets the presence status of a user
1531
+ #
1532
+ # @param [String,MXID] user_id The User ID to read the status for
1533
+ # @return [Response] A response hash containing the current user presence status
1534
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-presence-userid-status
1535
+ # The Matrix Spec, for more information about the event and data
1536
+ def get_presence_status(user_id)
1537
+ user_id = ERB::Util.url_encode user_id.to_s
1538
+
1539
+ request(:get, client_api_latest, "/presence/#{user_id}/status")
1540
+ end
1541
+
1542
+ # Sets the presence status of a user
1543
+ #
1544
+ # @param [String,MXID] user_id The User ID to set the status for
1545
+ # @param [:online,:offline,:unavailable] status The status to set
1546
+ # @param [String] messge The status message to store for the new status
1547
+ # @return [Response] An empty response hash if the status update succeeded
1548
+ # @note The specified user_id should be of the local user unless used for AS purposes
1549
+ # @see https://matrix.org/docs/spec/client_server/latest#put-matrix-client-r0-presence-userid-status
1550
+ # The Matrix Spec, for more information about the event and data
1551
+ def set_presence_status(user_id, status, message: nil)
1552
+ user_id = ERB::Util.url_encode user_id.to_s
1553
+
1554
+ body = {
1555
+ presence: status,
1556
+ status_msg: message
1557
+ }.compact
1558
+
1559
+ request(:put, client_api_latest, "/presence/#{user_id}/status", body: body)
1560
+ end
1561
+
1562
+ # Converts a Matrix content URL (mxc://) to a media download URL
1563
+ # @param [String,URI] mxcurl The Matrix content URL to convert
1564
+ # @param [String,URI] source A source HS to use for the convertion, defaults to the connected HS
1565
+ # @return [URI] The full download URL for the requested piece of media
1566
+ #
1567
+ # @example Converting a MXC URL
1568
+ # url = 'mxc://example.com/media_hash'
1569
+ #
1570
+ # api.get_download_url(url)
1571
+ # # => #<URI::HTTPS https://example.com/_matrix/media/r0/download/example.com/media_hash>
1572
+ # api.get_download_url(url, source: 'matrix.org')
1573
+ # # => #<URI::HTTPS https://matrix.org/_matrix/media/r0/download/example.com/media_hash>
1574
+ def get_download_url(mxcurl, source: nil, **_params)
1575
+ mxcurl = URI.parse(mxcurl.to_s) unless mxcurl.is_a? URI
1576
+ raise 'Not a mxc:// URL' unless mxcurl.is_a? URI::MXC
1577
+
1578
+ if source
1579
+ source = "https://#{source}" unless source.include? '://'
1580
+ source = URI(source.to_s) unless source.is_a?(URI)
1581
+ end
1582
+
1583
+ source ||= homeserver.dup
1584
+ source.tap do |u|
1585
+ full_path = mxcurl.full_path.to_s
1586
+ u.path = "/_matrix/media/r0/download/#{full_path}"
1587
+ end
1588
+ end
1589
+
1590
+ # Gets a preview of the given URL
1591
+ #
1592
+ # @param [String,URI] url The URL to retrieve a preview for
1593
+ # @return [Response] A response hash containing OpenGraph data for the URL
1594
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-media-r0-preview-url
1595
+ # The Matrix Spec, for more information about the data
1596
+ def get_url_preview(url, timestamp: nil)
1597
+ ts = (timestamp.to_i * 1000) if timestamp.is_a? Time
1598
+ ts = timestamp if timestamp.is_a? Integer
1599
+
1600
+ query = {
1601
+ url: url,
1602
+ ts: ts
1603
+ }.compact
1604
+
1605
+ request(:get, :media_r0, '/preview_url', query: query)
1606
+ end
1607
+
1608
+ # Gets the media configuration of the current server
1609
+ #
1610
+ # @return [Response] A response hash containing media configuration informtion
1611
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-media-r0-config
1612
+ # The Matrix Spec, for more information about the data
1613
+ def get_media_config
1614
+ request(:get, :media_r0, '/config')
1615
+ end
1616
+
1617
+ # Sends events directly to the specified devices
1618
+ #
1619
+ # @param [String] event_type The type of event to send
1620
+ # @param [Hash] messages The hash of events to send and devices to send them to
1621
+ # @param [Hash] params Additional parameters
1622
+ # @option params [Integer] :txn_id The ID of the transaction, automatically generated if not specified
1623
+ # @see https://matrix.org/docs/spec/client_server/latest#put-matrix-client-r0-sendtodevice-eventtype-txnid
1624
+ # The Matrix Spec, for more information about the data
1625
+ def send_to_device(event_type, messages:, **params)
1626
+ txn_id = transaction_id
1627
+ txn_id = params.fetch(:txn_id, "#{txn_id}#{Time.now.to_i}")
1628
+
1629
+ event_type = ERB::Util.url_encode event_type.to_s
1630
+ txn_id = ERB::Util.url_encode txn_id.to_s
1631
+
1632
+ body = {
1633
+ messages: messages
1634
+ }.compact
1635
+
1636
+ request(:put, client_api_latest, "/sendToDevice/#{event_type}/#{txn_id}", body: body)
1637
+ end
1638
+
1639
+ # Gets the room ID for an alias
1640
+ # @param [String,MXID] room_alias The room alias to look up
1641
+ # @return [Response] An object containing the :room_id key and a key of :servers that know of the room
1642
+ # @raise [MatrixNotFoundError] No room with the requested alias exists
1643
+ def get_room_id(room_alias, **params)
1644
+ query = {}
1645
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1646
+
1647
+ room_alias = ERB::Util.url_encode room_alias.to_s
1648
+
1649
+ request(:get, client_api_latest, "/directory/room/#{room_alias}", query: query)
1650
+ end
1651
+
1652
+ # Sets the room ID for an alias
1653
+ # @param [String,MXID] room_id The room to set an alias for
1654
+ # @param [String,MXID] room_alias The alias to configure for the room
1655
+ # @return [Response] An empty object denoting success
1656
+ # @raise [MatrixConflictError] The alias is already in use
1657
+ def set_room_alias(room_id, room_alias, **params)
1658
+ query = {}
1659
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1660
+
1661
+ content = {
1662
+ room_id: room_id
1663
+ }
1664
+ room_alias = ERB::Util.url_encode room_alias.to_s
1665
+
1666
+ request(:put, client_api_latest, "/directory/room/#{room_alias}", body: content, query: query)
1667
+ end
1668
+
1669
+ # Remove an alias from its room
1670
+ # @param [String,MXID] room_alias The alias to remove
1671
+ # @return [Response] An empty object denoting success
1672
+ def remove_room_alias(room_alias, **params)
1673
+ query = {}
1674
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1675
+
1676
+ room_alias = ERB::Util.url_encode room_alias.to_s
1677
+
1678
+ request(:delete, client_api_latest, "/directory/room/#{room_alias}", query: query)
1679
+ end
1680
+
1681
+ # Gets a list of all the members in a room
1682
+ # @param [String,MXID] room_id The ID of the room
1683
+ # @return [Response] A chunked object
1684
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-rooms-roomid-members
1685
+ # The Matrix Spec, for more information about the data
1686
+ def get_room_members(room_id, **params)
1687
+ query = {}
1688
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1689
+
1690
+ room_id = ERB::Util.url_encode room_id.to_s
1691
+
1692
+ request(:get, client_api_latest, "/rooms/#{room_id}/members", query: query.merge(params))
1693
+ end
1694
+
1695
+ # Gets a list of the joined members in a room
1696
+ #
1697
+ # @param [String,MXID] room_id The ID of the room
1698
+ # @return [Response] A chunked object
1699
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-rooms-roomid-joined-members
1700
+ # The Matrix Spec, for more information about the data
1701
+ def get_room_joined_members(room_id, **params)
1702
+ query = {}
1703
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1704
+
1705
+ room_id = ERB::Util.url_encode room_id.to_s
1706
+
1707
+ request(:get, client_api_latest, "/rooms/#{room_id}/joined_members", query: query)
1708
+ end
1709
+
1710
+ # Gets a list of the current users registered devices
1711
+ # @return [Response] An object including all information about the users devices.
1712
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-devices
1713
+ # The Matrix Spec, for more information about the data
1714
+ def get_devices
1715
+ request(:get, client_api_latest, '/devices')
1716
+ end
1717
+
1718
+ # Gets the information about a certain client device
1719
+ # @param [String] device_id The ID of the device to look up
1720
+ # @return [Response] An object containing all available device information
1721
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-devices-deviceid
1722
+ # The Matrix Spec, for more information about the data
1723
+ def get_device(device_id)
1724
+ device_id = ERB::Util.url_encode device_id.to_s
1725
+
1726
+ request(:get, client_api_latest, "/devices/#{device_id}")
1727
+ end
1728
+
1729
+ # Sets the metadata for a device
1730
+ # @param [String] device_id The ID of the device to modify
1731
+ # @param [String] display_name The new display name to set for the device
1732
+ # @see https://matrix.org/docs/spec/client_server/latest#put-matrix-client-r0-devices-deviceid
1733
+ # The Matrix Spec, for more information about the data
1734
+ def set_device(device_id, display_name:)
1735
+ device_id = ERB::Util.url_encode device_id.to_s
1736
+
1737
+ request(:put, client_api_latest, "/devices/#{device_id}", body: { display_name: display_name })
1738
+ end
1739
+
1740
+ # Removes a device from the current user
1741
+ # @param [String] device_id The device to remove
1742
+ # @param [Hash] auth Authentication data for the removal request
1743
+ # @raise [MatrixNotAuthorizeedError] The request did not contain enough authentication information,
1744
+ # the data in this error will include the necessary information to perform interactive auth
1745
+ # @see https://matrix.org/docs/spec/client_server/latest#delete-matrix-client-r0-devices-deviceid
1746
+ # The Matrix Spec, for more information about the data
1747
+ def delete_device(device_id, auth:)
1748
+ device_id = ERB::Util.url_encode device_id.to_s
1749
+
1750
+ request(:delete, client_api_latest, "/devices/#{device_id}", body: { auth: auth })
1751
+ end
1752
+
1753
+ # Run a query for device keys
1754
+ # @param [Numeric] timeout The timeout - in seconds - for the query
1755
+ # @param [Array] device_keys The list of devices to query
1756
+ # @param [String] token The sync token that led to this query - if any
1757
+ # @param [Hash] params Additional parameters
1758
+ # @option params [Integer] timeout_ms The timeout in milliseconds for the query, overrides _timeout_
1759
+ # @example Looking up all the device keys for a user
1760
+ # api.keys_query(device_keys: { '@alice:example.com': [] })
1761
+ # # => { :device_keys => { :'@alice:example.com' => { :JLAFKJWSCS => { ...
1762
+ # @example Looking up a specific device for a user
1763
+ # api.keys_query(device_keys: { '@alice:example.com': ['ABCDEFGHIJ'] })
1764
+ # # => { :device_keys => { :'@alice:example.com' => { :ABCDEFGHIJ => { ...
1765
+ # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-keys-query
1766
+ # The Matrix Spec, for more information about the parameters and data
1767
+ def keys_query(device_keys:, timeout: nil, token: nil, **params)
1768
+ body = {
1769
+ timeout: (timeout || 10) * 1000,
1770
+ device_keys: device_keys
1771
+ }
1772
+ body[:timeout] = params[:timeout_ms] if params.key? :timeout_ms
1773
+ body[:token] = token if token
1774
+
1775
+ request(:post, client_api_latest, '/keys/query', body: body)
1776
+ end
1777
+
1778
+ # Claim one-time keys for pre-key messaging
1779
+ #
1780
+ # @param [Hash] one_time_keys Hash mapping user IDs to hashes of device IDs and key types
1781
+ # @param [Numeric] timeout (10) The timeout - in seconds - for the request
1782
+ # @return [Response] A response hash containing one-time keys for the requested users and devices
1783
+ # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-keys-claim
1784
+ # The Matrix Spec, for more information about the parameters and data
1785
+ def claim_one_time_keys(one_time_keys, timeout: 10)
1786
+ body = {
1787
+ one_time_keys: one_time_keys,
1788
+ timeout: timeout * 1000
1789
+ }
1790
+ request(:post, client_api_latest, '/keys/claim', body: body)
1791
+ end
1792
+
1793
+ # Retrieve device key changes between two sync requests
1794
+ #
1795
+ # @param [String] from The sync token denoting the start of the range
1796
+ # @param [String] to The sync token denoting the end of the range
1797
+ # @return [Response] The users with device key changes during the specified range
1798
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-keys-changes
1799
+ # The Matrix Spec, for more information about the parameters and data
1800
+ def get_key_changes(from:, to:)
1801
+ query = {
1802
+ from: from,
1803
+ to: to
1804
+ }
1805
+
1806
+ request(:get, client_api_latest, '/keys/changes', query: query)
1807
+ end
1808
+
1809
+ # Gets the list of registered pushers for the current user
1810
+ #
1811
+ # @return [Response] A response hash containing all the currently registered pushers for the current user
1812
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-pushers
1813
+ # The Matrix Spec, for more information about the parameters and data
1814
+ def get_pushers
1815
+ request(:get, client_api_latest, '/pushers')
1816
+ end
1817
+
1818
+ # rubocop:disable Metrics/ParameterLists
1819
+
1820
+ # Sets a pusher on the current user
1821
+ #
1822
+ # @param [String] key The pushkey for the pusher, used for routing purposes and for unique identification in coordination with app_id
1823
+ # @param [String] kind The kind of pusher, should be either 'http' or 'email'
1824
+ # @param [String] app_id The ID of the application to push to
1825
+ # @param [String] app_name The user-visible name of the application to push to
1826
+ # @param [String] device_name The user-visible name of the device to push to
1827
+ # @param [String] lang The language that pushes should be sent in
1828
+ # @param [Hash] data Pusher configuration data, depends on the kind parameter
1829
+ # @param [Hash] params Additional optional parameters
1830
+ # @option params [String] profile_tag Specifies which device rules to use
1831
+ # @option params [Boolean] append Specifies if the pusher should replace or be appended to the pusher list based on uniqueness
1832
+ # @return [Response] An empty response hash if the pusher was added/replaced correctly
1833
+ # @see https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-pushers
1834
+ # The Matrix Spec, for more information about the parameters and data
1835
+ def set_pusher(key, kind:, app_id:, app_name:, device_name:, lang:, data:, **params)
1836
+ body = {
1837
+ pushkey: key,
1838
+ kind: kind,
1839
+ app_id: app_id,
1840
+ app_display_name: app_name,
1841
+ device_display_name: device_name,
1842
+ profile_tag: params[:profile_tag],
1843
+ lang: lang,
1844
+ data: data,
1845
+ append: params[:append]
1846
+ }.compact
1847
+
1848
+ request(:post, client_api_latest, '/pushers/set', body: body)
1849
+ end
1850
+ # rubocop:enable Metrics/ParameterLists
1851
+
1852
+ # Enumerates the list of notifies that the current user has/should have received.
1853
+ #
1854
+ # @param [String] from The pagination token to continue reading events from
1855
+ # @param [Integer] limit The maximum number of event to return
1856
+ # @param [String] only A filter string that is to be applied to the notification events
1857
+ # @return [Response] A response hash containing notifications for the current user
1858
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-notifications
1859
+ # The Matrix Spec, for more information about the parameters and data
1860
+ def get_notifications(from: nil, limit: nil, only: nil)
1861
+ raise ArgumentError, 'Limit must be an integer' unless limit.nil? || limit.is_a?(Integer)
1862
+
1863
+ query = {
1864
+ from: from,
1865
+ limit: limit,
1866
+ only: only
1867
+ }.compact
1868
+
1869
+ request(:get, client_api_latest, '/notifications', query: query)
1870
+ end
1871
+
1872
+ # Retrieves the full list of registered push rules for the current user
1873
+ #
1874
+ # @return [Response] A response hash containing the current list of push rules for the current user
1875
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-pushrules
1876
+ # The Matrix Spec, for more information about the parameters and data
1877
+ def get_pushrules
1878
+ request(:get, client_api_latest, '/pushrules/')
1879
+ end
1880
+
1881
+ # Retrieves a single registered push rule for the current user
1882
+ #
1883
+ # @param [String] scope ('global') The scope to look up push rules from
1884
+ # @param [:override,:underride,:sender,:room,:content] kind The kind of push rule to look up
1885
+ # @param [String] id The ID of the rule that's being retrieved
1886
+ # @return [Response] A response hash containing the full data of the requested push rule
1887
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-pushrules-scope-kind-ruleid
1888
+ # The Matrix Spec, for more information about the parameters and data
1889
+ def get_pushrule(kind:, id:, scope: 'global')
1890
+ scope = ERB::Util.url_encode scope.to_s
1891
+ kind = ERB::Util.url_encode kind.to_s
1892
+ id = ERB::Util.url_encode id.to_s
1893
+
1894
+ request(:get, client_api_latest, "/pushrules/#{scope}/#{kind}/#{id}")
1895
+ end
1896
+
1897
+ # Checks if a push rule for the current user is enabled
1898
+ #
1899
+ # @param [String] scope ('global') The scope to look up push rules from
1900
+ # @param [:override,:underride,:sender,:room,:content] kind The kind of push rule to look up
1901
+ # @param [String] id The ID of the rule that's being retrieved
1902
+ # @return [Response] A response hash containing an :enabled key for if the rule is enabled or not
1903
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-pushrules-scope-kind-ruleid-enabled
1904
+ # The Matrix Spec, for more information about the parameters and data
1905
+ def get_pushrule_enabled(kind:, id:, scope: 'global')
1906
+ scope = ERB::Util.url_encode scope.to_s
1907
+ kind = ERB::Util.url_encode kind.to_s
1908
+ id = ERB::Util.url_encode id.to_s
1909
+
1910
+ request(:get, client_api_latest, "/pushrules/#{scope}/#{kind}/#{id}/enabled")
1911
+ end
1912
+
1913
+ # Enabled/Disables a specific push rule for the current user
1914
+ #
1915
+ # @param [Boolean] enabled Should the push rule be enabled or not
1916
+ # @param [String] scope ('global') The scope to look up push rules from
1917
+ # @param [:override,:underride,:sender,:room,:content] kind The kind of push rule to look up
1918
+ # @param [String] id The ID of the rule that's being retrieved
1919
+ # @return [Response] An empty response hash if the push rule was enabled/disabled successfully
1920
+ # @see https://matrix.org/docs/spec/client_server/latest#put-matrix-client-r0-pushrules-scope-kind-ruleid-enabled
1921
+ # The Matrix Spec, for more information about the parameters and data
1922
+ def set_pushrule_enabled(enabled, kind:, id:, scope: 'global')
1923
+ scope = ERB::Util.url_encode scope.to_s
1924
+ kind = ERB::Util.url_encode kind.to_s
1925
+ id = ERB::Util.url_encode id.to_s
1926
+
1927
+ body = {
1928
+ enabled: enabled
1929
+ }
1930
+
1931
+ request(:put, client_api_latest, "/pushrules/#{scope}/#{kind}/#{id}/enabled", body: body)
1932
+ end
1933
+
1934
+ # Gets the current list of actions for a specific push rule for the current user
1935
+ #
1936
+ # @param [String] scope ('global') The scope to look up push rules from
1937
+ # @param [:override,:underride,:sender,:room,:content] kind The kind of push rule to look up
1938
+ # @param [String] id The ID of the rule that's being retrieved
1939
+ # @return [Response] A response hash containing an :enabled key for if the rule is enabled or not
1940
+ # @see https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-pushrules-scope-kind-ruleid-actions
1941
+ # The Matrix Spec, for more information about the parameters and data
1942
+ def get_pushrule_actions(kind:, id:, scope: 'global')
1943
+ scope = ERB::Util.url_encode scope.to_s
1944
+ kind = ERB::Util.url_encode kind.to_s
1945
+ id = ERB::Util.url_encode id.to_s
1946
+
1947
+ request(:get, client_api_latest, "/pushrules/#{scope}/#{kind}/#{id}/actions")
1948
+ end
1949
+
1950
+ # Replaces the list of actions for a push rule for the current user
1951
+ #
1952
+ # @param [String,Array[String]] actions The list of actions to apply on the push rule
1953
+ # @param [String] scope ('global') The scope to look up push rules from
1954
+ # @param [:override,:underride,:sender,:room,:content] kind The kind of push rule to look up
1955
+ # @param [String] id The ID of the rule that's being retrieved
1956
+ # @return [Response] An empty response hash if the push rule actions were modified successfully
1957
+ # @see https://matrix.org/docs/spec/client_server/latest#put-matrix-client-r0-pushrules-scope-kind-ruleid-actions
1958
+ # The Matrix Spec, for more information about the parameters and data
1959
+ def set_pushrule_actions(actions, kind:, id:, scope: 'global')
1960
+ scope = ERB::Util.url_encode scope.to_s
1961
+ kind = ERB::Util.url_encode kind.to_s
1962
+ id = ERB::Util.url_encode id.to_s
1963
+
1964
+ actions = [actions] unless actions.is_a? Array
1965
+
1966
+ body = {
1967
+ actions: actions
1968
+ }
1969
+
1970
+ request(:put, client_api_latest, "/pushrules/#{scope}/#{kind}/#{id}/actions", body: body)
1971
+ end
1972
+
1973
+ # Gets the MXID of the currently logged-in user
1974
+ # @return [Response] An object containing the key :user_id
1975
+ def whoami?(**params)
1976
+ query = {}
1977
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
1978
+
1979
+ request(:get, client_api_latest, '/account/whoami', query: query)
1980
+ end
1981
+ end
1982
+ # rubocop:enable Metrics/ModuleLength