matrix_sdk 0.0.4 → 0.1.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,5 @@
1
+ module MatrixSdk::Protocols::AS
2
+ def self.included(_klass)
3
+ # XXX
4
+ end
5
+ end
@@ -0,0 +1,799 @@
1
+ module MatrixSdk::Protocols::CS
2
+ # Gets the available client API versions
3
+ # @return [Array]
4
+ def client_api_versions
5
+ @client_api_versions ||= request(:get, :client, '/versions').versions.tap do |vers|
6
+ vers.instance_eval <<-'CODE', __FILE__, __LINE__ + 1
7
+ def latest
8
+ latest
9
+ end
10
+ CODE
11
+ end
12
+ end
13
+
14
+ # Gets the list of available unstable client API features
15
+ # @return [Array]
16
+ def client_api_unstable_features
17
+ @client_api_unstable_features ||= request(:get, :client, '/versions').unstable_features.tap do |vers|
18
+ vers.instance_eval <<-'CODE', __FILE__, __LINE__ + 1
19
+ def has?(feature)
20
+ fetch(feature, nil)
21
+ end
22
+ CODE
23
+ end
24
+ end
25
+
26
+ # Runs the client API /sync method
27
+ # @param timeout [Numeric] (30.0) The timeout in seconds for the sync
28
+ # @param params [Hash] The sync options to use
29
+ # @option params [String] :since The value of the batch token to base the sync from
30
+ # @option params [String,Hash] :filter The filter to use on the sync
31
+ # @option params [Boolean] :full_state Should the sync include the full state
32
+ # @option params [Boolean] :set_presence Should the sync set the user status to online
33
+ # @return [Response]
34
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#get-matrix-client-r0-sync
35
+ # For more information on the parameters and what they mean
36
+ def sync(timeout: 30.0, **params)
37
+ query = {
38
+ timeout: timeout
39
+ }.merge(params).select do |k, _v|
40
+ %i[since filter full_state set_presence].include? k
41
+ end
42
+
43
+ query[:timeout] = (query.fetch(:timeout, 30) * 1000).to_i
44
+ query[:timeout] = params.delete(:timeout_ms).to_i if params.key? :timeout_ms
45
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
46
+
47
+ request(:get, :client_r0, '/sync', query: query)
48
+ end
49
+
50
+ # Registers a user using the client API /register endpoint
51
+ #
52
+ # @example Regular user registration and login
53
+ # api.register(username: 'example', password: 'NotARealPass')
54
+ # # => { user_id: '@example:matrix.org', access_token: '...', home_server: 'matrix.org', device_id: 'ABCD123' }
55
+ # api.whoami?
56
+ # # => { user_id: '@example:matrix.org' }
57
+ #
58
+ # @param kind [String,Symbol] ('user') The kind of registration to use
59
+ # @param params [Hash] The registration information, all not handled by Ruby will be passed as JSON in the body
60
+ # @option params [Boolean] :store_token (true) Should the resulting access token be stored for the API
61
+ # @option params [Boolean] :store_device_id (store_token value) Should the resulting device ID be stored for the API
62
+ # @return [Response]
63
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-register
64
+ # For options that are permitted in this call
65
+ def register(kind: 'user', **params)
66
+ query = {}
67
+ query[:kind] = kind
68
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
69
+
70
+ store_token = params.delete(:store_token) { !protocol?(:AS) }
71
+ store_device_id = params.delete(:store_device_id) { store_token }
72
+
73
+ request(:post, :client_r0, '/register', body: params, query: query).tap do |resp|
74
+ @access_token = resp.token if resp.key?(:token) && store_token
75
+ @device_id = resp.device_id if resp.key?(:device_id) && store_device_id
76
+ end
77
+ end
78
+
79
+ # Logs in using the client API /login endpoint, and optionally stores the resulting access for API usage
80
+ #
81
+ # @example Logging in with username and password
82
+ # api.login(user: 'example', password: 'NotARealPass')
83
+ # # => { user_id: '@example:matrix.org', access_token: '...', home_server: 'matrix.org', device_id: 'ABCD123' }
84
+ # api.whoami?
85
+ # # => { user_id: '@example:matrix.org' }
86
+ #
87
+ # @example Advanced login, without storing details
88
+ # api.whoami?
89
+ # # => { user_id: '@example:matrix.org' }
90
+ # api.login(medium: 'email', address: 'someone@somewhere.net', password: '...', store_token: false)
91
+ # # => { user_id: '@someone:matrix.org', access_token: ...
92
+ # api.whoami?.user_id
93
+ # # => '@example:matrix.org'
94
+ #
95
+ # @param login_type [String] ('m.login.password') The type of login to attempt
96
+ # @param params [Hash] The login information to use, along with options for said log in
97
+ # @option params [Boolean] :store_token (true) Should the resulting access token be stored for the API
98
+ # @option params [Boolean] :store_device_id (store_token value) Should the resulting device ID be stored for the API
99
+ # @option params [String] :initial_device_display_name (USER_AGENT) The device display name to specify for this login attempt
100
+ # @option params [String] :device_id The device ID to set on the login
101
+ # @return [Response] A response hash with the parameters :user_id, :access_token, :home_server, and :device_id.
102
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-login
103
+ # The Matrix Spec, for more information about the call and response
104
+ def login(login_type: 'm.login.password', **params)
105
+ query = {}
106
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
107
+
108
+ options = {}
109
+ options[:store_token] = params.delete(:store_token) { true }
110
+ options[:store_device_id] = params.delete(:store_device_id) { options[:store_token] }
111
+
112
+ data = {
113
+ type: login_type,
114
+ initial_device_display_name: params.delete(:initial_device_display_name) { MatrixSdk::Api::USER_AGENT }
115
+ }.merge params
116
+ data[:device_id] = device_id if device_id
117
+
118
+ request(:post, :client_r0, '/login', body: data, query: query).tap do |resp|
119
+ @access_token = resp.token if resp.key?(:token) && options[:store_token]
120
+ @device_id = resp.device_id if resp.key?(:device_id) && options[:store_device_id]
121
+ end
122
+ end
123
+
124
+ # Logs out the currently logged in user
125
+ # @return [Response] An empty response if the logout was successful
126
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-logout
127
+ # The Matrix Spec, for more information about the call and response
128
+ def logout(**params)
129
+ query = {}
130
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
131
+
132
+ request(:post, :client_r0, '/logout', query: query)
133
+ end
134
+
135
+ # Creates a new room
136
+ # @param params [Hash] The room creation details
137
+ # @option params [Symbol] :visibility (:public) The room visibility
138
+ # @option params [String] :room_alias A room alias to apply on creation
139
+ # @option params [Boolean] :invite Should the room be created invite-only
140
+ # @return [Response] A response hash with ...
141
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-createroom
142
+ # The Matrix Spec, for more information about the call and response
143
+ def create_room(visibility: :public, **params)
144
+ query = {}
145
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
146
+
147
+ content = {
148
+ visibility: visibility
149
+ }
150
+ content[:room_alias_name] = params[:room_alias] if params[:room_alias]
151
+ content[:invite] = [params[:invite]].flatten if params[:invite]
152
+
153
+ request(:post, :client_r0, '/createRoom', content, query: query)
154
+ end
155
+
156
+ # Joins a room
157
+ # @param id_or_alias [MXID,String] The room ID or Alias to join
158
+ # @param params [Hash] Extra room join options
159
+ # @option params [String[]] :server_name A list of servers to perform the join through
160
+ # @return [Response] A response hash with the parameter :room_id
161
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-join-roomidoralias
162
+ # The Matrix Spec, for more information about the call and response
163
+ def join_room(id_or_alias, **params)
164
+ query = {}
165
+ query[:server_name] = params[:server_name] if params[:server_name]
166
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
167
+
168
+ # id_or_alias = MXID.new id_or_alias.to_s unless id_or_alias.is_a? MXID
169
+ # raise ArgumentError, 'Not a room ID or alias' unless id_or_alias.room?
170
+
171
+ id_or_alias = ERB::Util.url_encode id_or_alias.to_s
172
+
173
+ request(:post, :client_r0, "/join/#{id_or_alias}", query: query)
174
+ end
175
+
176
+ # Sends a state event to a room
177
+ # @param room_id [MXID,String] The room ID to send the state event to
178
+ # @param event_type [String] The event type to send
179
+ # @param content [Hash] The contents of the state event
180
+ # @param params [Hash] Options for the request
181
+ # @option params [String] :state_key The state key of the event, if there is one
182
+ # @return [Response] A response hash with the parameter :event_id
183
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#put-matrix-client-r0-rooms-roomid-state-eventtype-statekey
184
+ # https://matrix.org/docs/spec/client_server/r0.3.0.html#put-matrix-client-r0-rooms-roomid-state-eventtype
185
+ # The Matrix Spec, for more information about the call and response
186
+ def send_state_event(room_id, event_type, content, **params)
187
+ query = {}
188
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
189
+
190
+ room_id = ERB::Util.url_encode room_id.to_s
191
+ event_type = ERB::Util.url_encode event_type.to_s
192
+ state_key = ERB::Util.url_encode params[:state_key].to_s if params.key? :state_key
193
+
194
+ request(:put, :client_r0, "/rooms/#{room_id}/state/#{event_type}#{"/#{state_key}" unless state_key.nil?}", body: content, query: query)
195
+ end
196
+
197
+ # Sends a message event to a room
198
+ # @param room_id [MXID,String] The room ID to send the message event to
199
+ # @param event_type [String] The event type of the message
200
+ # @param content [Hash] The contents of the message
201
+ # @param params [Hash] Options for the request
202
+ # @option params [Integer] :txn_id The ID of the transaction, or automatically generated
203
+ # @return [Response] A response hash with the parameter :event_id
204
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid
205
+ # The Matrix Spec, for more information about the call and response
206
+ def send_message_event(room_id, event_type, content, **params)
207
+ query = {}
208
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
209
+
210
+ txn_id = transaction_id
211
+ txn_id = params.fetch(:txn_id, "#{txn_id}#{Time.now.to_i}")
212
+
213
+ room_id = ERB::Util.url_encode room_id.to_s
214
+ event_type = ERB::Util.url_encode event_type.to_s
215
+ txn_id = ERB::Util.url_encode txn_id.to_s
216
+
217
+ request(:put, :client_r0, "/rooms/#{room_id}/send/#{event_type}/#{txn_id}", body: content, query: query)
218
+ end
219
+
220
+ # Redact an event in a room
221
+ # @param room_id [MXID,String] The room ID to send the message event to
222
+ # @param event_id [String] The event ID of the event to redact
223
+ # @param params [Hash] Options for the request
224
+ # @option params [String] :reason The reason for the redaction
225
+ # @option params [Integer] :txn_id The ID of the transaction, or automatically generated
226
+ # @return [Response] A response hash with the parameter :event_id
227
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#put-matrix-client-r0-rooms-roomid-redact-eventid-txnid
228
+ # The Matrix Spec, for more information about the call and response
229
+ def redact_event(room_id, event_id, **params)
230
+ query = {}
231
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
232
+
233
+ content = {}
234
+ content[:reason] = params[:reason] if params[:reason]
235
+
236
+ txn_id = transaction_id
237
+ txn_id = params.fetch(:txn_id, "#{txn_id}#{Time.now.to_i}")
238
+
239
+ room_id = ERB::Util.url_encode room_id.to_s
240
+ event_id = ERB::Util.url_encode event_id.to_s
241
+ txn_id = ERB::Util.url_encode txn_id.to_s
242
+
243
+ request(:put, :client_r0, "/rooms/#{room_id}/redact/#{event_id}/#{txn_id}", body: content, query: query)
244
+ end
245
+
246
+ # Send a content message to a room
247
+ #
248
+ # @example Sending an image to a room
249
+ # send_content('!abcd123:localhost',
250
+ # 'mxc://localhost/1234567',
251
+ # 'An image of a cat',
252
+ # 'm.image',
253
+ # extra_information: {
254
+ # h: 128,
255
+ # w: 128,
256
+ # mimetype: 'image/png',
257
+ # size: 1024
258
+ # })
259
+ #
260
+ # @example Sending a file to a room
261
+ # send_content('!example:localhost',
262
+ # 'mxc://localhost/fileurl',
263
+ # 'Contract.pdf',
264
+ # 'm.file',
265
+ # extra_content: {
266
+ # filename: 'contract.pdf'
267
+ # },
268
+ # extra_information: {
269
+ # mimetype: 'application/pdf',
270
+ # size: 96674
271
+ # })
272
+ #
273
+ # @param room_id [MXID,String] The room ID to send the content to
274
+ # @param url [URI,String] The URL to the content
275
+ # @param name [String] The name of the content
276
+ # @param msg_type [String] The message type of the content
277
+ # @param params [Hash] Options for the request
278
+ # @option params [Hash] :extra_information ({}) Extra information for the content
279
+ # @option params [Hash] :extra_content Extra data to insert into the content hash
280
+ # @return [Response] A response hash with the parameter :event_id
281
+ # @see send_message_event For more information on the underlying call
282
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#m-image
283
+ # https://matrix.org/docs/spec/client_server/r0.3.0.html#m-file
284
+ # https://matrix.org/docs/spec/client_server/r0.3.0.html#m-video
285
+ # https://matrix.org/docs/spec/client_server/r0.3.0.html#m-audio
286
+ # The Matrix Spec, for more information about the call and response
287
+ def send_content(room_id, url, name, msg_type, **params)
288
+ content = {
289
+ url: url,
290
+ msgtype: msg_type,
291
+ body: name,
292
+ info: params.delete(:extra_information) { {} }
293
+ }
294
+ content.merge!(params.fetch(:extra_content)) if params.key? :extra_content
295
+
296
+ send_message_event(room_id, 'm.room.message', content, params)
297
+ end
298
+
299
+ # Send a geographic location to a room
300
+ #
301
+ # @param room_id [MXID,String] The room ID to send the location to
302
+ # @param geo_uri [URI,String] The geographical URI to send
303
+ # @param name [String] The name of the location
304
+ # @param params [Hash] Options for the request
305
+ # @option params [Hash] :extra_information ({}) Extra information for the location
306
+ # @option params [URI,String] :thumbnail_url The URL to a thumbnail of the location
307
+ # @option params [Hash] :thumbnail_info Image information about the location thumbnail
308
+ # @return [Response] A response hash with the parameter :event_id
309
+ # @see send_message_event For more information on the underlying call
310
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#m-location
311
+ # The Matrix Spec, for more information about the call and response
312
+ def send_location(room_id, geo_uri, name, **params)
313
+ content = {
314
+ geo_uri: geo_uri,
315
+ msgtype: 'm.location',
316
+ body: name,
317
+ info: params.delete(:extra_information) { {} }
318
+ }
319
+ content[:info][:thumbnail_url] = params.delete(:thumbnail_url) if params.key? :thumbnail_url
320
+ content[:info][:thumbnail_info] = params.delete(:thumbnail_info) if params.key? :thumbnail_info
321
+
322
+ send_message_event(room_id, 'm.room.message', content, params)
323
+ end
324
+
325
+ # Send a plaintext message to a room
326
+ #
327
+ # @param room_id [MXID,String] The room ID to send the message to
328
+ # @param message [String] The message to send
329
+ # @param params [Hash] Options for the request
330
+ # @option params [String] :msg_type ('m.text') The message type to send
331
+ # @return [Response] A response hash with the parameter :event_id
332
+ # @see send_message_event For more information on the underlying call
333
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#m-text
334
+ # The Matrix Spec, for more information about the call and response
335
+ def send_message(room_id, message, **params)
336
+ content = {
337
+ msgtype: params.delete(:msg_type) { 'm.text' },
338
+ body: message
339
+ }
340
+ send_message_event(room_id, 'm.room.message', content, params)
341
+ end
342
+
343
+ # Send a plaintext emote to a room
344
+ #
345
+ # @param room_id [MXID,String] The room ID to send the message to
346
+ # @param emote [String] The emote to send
347
+ # @param params [Hash] Options for the request
348
+ # @option params [String] :msg_type ('m.emote') The message type to send
349
+ # @return [Response] A response hash with the parameter :event_id
350
+ # @see send_message_event For more information on the underlying call
351
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#m-emote
352
+ # The Matrix Spec, for more information about the call and response
353
+ def send_emote(room_id, emote, **params)
354
+ content = {
355
+ msgtype: params.delete(:msg_type) { 'm.emote' },
356
+ body: emote
357
+ }
358
+ send_message_event(room_id, 'm.room.message', content, params)
359
+ end
360
+
361
+ # Send a plaintext notice to a room
362
+ #
363
+ # @param room_id [MXID,String] The room ID to send the message to
364
+ # @param notice [String] The notice to send
365
+ # @param params [Hash] Options for the request
366
+ # @option params [String] :msg_type ('m.notice') The message type to send
367
+ # @return [Response] A response hash with the parameter :event_id
368
+ # @see send_message_event For more information on the underlying call
369
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#m-notice
370
+ # The Matrix Spec, for more information about the call and response
371
+ def send_notice(room_id, notice, **params)
372
+ content = {
373
+ msgtype: params.delete(:msg_type) { 'm.notice' },
374
+ body: notice
375
+ }
376
+ send_message_event(room_id, 'm.room.message', content, params)
377
+ end
378
+
379
+ # Retrieve additional messages in a room
380
+ #
381
+ # @param room_id [MXID,String] The room ID to retrieve messages for
382
+ # @param token [String] The token to start retrieving from, can be from a sync or from an earlier get_room_messages call
383
+ # @param direction [:b,:f] The direction to retrieve messages
384
+ # @param limit [Integer] (10) The limit of messages to retrieve
385
+ # @param params [Hash] Additional options for the request
386
+ # @option params [String] :to A token to limit retrieval to
387
+ # @option params [String] :filter A filter to limit the retrieval to
388
+ # @return [Response] A response hash with the message information containing :start, :end, and :chunk fields
389
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#get-matrix-client-r0-rooms-roomid-messages
390
+ # The Matrix Spec, for more information about the call and response
391
+ def get_room_messages(room_id, token, direction, limit: 10, **params)
392
+ query = {
393
+ roomId: room_id,
394
+ from: token,
395
+ dir: direction,
396
+ limit: limit
397
+ }
398
+ query[:to] = params[:to] if params.key? :to
399
+ query[:filter] = params.fetch(:filter) if params.key? :filter
400
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
401
+
402
+ room_id = ERB::Util.url_encode room_id.to_s
403
+
404
+ request(:get, :client_r0, "/rooms/#{room_id}/messages", query: query)
405
+ end
406
+
407
+ # Reads the latest instance of a room state event
408
+ #
409
+ # @param room_id [MXID,String] The room ID to read from
410
+ # @param state_type [String] The state type to read
411
+ # @return [Response] A response hash with the contents of the state event
412
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#get-matrix-client-r0-rooms-roomid-state-eventtype
413
+ # The Matrix Spec, for more information about the call and response
414
+ def get_room_state(room_id, state_type, **params)
415
+ query = {}
416
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
417
+
418
+ room_id = ERB::Util.url_encode room_id.to_s
419
+ state_type = ERB::Util.url_encode state_type.to_s
420
+
421
+ request(:get, :client_r0, "/rooms/#{room_id}/state/#{state_type}", query: query)
422
+ end
423
+
424
+ # Gets the display name of a room
425
+ #
426
+ # @param room_id [MXID,String] The room ID to look up
427
+ # @return [Response] A response hash with the parameter :name
428
+ # @see get_room_state
429
+ # @see https://matrix.org/docs/spec/client_server/r0.3.0.html#m-room-name
430
+ # The Matrix Spec, for more information about the event and data
431
+ def get_room_name(room_id, **params)
432
+ get_room_state(room_id, 'm.room.name', params)
433
+ end
434
+
435
+ def set_room_name(room_id, name, **params)
436
+ content = {
437
+ name: name
438
+ }
439
+ send_state_event(room_id, 'm.room.name', content, params)
440
+ end
441
+
442
+ def get_room_topic(room_id, **params)
443
+ get_room_state(room_id, 'm.room.topic', params)
444
+ end
445
+
446
+ def set_room_topic(room_id, topic, **params)
447
+ content = {
448
+ topic: topic
449
+ }
450
+ send_state_event(room_id, 'm.room.topic', content, params)
451
+ end
452
+
453
+ def get_power_levels(room_id, **params)
454
+ get_room_state(room_id, 'm.room.power_levels', params)
455
+ end
456
+
457
+ def set_power_levels(room_id, content, **params)
458
+ content[:events] = {} unless content.key? :events
459
+ send_state_event(room_id, 'm.room.power_levels', content, params)
460
+ end
461
+
462
+ def leave_room(room_id, **params)
463
+ query = {}
464
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
465
+
466
+ room_id = ERB::Util.url_encode room_id.to_s
467
+
468
+ request(:post, :client_r0, "/rooms/#{room_id}/leave", query: query)
469
+ end
470
+
471
+ def forget_room(room_id, **params)
472
+ query = {}
473
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
474
+
475
+ room_id = ERB::Util.url_encode room_id.to_s
476
+
477
+ request(:post, :client_r0, "/rooms/#{room_id}/forget", query: query)
478
+ end
479
+
480
+ def invite_user(room_id, user_id, **params)
481
+ query = {}
482
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
483
+
484
+ content = {
485
+ user_id: user_id
486
+ }
487
+
488
+ room_id = ERB::Util.url_encode room_id.to_s
489
+
490
+ request(:post, :client_r0, "/rooms/#{room_id}/invite", body: content, query: query)
491
+ end
492
+
493
+ def kick_user(room_id, user_id, **params)
494
+ set_membership(room_id, user_id, 'leave', params)
495
+ end
496
+
497
+ def get_membership(room_id, user_id, **params)
498
+ query = {}
499
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
500
+
501
+ room_id = ERB::Util.url_encode room_id.to_s
502
+ user_id = ERB::Util.url_encode user_id.to_s
503
+
504
+ request(:get, :client_r0, "/rooms/#{room_id}/state/m.room.member/#{user_id}", query: query)
505
+ end
506
+
507
+ def set_membership(room_id, user_id, membership, reason: '', **params)
508
+ content = {
509
+ membership: membership,
510
+ reason: reason
511
+ }
512
+ content[:displayname] = params.delete(:displayname) if params.key? :displayname
513
+ content[:avatar_url] = params.delete(:avatar_url) if params.key? :avatar_url
514
+
515
+ send_state_event(room_id, 'm.room.member', content, params.merge(state_key: user_id))
516
+ end
517
+
518
+ def ban_user(room_id, user_id, reason: '', **params)
519
+ query = {}
520
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
521
+
522
+ content = {
523
+ user_id: user_id,
524
+ reason: reason
525
+ }
526
+ room_id = ERB::Util.url_encode room_id.to_s
527
+
528
+ request(:post, :client_r0, "/rooms/#{room_id}/ban", body: content, query: query)
529
+ end
530
+
531
+ def unban_user(room_id, user_id, **params)
532
+ query = {}
533
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
534
+
535
+ content = {
536
+ user_id: user_id
537
+ }
538
+ room_id = ERB::Util.url_encode room_id.to_s
539
+
540
+ request(:post, :client_r0, "/rooms/#{room_id}/unban", body: content, query: query)
541
+ end
542
+
543
+ def get_user_tags(user_id, room_id, **params)
544
+ query = {}
545
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
546
+
547
+ room_id = ERB::Util.url_encode room_id.to_s
548
+ user_id = ERB::Util.url_encode user_id.to_s
549
+
550
+ request(:get, :client_r0, "/user/#{user_id}/rooms/#{room_id}/tags", query: query)
551
+ end
552
+
553
+ def remove_user_tag(user_id, room_id, tag, **params)
554
+ query = {}
555
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
556
+
557
+ room_id = ERB::Util.url_encode room_id.to_s
558
+ user_id = ERB::Util.url_encode user_id.to_s
559
+ tag = ERB::Util.url_encode tag.to_s
560
+
561
+ request(:delete, :client_r0, "/user/#{user_id}/rooms/#{room_id}/tags/#{tag}", query: query)
562
+ end
563
+
564
+ def add_user_tag(user_id, room_id, tag, **params)
565
+ query = {}
566
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
567
+
568
+ if params[:body]
569
+ content = params[:body]
570
+ else
571
+ content = {}
572
+ content[:order] = params[:order] if params.key? :order
573
+ end
574
+
575
+ room_id = ERB::Util.url_encode room_id.to_s
576
+ user_id = ERB::Util.url_encode user_id.to_s
577
+ tag = ERB::Util.url_encode tag.to_s
578
+
579
+ request(:put, :client_r0, "/user/#{user_id}/rooms/#{room_id}/tags/#{tag}", body: content, query: query)
580
+ end
581
+
582
+ def get_account_data(user_id, type_key, **params)
583
+ query = {}
584
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
585
+
586
+ user_id = ERB::Util.url_encode user_id.to_s
587
+ type_key = ERB::Util.url_encode type_key.to_s
588
+
589
+ request(:get, :client_r0, "/user/#{user_id}/account_data/#{type_key}", query: query)
590
+ end
591
+
592
+ def set_account_data(user_id, type_key, account_data, **params)
593
+ query = {}
594
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
595
+
596
+ user_id = ERB::Util.url_encode user_id.to_s
597
+ type_key = ERB::Util.url_encode type_key.to_s
598
+
599
+ request(:put, :client_r0, "/user/#{user_id}/account_data/#{type_key}", body: account_data, query: query)
600
+ end
601
+
602
+ def get_room_account_data(user_id, room_id, type_key, **params)
603
+ query = {}
604
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
605
+
606
+ user_id = ERB::Util.url_encode user_id.to_s
607
+ room_id = ERB::Util.url_encode room_id.to_s
608
+ type_key = ERB::Util.url_encode type_key.to_s
609
+
610
+ request(:get, :client_r0, "/user/#{user_id}/rooms/#{room_id}/account_data/#{type_key}", query: query)
611
+ end
612
+
613
+ def set_room_account_data(user_id, room_id, type_key, account_data, **params)
614
+ query = {}
615
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
616
+
617
+ user_id = ERB::Util.url_encode user_id.to_s
618
+ room_id = ERB::Util.url_encode room_id.to_s
619
+ type_key = ERB::Util.url_encode type_key.to_s
620
+
621
+ request(:put, :client_r0, "/user/#{user_id}/rooms/#{room_id}/account_data/#{type_key}", body: account_data, query: query)
622
+ end
623
+
624
+ def get_filter(user_id, filter_id, **params)
625
+ query = {}
626
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
627
+
628
+ user_id = ERB::Util.url_encode user_id.to_s
629
+ filter_id = ERB::Util.url_encode filter_id.to_s
630
+
631
+ request(:get, :client_r0, "/user/#{user_id}/filter/#{filter_id}", query: query)
632
+ end
633
+
634
+ def create_filter(user_id, filter_params, **params)
635
+ query = {}
636
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
637
+
638
+ user_id = ERB::Util.url_encode user_id.to_s
639
+
640
+ request(:post, :client_r0, "/user/#{user_id}/filter", body: filter_params, query: query)
641
+ end
642
+
643
+ def media_upload(content, content_type, **params)
644
+ query = {}
645
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
646
+
647
+ request(:post, :media_r0, '/upload', body: content, headers: { 'content-type' => content_type }, query: query)
648
+ end
649
+
650
+ def get_display_name(user_id, **params)
651
+ query = {}
652
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
653
+
654
+ user_id = ERB::Util.url_encode user_id.to_s
655
+
656
+ request(:get, :client_r0, "/profile/#{user_id}/displayname", query: query)
657
+ end
658
+
659
+ def set_display_name(user_id, display_name, **params)
660
+ query = {}
661
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
662
+
663
+ content = {
664
+ displayname: display_name
665
+ }
666
+
667
+ user_id = ERB::Util.url_encode user_id.to_s
668
+
669
+ request(:put, :client_r0, "/profile/#{user_id}/displayname", body: content, query: query)
670
+ end
671
+
672
+ def get_avatar_url(user_id, **params)
673
+ query = {}
674
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
675
+
676
+ user_id = ERB::Util.url_encode user_id.to_s
677
+
678
+ request(:get, :client_r0, "/profile/#{user_id}/avatar_url", query: query)
679
+ end
680
+
681
+ def set_avatar_url(user_id, url, **params)
682
+ query = {}
683
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
684
+
685
+ content = {
686
+ avatar_url: url
687
+ }
688
+
689
+ user_id = ERB::Util.url_encode user_id.to_s
690
+
691
+ request(:put, :client_r0, "/profile/#{user_id}/avatar_url", body: content, query: query)
692
+ end
693
+
694
+ def get_download_url(mxcurl, **_params)
695
+ mxcurl = URI.parse(mxcurl.to_s) unless mxcurl.is_a? URI
696
+ raise 'Not a mxc:// URL' unless mxcurl.is_a? URI::MATRIX
697
+
698
+ homeserver.dup.tap do |u|
699
+ full_path = ERB::Util.url_encode mxcurl.full_path.to_s
700
+ u.path = "/_matrix/media/r0/download/#{full_path}"
701
+ end
702
+ end
703
+
704
+ def get_room_id(room_alias, **params)
705
+ query = {}
706
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
707
+
708
+ room_alias = ERB::Util.url_encode room_alias.to_s
709
+
710
+ request(:get, :client_r0, "/directory/room/#{room_alias}", query: query)
711
+ end
712
+
713
+ def set_room_alias(room_id, room_alias, **params)
714
+ query = {}
715
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
716
+
717
+ content = {
718
+ room_id: room_id
719
+ }
720
+ room_alias = ERB::Util.url_encode room_alias.to_s
721
+
722
+ request(:put, :client_r0, "/directory/room/#{room_alias}", body: content, query: query)
723
+ end
724
+
725
+ def remove_room_alias(room_alias, **params)
726
+ query = {}
727
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
728
+
729
+ room_alias = ERB::Util.url_encode room_alias.to_s
730
+
731
+ request(:delete, :client_r0, "/directory/room/#{room_alias}", query: query)
732
+ end
733
+
734
+ def get_room_members(room_id, **params)
735
+ query = {}
736
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
737
+
738
+ room_id = ERB::Util.url_encode room_id.to_s
739
+
740
+ request(:get, :client_r0, "/rooms/#{room_id}/members", query: query)
741
+ end
742
+
743
+ def set_join_rule(room_id, join_rule, **params)
744
+ content = {
745
+ join_rule: join_rule
746
+ }
747
+
748
+ send_state_event(room_id, 'm.room.join_rules', params.merge(content))
749
+ end
750
+
751
+ def set_guest_access(room_id, guest_access, **params)
752
+ # raise ArgumentError, '`guest_access` must be one of [:can_join, :forbidden]' unless %i[can_join forbidden].include? guest_access
753
+ content = {
754
+ guest_access: guest_access
755
+ }
756
+
757
+ send_state_event(room_id, 'm.room.guest_access', params.merge(content))
758
+ end
759
+
760
+ def get_devices
761
+ request(:get, :client_r0, '/devices')
762
+ end
763
+
764
+ def get_device(device_id)
765
+ device_id = ERB::Util.url_encode device_id.to_s
766
+
767
+ request(:get, :client_r0, "/devices/#{device_id}")
768
+ end
769
+
770
+ def set_device(device_id, display_name:)
771
+ device_id = ERB::Util.url_encode device_id.to_s
772
+
773
+ request(:put, :client_r0, "/devices/#{device_id}", body: { display_name: display_name })
774
+ end
775
+
776
+ def delete_device(device_id, auth:)
777
+ device_id = ERB::Util.url_encode device_id.to_s
778
+
779
+ request(:delete, :client_r0, "/devices/#{device_id}", body: { auth: auth })
780
+ end
781
+
782
+ def keys_query(timeout: nil, device_keys:, token: nil, **params)
783
+ body = {
784
+ timeout: (timeout || 10) * 1000,
785
+ device_keys: device_keys
786
+ }
787
+ body[:timeout] = params[:timeout_ms] if params.key? :timeout_ms
788
+ body[:token] = token if token
789
+
790
+ request(:post, :client_r0, '/keys/query', body: body)
791
+ end
792
+
793
+ def whoami?(**params)
794
+ query = {}
795
+ query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
796
+
797
+ request(:get, :client_r0, '/account/whoami', query: query)
798
+ end
799
+ end