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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.travis.yml +6 -0
- data/Gemfile +19 -0
- data/README.md +79 -4
- data/chatrix.gemspec +1 -6
- data/lib/chatrix.rb +1 -0
- data/lib/chatrix/api/api_component.rb +21 -0
- data/lib/chatrix/api/media.rb +67 -0
- data/lib/chatrix/api/push.rb +107 -0
- data/lib/chatrix/api/room_actions.rb +267 -0
- data/lib/chatrix/api/rooms.rb +213 -0
- data/lib/chatrix/api/session.rb +154 -0
- data/lib/chatrix/api/users.rb +176 -0
- data/lib/chatrix/client.rb +98 -0
- data/lib/chatrix/components/admin.rb +58 -0
- data/lib/chatrix/components/messaging.rb +42 -0
- data/lib/chatrix/components/permissions.rb +55 -0
- data/lib/chatrix/components/state.rb +160 -0
- data/lib/chatrix/components/timeline.rb +50 -0
- data/lib/chatrix/errors.rb +75 -7
- data/lib/chatrix/events.rb +39 -0
- data/lib/chatrix/matrix.rb +138 -595
- data/lib/chatrix/message.rb +53 -0
- data/lib/chatrix/room.rb +93 -0
- data/lib/chatrix/rooms.rb +90 -0
- data/lib/chatrix/user.rb +109 -0
- data/lib/chatrix/users.rb +74 -0
- data/lib/chatrix/version.rb +1 -1
- metadata +30 -81
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d46105489cd9f2748b15ea3a650893af40baad6d
|
4
|
+
data.tar.gz: 03d5bc731429c298f6e1d3367efab623c3d34549
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bd7b7098a58b632bf67e48cd5d4b7ae4685bcbb53c8876a7a210a3450980221f247b931803f434198c111d943f42cdd9d1b5d5aca7ee2b1ac88048277e9b619
|
7
|
+
data.tar.gz: 5a26a6d99f8d66905a50de48062eddd6880b176c7ca3ac61fbc574964651980d847ac25f9457d4c4775b7e04ff20832d31904bd7ef86d789b9310080db580723
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -2,3 +2,22 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in ratrix.gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
gem 'pry', '~> 0.10'
|
8
|
+
end
|
9
|
+
|
10
|
+
group :test do
|
11
|
+
gem 'rake', '~> 11.0'
|
12
|
+
gem 'rspec', '~> 3.0'
|
13
|
+
gem 'codeclimate-test-reporter', '~> 0.5', require: false
|
14
|
+
end
|
15
|
+
|
16
|
+
group :development, :test do
|
17
|
+
gem 'rubocop', '~> 0.40.0'
|
18
|
+
end
|
19
|
+
|
20
|
+
group :doc do
|
21
|
+
gem 'yard', '~> 0.8'
|
22
|
+
gem 'redcarpet', '~> 3.3'
|
23
|
+
end
|
data/README.md
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
chatrix
|
2
2
|
=======
|
3
3
|
|
4
|
+
[![Gem version][gem-badge-img]][gem-badge]
|
5
|
+
[![Dependency status][gemnasium-img]][gemnasium]
|
6
|
+
[![Build status][travis-img]][travis]
|
7
|
+
[![Code climate][cc-img]][cc]
|
8
|
+
[![Coverage][coverage-img]][coverage]
|
9
|
+
[![Inline docs][inch-img]][inch]
|
10
|
+
|
4
11
|
A Ruby implementation of the [Matrix][matrix] API.
|
5
12
|
|
6
13
|
## License
|
@@ -27,9 +34,10 @@ Or install it yourself as:
|
|
27
34
|
$ gem install chatrix
|
28
35
|
|
29
36
|
## Usage
|
30
|
-
|
37
|
+
### Using the API class `Chatrix::Matrix`
|
31
38
|
This implementation is currently very basic and exposes all the endpoints
|
32
|
-
in the `Matrix` class
|
39
|
+
in the `Matrix` class and some sub-classes available as attributes on the
|
40
|
+
main `Matrix` class. Example usage:
|
33
41
|
|
34
42
|
```ruby
|
35
43
|
# Uses the standard matrix.org homeserver
|
@@ -37,14 +45,65 @@ api = Chatrix::Matrix.new 'my secret token'
|
|
37
45
|
|
38
46
|
# Join may raise ForbiddenError if client does not have permission
|
39
47
|
# to join the room
|
40
|
-
if id = api.join '#myroom:myserver.org'
|
41
|
-
api.send_message id, 'Hello everyone!'
|
48
|
+
if id = api.rooms.actions.join '#myroom:myserver.org'
|
49
|
+
api.rooms.actions.send_message id, 'Hello everyone!'
|
42
50
|
end
|
43
51
|
```
|
44
52
|
|
45
53
|
Currently there is no asynchronous calls or built-in handling of
|
46
54
|
rate-limiting.
|
47
55
|
|
56
|
+
All of the available endpoints *should* be available, if there are some
|
57
|
+
missing that are not deprecated in the official API docs, please open an
|
58
|
+
issue about it or add them yourself and submit a PR!
|
59
|
+
|
60
|
+
### Using the client class `Chatrix::Client`
|
61
|
+
The client class works as a wrapper around the raw API calls to make working
|
62
|
+
with the API a little easier. It uses the [`wisper`][wisper] gem to broadcast
|
63
|
+
state changes.
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
# When setting up with an access token, there is no way to obtain your own
|
67
|
+
# user ID through the API, so it has to be supplied manually.
|
68
|
+
client = Chatrix::Client.new 'my token', 'my user id'
|
69
|
+
|
70
|
+
# This will spawn a new thread that continously syncs against the homeserver
|
71
|
+
# to check for new events. It can be stopped by calling Client#stop_syncing.
|
72
|
+
client.start_syncing
|
73
|
+
|
74
|
+
# Set up a listener for when a message arrives
|
75
|
+
client.on(:room_message) do |room, message|
|
76
|
+
puts "(#{room}) #{message.sender}: #{message.body}"
|
77
|
+
end
|
78
|
+
|
79
|
+
# We can also listen to messages in a specific room by subscribing to the
|
80
|
+
# timeline of that room.
|
81
|
+
myroom = client.get_room '#myroom:myserver.org'
|
82
|
+
myroom.timeline.on(:message) do |room, message|
|
83
|
+
# Reply with a "Pong!" if someone sends a message starting
|
84
|
+
# with the word "ping", but don't reply to ourselves.
|
85
|
+
if message.body.match(/^\bping\b/i) && message.sender != client.me
|
86
|
+
room.messaging.send_message 'Pong!'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Permissions and room actions can be used with relative ease.
|
91
|
+
myroom.timeline.on(:message) do |room, message|
|
92
|
+
if message.body.match(/^!kickme$/i) && message.sender != client.me
|
93
|
+
if room.state.permissions.can? message.sender, :kick
|
94
|
+
room.admin.kick message.sender, 'They asked for it'
|
95
|
+
else
|
96
|
+
room.messaging.send_message "You do not have kick privileges, #{message.sender}"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
When subscribing to an event, make sure to
|
103
|
+
[not return inside the block][no-return-blocks].
|
104
|
+
|
105
|
+
*The client is currently a WIP.*
|
106
|
+
|
48
107
|
## Development
|
49
108
|
|
50
109
|
After checking out the repo, run `bin/setup` to install dependencies.
|
@@ -61,3 +120,19 @@ Bug reports and pull requests are welcome on [GitHub][issues].
|
|
61
120
|
[issues]: https://github.com/Sharparam/chatrix/issues
|
62
121
|
[matrix]: http://matrix.org
|
63
122
|
[license-url]: http://opensource.org/licenses/MIT
|
123
|
+
|
124
|
+
[gem-badge]: https://badge.fury.io/rb/chatrix
|
125
|
+
[gem-badge-img]: https://badge.fury.io/rb/chatrix.svg
|
126
|
+
[gemnasium]: https://gemnasium.com/github.com/Sharparam/chatrix
|
127
|
+
[gemnasium-img]: https://gemnasium.com/badges/github.com/Sharparam/chatrix.svg
|
128
|
+
[travis]: https://travis-ci.org/Sharparam/chatrix
|
129
|
+
[travis-img]: https://travis-ci.org/Sharparam/chatrix.svg?branch=master
|
130
|
+
[cc]: https://codeclimate.com/github/Sharparam/chatrix
|
131
|
+
[cc-img]: https://codeclimate.com/github/Sharparam/chatrix/badges/gpa.svg
|
132
|
+
[coverage]: https://codeclimate.com/github/Sharparam/chatrix/coverage
|
133
|
+
[coverage-img]: https://codeclimate.com/github/Sharparam/chatrix/badges/coverage.svg
|
134
|
+
[inch]: http://inch-ci.org/github/Sharparam/chatrix
|
135
|
+
[inch-img]: http://inch-ci.org/github/Sharparam/chatrix.svg?branch=master
|
136
|
+
|
137
|
+
[wisper]: https://github.com/krisleech/wisper
|
138
|
+
[no-return-blocks]: http://product.reverb.com/2015/02/28/the-strange-case-of-wisper-and-ruby-blocks-behaving-like-procs/
|
data/chatrix.gemspec
CHANGED
@@ -23,12 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.require_paths = ['lib']
|
24
24
|
|
25
25
|
spec.add_runtime_dependency 'httparty', '~> 0.13'
|
26
|
+
spec.add_runtime_dependency 'wisper', '~> 1.6'
|
26
27
|
|
27
28
|
spec.add_development_dependency 'bundler', '~> 1.12'
|
28
|
-
spec.add_development_dependency 'rake', '~> 10.0'
|
29
|
-
spec.add_development_dependency 'rspec', '~> 3.0'
|
30
|
-
spec.add_development_dependency 'pry', '~> 0.10'
|
31
|
-
spec.add_development_dependency 'yard', '~> 0.8'
|
32
|
-
spec.add_development_dependency 'redcarpet', '~> 3.3'
|
33
|
-
spec.add_development_dependency 'rubocop', '~> 0.40.0'
|
34
29
|
end
|
data/lib/chatrix.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Chatrix
|
2
|
+
module Api
|
3
|
+
# Wraps a matrix instance for use in calling API endpoints.
|
4
|
+
class ApiComponent
|
5
|
+
# Initializes a new ApiComponent instance.
|
6
|
+
def initialize(matrix)
|
7
|
+
@matrix = matrix
|
8
|
+
end
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
# Makes an API request using the underlying Matrix instance.
|
13
|
+
# @param args Parameters to pass to Matrix#make_request.
|
14
|
+
# @yield (see Matrix#make_request)
|
15
|
+
# @return (see Matrix#make_request)
|
16
|
+
def make_request(*args, &block)
|
17
|
+
@matrix.make_request(*args, &block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Chatrix
|
2
|
+
module Api
|
3
|
+
# Contains methods for accessing the media endpoints of a server.
|
4
|
+
class Media < ApiComponent
|
5
|
+
# API path for media operations.
|
6
|
+
#
|
7
|
+
# Because for some reason this one is different.
|
8
|
+
MEDIA_PATH = '/_matrix/media/r0'.freeze
|
9
|
+
|
10
|
+
# Initializes a new Media instance.
|
11
|
+
# @param matrix [Matrix] The matrix API instance.
|
12
|
+
def initialize(matrix)
|
13
|
+
super
|
14
|
+
@media_uri = @matrix.homeserver + MEDIA_PATH
|
15
|
+
end
|
16
|
+
|
17
|
+
# Download media from the server.
|
18
|
+
# @param server [String] The server component of an `mxc://` URL.
|
19
|
+
# @param id [String] The media ID of the `mxc://` URL (the path).
|
20
|
+
# @return [HTTParty::Response] The HTTParty response object for the
|
21
|
+
# request. Use the response object to inspect the returned data.
|
22
|
+
def download(server, id)
|
23
|
+
make_request(
|
24
|
+
:get,
|
25
|
+
"/download/#{server}/#{id}",
|
26
|
+
headers: { 'Accept' => '*/*' },
|
27
|
+
base: @media_uri
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Download the thumbnail for a media resource.
|
32
|
+
# @param server [String] The server component of an `mxc://` URL.
|
33
|
+
# @param id [String] The media ID of the `mxc://` URL (the path).
|
34
|
+
# @param width [Fixnum] Desired width of the thumbnail.
|
35
|
+
# @param height [Fixnum] Desired height of the thumbnail.
|
36
|
+
# @param method ['scale', 'crop'] Desired resizing method.
|
37
|
+
# @return [HTTParty::Response] The HTTParty response object for the
|
38
|
+
# request. Use the response object to inspect the returned data.
|
39
|
+
def get_thumbnail(server, id, width, height, method = 'scale')
|
40
|
+
make_request(
|
41
|
+
:get,
|
42
|
+
"/thumbnail/#{server}/#{id}",
|
43
|
+
headers: { 'Accept' => 'image/jpeg, image/png' },
|
44
|
+
params: { width: width, height: height, method: method },
|
45
|
+
base: @media_uri
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Uploads a new media file to the server.
|
50
|
+
# @param type [String] The `Content-Type` of the media being uploaded.
|
51
|
+
# @param path [String] Path to a file to upload.
|
52
|
+
# @return [String] The MXC URL for the uploaded object (`mxc://...`).
|
53
|
+
def upload(type, path)
|
54
|
+
File.open(path, 'r') do |file|
|
55
|
+
make_request(
|
56
|
+
:post, '/upload',
|
57
|
+
headers: {
|
58
|
+
'Content-Type' => type, 'Content-Length' => file.size.to_s,
|
59
|
+
'Transfer-Encoding' => 'chunked'
|
60
|
+
},
|
61
|
+
content: file, base: @media_uri
|
62
|
+
)['content_uri']
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Chatrix
|
2
|
+
module Api
|
3
|
+
# Contains methods for accessing the "push" endpoints on the server.
|
4
|
+
#
|
5
|
+
# Refer to the official documentation for more information about these.
|
6
|
+
class Push < ApiComponent
|
7
|
+
# Get all active pushers for the current user.
|
8
|
+
# @return [Hash] A list of pushers for the user.
|
9
|
+
def pushers
|
10
|
+
make_request(:get, '/pushers').parsed_response
|
11
|
+
end
|
12
|
+
|
13
|
+
# Add, remove, or modify pushers for the current user.
|
14
|
+
# @param pusher [Hash] Pusher information.
|
15
|
+
# @return [Boolean] `true` if the operation was carried out successfully,
|
16
|
+
# otherwise `false`.
|
17
|
+
def modify_pusher(pusher)
|
18
|
+
make_request(:post, '/pushers/set', content: pusher).code == 200
|
19
|
+
end
|
20
|
+
|
21
|
+
# Gets all the push rules defined for this user, optionally limited
|
22
|
+
# to a specific scope.
|
23
|
+
# @param scope [String,nil] If set, only rules within that scope will
|
24
|
+
# be returned.
|
25
|
+
# @return [Hash] A list of push rules for the user.
|
26
|
+
def get_rules(scope = nil)
|
27
|
+
path = scope ? "/pushrules/#{scope}" : '/pushrules'
|
28
|
+
make_request(:get, path).parsed_response
|
29
|
+
end
|
30
|
+
|
31
|
+
# Gets a specific rule.
|
32
|
+
#
|
33
|
+
# @param scope [String] The scope to access.
|
34
|
+
# @param kind [String] The kind of rule.
|
35
|
+
# @param id [String] The rule to get.
|
36
|
+
# @return [Hash] Details about the rule.
|
37
|
+
def get_rule(scope, kind, id)
|
38
|
+
make_request(:get, "/pushrules/#{scope}/#{kind}/#{id}").parsed_response
|
39
|
+
end
|
40
|
+
|
41
|
+
# Deletes a push rule.
|
42
|
+
#
|
43
|
+
# @param (see #get_rule)
|
44
|
+
# @param id [String] The rule ID to delete.
|
45
|
+
# @return [Boolean] `true` if the rule was deleted successfully,
|
46
|
+
# otherwise `false`.
|
47
|
+
def delete_rule(scope, kind, id)
|
48
|
+
make_request(:delete, "/pushrules/#{scope}/#{kind}/#{id}").code == 200
|
49
|
+
end
|
50
|
+
|
51
|
+
# Adds or change a push rule.
|
52
|
+
#
|
53
|
+
# @param (see #get_rule)
|
54
|
+
# @param id [String] The rule to add or change.
|
55
|
+
# @param opts [Hash{Symbol => String}] Additional options to pass in
|
56
|
+
# the query string. Note that only one of the options should be set.
|
57
|
+
#
|
58
|
+
# @option opts [String] :before Add this rule as the next-most
|
59
|
+
# important rule with respect to the rule specified here.
|
60
|
+
# @option opts [String] :after Add this rule as the next-less
|
61
|
+
# important rule with respect to the rule specified here.
|
62
|
+
#
|
63
|
+
# @return [Boolean] `true` if the operation was carried out successfully,
|
64
|
+
# otherwise `false`.
|
65
|
+
def add_rule(scope, kind, id, rule, opts = {})
|
66
|
+
path = "/pushrules/#{scope}/#{kind}/#{id}"
|
67
|
+
make_request(:put, path, params: opts, content: rule).code == 200
|
68
|
+
end
|
69
|
+
|
70
|
+
# Sets or modifies the actions for a rule.
|
71
|
+
#
|
72
|
+
# @param (see #get_rule)
|
73
|
+
# @param id [String] The rule ID to modify actions for.
|
74
|
+
# @param actions [Hash] Actions to perform when the conditions for
|
75
|
+
# this rule are met.
|
76
|
+
# @return [Boolean] `true` if the actions were modified successfully,
|
77
|
+
# otherwise `false`.
|
78
|
+
def set_actions(scope, kind, id, actions)
|
79
|
+
path = "/pushrules/#{scope}/#{kind}/#{id}/actions"
|
80
|
+
make_request(:put, path, content: actions).code == 200
|
81
|
+
end
|
82
|
+
|
83
|
+
# Sets the enabled state of a rule, the default is to enable it.
|
84
|
+
#
|
85
|
+
# @param (see #get_rule)
|
86
|
+
# @param id [String] The rule ID to modify the enable state for.
|
87
|
+
# @param enabled [Boolean] Whether to enable or disable the rule.
|
88
|
+
# @return [Boolean] `true` if the state was modified successfully,
|
89
|
+
# otherwise `false`.
|
90
|
+
def enable(scope, kind, id, enabled = true)
|
91
|
+
path = "/pushrules/#{scope}/#{kind}/#{id}/actions"
|
92
|
+
make_request(:put, path, content: { enabled: enabled }).code == 200
|
93
|
+
end
|
94
|
+
|
95
|
+
# Disable a push rule.
|
96
|
+
# This is essentially an alias for #enable with the last parameter
|
97
|
+
# as `false`.
|
98
|
+
#
|
99
|
+
# @param (see #get_rule)
|
100
|
+
# @param id [String] The rule ID to disable.
|
101
|
+
# @return [Boolean] `true` if the rule was disabled, otherwise `false`.
|
102
|
+
def disable(scope, kind, id)
|
103
|
+
enable(scope, kind, id, false)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,267 @@
|
|
1
|
+
module Chatrix
|
2
|
+
module Api
|
3
|
+
# Contains methods for performing actions on rooms.
|
4
|
+
class RoomActions < ApiComponent
|
5
|
+
# Initializes a new RoomActions instance.
|
6
|
+
# @param matrix [Matrix] The matrix API instance.
|
7
|
+
def initialize(matrix)
|
8
|
+
super
|
9
|
+
@transaction_id = 0
|
10
|
+
end
|
11
|
+
|
12
|
+
# Creates a new room on the server.
|
13
|
+
#
|
14
|
+
# @param data [Hash] Additional data to send when creating the room.
|
15
|
+
# None of these are required when creating a new room.
|
16
|
+
#
|
17
|
+
# @option data [Array<String>] :invite A list of user IDs to invite
|
18
|
+
# when the room has been created.
|
19
|
+
# @option data [String] :name A custom name to give the room.
|
20
|
+
# @option data ['public', 'private'] :visibility The visibility to
|
21
|
+
# create the room with.
|
22
|
+
# @option data [Array<Hash>] :invite_3pid A list of third-party
|
23
|
+
# ID objects to invite to the room.
|
24
|
+
# @option data [String] :topic A topic to set for the room.
|
25
|
+
# @option data ['public_chat', 'trusted_private_chat', 'private_chat']
|
26
|
+
# :preset Sets various state events based on a preset.
|
27
|
+
#
|
28
|
+
# * **`private_chat`**: `join_rules` is `invite`,
|
29
|
+
# `history_visibility` is `shared`.
|
30
|
+
# * **`trusted_private_chat`**: `join_rules` is `invite`,
|
31
|
+
# `history_visibility` is `shared`, all invited users get the
|
32
|
+
# same power level as the room creator.
|
33
|
+
# * **`public_chat`**: `join_rules` is `public`,
|
34
|
+
# `history_visibility` is `shared`.
|
35
|
+
# @option data [Hash{String => Object}] :creation_content Additional data
|
36
|
+
# to add to the `'m.room.create'` content.
|
37
|
+
# @option data [Array<Hash>] :initial_state A list of state events to
|
38
|
+
# set in the room.
|
39
|
+
# @option data [String] :room_alias_name The **localpart** of the alias
|
40
|
+
# to sets for this room. The localpart is the part of the alias
|
41
|
+
# between the "`#`" sign and the "`:host.tld`" ending part. In the
|
42
|
+
# alias `#hello:world.org`, the "`hello`" part is the localpart.
|
43
|
+
#
|
44
|
+
# @return [String] the ID of the created room.
|
45
|
+
#
|
46
|
+
# @example Create a room with an alias, name, and invited user
|
47
|
+
# id = create(
|
48
|
+
# room_alias_name: 'foobar',
|
49
|
+
# name: 'Foo Bar Baz!',
|
50
|
+
# invite: ['@silly:example.org']
|
51
|
+
# )
|
52
|
+
#
|
53
|
+
# puts "Room #{id} created!"
|
54
|
+
def create(data = {})
|
55
|
+
make_request(:post, '/createRoom', content: data)['room_id']
|
56
|
+
end
|
57
|
+
|
58
|
+
# Joins a room on the homeserver.
|
59
|
+
#
|
60
|
+
# @param room [String] The room to join.
|
61
|
+
# @param third_party_signed [Hash,nil] If provided, the homeserver must
|
62
|
+
# verify that it matches a pending `m.room.third_party_invite` event in
|
63
|
+
# the room, and perform key validity checking if required by the event.
|
64
|
+
# @return [String] The ID of the room that was joined is returned.
|
65
|
+
def join(room, third_party_signed = nil)
|
66
|
+
if third_party_signed
|
67
|
+
make_request(
|
68
|
+
:post,
|
69
|
+
"/join/#{room}",
|
70
|
+
content: { third_party_signed: third_party_signed }
|
71
|
+
)['room_id']
|
72
|
+
else
|
73
|
+
make_request(:post, "/join/#{room}")['room_id']
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# @overload invite(room, user)
|
78
|
+
# Invites a user to a room by ID.
|
79
|
+
# @param room [String] The room to invite the user to.
|
80
|
+
# @param user [String] The user ID to send the invite to.
|
81
|
+
# @return [Boolean] `true` if the user was successfully invited,
|
82
|
+
# otherwise `false`.
|
83
|
+
# @overload invite(room, data)
|
84
|
+
# Invites a user to a room by their 3PID information.
|
85
|
+
# @param room [String] The room to invite the user to.
|
86
|
+
# @param data [Hash] 3PID info for the user.
|
87
|
+
# @return [Boolean] `true` if the user was successfully invited,
|
88
|
+
# otherwise `false`.
|
89
|
+
def invite(room, data)
|
90
|
+
data = { user_id: data } if data.is_a? String
|
91
|
+
make_request(:post, "/rooms/#{room}/invite", content: data).code == 200
|
92
|
+
end
|
93
|
+
|
94
|
+
# Leaves a room (but does not forget about it).
|
95
|
+
#
|
96
|
+
# @param room [String] The room to leave.
|
97
|
+
# @return [Boolean] `true` if the room was left successfully,
|
98
|
+
# otherwise `false`.
|
99
|
+
def leave(room)
|
100
|
+
make_request(:post, "/rooms/#{room}/leave").code == 200
|
101
|
+
end
|
102
|
+
|
103
|
+
# Forgets about a room.
|
104
|
+
#
|
105
|
+
# @param room [String] The room to forget about.
|
106
|
+
# @return [Boolean] `true` if the room was forgotten successfully,
|
107
|
+
# otherwise `false`.
|
108
|
+
def forget(room)
|
109
|
+
make_request(:post, "/rooms/#{room}/forget").code == 200
|
110
|
+
end
|
111
|
+
|
112
|
+
# Kicks a user from a room.
|
113
|
+
#
|
114
|
+
# This does not ban the user, they can rejoin unless the room is
|
115
|
+
# invite-only, in which case they need a new invite to join back.
|
116
|
+
#
|
117
|
+
# @param room [String] The room to kick the user from.
|
118
|
+
# @param user [String] The user to kick.
|
119
|
+
# @param reason [String] The reason for the kick.
|
120
|
+
# @return [Boolean] `true` if the user was successfully kicked,
|
121
|
+
# otherwise `false`.
|
122
|
+
#
|
123
|
+
# @example Kicking an annoying user
|
124
|
+
# kick('#fun:matrix.org', '@anon:4chan.org', 'Bad cropping')
|
125
|
+
def kick(room, user, reason)
|
126
|
+
make_request(
|
127
|
+
:post,
|
128
|
+
"/rooms/#{room}/kick",
|
129
|
+
content: { reason: reason, user_id: user }
|
130
|
+
).code == 200
|
131
|
+
end
|
132
|
+
|
133
|
+
# Kicks and bans a user from a room.
|
134
|
+
#
|
135
|
+
# @param room [String] The room to ban the user from.
|
136
|
+
# @param user [String] The user to ban.
|
137
|
+
# @param reason [String] Reason why the ban was made.
|
138
|
+
# @return [Boolean] `true` if the ban was carried out successfully,
|
139
|
+
# otherwise `false`.
|
140
|
+
#
|
141
|
+
# @example Banning a spammer
|
142
|
+
# ban('#haven:matrix.org', '@spammer:spam.com', 'Spamming the room')
|
143
|
+
def ban(room, user, reason)
|
144
|
+
make_request(
|
145
|
+
:post,
|
146
|
+
"/rooms/#{room}/ban",
|
147
|
+
content: { reason: reason, user_id: user }
|
148
|
+
).code == 200
|
149
|
+
end
|
150
|
+
|
151
|
+
# Unbans a user from a room.
|
152
|
+
#
|
153
|
+
# @param room [String] The room to unban the user from.
|
154
|
+
# @param user [String] The user to unban.
|
155
|
+
# @return [Boolean] `true` if the user was successfully unbanned,
|
156
|
+
# otherwise `false`.
|
157
|
+
def unban(room, user)
|
158
|
+
make_request(:post, "/rooms/#{room}/unban", content: { user_id: user })
|
159
|
+
.code == 200
|
160
|
+
end
|
161
|
+
|
162
|
+
# Sends a message object to a room.
|
163
|
+
#
|
164
|
+
# @param room [String] The room to send to.
|
165
|
+
# @param content [Hash] The message content to send.
|
166
|
+
# @param type [String] The type of message to send.
|
167
|
+
# @return [String] The event ID of the sent message is returned.
|
168
|
+
# @see #send_message_type
|
169
|
+
# @see #send_message
|
170
|
+
# @see #send_emote
|
171
|
+
# @see #send_notice
|
172
|
+
# @see #send_html
|
173
|
+
def send_message_raw(room, content, type = 'm.room.message')
|
174
|
+
make_request(
|
175
|
+
:put,
|
176
|
+
"/rooms/#{room}/send/#{type}/#{@transaction_id += 1}",
|
177
|
+
content: content
|
178
|
+
)['event_id']
|
179
|
+
end
|
180
|
+
|
181
|
+
# A helper method to send a simple message construct.
|
182
|
+
#
|
183
|
+
# @param room [String] The room to send the message to.
|
184
|
+
# @param content [String] The message to send.
|
185
|
+
# @param type [String] The type of message this is.
|
186
|
+
# For example: `'m.text'`, `'m.notice'`, `'m.emote'`.
|
187
|
+
# @return (see #send_message_raw)
|
188
|
+
def send_message(room, content, type = 'm.text')
|
189
|
+
send_message_raw room, msgtype: type, body: content
|
190
|
+
end
|
191
|
+
|
192
|
+
# Sends a message formatted using HTML markup.
|
193
|
+
#
|
194
|
+
# The `body` field in the content will have the HTML stripped out, and is
|
195
|
+
# usually presented in clients that don't support the formatting.
|
196
|
+
#
|
197
|
+
# The `formatted_body` field in the content will contain the actual HTML
|
198
|
+
# formatted message (as passed to the `html` parameter).
|
199
|
+
#
|
200
|
+
# @param room [String] The room to send to.
|
201
|
+
# @param html [String] The HTML formatted text to send.
|
202
|
+
# @return (see #send_message_raw)
|
203
|
+
#
|
204
|
+
# @example Sending an HTML message
|
205
|
+
# send_html('#html:matrix.org',
|
206
|
+
# '<strong>Hello</strong> <em>world</em>!')
|
207
|
+
def send_html(room, html)
|
208
|
+
send_message_raw(
|
209
|
+
room,
|
210
|
+
msgtype: 'm.text',
|
211
|
+
format: 'org.matrix.custom.html',
|
212
|
+
body: html.gsub(%r{</?[^>]*?>}, ''), # TODO: Make this better
|
213
|
+
formatted_body: html
|
214
|
+
)
|
215
|
+
end
|
216
|
+
|
217
|
+
# Sends a message to the server informing it about a user having started
|
218
|
+
# or stopped typing.
|
219
|
+
#
|
220
|
+
# @param room [String] The affected room.
|
221
|
+
# @param user [String] The user that started or stopped typing.
|
222
|
+
# @param typing [Boolean] Whether the user is typing.
|
223
|
+
# @param duration [Fixnum] How long the user will be typing for
|
224
|
+
# (in milliseconds).
|
225
|
+
# @return [Boolean] `true` if the message sent successfully, otherwise
|
226
|
+
# `false`.
|
227
|
+
def send_typing(room, user, typing = true, duration = 30_000)
|
228
|
+
make_request(
|
229
|
+
:put,
|
230
|
+
"/rooms/#{room}/typing/#{user}",
|
231
|
+
content: { typingState: { typing: typing, timeout: duration } }
|
232
|
+
).code == 200
|
233
|
+
end
|
234
|
+
|
235
|
+
# Updates the marker for the given receipt type to point to the
|
236
|
+
# specified event.
|
237
|
+
#
|
238
|
+
# @param room [String] The room to update the receipt in.
|
239
|
+
# @param event [String] The new event to point the receipt to.
|
240
|
+
# @param type [String] The receipt type to update.
|
241
|
+
# @param data [Hash] Any additional data to attach to `content`.
|
242
|
+
# @return [Boolean] `true` if the receipt was successfully updated,
|
243
|
+
# otherwise `false`.
|
244
|
+
def set_receipt(room, event, type = 'm.read', data = {})
|
245
|
+
make_request(
|
246
|
+
:post,
|
247
|
+
"/rooms/#{room}/receipt/#{type}/#{event}",
|
248
|
+
content: data
|
249
|
+
).code == 200
|
250
|
+
end
|
251
|
+
|
252
|
+
# Redacts a room event from the server.
|
253
|
+
#
|
254
|
+
# @param room [String] The room to redact the event from.
|
255
|
+
# @param event [String] The event to redact.
|
256
|
+
# @param reason [String] The reason for redacting the event.
|
257
|
+
# @return [String] The ID for the redaction event.
|
258
|
+
def redact(room, event, reason)
|
259
|
+
make_request(
|
260
|
+
:put,
|
261
|
+
"/rooms/#{room}/redact/#{event}/#{@transaction_id += 1}",
|
262
|
+
content: { reason: reason }
|
263
|
+
)['event_id']
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|