chatrix 1.0.0.pre → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,213 @@
1
+ require 'chatrix/api/api_component'
2
+ require 'chatrix/api/room_actions'
3
+
4
+ module Chatrix
5
+ module Api
6
+ # Contains methods for using room endpoints in the API.
7
+ class Rooms < ApiComponent
8
+ # @return [RoomActions] an instance of RoomActions to perform
9
+ # room actions such as joining a room or sending messages.
10
+ attr_reader :actions
11
+
12
+ # Initializes a new Rooms instance.
13
+ # @param matrix [Matrix] The matrix API instance.
14
+ def initialize(matrix)
15
+ super
16
+ @actions = Api::RoomActions.new @matrix
17
+ end
18
+
19
+ # Get the list of public rooms on the server.
20
+ #
21
+ # The `start` and `end` values returned in the result can be passed to
22
+ # `from` and `to`, for pagination purposes.
23
+ #
24
+ # @param from [String] The stream token to start looking from.
25
+ # @param to [String] The stream token to stop looking at.
26
+ # @param limit [Fixnum] Maximum number of results to
27
+ # return in one request.
28
+ # @param direction ['f', 'b'] Direction to look in.
29
+ # @return [Hash] Hash containing the list of rooms (in the `chunk` value),
30
+ # and pagination parameters `start` and `end`.
31
+ def get_rooms(from: 'START', to: 'END', limit: 10, direction: 'b')
32
+ make_request(
33
+ :get,
34
+ '/publicRooms',
35
+ params: { from: from, to: to, limit: limit, dir: direction }
36
+ ).parsed_response
37
+ end
38
+
39
+ # Get tags that a specific user has set on a room.
40
+ #
41
+ # @param user [String] The user whose settings to retrieve
42
+ # (`@user:host.tld`).
43
+ # @param room [String] The room to get tags from.
44
+ # @return [Hash{String=>Hash}] A hash with tag data. The tag name is
45
+ # the key and any additional metadata is contained in the Hash value.
46
+ def get_user_tags(user, room)
47
+ make_request(:get, "/user/#{user}/rooms/#{room}/tags")['tags']
48
+ end
49
+
50
+ # Deletes a user tag from a room.
51
+ #
52
+ # @param user [String] The user to remove the tag for.
53
+ # @param room [String] The room to remove the tag from.
54
+ # @param tag [String] The tag to remove.
55
+ # @return [Boolean] `true` if the tag was removed successfully,
56
+ # otherwise `false`.
57
+ def delete_user_tag(user, room, tag)
58
+ make_request(
59
+ :delete,
60
+ "/user/#{user}/rooms/#{room}/tags/#{tag}"
61
+ ).code == 200
62
+ end
63
+
64
+ # Adds a user tag to a room.
65
+ #
66
+ # @param user [String] The user adding the tag.
67
+ # @param room [String] The room to add the tag to.
68
+ # @param tag [String] The tag to add.
69
+ # @param data [Hash] Any additional data to add to the tag, e.g. ordering.
70
+ # @return [Boolean] `true` if the tag was successfully added,
71
+ # otherwise `false`.
72
+ def add_user_tag(user, room, tag, data = {})
73
+ make_request(
74
+ :put,
75
+ "/user/#{user}/rooms/#{room}/tags/#{tag}",
76
+ content: data
77
+ ).code == 200
78
+ end
79
+
80
+ # Get information about a room alias.
81
+ #
82
+ # This can be used to get the room ID that an alias points to.
83
+ #
84
+ # @param room_alias [String] The room alias to query, this **must** be an
85
+ # alias and not an ID.
86
+ # @return [Hash] Returns information about the alias in a Hash.
87
+ #
88
+ # @see #get_id #get_id is an example of how this method could be
89
+ # used to get a room's ID.
90
+ def get_alias_info(room_alias)
91
+ make_request(:get, "/directory/room/#{room_alias}").parsed_response
92
+ rescue NotFoundError
93
+ raise RoomNotFoundError.new(room_alias),
94
+ 'The specified room alias could not be found'
95
+ end
96
+
97
+ # Deletes a room alias.
98
+ # @param room_alias [String] The alias to delete.
99
+ # @return [Boolean] `true` if the alias was successfully removed,
100
+ # otherwise `false`.
101
+ def delete_alias(room_alias)
102
+ make_request(:delete, "/directory/room/#{room_alias}").code == 200
103
+ end
104
+
105
+ # Creates a new alias for a room.
106
+ #
107
+ # @param room [String] The room to create an alias for.
108
+ # @param room_alias [String] The alias to create for the room.
109
+ # @return [Boolean] `true` if the alias was created successfully,
110
+ # otherwise `false`.
111
+ def create_alias(room, room_alias)
112
+ make_request(
113
+ :put,
114
+ "/directory/room/#{room_alias}",
115
+ content: { room_id: room }
116
+ ).code == 200
117
+ end
118
+
119
+ # Get a room's ID from its alias.
120
+ #
121
+ # @param room_alias [String] The room alias to query.
122
+ # @return [String] The actual room ID for the room.
123
+ def get_id(room_alias)
124
+ get_room_alias_info(room_alias)['room_id']
125
+ end
126
+
127
+ # Gets context for an event in a room.
128
+ #
129
+ # The method will return events that happened before and after the
130
+ # specified event.
131
+ #
132
+ # @param room [String] The room to query.
133
+ # @param event [String] The event to get context for.
134
+ # @param limit [Fixnum] Maximum number of events to retrieve.
135
+ # @return [Hash] The returned hash contains information about the events
136
+ # happening before and after the specified event, as well as start and
137
+ # end timestamps and state information for the event.
138
+ def get_event_context(room, event, limit = 10)
139
+ make_request(
140
+ :get,
141
+ "/rooms/#{room}/context/#{event}",
142
+ params: { limit: limit }
143
+ ).parsed_response
144
+ end
145
+
146
+ # Get the members of a room.
147
+ #
148
+ # @param room [String] The room to query.
149
+ # @return [Array] An array of users that are in this room.
150
+ def get_members(room)
151
+ make_request(:get, "/rooms/#{room}/members")['chunk']
152
+ end
153
+
154
+ # Get a list of messages from a room.
155
+ #
156
+ # @param room [String] The room to get messages from.
157
+ # @param from [String] Token to return events from.
158
+ # @param direction ['b', 'f'] Direction to return events from.
159
+ # @param limit [Fixnum] Maximum number of events to return.
160
+ # @return [Hash] A hash containing the messages, as well as `start` and
161
+ # `end` tokens for pagination.
162
+ def get_messages(room, from: 'START', to: 'END',
163
+ direction: 'b', limit: 10)
164
+ make_request(
165
+ :get,
166
+ "/rooms/#{room}/messages",
167
+ params: { from: from, to: to, dir: direction, limit: limit }
168
+ ).parsed_response
169
+ end
170
+
171
+ # @overload get_room_state(room)
172
+ # Get state events for the current state of a room.
173
+ # @param room [String] The room to get events for.
174
+ # @return [Array] An array with state events for the room.
175
+ # @overload get_room_state(room, type)
176
+ # Get the contents of a specific kind of state in the room.
177
+ # @param room [String] The room to get the data from.
178
+ # @param type [String] The type of state to get.
179
+ # @return [Hash] Information about the state type.
180
+ # @overload get_room_state(room, type, key)
181
+ # Get the contents of a specific kind of state including only the
182
+ # specified key in the result.
183
+ # @param room [String] The room to get the data from.
184
+ # @param type [String] The type of state to get.
185
+ # @param key [String] The key of the state to look up.
186
+ # @return [Hash] Information about the requested state.
187
+ def get_state(room, type = nil, key = nil)
188
+ if type && key
189
+ make_request(:get, "/rooms/#{room}/state/#{type}/#{key}")
190
+ .parsed_response
191
+ elsif type
192
+ make_request(:get, "/rooms/#{room}/state/#{type}").parsed_response
193
+ else
194
+ make_request(:get, "/rooms/#{room}/state").parsed_response
195
+ end
196
+ end
197
+
198
+ # Sends a state event to a room, with an optional state key.
199
+ # @param room [String] The room to send the event to.
200
+ # @param type [String] The event type to send.
201
+ # @param content [Hash] The content to set for the event.
202
+ # @param key [String,nil] Optional `state_key` to use.
203
+ # @return [String] The event ID for the sent event.
204
+ def send_state(room, type, content, key = nil)
205
+ path = "/rooms/#{room}/state/#{type}"
206
+
207
+ path += "/#{key}" if key
208
+
209
+ make_request(:put, path, content: content)['event_id']
210
+ end
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,154 @@
1
+ require 'chatrix/api/api_component'
2
+
3
+ module Chatrix
4
+ module Api
5
+ # Contains methods to use session related endpoints in the API.
6
+ class Session < ApiComponent
7
+ # Gets third-party IDs associated with the current account.
8
+ # @return [Array] A list of 3rd party IDs.
9
+ def threepids
10
+ make_request(:get, '/account/3pid')['threepids']
11
+ end
12
+
13
+ # Adds third-party identification information to the user account.
14
+ # @param data [Hash] The data to add. Refer to the official documentation
15
+ # for more information.
16
+ # @return [Boolean] `true` if the information was added successfully,
17
+ # otherwise `false`.
18
+ def add_threepid(data)
19
+ make_request(:post, '/account/3pid', content: data).code == 200
20
+ end
21
+
22
+ # Set a new password for the current account.
23
+ #
24
+ # @note The server may request additional authentication as per the
25
+ # official documentation on the "User-Interactive Authentication API".
26
+ #
27
+ # @param password [String] The new password to set.
28
+ # @param auth [Hash,nil] If provided, the hash will be passed in the
29
+ # request as additional parameters inside the `auth` field.
30
+ # @return [Boolean] `true` if the password was successfully changed,
31
+ # otherwise `false`.
32
+ def set_password(password, auth = nil)
33
+ data = { new_password: password }
34
+ data[:auth] = auth if auth
35
+
36
+ make_request(:post, '/account/password', content: data).code == 200
37
+ end
38
+
39
+ # Registers a new user on the homeserver.
40
+ #
41
+ # @note On a successful registration, the
42
+ # {Matrix#access_token access_token} and `refresh_token` will be
43
+ # updated to the values returned by the server.
44
+ #
45
+ # @param data [Hash] Registration data. Populate this with the
46
+ # information needed to register the new user.
47
+ #
48
+ # Refer to the official API documentation on how to populate the
49
+ # data hash.
50
+ #
51
+ # @param kind [String] The kind of registration to make.
52
+ # Either `'guest'` or `'user'`.
53
+ #
54
+ # @return [Hash] On success, returns a hash with information about the
55
+ # newly registered user. An example return value is given below.
56
+ #
57
+ # ```ruby
58
+ # {
59
+ # 'user_id' => '@foo:bar.org',
60
+ # 'home_server' => 'https://bar.org',
61
+ # 'access_token' => 'some secret token',
62
+ # 'refresh_token' => 'refresh token here'
63
+ # }
64
+ # ```
65
+ def register(data, kind = 'user')
66
+ response = make_request(
67
+ :post,
68
+ '/register',
69
+ params: { kind: kind },
70
+ content: data
71
+ )
72
+
73
+ @matrix.access_token = response['access_token']
74
+ @refresh_token = response['refresh_token']
75
+
76
+ response.parsed_response
77
+ end
78
+
79
+ # Performs a login attempt.
80
+ #
81
+ # @note A successful login will update the
82
+ # {Matrix#access_token access_token} to the new one returned from
83
+ # the login response.
84
+ #
85
+ # @param method [String] The method to use for logging in.
86
+ # For user/password combination, this should be `m.login.password`.
87
+ # @param options [Hash{String=>String}] Options to pass for logging in.
88
+ # For a password login, this should contain a key `:user` for the
89
+ # username, and a key `:password` for the password.
90
+ # @return [Hash] The response from the server. A successful login will
91
+ # return a hash containing the user id, access token, and homeserver.
92
+ #
93
+ # @example Logging in with username and password
94
+ # login('m.login.password',
95
+ # user: '@snoo:reddit.com', password: 'hunter2')
96
+ def login(method, options)
97
+ response = make_request(
98
+ :post,
99
+ '/login',
100
+ content: { type: method }.merge!(options)
101
+ )
102
+
103
+ # Update the local access token
104
+ @matrix.access_token = response['access_token']
105
+
106
+ response.parsed_response
107
+ end
108
+
109
+ # Logs out.
110
+ #
111
+ # @note This will **invalidate the access token**. It will no longer be
112
+ # valid for further API calls.
113
+ #
114
+ # @return [Boolean] `true` if the user was successfully logged out,
115
+ # otherwise `false`.
116
+ def logout
117
+ response = make_request :post, '/logout'
118
+
119
+ # A successful logout means the access token has been invalidated
120
+ @matrix.access_token = nil
121
+
122
+ response.code == 200
123
+ end
124
+
125
+ # Gets a new access token to use for API calls when the current one
126
+ # expires.
127
+ #
128
+ # @note On success, the internal {Matrix#access_token access_token} and
129
+ # `refresh_token` will be updated automatically for use in
130
+ # subsequent API calls.
131
+ #
132
+ # @param token [String,nil] The `refresh_token` to provide for the server
133
+ # when requesting a new token. If not set, the internal refresh and
134
+ # access tokens will be used.
135
+ # @return [Hash] The response hash from the server will contain the new
136
+ # access token and a refresh token to use the next time a new access
137
+ # token is needed.
138
+ def refresh(token = nil)
139
+ refresh_token = token || @refresh_token || @access_token
140
+
141
+ response = make_request(
142
+ :post,
143
+ '/tokenrefresh',
144
+ content: { refresh_token: refresh_token }
145
+ )
146
+
147
+ @matrix.access_token = response['access_token']
148
+ @refresh_token = response['refresh_token']
149
+
150
+ response.parsed_response
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,176 @@
1
+ require 'chatrix/api/api_component'
2
+
3
+ module Chatrix
4
+ module Api
5
+ # Contains methods to use user endpoints in the API.
6
+ class Users < ApiComponent
7
+ # Gets information about a specific user.
8
+ #
9
+ # @param user [String] The user to query (`@user:host.tld`).
10
+ # @return [Hash] The user information.
11
+ # @raise [UserNotFoundError] If the user could not be found.
12
+ #
13
+ # @example Print a user's display name
14
+ # puts get_user('@foo:matrix.org')['displayname']
15
+ def get(user)
16
+ make_request(:get, "/profile/#{user}").parsed_response
17
+ rescue NotFoundError => e
18
+ raise UserNotFoundError.new(user, e.error),
19
+ 'The specified user could not be found'
20
+ end
21
+
22
+ # Get the URL to a user's avatar (an `mxp://` URL).
23
+ #
24
+ # @param (see #get_user)
25
+ # @return [String] The avatar URL.
26
+ # @raise [AvatarNotFoundError] If the avatar or user could not be found.
27
+ def get_avatar(user)
28
+ make_request(:get, "/profile/#{user}/avatar_url")['avatar_url']
29
+ rescue NotFoundError => e
30
+ raise AvatarNotFoundError.new(user, e.error),
31
+ 'Avatar or user could not be found'
32
+ end
33
+
34
+ # Sets a new avatar for a user.
35
+ #
36
+ # @param user [String] The user to update.
37
+ # @param avatar [String] The new avatar to set, an `mxc://` URL.
38
+ # @return [Boolean] `true` if the new avatar was set successfully,
39
+ # otherwise `false`.
40
+ def set_avatar(user, avatar)
41
+ make_request(
42
+ :put,
43
+ "/profile/#{user}/avatar_url",
44
+ content: { avatar_url: avatar }
45
+ ).code == 200
46
+ end
47
+
48
+ # Get a user's display name (**not** username).
49
+ #
50
+ # @param (see #get_user)
51
+ # @raise (see #get_user)
52
+ def get_displayname(user)
53
+ make_request(:get, "/profile/#{user}/displayname")['displayname']
54
+ rescue NotFoundError => e
55
+ raise UserNotFoundError.new(user, e.error),
56
+ 'The specified user could not be found'
57
+ end
58
+
59
+ # Sets a new display name for a user.
60
+ #
61
+ # @note Can only be used on the user who possesses the
62
+ # {Matrix#access_token access_token} currently in use.
63
+ #
64
+ # @param user [String] The user to modify (`@user:host.tld`).
65
+ # @param displayname [String] The new displayname to set.
66
+ # @return [Boolean] `true` if the new display name was successfully set,
67
+ # otherwise `false`.
68
+ def set_displayname(user, displayname)
69
+ make_request(
70
+ :put,
71
+ "/profile/#{user}/displayname",
72
+ content: { displayname: displayname }
73
+ ).code == 200
74
+ end
75
+
76
+ # Sets account data for a user.
77
+ #
78
+ # @param user [String] The user to add the data to.
79
+ # @param type [String] The event type of `account_data` to set.
80
+ # @param data [Hash] The actual data to set.
81
+ # @return [Boolean] `true` if the account data was successfully set,
82
+ # otherwise `false`.
83
+ def set_data(user, type, data)
84
+ make_request(
85
+ :put,
86
+ "/user/#{user}/account_data/#{type}",
87
+ content: data
88
+ ).code == 200
89
+ end
90
+
91
+ # Sets account data for a user specific to a certain room.
92
+ #
93
+ # @param (see #set_data)
94
+ # @param room [String] The room to add the data in.
95
+ # @return [Boolean] `true` if the account data was successfully set
96
+ # in the specified room, otherwise `false`.
97
+ def set_room_data(user, room, type, data)
98
+ make_request(
99
+ :put,
100
+ "/user/#{user}/rooms/#{room}/account_data/#{type}",
101
+ content: data
102
+ ).code == 200
103
+ end
104
+
105
+ # Gets the presence list for a user.
106
+ #
107
+ # @param user [String] The user whose list to get.
108
+ # @return [Array] A list of presences for this user.
109
+ #
110
+ # @todo The official documentation on this endpoint is weird, what does
111
+ # this really do?
112
+ def get_presence_list(user)
113
+ make_request(:get, "/presence/list/#{user}").parsed_response
114
+ end
115
+
116
+ # Adds or removes users from a user's presence list.
117
+ #
118
+ # @param user [String] The user whose list to modify.
119
+ # @param data [Hash{String=>Array<String>}] Contains two arrays,
120
+ # `invite` and `drop`. Users listed in the `invite` array will be
121
+ # invited to join the presence list. Users listed in the `drop` array
122
+ # will be removed from the presence list.
123
+ # Note that both arrays are not required but at least one must be
124
+ # present.
125
+ # @return [Boolean] `true` if the list was successfully updated,
126
+ # otherwise `false`.
127
+ #
128
+ # @example Add and remove two users
129
+ # update_presence_list(
130
+ # '@me:home.org',
131
+ # {
132
+ # invite: ['@friend:home.org'],
133
+ # drop: ['@enemy:other.org']
134
+ # }
135
+ # )
136
+ def update_presence_list(user, data)
137
+ make_request(
138
+ :post,
139
+ "/presence/list/#{user}",
140
+ content: { presence_diff: data }
141
+ ).code == 200
142
+ end
143
+
144
+ # Gets the presence status of a user.
145
+ #
146
+ # @param user [String] The user to query.
147
+ # @return [Hash] Hash with information about the user's presence,
148
+ # contains information indicating if they are available and when
149
+ # they were last active.
150
+ def get_presence_status(user)
151
+ make_request(:get, "/presence/#{user}/status").parsed_response
152
+ end
153
+
154
+ # Updates the presence status of a user.
155
+ #
156
+ # @note Only the user for whom the {Matrix#access_token access_token} is
157
+ # valid for can have their presence updated.
158
+ #
159
+ # @param user [String] The user to update.
160
+ # @param status [String] The new status to set. Eg. `'online'`
161
+ # or `'offline'`.
162
+ # @param message [String,nil] If set,
163
+ # associates a message with the status.
164
+ # @return [Boolean] `true` if the presence was updated successfully,
165
+ # otherwise `false`.
166
+ def update_presence_status(user, status, message = nil)
167
+ content = { presenceState: { presence: status } }
168
+
169
+ content[:presenceState][:status_msg] = message if message
170
+
171
+ make_request(:put, "/presence/#{user}/status", content: content)
172
+ .code == 200
173
+ end
174
+ end
175
+ end
176
+ end