|
|
|
|
53
|
|
53
|
|
54
|
Now that we know what a room is, let's talk about what's passing inside of one. Earlier, I've been talking about messages, which are actually called "events". Technically speaking, a Matrix event is a JSON object that's sent in a room and dispatched to all other members of the room. It, of course, has an ID that's generated by the homeserver hosting the user who sent the message, taking the general form we saw earlier and the `$` sigil character. This JSON has metadata, such as a class name to identify different event types, an author, a creation timestamp, etc. It basically looks like this:
|
54
|
Now that we know what a room is, let's talk about what's passing inside of one. Earlier, I've been talking about messages, which are actually called "events". Technically speaking, a Matrix event is a JSON object that's sent in a room and dispatched to all other members of the room. It, of course, has an ID that's generated by the homeserver hosting the user who sent the message, taking the general form we saw earlier and the `$` sigil character. This JSON has metadata, such as a class name to identify different event types, an author, a creation timestamp, etc. It basically looks like this:
|
55
|
|
55
|
|
56
|
-{{< highlight json >}}
|
|
|
|
|
56
|
+{{< highlight json "lineos=table" >}}
|
57
|
{
|
57
|
{
|
58
|
"origin_server_ts": 1526072700313,
|
58
|
"origin_server_ts": 1526072700313,
|
59
|
"sender": "@Alice:matrix.alice.tld",
|
59
|
"sender": "@Alice:matrix.alice.tld",
|
|
|
|
|
107
|
|
107
|
|
108
|
The request body is a JSON which takes the following form:
|
108
|
The request body is a JSON which takes the following form:
|
109
|
|
109
|
|
110
|
-{{< highlight json >}}
|
|
|
|
|
110
|
+{{< highlight json "lineos=table" >}}
|
111
|
{
|
111
|
{
|
112
|
"username": "Alice",
|
112
|
"username": "Alice",
|
113
|
"password": "1L0v3M4tr!x",
|
113
|
"password": "1L0v3M4tr!x",
|
|
|
|
|
118
|
|
118
|
|
119
|
Fire this request. You'll now get a `401` status code along with some JSON, which looks like this:
|
119
|
Fire this request. You'll now get a `401` status code along with some JSON, which looks like this:
|
120
|
|
120
|
|
121
|
-{{< highlight json >}}
|
|
|
|
|
121
|
+{{< highlight json "lineos=table" >}}
|
122
|
{
|
122
|
{
|
123
|
"flows": [
|
123
|
"flows": [
|
124
|
{
|
124
|
{
|
|
|
|
|
139
|
|
139
|
|
140
|
Now, this enpoint uses a part of the spec called the [User-Interactive Authentication API](https://matrix.org/docs/spec/client_server/r0.3.0.html#user-interactive-authentication-api). This means that authentication can be seen as flows of consecutive stages. That's exactly what we have here: two flows, each containing one stage. This example is a very simple one, but it can get quite more complex, such as:
|
140
|
Now, this enpoint uses a part of the spec called the [User-Interactive Authentication API](https://matrix.org/docs/spec/client_server/r0.3.0.html#user-interactive-authentication-api). This means that authentication can be seen as flows of consecutive stages. That's exactly what we have here: two flows, each containing one stage. This example is a very simple one, but it can get quite more complex, such as:
|
141
|
|
141
|
|
142
|
-{{< highlight json >}}
|
|
|
|
|
142
|
+{{< highlight json "lineos=table" >}}
|
143
|
{
|
143
|
{
|
144
|
"flows": [
|
144
|
"flows": [
|
145
|
{
|
145
|
{
|
|
|
|
|
169
|
|
169
|
|
170
|
To register against this stage, we'll only add a few lines to our initial request's JSON:
|
170
|
To register against this stage, we'll only add a few lines to our initial request's JSON:
|
171
|
|
171
|
|
172
|
-{{< highlight json >}}
|
|
|
|
|
172
|
+{{< highlight json "lineos=table" >}}
|
173
|
{
|
173
|
{
|
174
|
"auth": {
|
174
|
"auth": {
|
175
|
"type": "m.login.dummy",
|
175
|
"type": "m.login.dummy",
|
|
|
|
|
182
|
|
182
|
|
183
|
Note that the value to the `session` property in the newly added `auth` object is the value from `sessions` taken from the homeserver's response to our intial request. This `auth` object will tell the homeserver that this request is a follow-up to the initial request, using the stage `m.login.dummy`. The homeserver will automatically recognise the flow we're using, and will succeed (because we use `m.login.dummy`), returning this JSON along with a `200` status code:
|
183
|
Note that the value to the `session` property in the newly added `auth` object is the value from `sessions` taken from the homeserver's response to our intial request. This `auth` object will tell the homeserver that this request is a follow-up to the initial request, using the stage `m.login.dummy`. The homeserver will automatically recognise the flow we're using, and will succeed (because we use `m.login.dummy`), returning this JSON along with a `200` status code:
|
184
|
|
184
|
|
185
|
-{{< highlight json >}}
|
|
|
|
|
185
|
+{{< highlight json "lineos=table" >}}
|
186
|
{
|
186
|
{
|
187
|
"access_token": "olic0yeVa1pore2Kie4Wohsh",
|
187
|
"access_token": "olic0yeVa1pore2Kie4Wohsh",
|
188
|
"device_id": "FOZLAWNKLD",
|
188
|
"device_id": "FOZLAWNKLD",
|
|
|
|
|
208
|
|
208
|
|
209
|
Before responding, the homeserver will create the room, fire a few state events in it (such as the initial `m.room.create` state event or a join event for your user). It should then respond with a `200` status code and a JSON body looking like this:
|
209
|
Before responding, the homeserver will create the room, fire a few state events in it (such as the initial `m.room.create` state event or a join event for your user). It should then respond with a `200` status code and a JSON body looking like this:
|
210
|
|
210
|
|
211
|
-{{< highlight json >}}
|
|
|
|
|
211
|
+{{< highlight json "lineos=table" >}}
|
212
|
{
|
212
|
{
|
213
|
"room_id": "!RtZiWTovChPysCUIgn:matrix.project.tld"
|
213
|
"room_id": "!RtZiWTovChPysCUIgn:matrix.project.tld"
|
214
|
}
|
214
|
}
|
|
|
|
|
222
|
|
222
|
|
223
|
The request should return a JSON array containing state events such as:
|
223
|
The request should return a JSON array containing state events such as:
|
224
|
|
224
|
|
225
|
-{{< highlight json >}}
|
|
|
|
|
225
|
+{{< highlight json "lineos=table" >}}
|
226
|
{
|
226
|
{
|
227
|
"age": 654742,
|
227
|
"age": 654742,
|
228
|
"content": {
|
228
|
"content": {
|
|
|
|
|
246
|
|
246
|
|
247
|
Let's create a `tld.project.foo` event with `bar` as its state key, and `{"baz": "qux"}` as its content. To achieve that, let's send a `PUT` request to `/_matrix/client/r0/rooms/!RtZiWTovChPysCUIgn:matrix.project.tld/state/tld.project.foo/bar?access_token=olic0yeVa1pore2Kie4Wohsh` (from which I've stripped the protocol scheme and FQDN so it doesn't appear too in the post) with the fillowing content:
|
247
|
Let's create a `tld.project.foo` event with `bar` as its state key, and `{"baz": "qux"}` as its content. To achieve that, let's send a `PUT` request to `/_matrix/client/r0/rooms/!RtZiWTovChPysCUIgn:matrix.project.tld/state/tld.project.foo/bar?access_token=olic0yeVa1pore2Kie4Wohsh` (from which I've stripped the protocol scheme and FQDN so it doesn't appear too in the post) with the fillowing content:
|
248
|
|
248
|
|
249
|
-{{< highlight json >}}
|
|
|
|
|
249
|
+{{< highlight json "lineos=table" >}}
|
250
|
{
|
250
|
{
|
251
|
"baz": "qux"
|
251
|
"baz": "qux"
|
252
|
}
|
252
|
}
|
|
|
|
|
256
|
|
256
|
|
257
|
If we retry the request we previously made to retrieve the whole room state, we can now see our event:
|
257
|
If we retry the request we previously made to retrieve the whole room state, we can now see our event:
|
258
|
|
258
|
|
259
|
-{{< highlight json >}}
|
|
|
|
|
259
|
+{{< highlight json "lineos=table" >}}
|
260
|
{
|
260
|
{
|
261
|
"age": 58357,
|
261
|
"age": 58357,
|
262
|
"content": {
|
262
|
"content": {
|
|
|
|
|
292
|
|
292
|
|
293
|
Inviting someone into a room is also quite simple, and only requires a `POST` request on the [`/_matrix/client/r0/rooms/{roomId}/invite`](https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-rooms-roomid-invite) endpoint. The request's body must contain the invited Matrix ID as such:
|
293
|
Inviting someone into a room is also quite simple, and only requires a `POST` request on the [`/_matrix/client/r0/rooms/{roomId}/invite`](https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-rooms-roomid-invite) endpoint. The request's body must contain the invited Matrix ID as such:
|
294
|
|
294
|
|
295
|
-{{< highlight json >}}
|
|
|
|
|
295
|
+{{< highlight json "lineos=table" >}}
|
296
|
{
|
296
|
{
|
297
|
"user_id": "@Bob:matrix.bob.tld"
|
297
|
"user_id": "@Bob:matrix.bob.tld"
|
298
|
}
|
298
|
}
|
|
|
|
|
304
|
|
304
|
|
305
|
In the next request on the [`/_matrix/client/r0/sync`](https://matrix.org/docs/spec/client_server/r0.3.0.html#get-matrix-client-r0-sync) he'll made, Bob will now see an `invite` object inside the `rooms` one contaning the invite Alice sent him, containing a few events including the invite event:
|
305
|
In the next request on the [`/_matrix/client/r0/sync`](https://matrix.org/docs/spec/client_server/r0.3.0.html#get-matrix-client-r0-sync) he'll made, Bob will now see an `invite` object inside the `rooms` one contaning the invite Alice sent him, containing a few events including the invite event:
|
306
|
|
306
|
|
307
|
-{{< highlight json >}}
|
|
|
|
|
307
|
+{{< highlight json "lineos=table" >}}
|
308
|
{
|
308
|
{
|
309
|
"invite": {
|
309
|
"invite": {
|
310
|
"!RtZiWTovChPysCUIgn:matrix.project.tld": {
|
310
|
"!RtZiWTovChPysCUIgn:matrix.project.tld": {
|