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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f4d840405e59e950232bf4a82a906c7395d3c581
4
- data.tar.gz: 26d630e954f5cc66b8bdd9dd5f01132ef6ca84af
3
+ metadata.gz: d46105489cd9f2748b15ea3a650893af40baad6d
4
+ data.tar.gz: 03d5bc731429c298f6e1d3367efab623c3d34549
5
5
  SHA512:
6
- metadata.gz: bd3aa274eb0b3da53e24f8cfb95b354025513a421fd094172a912791de0962e171f9817906bb811bdc125047f415173c78a612ca7f9179bc1fc34ed710cf9e51
7
- data.tar.gz: 61275fb3232b31c24b3e0d215107655ecbd65d4836b04d97b3d8c6a79c7896100428f59a509eb1e27c863597c08dc2455e265e75d53b7543b67ef48cecb39306
6
+ metadata.gz: 6bd7b7098a58b632bf67e48cd5d4b7ae4685bcbb53c8876a7a210a3450980221f247b931803f434198c111d943f42cdd9d1b5d5aca7ee2b1ac88048277e9b619
7
+ data.tar.gz: 5a26a6d99f8d66905a50de48062eddd6880b176c7ca3ac61fbc574964651980d847ac25f9457d4c4775b7e04ff20832d31904bd7ef86d789b9310080db580723
data/.gitignore CHANGED
@@ -165,3 +165,6 @@ GitHub.sublime-settings
165
165
  ### Custom rules ###
166
166
  # Ignore access token file
167
167
  access_token.txt
168
+
169
+ # Ignore API dumps
170
+ dumps/
@@ -5,4 +5,10 @@ language: ruby
5
5
  rvm:
6
6
  - 2.3.1
7
7
 
8
+ bundler_args: --without development doc
9
+
8
10
  before_install: gem install bundler -v 1.12.5
11
+
12
+ addons:
13
+ code_climate:
14
+ repo_token: 97786ceac8f7388a6ac89408a63f98454678567c780deef82377f8e66b9f7cd6
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. Example usage:
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/
@@ -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
@@ -1,6 +1,7 @@
1
1
  require 'chatrix/version'
2
2
  require 'chatrix/errors'
3
3
  require 'chatrix/matrix'
4
+ require 'chatrix/client'
4
5
 
5
6
  # Encapsulates all gem functionality.
6
7
  module Chatrix
@@ -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