UNPKG

10.9 kBMarkdownView Raw
1Matrix Javascript SDK
2=====================
3
4This is the [Matrix](https://matrix.org) Client-Server r0 SDK for
5JavaScript. This SDK can be run in a browser or in Node.js.
6
7Quickstart
8==========
9
10In a browser
11------------
12Download either the full or minified version from
13https://github.com/matrix-org/matrix-js-sdk/releases/latest and add that as a
14``<script>`` to your page. There will be a global variable ``matrixcs``
15attached to ``window`` through which you can access the SDK. See below for how to
16include libolm to enable end-to-end-encryption.
17
18Please check [the working browser example](examples/browser) for more information.
19
20In Node.js
21----------
22
23Ensure you have the latest LTS version of Node.js installed.
24
25Using `yarn` instead of `npm` is recommended. Please see the Yarn [install guide](https://yarnpkg.com/docs/install/) if you do not have it already.
26
27``yarn add matrix-js-sdk``
28
29```javascript
30 var sdk = require("matrix-js-sdk");
31 var client = sdk.createClient("https://matrix.org");
32 client.publicRooms(function(err, data) {
33 console.log("Public Rooms: %s", JSON.stringify(data));
34 });
35```
36
37See below for how to include libolm to enable end-to-end-encryption. Please check
38[the Node.js terminal app](examples/node) for a more complex example.
39
40To start the client:
41
42```javascript
43await client.startClient({initialSyncLimit: 10});
44```
45
46You can perform a call to `/sync` to get the current state of the client:
47
48```javascript
49client.once('sync', function(state, prevState, res) {
50 if(state === 'PREPARED') {
51 console.log("prepared");
52 } else {
53 console.log(state);
54 process.exit(1);
55 }
56});
57```
58
59To send a message:
60
61```javascript
62var content = {
63 "body": "message text",
64 "msgtype": "m.text"
65};
66client.sendEvent("roomId", "m.room.message", content, "", (err, res) => {
67 console.log(err);
68});
69```
70
71To listen for message events:
72
73```javascript
74client.on("Room.timeline", function(event, room, toStartOfTimeline) {
75 if (event.getType() !== "m.room.message") {
76 return; // only use messages
77 }
78 console.log(event.event.content.body);
79});
80```
81
82By default, the `matrix-js-sdk` client uses the `MemoryStore` to store events as they are received. For example to iterate through the currently stored timeline for a room:
83
84```javascript
85Object.keys(client.store.rooms).forEach((roomId) => {
86 client.getRoom(roomId).timeline.forEach(t => {
87 console.log(t.event);
88 });
89});
90```
91
92What does this SDK do?
93----------------------
94
95This SDK provides a full object model around the Matrix Client-Server API and emits
96events for incoming data and state changes. Aside from wrapping the HTTP API, it:
97 - Handles syncing (via `/initialSync` and `/events`)
98 - Handles the generation of "friendly" room and member names.
99 - Handles historical `RoomMember` information (e.g. display names).
100 - Manages room member state across multiple events (e.g. it handles typing, power
101 levels and membership changes).
102 - Exposes high-level objects like `Rooms`, `RoomState`, `RoomMembers` and `Users`
103 which can be listened to for things like name changes, new messages, membership
104 changes, presence changes, and more.
105 - Handle "local echo" of messages sent using the SDK. This means that messages
106 that have just been sent will appear in the timeline as 'sending', until it
107 completes. This is beneficial because it prevents there being a gap between
108 hitting the send button and having the "remote echo" arrive.
109 - Mark messages which failed to send as not sent.
110 - Automatically retry requests to send messages due to network errors.
111 - Automatically retry requests to send messages due to rate limiting errors.
112 - Handle queueing of messages.
113 - Handles pagination.
114 - Handle assigning push actions for events.
115 - Handles room initial sync on accepting invites.
116 - Handles WebRTC calling.
117
118Later versions of the SDK will:
119 - Expose a `RoomSummary` which would be suitable for a recents page.
120 - Provide different pluggable storage layers (e.g. local storage, database-backed)
121
122Usage
123=====
124
125
126Conventions
127-----------
128
129### Emitted events
130
131The SDK will emit events using an ``EventEmitter``. It also
132emits object models (e.g. ``Rooms``, ``RoomMembers``) when they
133are updated.
134
135```javascript
136 // Listen for low-level MatrixEvents
137 client.on("event", function(event) {
138 console.log(event.getType());
139 });
140
141 // Listen for typing changes
142 client.on("RoomMember.typing", function(event, member) {
143 if (member.typing) {
144 console.log(member.name + " is typing...");
145 }
146 else {
147 console.log(member.name + " stopped typing.");
148 }
149 });
150
151 // start the client to setup the connection to the server
152 client.startClient();
153```
154
155### Promises and Callbacks
156
157Most of the methods in the SDK are asynchronous: they do not directly return a
158result, but instead return a [Promise](http://documentup.com/kriskowal/q/)
159which will be fulfilled in the future.
160
161The typical usage is something like:
162
163```javascript
164 matrixClient.someMethod(arg1, arg2).done(function(result) {
165 ...
166 });
167```
168
169Alternatively, if you have a Node.js-style ``callback(err, result)`` function,
170you can pass the result of the promise into it with something like:
171
172```javascript
173 matrixClient.someMethod(arg1, arg2).nodeify(callback);
174```
175
176The main thing to note is that it is an error to discard the result of a
177promise-returning function, as that will cause exceptions to go unobserved. If
178you have nothing better to do with the result, just call ``.done()`` on it. See
179http://documentup.com/kriskowal/q/#the-end for more information.
180
181Methods which return a promise show this in their documentation.
182
183Many methods in the SDK support *both* Node.js-style callbacks *and* Promises,
184via an optional ``callback`` argument. The callback support is now deprecated:
185new methods do not include a ``callback`` argument, and in the future it may be
186removed from existing methods.
187
188Examples
189--------
190This section provides some useful code snippets which demonstrate the
191core functionality of the SDK. These examples assume the SDK is setup like this:
192
193```javascript
194 var sdk = require("matrix-js-sdk");
195 var myUserId = "@example:localhost";
196 var myAccessToken = "QGV4YW1wbGU6bG9jYWxob3N0.qPEvLuYfNBjxikiCjP";
197 var matrixClient = sdk.createClient({
198 baseUrl: "http://localhost:8008",
199 accessToken: myAccessToken,
200 userId: myUserId
201 });
202```
203
204### Automatically join rooms when invited
205
206```javascript
207 matrixClient.on("RoomMember.membership", function(event, member) {
208 if (member.membership === "invite" && member.userId === myUserId) {
209 matrixClient.joinRoom(member.roomId).done(function() {
210 console.log("Auto-joined %s", member.roomId);
211 });
212 }
213 });
214
215 matrixClient.startClient();
216```
217
218### Print out messages for all rooms
219
220```javascript
221 matrixClient.on("Room.timeline", function(event, room, toStartOfTimeline) {
222 if (toStartOfTimeline) {
223 return; // don't print paginated results
224 }
225 if (event.getType() !== "m.room.message") {
226 return; // only print messages
227 }
228 console.log(
229 // the room name will update with m.room.name events automatically
230 "(%s) %s :: %s", room.name, event.getSender(), event.getContent().body
231 );
232 });
233
234 matrixClient.startClient();
235```
236
237Output:
238```
239 (My Room) @megan:localhost :: Hello world
240 (My Room) @megan:localhost :: how are you?
241 (My Room) @example:localhost :: I am good
242 (My Room) @example:localhost :: change the room name
243 (My New Room) @megan:localhost :: done
244```
245
246### Print out membership lists whenever they are changed
247
248```javascript
249 matrixClient.on("RoomState.members", function(event, state, member) {
250 var room = matrixClient.getRoom(state.roomId);
251 if (!room) {
252 return;
253 }
254 var memberList = state.getMembers();
255 console.log(room.name);
256 console.log(Array(room.name.length + 1).join("=")); // underline
257 for (var i = 0; i < memberList.length; i++) {
258 console.log(
259 "(%s) %s",
260 memberList[i].membership,
261 memberList[i].name
262 );
263 }
264 });
265
266 matrixClient.startClient();
267```
268
269Output:
270```
271 My Room
272 =======
273 (join) @example:localhost
274 (leave) @alice:localhost
275 (join) Bob
276 (invite) @charlie:localhost
277```
278
279API Reference
280=============
281
282A hosted reference can be found at
283http://matrix-org.github.io/matrix-js-sdk/index.html
284
285This SDK uses JSDoc3 style comments. You can manually build and
286host the API reference from the source files like this:
287
288```
289 $ yarn gendoc
290 $ cd .jsdoc
291 $ python -m SimpleHTTPServer 8005
292```
293
294Then visit ``http://localhost:8005`` to see the API docs.
295
296End-to-end encryption support
297=============================
298
299The SDK supports end-to-end encryption via the Olm and Megolm protocols, using
300[libolm](https://gitlab.matrix.org/matrix-org/olm). It is left up to the
301application to make libolm available, via the ``Olm`` global.
302
303It is also necessry to call ``matrixClient.initCrypto()`` after creating a new
304``MatrixClient`` (but **before** calling ``matrixClient.startClient()``) to
305initialise the crypto layer.
306
307If the ``Olm`` global is not available, the SDK will show a warning, as shown
308below; ``initCrypto()`` will also fail.
309
310```
311Unable to load crypto module: crypto will be disabled: Error: global.Olm is not defined
312```
313
314If the crypto layer is not (successfully) initialised, the SDK will continue to
315work for unencrypted rooms, but it will not support the E2E parts of the Matrix
316specification.
317
318To provide the Olm library in a browser application:
319
320 * download the transpiled libolm (from https://packages.matrix.org/npm/olm/).
321 * load ``olm.js`` as a ``<script>`` *before* ``browser-matrix.js``.
322
323To provide the Olm library in a node.js application:
324
325 * ``yarn add https://packages.matrix.org/npm/olm/olm-3.1.4.tgz``
326 (replace the URL with the latest version you want to use from
327 https://packages.matrix.org/npm/olm/)
328 * ``global.Olm = require('olm');`` *before* loading ``matrix-js-sdk``.
329
330If you want to package Olm as dependency for your node.js application, you can
331use ``yarn add https://packages.matrix.org/npm/olm/olm-3.1.4.tgz``. If your
332application also works without e2e crypto enabled, add ``--optional`` to mark it
333as an optional dependency.
334
335
336Contributing
337============
338*This section is for people who want to modify the SDK. If you just
339want to use this SDK, skip this section.*
340
341First, you need to pull in the right build tools:
342```
343 $ yarn install
344```
345
346Building
347--------
348
349To build a browser version from scratch when developing::
350```
351 $ yarn build
352```
353
354To constantly do builds when files are modified (using ``watchify``)::
355```
356 $ yarn watch
357```
358
359To run tests (Jasmine)::
360```
361 $ yarn test
362```
363
364To run linting:
365```
366 $ yarn lint
367```