chatrix 1.0.0.pre → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,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