UNPKG

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