matrix_sdk 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -0
- data/CHANGELOG.md +11 -0
- data/README.md +2 -0
- data/examples/simple_client.rb +6 -3
- data/lib/matrix_sdk.rb +13 -2
- data/lib/matrix_sdk/api.rb +70 -720
- data/lib/matrix_sdk/application_service.rb +210 -0
- data/lib/matrix_sdk/client.rb +69 -44
- data/lib/matrix_sdk/extensions.rb +22 -10
- data/lib/matrix_sdk/protocols/as.rb +5 -0
- data/lib/matrix_sdk/protocols/cs.rb +799 -0
- data/lib/matrix_sdk/protocols/is.rb +33 -0
- data/lib/matrix_sdk/protocols/ss.rb +12 -0
- data/lib/matrix_sdk/room.rb +15 -38
- data/lib/matrix_sdk/user.rb +6 -4
- data/lib/matrix_sdk/version.rb +1 -1
- data/matrix-sdk.gemspec +4 -3
- metadata +25 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4cf8d41f930fae4069a51d6fff87e211a790529c5f157ff6402c15b44770f64d
|
4
|
+
data.tar.gz: 7c06c98e08232dd24f9667dfbb850a2d12ed2021b2f30cb3ad0cbd2a38e8f6e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dfc1717d3b368fffd50f3fb717a3742bf821f3863e4c493797117f15a724ee4bf15be3b45d2dc1d7971a0206e1f21febf128eef389cdd8fa42274e6da1208530
|
7
|
+
data.tar.gz: 1025e4fc9d9f6fe7718971ba3b4c74a0ac35297eb0bb592ad3e25505ec2ec39a36c5d518a835e357b93994db4197066566b17c0696c2298017cdc560e7e7a1ee
|
data/.rubocop.yml
CHANGED
@@ -8,6 +8,9 @@ AllCops:
|
|
8
8
|
Lint/Void:
|
9
9
|
Enabled: false
|
10
10
|
|
11
|
+
Style/ClassAndModuleChildren:
|
12
|
+
Enabled: false
|
13
|
+
|
11
14
|
# Don't enforce documentation
|
12
15
|
Style/Documentation:
|
13
16
|
Enabled: false
|
@@ -18,6 +21,10 @@ Metrics/ClassLength:
|
|
18
21
|
Metrics/MethodLength:
|
19
22
|
Max: 50
|
20
23
|
|
24
|
+
# Matrix has a lot of methods in the CS API
|
25
|
+
Metrics/ModuleLength:
|
26
|
+
Max: 500
|
27
|
+
|
21
28
|
Metrics/LineLength:
|
22
29
|
Max: 190
|
23
30
|
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## v0.1.0 - 2019-05-10
|
2
|
+
|
3
|
+
- Adds code for handling member lazy load in the client abstraction, and activates it by default
|
4
|
+
- Adds methods to read device keys from users
|
5
|
+
- Adds basic methods for device handling
|
6
|
+
- Restructures the API code to separate protocol implementations
|
7
|
+
- Improves the domain discovery code to support all currently specced methods
|
8
|
+
- Improves performance in sync calls
|
9
|
+
- Started work on an application service prototype, not ready for use yet
|
10
|
+
- Testing has been written for large parts of the code
|
11
|
+
|
1
12
|
## v0.0.4 - 2019-02-20
|
2
13
|
|
3
14
|
- Adds a parameter to the client abstraction to allow retrying syncs on timeouts
|
data/README.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
A Ruby gem for easing the development of software that communicates with servers implementing the Matrix protocol.
|
4
4
|
|
5
|
+
There is a Matrix room for the discussion about usage and development at [#ruby-matrix-sdk:kittenface.studio](https://matrix.to/#/#ruby-matrix-sdk:kittenface.studio).
|
6
|
+
|
5
7
|
Live YARD documentation can be found at; http://aleol57.gitlab-pages.liu.se/ruby-matrix-sdk
|
6
8
|
|
7
9
|
## Example usage
|
data/examples/simple_client.rb
CHANGED
@@ -16,7 +16,8 @@ ROOM_DISCOVERY_FILTER = {
|
|
16
16
|
'm.room.aliases',
|
17
17
|
'm.room.canonical_alias',
|
18
18
|
'm.room.member'
|
19
|
-
]
|
19
|
+
],
|
20
|
+
lazy_load_members: true
|
20
21
|
},
|
21
22
|
timeline: { senders: [], types: [] },
|
22
23
|
account_data: { senders: [], types: [] }
|
@@ -30,7 +31,8 @@ ROOM_STATE_FILTER = {
|
|
30
31
|
room: {
|
31
32
|
ephemeral: { senders: [], types: [] },
|
32
33
|
state: {
|
33
|
-
types: ['m.room.member']
|
34
|
+
types: ['m.room.member'],
|
35
|
+
lazy_load_members: true
|
34
36
|
},
|
35
37
|
timeline: {
|
36
38
|
types: ['m.room.message']
|
@@ -93,6 +95,7 @@ if $PROGRAM_NAME == __FILE__
|
|
93
95
|
raise "Usage: #{$PROGRAM_NAME} [-d] homeserver_url room_id_or_alias" unless ARGV.length >= 2
|
94
96
|
begin
|
95
97
|
if ARGV.first == '-d'
|
98
|
+
Thread.abort_on_exception = true
|
96
99
|
MatrixSdk.debug!
|
97
100
|
ARGV.shift
|
98
101
|
end
|
@@ -111,7 +114,7 @@ if $PROGRAM_NAME == __FILE__
|
|
111
114
|
# Only retrieve list of joined room in first sync
|
112
115
|
sync_filter = client.sync_filter.merge(ROOM_DISCOVERY_FILTER)
|
113
116
|
sync_filter[:room][:state][:senders] << client.mxid
|
114
|
-
client.listen_for_events(5, filter: sync_filter.to_json)
|
117
|
+
client.listen_for_events(timeout: 5, filter: sync_filter.to_json)
|
115
118
|
|
116
119
|
puts 'Finding room...'
|
117
120
|
room = client.find_room(ARGV.last)
|
data/lib/matrix_sdk.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'matrix_sdk/extensions'
|
2
2
|
require 'matrix_sdk/version'
|
3
3
|
|
4
|
+
require 'json'
|
5
|
+
|
4
6
|
autoload :Logging, 'logging'
|
5
7
|
|
6
8
|
module MatrixSdk
|
7
9
|
autoload :Api, 'matrix_sdk/api'
|
10
|
+
autoload :ApplicationService, 'matrix_sdk/application_service'
|
8
11
|
autoload :Client, 'matrix_sdk/client'
|
9
12
|
autoload :MXID, 'matrix_sdk/mxid'
|
10
13
|
autoload :Response, 'matrix_sdk/response'
|
@@ -14,15 +17,23 @@ module MatrixSdk
|
|
14
17
|
autoload :MatrixError, 'matrix_sdk/errors'
|
15
18
|
autoload :MatrixRequestError, 'matrix_sdk/errors'
|
16
19
|
autoload :MatrixConnectionError, 'matrix_sdk/errors'
|
20
|
+
autoload :MatrixTimeoutError, 'matrix_sdk/errors'
|
17
21
|
autoload :MatrixUnexpectedResponseError, 'matrix_sdk/errors'
|
18
22
|
|
23
|
+
module Protocols
|
24
|
+
autoload :AS, 'matrix_sdk/protocols/as'
|
25
|
+
autoload :CS, 'matrix_sdk/protocols/cs'
|
26
|
+
autoload :IS, 'matrix_sdk/protocols/is'
|
27
|
+
autoload :SS, 'matrix_sdk/protocols/ss'
|
28
|
+
end
|
29
|
+
|
19
30
|
def self.debug!
|
20
31
|
logger.level = :debug
|
21
32
|
end
|
22
33
|
|
23
34
|
def self.logger
|
24
|
-
@logger ||= Logging.logger[self].tap do |logger|
|
25
|
-
logger.add_appenders Logging.appenders.stdout
|
35
|
+
@logger ||= ::Logging.logger[self].tap do |logger|
|
36
|
+
logger.add_appenders ::Logging.appenders.stdout
|
26
37
|
logger.level = :info
|
27
38
|
end
|
28
39
|
end
|
data/lib/matrix_sdk/api.rb
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
require 'matrix_sdk'
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'json'
|
3
|
+
require 'erb'
|
5
4
|
require 'net/http'
|
6
5
|
require 'openssl'
|
7
6
|
require 'uri'
|
8
7
|
|
9
8
|
module MatrixSdk
|
10
9
|
class Api
|
10
|
+
include MatrixSdk::Logging
|
11
|
+
include MatrixSdk::Protocols::AS
|
12
|
+
include MatrixSdk::Protocols::CS
|
13
|
+
include MatrixSdk::Protocols::IS
|
14
|
+
include MatrixSdk::Protocols::CS
|
15
|
+
|
11
16
|
USER_AGENT = "Ruby Matrix SDK v#{MatrixSdk::VERSION}".freeze
|
12
17
|
DEFAULT_HEADERS = {
|
13
18
|
'accept' => 'application/json',
|
@@ -15,12 +20,13 @@ module MatrixSdk
|
|
15
20
|
}.freeze
|
16
21
|
|
17
22
|
attr_accessor :access_token, :connection_address, :connection_port, :device_id, :autoretry, :global_headers
|
18
|
-
attr_reader :homeserver, :validate_certificate, :read_timeout
|
23
|
+
attr_reader :homeserver, :validate_certificate, :read_timeout, :protocols, :well_known
|
19
24
|
|
20
25
|
ignore_inspect :access_token, :logger
|
21
26
|
|
22
27
|
# @param homeserver [String,URI] The URL to the Matrix homeserver, without the /_matrix/ part
|
23
28
|
# @param params [Hash] Additional parameters on creation
|
29
|
+
# @option params [Symbol[]] :protocols The protocols to include (:AS, :CS, :IS, :SS), defaults to :CS
|
24
30
|
# @option params [String] :address The connection address to the homeserver, if different to the HS URL
|
25
31
|
# @option params [Integer] :port The connection port to the homeserver, if different to the HS URL
|
26
32
|
# @option params [String] :access_token The access token to use for the connection
|
@@ -32,12 +38,17 @@ module MatrixSdk
|
|
32
38
|
# @option params [Numeric] :read_timeout (240) The timeout in seconds for reading responses
|
33
39
|
# @option params [Hash] :global_headers Additional headers to set for all requests
|
34
40
|
# @option params [Boolean] :skip_login Should the API skip logging in if the HS URL contains user information
|
41
|
+
# @option params [Hash] :well_known The .well-known object that the server was discovered through, should not be set manually
|
35
42
|
def initialize(homeserver, params = {})
|
36
43
|
@homeserver = homeserver
|
37
44
|
@homeserver = URI.parse("#{'https://' unless @homeserver.start_with? 'http'}#{@homeserver}") unless @homeserver.is_a? URI
|
38
45
|
@homeserver.path.gsub!(/\/?_matrix\/?/, '') if @homeserver.path =~ /_matrix\/?$/
|
39
46
|
raise 'Please use the base URL for your HS (without /_matrix/)' if @homeserver.path.include? '/_matrix/'
|
40
47
|
|
48
|
+
@protocols = params.fetch(:protocols, %i[CS])
|
49
|
+
@protocols = [@protocols] unless @protocols.is_a? Array
|
50
|
+
@protocols << :CS if @protocols.include?(:AS) && !@protocols.include?(:CS)
|
51
|
+
|
41
52
|
@connection_address = params.fetch(:address, nil)
|
42
53
|
@connection_port = params.fetch(:port, nil)
|
43
54
|
@access_token = params.fetch(:access_token, nil)
|
@@ -47,10 +58,11 @@ module MatrixSdk
|
|
47
58
|
@transaction_id = params.fetch(:transaction_id, 0)
|
48
59
|
@backoff_time = params.fetch(:backoff_time, 5000)
|
49
60
|
@read_timeout = params.fetch(:read_timeout, 240)
|
61
|
+
@well_known = params.fetch(:well_known, {})
|
50
62
|
@global_headers = DEFAULT_HEADERS.dup
|
51
63
|
@global_headers.merge!(params.fetch(:global_headers)) if params.key? :global_headers
|
52
64
|
|
53
|
-
login(user: @homeserver.user, password: @homeserver.password) if @homeserver.user && @homeserver.password && !@access_token && !params[:skip_login]
|
65
|
+
login(user: @homeserver.user, password: @homeserver.password) if @homeserver.user && @homeserver.password && !@access_token && !params[:skip_login] && protocol?(:CS)
|
54
66
|
@homeserver.userinfo = '' unless params[:skip_login]
|
55
67
|
end
|
56
68
|
|
@@ -66,25 +78,42 @@ module MatrixSdk
|
|
66
78
|
# # => 443
|
67
79
|
#
|
68
80
|
# @param domain [String] The domain to set up the API connection for, can contain a ':' to denote a port
|
81
|
+
# @param target [:client,:identity,:server] The target for the domain lookup
|
82
|
+
# @param keep_wellknown [Boolean] Should the .well-known response be kept for further handling
|
69
83
|
# @param params [Hash] Additional options to pass to .new
|
70
84
|
# @return [API] The API connection
|
71
|
-
def self.new_for_domain(domain,
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
85
|
+
def self.new_for_domain(domain, target: :client, keep_wellknown: false, ssl: true, **params)
|
86
|
+
domain, port = domain.split(':')
|
87
|
+
uri = URI("http#{ssl ? 's' : ''}://#{domain}")
|
88
|
+
well_known = nil
|
89
|
+
target_uri = nil
|
90
|
+
|
91
|
+
if !port.nil? && !port.empty?
|
92
|
+
target_uri = URI("https://#{domain}:#{port}")
|
93
|
+
elsif target == :server
|
94
|
+
# Attempt SRV record discovery
|
95
|
+
target_uri = begin
|
96
|
+
require 'resolv'
|
97
|
+
resolver = Resolv::DNS.new
|
98
|
+
resolver.getresource("_matrix._tcp.#{domain}")
|
99
|
+
rescue StandardError
|
100
|
+
nil
|
101
|
+
end
|
102
|
+
|
103
|
+
if target_uri.nil?
|
104
|
+
well_known = begin
|
105
|
+
data = Net::HTTP.get("https://#{domain}/.well-known/matrix/server")
|
106
|
+
JSON.parse(data)
|
107
|
+
rescue StandardError
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
|
111
|
+
target_uri = well_known['m.server'] if well_known && well_known.key?('m.server')
|
112
|
+
else
|
113
|
+
target_uri = URI("https://#{target_uri.target}:#{target_uri.port}")
|
114
|
+
end
|
115
|
+
elsif %i[client identity].include? target
|
116
|
+
# Attempt .well-known discovery
|
88
117
|
well_known = begin
|
89
118
|
data = Net::HTTP.get("https://#{domain}/.well-known/matrix/client")
|
90
119
|
JSON.parse(data)
|
@@ -92,26 +121,31 @@ module MatrixSdk
|
|
92
121
|
nil
|
93
122
|
end
|
94
123
|
|
95
|
-
|
96
|
-
|
97
|
-
|
124
|
+
if well_known
|
125
|
+
key = 'm.homeserver'
|
126
|
+
key = 'm.identity_server' if target == :identity
|
127
|
+
|
128
|
+
if well_known.key?(key) && well_known[key].key?('base_url')
|
129
|
+
uri = URI(well_known[key]['base_url'])
|
130
|
+
target_uri = uri
|
131
|
+
end
|
132
|
+
end
|
98
133
|
end
|
99
134
|
|
100
|
-
# Fall back to
|
101
|
-
|
135
|
+
# Fall back to direct domain connection
|
136
|
+
target_uri ||= URI("https://#{domain}:8448")
|
137
|
+
|
138
|
+
params[:well_known] = well_known if keep_wellknown
|
102
139
|
|
103
|
-
|
104
|
-
new("https://#{domain}",
|
140
|
+
new(uri,
|
105
141
|
params.merge(
|
106
|
-
address:
|
107
|
-
port:
|
142
|
+
address: target_uri.host,
|
143
|
+
port: target_uri.port
|
108
144
|
))
|
109
145
|
end
|
110
146
|
|
111
|
-
|
112
|
-
|
113
|
-
def logger
|
114
|
-
@logger ||= Logging.logger[self]
|
147
|
+
def protocol?(protocol)
|
148
|
+
protocols.include? protocol
|
115
149
|
end
|
116
150
|
|
117
151
|
# @param seconds [Numeric]
|
@@ -139,690 +173,6 @@ module MatrixSdk
|
|
139
173
|
@homeserver = hs_info
|
140
174
|
end
|
141
175
|
|
142
|
-
# Gets the available client API versions
|
143
|
-
# @return [Array]
|
144
|
-
def client_api_versions
|
145
|
-
@client_api_versions ||= request(:get, :client, '/versions').versions.tap do |vers|
|
146
|
-
vers.instance_eval <<-'CODE', __FILE__, __LINE__ + 1
|
147
|
-
def latest
|
148
|
-
latest
|
149
|
-
end
|
150
|
-
CODE
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
# Gets the list of available unstable client API features
|
155
|
-
# @return [Array]
|
156
|
-
def client_api_unstable_features
|
157
|
-
@client_api_unstable_features ||= request(:get, :client, '/versions').unstable_features.tap do |vers|
|
158
|
-
vers.instance_eval <<-'CODE', __FILE__, __LINE__ + 1
|
159
|
-
def has?(feature)
|
160
|
-
fetch(feature, nil)
|
161
|
-
end
|
162
|
-
CODE
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
# Gets the server version
|
167
|
-
# @note This uses the unstable federation/v1 API
|
168
|
-
def server_version
|
169
|
-
Response.new(self, request(:get, :federation_v1, '/version').server).tap do |resp|
|
170
|
-
resp.instance_eval <<-'CODE', __FILE__, __LINE__ + 1
|
171
|
-
def to_s
|
172
|
-
"#{name} #{version}"
|
173
|
-
end
|
174
|
-
CODE
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
# Runs the client API /sync method
|
179
|
-
# @param params [Hash] The sync options to use
|
180
|
-
# @option params [Numeric] :timeout (30.0) The timeout in seconds for the sync
|
181
|
-
# @option params :since The value of the batch token to base the sync from
|
182
|
-
# @option params [String,Hash] :filter The filter to use on the sync
|
183
|
-
# @option params [Boolean] :full_state Should the sync include the full state
|
184
|
-
# @option params [Boolean] :set_presence Should the sync set the user status to online
|
185
|
-
# @return [Response]
|
186
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#get-matrix-client-r0-sync
|
187
|
-
# For more information on the parameters and what they mean
|
188
|
-
def sync(params = {})
|
189
|
-
query = {
|
190
|
-
timeout: 30.0
|
191
|
-
}.merge(params).select do |k, _v|
|
192
|
-
%i[since timeout filter full_state set_presence].include? k
|
193
|
-
end
|
194
|
-
|
195
|
-
query[:timeout] = ((query[:timeout] || 30) * 1000).to_i
|
196
|
-
query[:timeout] = params.delete(:timeout_ms).to_i if params.key? :timeout_ms
|
197
|
-
|
198
|
-
request(:get, :client_r0, '/sync', query: query)
|
199
|
-
end
|
200
|
-
|
201
|
-
# Registers a user using the client API /register endpoint
|
202
|
-
#
|
203
|
-
# @example Regular user registration and login
|
204
|
-
# api.register(username: 'example', password: 'NotARealPass')
|
205
|
-
# # => { user_id: '@example:matrix.org', access_token: '...', home_server: 'matrix.org', device_id: 'ABCD123' }
|
206
|
-
# api.whoami?
|
207
|
-
# # => { user_id: '@example:matrix.org' }
|
208
|
-
#
|
209
|
-
# @param params [Hash] The registration information, all not handled by Ruby will be passed as JSON in the body
|
210
|
-
# @option params [String,Symbol] :kind ('user') The kind of registration to use
|
211
|
-
# @option params [Boolean] :store_token (true) Should the resulting access token be stored for the API
|
212
|
-
# @option params [Boolean] :store_device_id (store_token value) Should the resulting device ID be stored for the API
|
213
|
-
# @return [Response]
|
214
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-register
|
215
|
-
# For options that are permitted in this call
|
216
|
-
def register(params = {})
|
217
|
-
kind = params.delete(:kind) { 'user' }
|
218
|
-
store_token = params.delete(:store_token) { true }
|
219
|
-
store_device_id = params.delete(:store_device_id) { store_token }
|
220
|
-
|
221
|
-
request(:post, :client_r0, '/register', body: params, query: { kind: kind }).tap do |resp|
|
222
|
-
@access_token = resp.token if resp.key?(:token) && store_token
|
223
|
-
@device_id = resp.device_id if resp.key?(:device_id) && store_device_id
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
# Logs in using the client API /login endpoint, and optionally stores the resulting access for API usage
|
228
|
-
#
|
229
|
-
# @example Logging in with username and password
|
230
|
-
# api.login(user: 'example', password: 'NotARealPass')
|
231
|
-
# # => { user_id: '@example:matrix.org', access_token: '...', home_server: 'matrix.org', device_id: 'ABCD123' }
|
232
|
-
# api.whoami?
|
233
|
-
# # => { user_id: '@example:matrix.org' }
|
234
|
-
#
|
235
|
-
# @example Advanced login, without storing details
|
236
|
-
# api.whoami?
|
237
|
-
# # => { user_id: '@example:matrix.org' }
|
238
|
-
# api.login(medium: 'email', address: 'someone@somewhere.net', password: '...', store_token: false)
|
239
|
-
# # => { user_id: '@someone:matrix.org', access_token: ...
|
240
|
-
# api.whoami?.user_id
|
241
|
-
# # => '@example:matrix.org'
|
242
|
-
#
|
243
|
-
# @param params [Hash] The login information to use, along with options for said log in
|
244
|
-
# @option params [Boolean] :store_token (true) Should the resulting access token be stored for the API
|
245
|
-
# @option params [Boolean] :store_device_id (store_token value) Should the resulting device ID be stored for the API
|
246
|
-
# @option params [String] :login_type ('m.login.password') The type of login to attempt
|
247
|
-
# @option params [String] :initial_device_display_name (USER_AGENT) The device display name to specify for this login attempt
|
248
|
-
# @option params [String] :device_id The device ID to set on the login
|
249
|
-
# @return [Response] A response hash with the parameters :user_id, :access_token, :home_server, and :device_id.
|
250
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-login
|
251
|
-
# The Matrix Spec, for more information about the call and response
|
252
|
-
def login(params = {})
|
253
|
-
options = {}
|
254
|
-
options[:store_token] = params.delete(:store_token) { true }
|
255
|
-
options[:store_device_id] = params.delete(:store_device_id) { options[:store_token] }
|
256
|
-
|
257
|
-
data = {
|
258
|
-
type: params.delete(:login_type) { 'm.login.password' },
|
259
|
-
initial_device_display_name: params.delete(:initial_device_display_name) { USER_AGENT }
|
260
|
-
}.merge params
|
261
|
-
data[:device_id] = device_id if device_id
|
262
|
-
|
263
|
-
request(:post, :client_r0, '/login', body: data).tap do |resp|
|
264
|
-
@access_token = resp.token if resp.key?(:token) && options[:store_token]
|
265
|
-
@device_id = resp.device_id if resp.key?(:device_id) && options[:store_device_id]
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
|
-
# Logs out the currently logged in user
|
270
|
-
# @return [Response] An empty response if the logout was successful
|
271
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-logout
|
272
|
-
# The Matrix Spec, for more information about the call and response
|
273
|
-
def logout
|
274
|
-
request(:post, :client_r0, '/logout')
|
275
|
-
end
|
276
|
-
|
277
|
-
# Creates a new room
|
278
|
-
# @param params [Hash] The room creation details
|
279
|
-
# @option params [Symbol] :visibility (:public) The room visibility
|
280
|
-
# @option params [String] :room_alias A room alias to apply on creation
|
281
|
-
# @option params [Boolean] :invite Should the room be created invite-only
|
282
|
-
# @return [Response] A response hash with ...
|
283
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-createroom
|
284
|
-
# The Matrix Spec, for more information about the call and response
|
285
|
-
def create_room(params = {})
|
286
|
-
content = {
|
287
|
-
visibility: params.fetch(:visibility, :public)
|
288
|
-
}
|
289
|
-
content[:room_alias_name] = params[:room_alias] if params[:room_alias]
|
290
|
-
content[:invite] = [params[:invite]].flatten if params[:invite]
|
291
|
-
|
292
|
-
request(:post, :client_r0, '/createRoom', content)
|
293
|
-
end
|
294
|
-
|
295
|
-
# Joins a room
|
296
|
-
# @param id_or_alias [MXID,String] The room ID or Alias to join
|
297
|
-
# @return [Response] A response hash with the parameter :room_id
|
298
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-join-roomidoralias
|
299
|
-
# The Matrix Spec, for more information about the call and response
|
300
|
-
def join_room(id_or_alias)
|
301
|
-
# id_or_alias = MXID.new id_or_alias.to_s unless id_or_alias.is_a? MXID
|
302
|
-
# raise ArgumentError, 'Not a room ID or alias' unless id_or_alias.room?
|
303
|
-
|
304
|
-
id_or_alias = CGI.escape id_or_alias.to_s
|
305
|
-
|
306
|
-
request(:post, :client_r0, "/join/#{id_or_alias}")
|
307
|
-
end
|
308
|
-
|
309
|
-
# Sends a state event to a room
|
310
|
-
# @param room_id [MXID,String] The room ID to send the state event to
|
311
|
-
# @param event_type [String] The event type to send
|
312
|
-
# @param content [Hash] The contents of the state event
|
313
|
-
# @param params [Hash] Options for the request
|
314
|
-
# @option params [Integer] :timestamp The timestamp when the event was created, only used for AS events
|
315
|
-
# @option params [String] :state_key The state key of the event, if there is one
|
316
|
-
# @return [Response] A response hash with the parameter :event_id
|
317
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#put-matrix-client-r0-rooms-roomid-state-eventtype-statekey
|
318
|
-
# https://matrix.org/docs/spec/client_server/r0.3.0.html#put-matrix-client-r0-rooms-roomid-state-eventtype
|
319
|
-
# The Matrix Spec, for more information about the call and response
|
320
|
-
def send_state_event(room_id, event_type, content, params = {})
|
321
|
-
query = {}
|
322
|
-
query[:ts] = params[:timestamp].to_i if params.key? :timestamp
|
323
|
-
|
324
|
-
room_id = CGI.escape room_id.to_s
|
325
|
-
event_type = CGI.escape event_type.to_s
|
326
|
-
state_key = CGI.escape params[:state_key].to_s if params.key? :state_key
|
327
|
-
|
328
|
-
request(:put, :client_r0, "/rooms/#{room_id}/state/#{event_type}#{"/#{state_key}" unless state_key.nil?}", body: content, query: query)
|
329
|
-
end
|
330
|
-
|
331
|
-
# Sends a message event to a room
|
332
|
-
# @param room_id [MXID,String] The room ID to send the message event to
|
333
|
-
# @param event_type [String] The event type of the message
|
334
|
-
# @param content [Hash] The contents of the message
|
335
|
-
# @param params [Hash] Options for the request
|
336
|
-
# @option params [Integer] :timestamp The timestamp when the event was created, only used for AS events
|
337
|
-
# @option params [Integer] :txn_id The ID of the transaction, or automatically generated
|
338
|
-
# @return [Response] A response hash with the parameter :event_id
|
339
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid
|
340
|
-
# The Matrix Spec, for more information about the call and response
|
341
|
-
def send_message_event(room_id, event_type, content, params = {})
|
342
|
-
query = {}
|
343
|
-
query[:ts] = params[:timestamp].to_i if params.key? :timestamp
|
344
|
-
|
345
|
-
txn_id = transaction_id
|
346
|
-
txn_id = params.fetch(:txn_id, "#{txn_id}#{Time.now.to_i}")
|
347
|
-
|
348
|
-
room_id = CGI.escape room_id.to_s
|
349
|
-
event_type = CGI.escape event_type.to_s
|
350
|
-
txn_id = CGI.escape txn_id.to_s
|
351
|
-
|
352
|
-
request(:put, :client_r0, "/rooms/#{room_id}/send/#{event_type}/#{txn_id}", body: content, query: query)
|
353
|
-
end
|
354
|
-
|
355
|
-
# Redact an event in a room
|
356
|
-
# @param room_id [MXID,String] The room ID to send the message event to
|
357
|
-
# @param event_id [String] The event ID of the event to redact
|
358
|
-
# @param params [Hash] Options for the request
|
359
|
-
# @option params [Integer] :timestamp The timestamp when the event was created, only used for AS events
|
360
|
-
# @option params [String] :reason The reason for the redaction
|
361
|
-
# @option params [Integer] :txn_id The ID of the transaction, or automatically generated
|
362
|
-
# @return [Response] A response hash with the parameter :event_id
|
363
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#put-matrix-client-r0-rooms-roomid-redact-eventid-txnid
|
364
|
-
# The Matrix Spec, for more information about the call and response
|
365
|
-
def redact_event(room_id, event_id, params = {})
|
366
|
-
query = {}
|
367
|
-
query[:ts] = params[:timestamp].to_i if params.key? :timestamp
|
368
|
-
|
369
|
-
content = {}
|
370
|
-
content[:reason] = params[:reason] if params[:reason]
|
371
|
-
|
372
|
-
txn_id = transaction_id
|
373
|
-
txn_id = params.fetch(:txn_id, "#{txn_id}#{Time.now.to_i}")
|
374
|
-
|
375
|
-
room_id = CGI.escape room_id.to_s
|
376
|
-
event_id = CGI.escape event_id.to_s
|
377
|
-
txn_id = CGI.escape txn_id.to_s
|
378
|
-
|
379
|
-
request(:put, :client_r0, "/rooms/#{room_id}/redact/#{event_id}/#{txn_id}", body: content, query: query)
|
380
|
-
end
|
381
|
-
|
382
|
-
# Send a content message to a room
|
383
|
-
#
|
384
|
-
# @example Sending an image to a room
|
385
|
-
# send_content('!abcd123:localhost',
|
386
|
-
# 'mxc://localhost/1234567',
|
387
|
-
# 'An image of a cat',
|
388
|
-
# 'm.image',
|
389
|
-
# extra_information: {
|
390
|
-
# h: 128,
|
391
|
-
# w: 128,
|
392
|
-
# mimetype: 'image/png',
|
393
|
-
# size: 1024
|
394
|
-
# })
|
395
|
-
#
|
396
|
-
# @example Sending a file to a room
|
397
|
-
# send_content('!example:localhost',
|
398
|
-
# 'mxc://localhost/fileurl',
|
399
|
-
# 'Contract.pdf',
|
400
|
-
# 'm.file',
|
401
|
-
# extra_content: {
|
402
|
-
# filename: 'contract.pdf'
|
403
|
-
# },
|
404
|
-
# extra_information: {
|
405
|
-
# mimetype: 'application/pdf',
|
406
|
-
# size: 96674
|
407
|
-
# })
|
408
|
-
#
|
409
|
-
# @param room_id [MXID,String] The room ID to send the content to
|
410
|
-
# @param url [URI,String] The URL to the content
|
411
|
-
# @param name [String] The name of the content
|
412
|
-
# @param msg_type [String] The message type of the content
|
413
|
-
# @param params [Hash] Options for the request
|
414
|
-
# @option params [Hash] :extra_information ({}) Extra information for the content
|
415
|
-
# @option params [Hash] :extra_content Extra data to insert into the content hash
|
416
|
-
# @return [Response] A response hash with the parameter :event_id
|
417
|
-
# @see send_message_event For more information on the underlying call
|
418
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#m-image
|
419
|
-
# https://matrix.org/docs/spec/client_server/r0.3.0.html#m-file
|
420
|
-
# https://matrix.org/docs/spec/client_server/r0.3.0.html#m-video
|
421
|
-
# https://matrix.org/docs/spec/client_server/r0.3.0.html#m-audio
|
422
|
-
# The Matrix Spec, for more information about the call and response
|
423
|
-
def send_content(room_id, url, name, msg_type, params = {})
|
424
|
-
content = {
|
425
|
-
url: url,
|
426
|
-
msgtype: msg_type,
|
427
|
-
body: name,
|
428
|
-
info: params.delete(:extra_information) { {} }
|
429
|
-
}
|
430
|
-
content.merge!(params.fetch(:extra_content)) if params.key? :extra_content
|
431
|
-
|
432
|
-
send_message_event(room_id, 'm.room.message', content, params)
|
433
|
-
end
|
434
|
-
|
435
|
-
# Send a geographic location to a room
|
436
|
-
#
|
437
|
-
# @param room_id [MXID,String] The room ID to send the location to
|
438
|
-
# @param geo_uri [URI,String] The geographical URI to send
|
439
|
-
# @param name [String] The name of the location
|
440
|
-
# @param params [Hash] Options for the request
|
441
|
-
# @option params [Hash] :extra_information ({}) Extra information for the location
|
442
|
-
# @option params [URI,String] :thumbnail_url The URL to a thumbnail of the location
|
443
|
-
# @option params [Hash] :thumbnail_info Image information about the location thumbnail
|
444
|
-
# @return [Response] A response hash with the parameter :event_id
|
445
|
-
# @see send_message_event For more information on the underlying call
|
446
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#m-location
|
447
|
-
# The Matrix Spec, for more information about the call and response
|
448
|
-
def send_location(room_id, geo_uri, name, params = {})
|
449
|
-
content = {
|
450
|
-
geo_uri: geo_uri,
|
451
|
-
msgtype: 'm.location',
|
452
|
-
body: name,
|
453
|
-
info: params.delete(:extra_information) { {} }
|
454
|
-
}
|
455
|
-
content[:info][:thumbnail_url] = params.delete(:thumbnail_url) if params.key? :thumbnail_url
|
456
|
-
content[:info][:thumbnail_info] = params.delete(:thumbnail_info) if params.key? :thumbnail_info
|
457
|
-
|
458
|
-
send_message_event(room_id, 'm.room.message', content, params)
|
459
|
-
end
|
460
|
-
|
461
|
-
# Send a plaintext message to a room
|
462
|
-
#
|
463
|
-
# @param room_id [MXID,String] The room ID to send the message to
|
464
|
-
# @param message [String] The message to send
|
465
|
-
# @param params [Hash] Options for the request
|
466
|
-
# @option params [String] :msg_type ('m.text') The message type to send
|
467
|
-
# @return [Response] A response hash with the parameter :event_id
|
468
|
-
# @see send_message_event For more information on the underlying call
|
469
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#m-text
|
470
|
-
# The Matrix Spec, for more information about the call and response
|
471
|
-
def send_message(room_id, message, params = {})
|
472
|
-
content = {
|
473
|
-
msgtype: params.delete(:msg_type) { 'm.text' },
|
474
|
-
body: message
|
475
|
-
}
|
476
|
-
send_message_event(room_id, 'm.room.message', content, params)
|
477
|
-
end
|
478
|
-
|
479
|
-
# Send a plaintext emote to a room
|
480
|
-
#
|
481
|
-
# @param room_id [MXID,String] The room ID to send the message to
|
482
|
-
# @param emote [String] The emote to send
|
483
|
-
# @param params [Hash] Options for the request
|
484
|
-
# @option params [String] :msg_type ('m.emote') The message type to send
|
485
|
-
# @return [Response] A response hash with the parameter :event_id
|
486
|
-
# @see send_message_event For more information on the underlying call
|
487
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#m-emote
|
488
|
-
# The Matrix Spec, for more information about the call and response
|
489
|
-
def send_emote(room_id, emote, params = {})
|
490
|
-
content = {
|
491
|
-
msgtype: params.delete(:msg_type) { 'm.emote' },
|
492
|
-
body: emote
|
493
|
-
}
|
494
|
-
send_message_event(room_id, 'm.room.message', content, params)
|
495
|
-
end
|
496
|
-
|
497
|
-
# Send a plaintext notice to a room
|
498
|
-
#
|
499
|
-
# @param room_id [MXID,String] The room ID to send the message to
|
500
|
-
# @param notice [String] The notice to send
|
501
|
-
# @param params [Hash] Options for the request
|
502
|
-
# @option params [String] :msg_type ('m.notice') The message type to send
|
503
|
-
# @return [Response] A response hash with the parameter :event_id
|
504
|
-
# @see send_message_event For more information on the underlying call
|
505
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#m-notice
|
506
|
-
# The Matrix Spec, for more information about the call and response
|
507
|
-
def send_notice(room_id, notice, params = {})
|
508
|
-
content = {
|
509
|
-
msgtype: params.delete(:msg_type) { 'm.notice' },
|
510
|
-
body: notice
|
511
|
-
}
|
512
|
-
send_message_event(room_id, 'm.room.message', content, params)
|
513
|
-
end
|
514
|
-
|
515
|
-
# Retrieve additional messages in a room
|
516
|
-
#
|
517
|
-
# @param room_id [MXID,String] The room ID to retrieve messages for
|
518
|
-
# @param token [String] The token to start retrieving from, can be from a sync or from an earlier get_room_messages call
|
519
|
-
# @param direction [:b,:f] The direction to retrieve messages
|
520
|
-
# @param params [Hash] Additional options for the request
|
521
|
-
# @option params [Integer] :limit (10) The limit of messages to retrieve
|
522
|
-
# @option params [String] :to A token to limit retrieval to
|
523
|
-
# @option params [String] :filter A filter to limit the retrieval to
|
524
|
-
# @return [Response] A response hash with the message information containing :start, :end, and :chunk fields
|
525
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#get-matrix-client-r0-rooms-roomid-messages
|
526
|
-
# The Matrix Spec, for more information about the call and response
|
527
|
-
def get_room_messages(room_id, token, direction, params = {})
|
528
|
-
query = {
|
529
|
-
roomId: room_id,
|
530
|
-
from: token,
|
531
|
-
dir: direction,
|
532
|
-
limit: params.fetch(:limit, 10)
|
533
|
-
}
|
534
|
-
query[:to] = params[:to] if params.key? :to
|
535
|
-
query[:filter] = params.fetch(:filter) if params.key? :filter
|
536
|
-
|
537
|
-
room_id = CGI.escape room_id.to_s
|
538
|
-
|
539
|
-
request(:get, :client_r0, "/rooms/#{room_id}/messages", query: query)
|
540
|
-
end
|
541
|
-
|
542
|
-
# Reads the latest instance of a room state event
|
543
|
-
#
|
544
|
-
# @param room_id [MXID,String] The room ID to read from
|
545
|
-
# @param state_type [String] The state type to read
|
546
|
-
# @return [Response] A response hash with the contents of the state event
|
547
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#get-matrix-client-r0-rooms-roomid-state-eventtype
|
548
|
-
# The Matrix Spec, for more information about the call and response
|
549
|
-
def get_room_state(room_id, state_type)
|
550
|
-
room_id = CGI.escape room_id.to_s
|
551
|
-
state_type = CGI.escape state_type.to_s
|
552
|
-
|
553
|
-
request(:get, :client_r0, "/rooms/#{room_id}/state/#{state_type}")
|
554
|
-
end
|
555
|
-
|
556
|
-
# Gets the display name of a room
|
557
|
-
#
|
558
|
-
# @param room_id [MXID,String] The room ID to look up
|
559
|
-
# @return [Response] A response hash with the parameter :name
|
560
|
-
# @see get_room_state
|
561
|
-
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#m-room-name
|
562
|
-
# The Matrix Spec, for more information about the event and data
|
563
|
-
def get_room_name(room_id)
|
564
|
-
get_room_state(room_id, 'm.room.name')
|
565
|
-
end
|
566
|
-
|
567
|
-
def set_room_name(room_id, name, params = {})
|
568
|
-
content = {
|
569
|
-
name: name
|
570
|
-
}
|
571
|
-
send_state_event(room_id, 'm.room.name', content, params)
|
572
|
-
end
|
573
|
-
|
574
|
-
def get_room_topic(room_id)
|
575
|
-
get_room_state(room_id, 'm.room.topic')
|
576
|
-
end
|
577
|
-
|
578
|
-
def set_room_topic(room_id, topic, params = {})
|
579
|
-
content = {
|
580
|
-
topic: topic
|
581
|
-
}
|
582
|
-
send_state_event(room_id, 'm.room.topic', content, params)
|
583
|
-
end
|
584
|
-
|
585
|
-
def get_power_levels(room_id)
|
586
|
-
get_room_state(room_id, 'm.room.power_levels')
|
587
|
-
end
|
588
|
-
|
589
|
-
def set_power_levels(room_id, content)
|
590
|
-
content[:events] = {} unless content.key? :events
|
591
|
-
send_state_event(room_id, 'm.room.power_levels', content)
|
592
|
-
end
|
593
|
-
|
594
|
-
def leave_room(room_id)
|
595
|
-
room_id = CGI.escape room_id.to_s
|
596
|
-
|
597
|
-
request(:post, :client_r0, "/rooms/#{room_id}/leave")
|
598
|
-
end
|
599
|
-
|
600
|
-
def forget_room(room_id)
|
601
|
-
room_id = CGI.escape room_id.to_s
|
602
|
-
|
603
|
-
request(:post, :client_r0, "/rooms/#{room_id}/forget")
|
604
|
-
end
|
605
|
-
|
606
|
-
def invite_user(room_id, user_id)
|
607
|
-
content = {
|
608
|
-
user_id: user_id
|
609
|
-
}
|
610
|
-
|
611
|
-
room_id = CGI.escape room_id.to_s
|
612
|
-
|
613
|
-
request(:post, :client_r0, "/rooms/#{room_id}/invite", body: content)
|
614
|
-
end
|
615
|
-
|
616
|
-
def kick_user(room_id, user_id, params = {})
|
617
|
-
set_membership(room_id, user_id, 'leave', params)
|
618
|
-
end
|
619
|
-
|
620
|
-
def get_membership(room_id, user_id)
|
621
|
-
room_id = CGI.escape room_id.to_s
|
622
|
-
user_id = CGI.escape user_id.to_s
|
623
|
-
|
624
|
-
request(:get, :client_r0, "/rooms/#{room_id}/state/m.room.member/#{user_id}")
|
625
|
-
end
|
626
|
-
|
627
|
-
def set_membership(room_id, user_id, membership, params = {})
|
628
|
-
content = {
|
629
|
-
membership: membership,
|
630
|
-
reason: params.delete(:reason) { '' }
|
631
|
-
}
|
632
|
-
content[:displayname] = params.delete(:displayname) if params.key? :displayname
|
633
|
-
content[:avatar_url] = params.delete(:avatar_url) if params.key? :avatar_url
|
634
|
-
|
635
|
-
send_state_event(room_id, 'm.room.member', content, params.merge(state_key: user_id))
|
636
|
-
end
|
637
|
-
|
638
|
-
def ban_user(room_id, user_id, params = {})
|
639
|
-
content = {
|
640
|
-
user_id: user_id,
|
641
|
-
reason: params[:reason] || ''
|
642
|
-
}
|
643
|
-
|
644
|
-
room_id = CGI.escape room_id.to_s
|
645
|
-
|
646
|
-
request(:post, :client_r0, "/rooms/#{room_id}/ban", body: content)
|
647
|
-
end
|
648
|
-
|
649
|
-
def unban_user(room_id, user_id)
|
650
|
-
content = {
|
651
|
-
user_id: user_id
|
652
|
-
}
|
653
|
-
|
654
|
-
room_id = CGI.escape room_id.to_s
|
655
|
-
|
656
|
-
request(:post, :client_r0, "/rooms/#{room_id}/unban", body: content)
|
657
|
-
end
|
658
|
-
|
659
|
-
def get_user_tags(user_id, room_id)
|
660
|
-
room_id = CGI.escape room_id.to_s
|
661
|
-
user_id = CGI.escape user_id.to_s
|
662
|
-
|
663
|
-
request(:get, :client_r0, "/user/#{user_id}/rooms/#{room_id}/tags")
|
664
|
-
end
|
665
|
-
|
666
|
-
def remove_user_tag(user_id, room_id, tag)
|
667
|
-
room_id = CGI.escape room_id.to_s
|
668
|
-
user_id = CGI.escape user_id.to_s
|
669
|
-
tag = CGI.escape tag.to_s
|
670
|
-
|
671
|
-
request(:delete, :client_r0, "/user/#{user_id}/rooms/#{room_id}/tags/#{tag}")
|
672
|
-
end
|
673
|
-
|
674
|
-
def add_user_tag(user_id, room_id, tag, params = {})
|
675
|
-
if params[:body]
|
676
|
-
content = params[:body]
|
677
|
-
else
|
678
|
-
content = {}
|
679
|
-
content[:order] = params[:order] if params.key? :order
|
680
|
-
end
|
681
|
-
|
682
|
-
room_id = CGI.escape room_id.to_s
|
683
|
-
user_id = CGI.escape user_id.to_s
|
684
|
-
tag = CGI.escape tag.to_s
|
685
|
-
|
686
|
-
request(:put, :client_r0, "/user/#{user_id}/rooms/#{room_id}/tags/#{tag}", body: content)
|
687
|
-
end
|
688
|
-
|
689
|
-
def get_account_data(user_id, type_key)
|
690
|
-
user_id = CGI.escape user_id.to_s
|
691
|
-
type_key = CGI.escape type_key.to_s
|
692
|
-
|
693
|
-
request(:get, :client_r0, "/user/#{user_id}/account_data/#{type_key}")
|
694
|
-
end
|
695
|
-
|
696
|
-
def set_account_data(user_id, type_key, account_data)
|
697
|
-
user_id = CGI.escape user_id.to_s
|
698
|
-
type_key = CGI.escape type_key.to_s
|
699
|
-
|
700
|
-
request(:put, :client_r0, "/user/#{user_id}/account_data/#{type_key}", body: account_data)
|
701
|
-
end
|
702
|
-
|
703
|
-
def get_room_account_data(user_id, room_id, type_key)
|
704
|
-
user_id = CGI.escape user_id.to_s
|
705
|
-
room_id = CGI.escape room_id.to_s
|
706
|
-
type_key = CGI.escape type_key.to_s
|
707
|
-
|
708
|
-
request(:get, :client_r0, "/user/#{user_id}/rooms/#{room_id}/account_data/#{type_key}")
|
709
|
-
end
|
710
|
-
|
711
|
-
def set_room_account_data(user_id, room_id, type_key, account_data)
|
712
|
-
user_id = CGI.escape user_id.to_s
|
713
|
-
room_id = CGI.escape room_id.to_s
|
714
|
-
type_key = CGI.escape type_key.to_s
|
715
|
-
|
716
|
-
request(:put, :client_r0, "/user/#{user_id}/rooms/#{room_id}/account_data/#{type_key}", body: account_data)
|
717
|
-
end
|
718
|
-
|
719
|
-
def get_filter(user_id, filter_id)
|
720
|
-
user_id = CGI.escape user_id.to_s
|
721
|
-
filter_id = CGI.escape filter_id.to_s
|
722
|
-
|
723
|
-
request(:get, :client_r0, "/user/#{user_id}/filter/#{filter_id}")
|
724
|
-
end
|
725
|
-
|
726
|
-
def create_filter(user_id, filter_params)
|
727
|
-
user_id = CGI.escape user_id.to_s
|
728
|
-
|
729
|
-
request(:post, :client_r0, "/user/#{user_id}/filter", body: filter_params)
|
730
|
-
end
|
731
|
-
|
732
|
-
def media_upload(content, content_type)
|
733
|
-
request(:post, :media_r0, '/upload', body: content, headers: { 'content-type' => content_type })
|
734
|
-
end
|
735
|
-
|
736
|
-
def get_display_name(user_id)
|
737
|
-
user_id = CGI.escape user_id.to_s
|
738
|
-
|
739
|
-
request(:get, :client_r0, "/profile/#{user_id}/displayname")
|
740
|
-
end
|
741
|
-
|
742
|
-
def set_display_name(user_id, display_name)
|
743
|
-
content = {
|
744
|
-
displayname: display_name
|
745
|
-
}
|
746
|
-
|
747
|
-
user_id = CGI.escape user_id.to_s
|
748
|
-
|
749
|
-
request(:put, :client_r0, "/profile/#{user_id}/displayname", body: content)
|
750
|
-
end
|
751
|
-
|
752
|
-
def get_avatar_url(user_id)
|
753
|
-
user_id = CGI.escape user_id.to_s
|
754
|
-
|
755
|
-
request(:get, :client_r0, "/profile/#{user_id}/avatar_url")
|
756
|
-
end
|
757
|
-
|
758
|
-
def set_avatar_url(user_id, url)
|
759
|
-
content = {
|
760
|
-
avatar_url: url
|
761
|
-
}
|
762
|
-
|
763
|
-
user_id = CGI.escape user_id.to_s
|
764
|
-
|
765
|
-
request(:put, :client_r0, "/profile/#{user_id}/avatar_url", body: content)
|
766
|
-
end
|
767
|
-
|
768
|
-
def get_download_url(mxcurl)
|
769
|
-
mxcurl = URI.parse(mxcurl.to_s) unless mxcurl.is_a? URI
|
770
|
-
raise 'Not a mxc:// URL' unless mxcurl.is_a? URI::MATRIX
|
771
|
-
|
772
|
-
homeserver.dup.tap do |u|
|
773
|
-
full_path = CGI.escape mxcurl.full_path.to_s
|
774
|
-
u.path = "/_matrix/media/r0/download/#{full_path}"
|
775
|
-
end
|
776
|
-
end
|
777
|
-
|
778
|
-
def get_room_id(room_alias)
|
779
|
-
room_alias = CGI.escape room_alias.to_s
|
780
|
-
|
781
|
-
request(:get, :client_r0, "/directory/room/#{room_alias}")
|
782
|
-
end
|
783
|
-
|
784
|
-
def set_room_alias(room_id, room_alias)
|
785
|
-
content = {
|
786
|
-
room_id: room_id
|
787
|
-
}
|
788
|
-
|
789
|
-
room_alias = CGI.escape room_alias.to_s
|
790
|
-
|
791
|
-
request(:put, :client_r0, "/directory/room/#{room_alias}", body: content)
|
792
|
-
end
|
793
|
-
|
794
|
-
def remove_room_alias(room_alias)
|
795
|
-
room_alias = CGI.escape room_alias.to_s
|
796
|
-
|
797
|
-
request(:delete, :client_r0, "/directory/room/#{room_alias}")
|
798
|
-
end
|
799
|
-
|
800
|
-
def get_room_members(room_id)
|
801
|
-
room_id = CGI.escape room_id.to_s
|
802
|
-
|
803
|
-
request(:get, :client_r0, "/rooms/#{room_id}/members")
|
804
|
-
end
|
805
|
-
|
806
|
-
def set_join_rule(room_id, join_rule)
|
807
|
-
content = {
|
808
|
-
join_rule: join_rule
|
809
|
-
}
|
810
|
-
|
811
|
-
send_state_event(room_id, 'm.room.join_rules', content)
|
812
|
-
end
|
813
|
-
|
814
|
-
def set_guest_access(room_id, guest_access)
|
815
|
-
# raise ArgumentError, '`guest_access` must be one of [:can_join, :forbidden]' unless %i[can_join forbidden].include? guest_access
|
816
|
-
content = {
|
817
|
-
guest_access: guest_access
|
818
|
-
}
|
819
|
-
send_state_event(room_id, 'm.room.guest_access', content)
|
820
|
-
end
|
821
|
-
|
822
|
-
def whoami?
|
823
|
-
request(:get, :client_r0, '/account/whoami')
|
824
|
-
end
|
825
|
-
|
826
176
|
def request(method, api, path, options = {})
|
827
177
|
url = homeserver.dup.tap do |u|
|
828
178
|
u.path = api_to_path(api) + path
|
@@ -891,8 +241,8 @@ module MatrixSdk
|
|
891
241
|
clean_body = JSON.parse(http.body) rescue nil if http.body
|
892
242
|
clean_body.keys.each { |k| clean_body[k] = '[ REDACTED ]' if %w[password access_token].include?(k) }.to_json if clean_body
|
893
243
|
logger.debug "#{dir} #{clean_body.length < 200 ? clean_body : clean_body.slice(0..200) + "... [truncated, #{clean_body.length} Bytes]"}" if clean_body
|
894
|
-
rescue StandardError =>
|
895
|
-
logger.warn "#{
|
244
|
+
rescue StandardError => e
|
245
|
+
logger.warn "#{e.class} occured while printing request debug; #{e.message}\n#{e.backtrace.join "\n"}"
|
896
246
|
end
|
897
247
|
|
898
248
|
def transaction_id
|