matrix_sdk 1.5.0 → 2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/lib/matrix_sdk/api.rb +35 -2
- data/lib/matrix_sdk/client.rb +222 -22
- data/lib/matrix_sdk/extensions.rb +1 -0
- data/lib/matrix_sdk/mxid.rb +24 -2
- data/lib/matrix_sdk/protocols/cs.rb +728 -52
- data/lib/matrix_sdk/response.rb +11 -0
- data/lib/matrix_sdk/room.rb +110 -13
- data/lib/matrix_sdk/user.rb +75 -8
- data/lib/matrix_sdk/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e0e5819346e56fd4eac1564434e88399500adefe0def16bc706a25ec7a254b2
|
4
|
+
data.tar.gz: 2d74cd2d5203f5431396b03717c4302f9a0c7816c47eaa969e2395ab2eb46586
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7eb8ef8277b0bda1191915e5be4dcf93856cd876f611b77974b8dc88e5e230ba5c3300995157f9717a4b00d1a7cba7f7a618844cc436ad0b6a3ea5865367049d
|
7
|
+
data.tar.gz: bd888c36cf3a082360dbecc408c0a67e16ddb337a721105be7abf3a9662d81bfa564a1093a64d1f934d484af6a22a36e5b91bafde70f02a882e6d092e81d5459
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
## 2.0.0 - 2020-02-14
|
2
|
+
|
3
|
+
**NB**, this release includes backwards-incompatible changes;
|
4
|
+
- Changes room state lookup to separate specific state lookups from full state retrieval.
|
5
|
+
This will require changes in client code where `#get_room_state` is called to retrieve
|
6
|
+
all state, as it now requires a state key. For retrieving full room state,
|
7
|
+
`#get_room_state_all` is now the method to use.
|
8
|
+
- Changes some advanced parameters to named parameters, ensure your code is updated if it makes use of them
|
9
|
+
- Fixes SSL verification to actually verify certs (#9)
|
10
|
+
|
11
|
+
- Adds multiple CS API endpoints
|
12
|
+
- Adds `:room_id` key to all room events
|
13
|
+
- Adds `:self` as a valid option to the client abstraction's `#get_user` method
|
14
|
+
- Separates homeserver part stringification for MXIDs
|
15
|
+
- Exposes some previously private client abstraction methods (`#ensure_room`, `#next_batch`) for easier bot usage
|
16
|
+
- Changes room abstraction member lookups to use `#get_room_joined_members`, reducing transferred data amounts
|
17
|
+
- Fixes debug print of methods that return arrays (e.g. CS `/room/{id}/state`)
|
18
|
+
|
1
19
|
## 1.5.0 - 2019-10-25
|
2
20
|
|
3
21
|
- Adds error event to the client abstraction, for handling errors in the background listener
|
data/lib/matrix_sdk/api.rb
CHANGED
@@ -98,6 +98,7 @@ module MatrixSdk
|
|
98
98
|
target_uri = nil
|
99
99
|
|
100
100
|
if !port.nil? && !port.empty?
|
101
|
+
# If the domain is fully qualified according to Matrix (FQDN and port) then skip discovery
|
101
102
|
target_uri = URI("https://#{domain}:#{port}")
|
102
103
|
elsif target == :server
|
103
104
|
# Attempt SRV record discovery
|
@@ -110,6 +111,7 @@ module MatrixSdk
|
|
110
111
|
end
|
111
112
|
|
112
113
|
if target_uri.nil?
|
114
|
+
# Attempt .well-known discovery for server-to-server
|
113
115
|
well_known = begin
|
114
116
|
data = Net::HTTP.get("https://#{domain}/.well-known/matrix/server")
|
115
117
|
JSON.parse(data)
|
@@ -153,6 +155,14 @@ module MatrixSdk
|
|
153
155
|
))
|
154
156
|
end
|
155
157
|
|
158
|
+
# Check if a protocol is enabled on the API connection
|
159
|
+
#
|
160
|
+
# @example Checking for identity server API support
|
161
|
+
# api.protocol? :IS
|
162
|
+
# # => false
|
163
|
+
#
|
164
|
+
# @param protocol [Symbol] The protocol to check
|
165
|
+
# @return [Boolean] Is the protocol enabled
|
156
166
|
def protocol?(protocol)
|
157
167
|
protocols.include? protocol
|
158
168
|
end
|
@@ -201,6 +211,28 @@ module MatrixSdk
|
|
201
211
|
@proxy_uri = proxy_uri
|
202
212
|
end
|
203
213
|
|
214
|
+
# Perform a raw Matrix API request
|
215
|
+
#
|
216
|
+
# @example Simple API query
|
217
|
+
# api.request(:get, :client_r0, '/account/whoami')
|
218
|
+
# # => { :user_id => "@alice:matrix.org" }
|
219
|
+
#
|
220
|
+
# @example Advanced API request
|
221
|
+
# api.request(:post,
|
222
|
+
# :media_r0,
|
223
|
+
# '/upload',
|
224
|
+
# body_stream: open('./file'),
|
225
|
+
# headers: { 'content-type' => 'image/png' })
|
226
|
+
# # => { :content_uri => "mxc://example.com/AQwafuaFswefuhsfAFAgsw" }
|
227
|
+
#
|
228
|
+
# @param method [Symbol] The method to use, can be any of the ones under Net::HTTP
|
229
|
+
# @param api [Symbol] The API symbol to use, :client_r0 is the current CS one
|
230
|
+
# @param path [String] The API path to call, this is the part that comes after the API definition in the spec
|
231
|
+
# @param options [Hash] Additional options to pass along to the request
|
232
|
+
# @option options [Hash] :query Query parameters to set on the URL
|
233
|
+
# @option options [Hash,String] :body The body to attach to the request, will be JSON-encoded if sent as a hash
|
234
|
+
# @option options [IO] :body_stream A body stream to attach to the request
|
235
|
+
# @option options [Hash] :headers Additional headers to set on the request
|
204
236
|
def request(method, api, path, **options)
|
205
237
|
url = homeserver.dup.tap do |u|
|
206
238
|
u.path = api_to_path(api) + path
|
@@ -272,7 +304,8 @@ module MatrixSdk
|
|
272
304
|
end
|
273
305
|
logger.debug dir
|
274
306
|
clean_body = JSON.parse(http.body) rescue nil if http.body
|
275
|
-
clean_body.keys.each { |k| clean_body[k] = '[ REDACTED ]' if %w[password access_token].include?(k) }.to_json if clean_body
|
307
|
+
clean_body.keys.each { |k| clean_body[k] = '[ REDACTED ]' if %w[password access_token].include?(k) }.to_json if clean_body.is_a? Hash
|
308
|
+
clean_body = clean_body.to_s if clean_body
|
276
309
|
logger.debug "#{dir} #{clean_body.length < 200 ? clean_body : clean_body.slice(0..200) + "... [truncated, #{clean_body.length} Bytes]"}" if clean_body
|
277
310
|
rescue StandardError => e
|
278
311
|
logger.warn "#{e.class} occured while printing request debug; #{e.message}\n#{e.backtrace.join "\n"}"
|
@@ -303,7 +336,7 @@ module MatrixSdk
|
|
303
336
|
@http.open_timeout = open_timeout
|
304
337
|
@http.read_timeout = read_timeout
|
305
338
|
@http.use_ssl = homeserver.scheme == 'https'
|
306
|
-
@http.verify_mode = validate_certificate ? ::OpenSSL::SSL::
|
339
|
+
@http.verify_mode = validate_certificate ? ::OpenSSL::SSL::VERIFY_PEER : ::OpenSSL::SSL::VERIFY_NONE
|
307
340
|
@http.start
|
308
341
|
@http
|
309
342
|
end
|
data/lib/matrix_sdk/client.rb
CHANGED
@@ -11,7 +11,16 @@ module MatrixSdk
|
|
11
11
|
include MatrixSdk::Logging
|
12
12
|
extend Forwardable
|
13
13
|
|
14
|
-
|
14
|
+
# @!attribute api [r] The underlying API connection
|
15
|
+
# @return [Api] The underlying API connection
|
16
|
+
# @!attribute next_batch [r] The batch token for a running sync
|
17
|
+
# @return [String] The opaque batch token
|
18
|
+
# @!attribute cache [rw] The cache level
|
19
|
+
# @return [:all,:some,:none] The level of caching to do
|
20
|
+
# @!attribute sync_filter [rw] The global sync filter
|
21
|
+
# @return [Hash,String] A filter definition, either as defined by the
|
22
|
+
# Matrix spec, or as an identifier returned by a filter creation request
|
23
|
+
attr_reader :api, :next_batch
|
15
24
|
attr_accessor :cache, :sync_filter
|
16
25
|
|
17
26
|
events :error, :event, :presence_event, :invite_event, :leave_event, :ephemeral_event
|
@@ -22,6 +31,17 @@ module MatrixSdk
|
|
22
31
|
:access_token, :access_token=, :device_id, :device_id=, :homeserver, :homeserver=,
|
23
32
|
:validate_certificate, :validate_certificate=
|
24
33
|
|
34
|
+
# Create a new client instance from only a Matrix HS domain
|
35
|
+
#
|
36
|
+
# This will use the well-known delegation lookup to find the correct client URL
|
37
|
+
#
|
38
|
+
# @note This method will not verify that the created client has a valid connection,
|
39
|
+
# it will only perform the necessary lookups to build a connection URL.
|
40
|
+
# @return [Client] The new client instance
|
41
|
+
# @param domain [String] The domain name to look up
|
42
|
+
# @param params [Hash] Additional parameters to pass along to {Api.new_for_domain} as well as {initialize}
|
43
|
+
# @see Api.new_for_domain
|
44
|
+
# @see #initialize
|
25
45
|
def self.new_for_domain(domain, **params)
|
26
46
|
api = MatrixSdk::Api.new_for_domain(domain, keep_wellknown: true)
|
27
47
|
return new(api, params) unless api.well_known.key? 'm.identity_server'
|
@@ -53,7 +73,7 @@ module MatrixSdk
|
|
53
73
|
@rooms = {}
|
54
74
|
@users = {}
|
55
75
|
@cache = client_cache
|
56
|
-
@identity_server =
|
76
|
+
@identity_server = nil
|
57
77
|
|
58
78
|
@sync_token = nil
|
59
79
|
@sync_thread = nil
|
@@ -75,22 +95,42 @@ module MatrixSdk
|
|
75
95
|
@mxid = params[:user_id]
|
76
96
|
end
|
77
97
|
|
98
|
+
# Gets the currently logged in user's MXID
|
99
|
+
#
|
100
|
+
# @return [MXID] The MXID of the current user
|
78
101
|
def mxid
|
79
102
|
@mxid ||= begin
|
80
|
-
api.whoami?[:user_id] if api&.access_token
|
103
|
+
MXID.new api.whoami?[:user_id] if api&.access_token
|
81
104
|
end
|
82
105
|
end
|
83
106
|
|
84
|
-
|
85
|
-
id = MXID.new id.to_s unless id.is_a? MXID
|
86
|
-
raise ArgumentError, 'Must be a User ID' unless id.user?
|
107
|
+
alias user_id mxid
|
87
108
|
|
88
|
-
|
109
|
+
# Gets the current user presence status object
|
110
|
+
#
|
111
|
+
# @return [Response] The user presence
|
112
|
+
# @see User#presence
|
113
|
+
# @see Protocols::CS#get_presence_status
|
114
|
+
def presence
|
115
|
+
api.get_presence_status(mxid).tap { |h| h.delete :user_id }
|
89
116
|
end
|
90
117
|
|
91
|
-
|
92
|
-
|
118
|
+
# Sets the current user's presence status
|
119
|
+
#
|
120
|
+
# @param status [:online,:offline,:unavailable] The new status to use
|
121
|
+
# @param message [String] A custom status message to set
|
122
|
+
# @see User#presence=
|
123
|
+
# @see Protocols::CS#set_presence_status
|
124
|
+
def set_presence(status, message: nil)
|
125
|
+
raise ArgumentError, 'Presence must be one of :online, :offline, :unavailable' unless %i[online offline unavailable].include?(status)
|
126
|
+
|
127
|
+
api.set_presence_status(mxid, status, message: message)
|
128
|
+
end
|
93
129
|
|
130
|
+
# Gets a list of all the public rooms on the connected HS
|
131
|
+
#
|
132
|
+
# @note This will try to list all public rooms on the HS, and may take a while on larger instances
|
133
|
+
# @return [Array[Room]] The public rooms
|
94
134
|
def public_rooms
|
95
135
|
rooms = []
|
96
136
|
since = nil
|
@@ -114,6 +154,12 @@ module MatrixSdk
|
|
114
154
|
rooms
|
115
155
|
end
|
116
156
|
|
157
|
+
# Gets a list of all relevant rooms, either the ones currently handled by
|
158
|
+
# the client, or the list of currently joined ones if no rooms are handled
|
159
|
+
#
|
160
|
+
# @return [Array[Room]] All the currently handled rooms
|
161
|
+
# @note This will always return the empty array if the cache level is set
|
162
|
+
# to :none
|
117
163
|
def rooms
|
118
164
|
if @rooms.empty? && cache != :none
|
119
165
|
api.get_joined_rooms.joined_rooms.each do |id|
|
@@ -124,6 +170,11 @@ module MatrixSdk
|
|
124
170
|
@rooms.values
|
125
171
|
end
|
126
172
|
|
173
|
+
# Refresh the list of currently handled rooms, replacing it with the user's
|
174
|
+
# currently joined rooms.
|
175
|
+
#
|
176
|
+
# @note This will be a no-op if the cache level is set to :none
|
177
|
+
# @return [Boolean] If the refresh succeeds
|
127
178
|
def reload_rooms!
|
128
179
|
return true if cache == :none
|
129
180
|
|
@@ -137,12 +188,25 @@ module MatrixSdk
|
|
137
188
|
end
|
138
189
|
alias refresh_rooms! reload_rooms!
|
139
190
|
|
191
|
+
# Register - and log in - on the connected HS as a guest
|
192
|
+
#
|
193
|
+
# @note This feature is not commonly supported by many HSes
|
140
194
|
def register_as_guest
|
141
195
|
data = api.register(kind: :guest)
|
142
196
|
post_authentication(data)
|
143
197
|
end
|
144
198
|
|
145
|
-
|
199
|
+
# Register a new user account on the connected HS
|
200
|
+
#
|
201
|
+
# This will also trigger an initial sync unless no_sync is set
|
202
|
+
#
|
203
|
+
# @note This method will currently always use auth type 'm.login.dummy'
|
204
|
+
# @param username [String] The new user's name
|
205
|
+
# @param password [String] The new user's password
|
206
|
+
# @param params [Hash] Additional options
|
207
|
+
# @option params [Boolean] :no_sync Skip the initial sync on registering
|
208
|
+
# @option params [Boolean] :allow_sync_retry Allow sync to retry on failure
|
209
|
+
def register_with_password(username, password, **params)
|
146
210
|
username = username.to_s unless username.is_a?(String)
|
147
211
|
password = password.to_s unless password.is_a?(String)
|
148
212
|
|
@@ -154,10 +218,21 @@ module MatrixSdk
|
|
154
218
|
|
155
219
|
return if params[:no_sync]
|
156
220
|
|
157
|
-
sync full_state:
|
221
|
+
sync full_state: true,
|
158
222
|
allow_sync_retry: params.fetch(:allow_sync_retry, nil)
|
159
223
|
end
|
160
224
|
|
225
|
+
# Logs in as a user on the connected HS
|
226
|
+
#
|
227
|
+
# This will also trigger an initial sync unless no_sync is set
|
228
|
+
#
|
229
|
+
# @param username [String] The username of the user
|
230
|
+
# @param password [String] The password of the user
|
231
|
+
# @param sync_timeout [Numeric] The timeout of the initial sync on login
|
232
|
+
# @param full_state [Boolean] Should the initial sync retrieve full state
|
233
|
+
# @param params [Hash] Additional options
|
234
|
+
# @option params [Boolean] :no_sync Skip the initial sync on registering
|
235
|
+
# @option params [Boolean] :allow_sync_retry Allow sync to retry on failure
|
161
236
|
def login(username, password, sync_timeout: 15, full_state: false, **params)
|
162
237
|
username = username.to_s unless username.is_a?(String)
|
163
238
|
password = password.to_s unless password.is_a?(String)
|
@@ -175,6 +250,17 @@ module MatrixSdk
|
|
175
250
|
allow_sync_retry: params.fetch(:allow_sync_retry, nil)
|
176
251
|
end
|
177
252
|
|
253
|
+
# Logs in as a user on the connected HS
|
254
|
+
#
|
255
|
+
# This will also trigger an initial sync unless no_sync is set
|
256
|
+
#
|
257
|
+
# @param username [String] The username of the user
|
258
|
+
# @param token [String] The token to log in with
|
259
|
+
# @param sync_timeout [Numeric] The timeout of the initial sync on login
|
260
|
+
# @param full_state [Boolean] Should the initial sync retrieve full state
|
261
|
+
# @param params [Hash] Additional options
|
262
|
+
# @option params [Boolean] :no_sync Skip the initial sync on registering
|
263
|
+
# @option params [Boolean] :allow_sync_retry Allow sync to retry on failure
|
178
264
|
def login_with_token(username, token, sync_timeout: 15, full_state: false, **params)
|
179
265
|
username = username.to_s unless username.is_a?(String)
|
180
266
|
token = token.to_s unless token.is_a?(String)
|
@@ -192,30 +278,90 @@ module MatrixSdk
|
|
192
278
|
allow_sync_retry: params.fetch(:allow_sync_retry, nil)
|
193
279
|
end
|
194
280
|
|
281
|
+
# Logs out of the current session
|
195
282
|
def logout
|
196
283
|
api.logout
|
197
284
|
@api.access_token = nil
|
198
285
|
@mxid = nil
|
199
286
|
end
|
200
287
|
|
288
|
+
# Check if there's a currently logged in session
|
289
|
+
#
|
290
|
+
# @note This will not check if the session is valid, only if it exists
|
291
|
+
# @return [Boolean] If there's a current session
|
201
292
|
def logged_in?
|
202
|
-
|
293
|
+
!@api.access_token.nil?
|
203
294
|
end
|
204
295
|
|
296
|
+
# Retrieve a list of all registered third-party IDs for the current user
|
297
|
+
#
|
298
|
+
# @return [Response] A response hash containing the key :threepids
|
299
|
+
# @see Protocols::CS#get_3pids
|
300
|
+
def registered_3pids
|
301
|
+
data = api.get_3pids
|
302
|
+
data.threepids.each do |obj|
|
303
|
+
obj.instance_eval do
|
304
|
+
def added_at
|
305
|
+
Time.at(self[:added_at] / 1000)
|
306
|
+
end
|
307
|
+
|
308
|
+
def validated_at
|
309
|
+
return unless validated?
|
310
|
+
|
311
|
+
Time.at(self[:validated_at] / 1000)
|
312
|
+
end
|
313
|
+
|
314
|
+
def validated?
|
315
|
+
key? :validated_at
|
316
|
+
end
|
317
|
+
|
318
|
+
def to_s
|
319
|
+
"#{self[:medium]}:#{self[:address]}"
|
320
|
+
end
|
321
|
+
|
322
|
+
def inspect
|
323
|
+
"#<MatrixSdk::Response 3pid=#{to_s.inspect} added_at=\"#{added_at}\"#{validated? ? " validated_at=\"#{validated_at}\"" : ''}>"
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
327
|
+
data
|
328
|
+
end
|
329
|
+
|
330
|
+
# Creates a new room
|
331
|
+
#
|
332
|
+
# @example Creating a room with an alias
|
333
|
+
# client.create_room('myroom')
|
334
|
+
# #<MatrixSdk::Room ... >
|
335
|
+
#
|
336
|
+
# @param room_alias [String] A default alias to set on the room, should only be the localpart
|
337
|
+
# @return [Room] The resulting room
|
338
|
+
# @see Protocols::CS#create_room
|
205
339
|
def create_room(room_alias = nil, **params)
|
206
340
|
data = api.create_room(params.merge(room_alias: room_alias))
|
207
341
|
ensure_room(data.room_id)
|
208
342
|
end
|
209
343
|
|
344
|
+
# Joins an already created room
|
345
|
+
#
|
346
|
+
# @param room_id_or_alias [String,MXID] A room alias (#room:exmaple.com) or a room ID (!id:example.com)
|
347
|
+
# @param server_name [Array[String]] A list of servers to attempt the join through, required for IDs
|
348
|
+
# @return [Room] The resulting room
|
349
|
+
# @see Protocols::CS#join_room
|
210
350
|
def join_room(room_id_or_alias, server_name: [])
|
211
351
|
server_name = [server_name] unless server_name.is_a? Array
|
212
352
|
data = api.join_room(room_id_or_alias, server_name: server_name)
|
213
353
|
ensure_room(data.fetch(:room_id, room_id_or_alias))
|
214
354
|
end
|
215
355
|
|
356
|
+
# Find a room in the locally cached list of rooms that the current user is part of
|
357
|
+
#
|
358
|
+
# @param room_id_or_alias [String,MXID] A room ID or alias
|
359
|
+
# @param only_canonical [Boolean] Only match alias against the canonical alias
|
360
|
+
# @return [Room] The found room
|
361
|
+
# @return [nil] If no room was found
|
216
362
|
def find_room(room_id_or_alias, only_canonical: false)
|
217
363
|
room_id_or_alias = MXID.new(room_id_or_alias.to_s) unless room_id_or_alias.is_a? MXID
|
218
|
-
raise ArgumentError, 'Must be a room id or alias' unless
|
364
|
+
raise ArgumentError, 'Must be a room id or alias' unless room_id_or_alias.room?
|
219
365
|
|
220
366
|
return @rooms.fetch(room_id_or_alias.to_s, nil) if room_id_or_alias.room_id?
|
221
367
|
|
@@ -224,7 +370,21 @@ module MatrixSdk
|
|
224
370
|
@rooms.values.find { |r| r.aliases.include? room_id_or_alias.to_s }
|
225
371
|
end
|
226
372
|
|
373
|
+
# Get a User instance from a MXID
|
374
|
+
#
|
375
|
+
# @param user_id [String,MXID,:self] The MXID to look up, will also accept :self in order to get the currently logged-in user
|
376
|
+
# @return [User] The User instance for the specified user
|
377
|
+
# @raise [ArgumentError] If the input isn't a valid user ID
|
378
|
+
# @note The method doesn't perform any existence checking, so the returned User object may point to a non-existent user
|
227
379
|
def get_user(user_id)
|
380
|
+
user_id = mxid if user_id == :self
|
381
|
+
|
382
|
+
user_id = MXID.new user_id.to_s unless user_id.is_a? MXID
|
383
|
+
raise ArgumentError, 'Must be a User ID' unless user_id.user?
|
384
|
+
|
385
|
+
# To still use regular string storage in the hash itself
|
386
|
+
user_id = user_id.to_s
|
387
|
+
|
228
388
|
if cache == :all
|
229
389
|
@users[user_id] ||= User.new(self, user_id)
|
230
390
|
else
|
@@ -232,10 +392,23 @@ module MatrixSdk
|
|
232
392
|
end
|
233
393
|
end
|
234
394
|
|
395
|
+
# Remove a room alias
|
396
|
+
#
|
397
|
+
# @param room_alias [String,MXID] The room alias to remove
|
398
|
+
# @see Protocols::CS#remove_room_alias
|
235
399
|
def remove_room_alias(room_alias)
|
400
|
+
room_alias = MXID.new room_alias.to_s unless room_alias.is_a? MXID
|
401
|
+
raise ArgumentError, 'Must be a room alias' unless room_alias.room_alias?
|
402
|
+
|
236
403
|
api.remove_room_alias(room_alias)
|
237
404
|
end
|
238
405
|
|
406
|
+
# Upload a piece of data to the media repo
|
407
|
+
#
|
408
|
+
# @return [URI::MATRIX] A Matrix content (mxc://) URL pointing to the uploaded data
|
409
|
+
# @param content [String] The data to upload
|
410
|
+
# @param content_type [String] The MIME type of the data
|
411
|
+
# @see Protocols::CS#media_upload
|
239
412
|
def upload(content, content_type)
|
240
413
|
data = api.media_upload(content, content_type)
|
241
414
|
return data[:content_uri] if data.key? :content_uri
|
@@ -243,13 +416,19 @@ module MatrixSdk
|
|
243
416
|
raise MatrixUnexpectedResponseError, 'Upload succeeded, but no media URI returned'
|
244
417
|
end
|
245
418
|
|
419
|
+
# Starts a background thread that will listen to new events
|
420
|
+
#
|
421
|
+
# @see sync For What parameters are accepted
|
246
422
|
def start_listener_thread(**params)
|
423
|
+
return if listening?
|
424
|
+
|
247
425
|
@should_listen = true
|
248
426
|
thread = Thread.new { listen_forever(params) }
|
249
427
|
@sync_thread = thread
|
250
428
|
thread.run
|
251
429
|
end
|
252
430
|
|
431
|
+
# Stops the running background thread if one is active
|
253
432
|
def stop_listener_thread
|
254
433
|
return unless @sync_thread
|
255
434
|
|
@@ -258,10 +437,21 @@ module MatrixSdk
|
|
258
437
|
@sync_thread = nil
|
259
438
|
end
|
260
439
|
|
440
|
+
# Check if there's a thread listening for events
|
261
441
|
def listening?
|
262
442
|
@sync_thread&.alive? == true
|
263
443
|
end
|
264
444
|
|
445
|
+
# Run a message sync round, triggering events as necessary
|
446
|
+
#
|
447
|
+
# @param skip_store_batch [Boolean] Should this sync skip storing the returned next_batch token,
|
448
|
+
# doing this would mean the next sync re-runs from the same point. Useful with use of filters.
|
449
|
+
# @param params [Hash] Additional options
|
450
|
+
# @option params [String,Hash] :filter (#sync_filter) A filter to use for this sync
|
451
|
+
# @option params [Numeric] :timeout (30) A timeout value in seconds for the sync request
|
452
|
+
# @option params [Numeric] :allow_sync_retry (0) The number of retries allowed for this sync request
|
453
|
+
# @option params [String] :since An override of the "since" token to provide to the sync request
|
454
|
+
# @see Protocols::CS#sync
|
265
455
|
def sync(skip_store_batch: false, **params)
|
266
456
|
extra_params = {
|
267
457
|
filter: sync_filter,
|
@@ -283,10 +473,27 @@ module MatrixSdk
|
|
283
473
|
@next_batch = data[:next_batch] unless skip_store_batch
|
284
474
|
|
285
475
|
handle_sync_response(data)
|
476
|
+
true
|
286
477
|
end
|
287
478
|
|
288
479
|
alias listen_for_events sync
|
289
480
|
|
481
|
+
# Ensures that a room exists in the cache
|
482
|
+
#
|
483
|
+
# @param room_id [String,MXID] The room ID to ensure
|
484
|
+
# @return [Room] The room object for the requested room
|
485
|
+
def ensure_room(room_id)
|
486
|
+
room_id = MXID.new room_id.to_s unless room_id.is_a? MXID
|
487
|
+
raise ArgumentError, 'Must be a room ID' unless room_id.room_id?
|
488
|
+
|
489
|
+
room_id = room_id.to_s
|
490
|
+
@rooms.fetch(room_id) do
|
491
|
+
room = Room.new(self, room_id)
|
492
|
+
@rooms[room_id] = room unless cache == :none
|
493
|
+
room
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
290
497
|
private
|
291
498
|
|
292
499
|
def listen_forever(timeout: 30, bad_sync_timeout: 5, sync_interval: 30, **params)
|
@@ -320,15 +527,6 @@ module MatrixSdk
|
|
320
527
|
access_token
|
321
528
|
end
|
322
529
|
|
323
|
-
def ensure_room(room_id)
|
324
|
-
room_id = room_id.to_s unless room_id.is_a? String
|
325
|
-
@rooms.fetch(room_id) do
|
326
|
-
room = Room.new(self, room_id)
|
327
|
-
@rooms[room_id] = room unless cache == :none
|
328
|
-
room
|
329
|
-
end
|
330
|
-
end
|
331
|
-
|
332
530
|
def handle_state(room_id, state_event)
|
333
531
|
return unless state_event.key? :type
|
334
532
|
|
@@ -368,10 +566,12 @@ module MatrixSdk
|
|
368
566
|
end
|
369
567
|
|
370
568
|
data[:rooms][:invite].each do |room_id, invite|
|
569
|
+
invite[:room_id] = room_id.to_s
|
371
570
|
fire_invite_event(MatrixEvent.new(self, invite), room_id.to_s)
|
372
571
|
end
|
373
572
|
|
374
573
|
data[:rooms][:leave].each do |room_id, left|
|
574
|
+
left[:room_id] = room_id.to_s
|
375
575
|
fire_leave_event(MatrixEvent.new(self, left), room_id.to_s)
|
376
576
|
end
|
377
577
|
|