1 | # matrix-js-bot-sdk
|
2 |
|
3 | [![npm version](https://badge.fury.io/js/matrix-bot-sdk.svg)](https://www.npmjs.com/package/matrix-bot-sdk)
|
4 | [![TravisCI badge](https://travis-ci.org/turt2live/matrix-js-bot-sdk.svg?branch=master)](https://travis-ci.org/turt2live/matrix-js-bot-sdk)
|
5 |
|
6 | A lightweight version of the matrix-js-sdk intended for bots. For help and support, visit [#matrix-bot-sdk:t2bot.io](https://matrix.to/#/#matrix-bot-sdk:t2bot.io)
|
7 |
|
8 | # Installing
|
9 |
|
10 | This package can be found on [npm](https://www.npmjs.com):
|
11 | ```
|
12 | npm install matrix-bot-sdk
|
13 | ```
|
14 |
|
15 | # Quickstart Bot
|
16 |
|
17 | Here's an example of a very simple bot written using this library. It will auto-join rooms and respond to `!hello` as a command.
|
18 |
|
19 | ```typescript
|
20 | import {
|
21 | MatrixClient,
|
22 | SimpleFsStorageProvider,
|
23 | AutojoinRoomsMixin,
|
24 | RichReply,
|
25 | } from "matrix-bot-sdk";
|
26 |
|
27 | // where you would point a client to talk to a homeserver
|
28 | const homeserverUrl = "https://matrix.org";
|
29 |
|
30 | // see https://t2bot.io/docs/access_tokens
|
31 | const accessToken = "YourSecretAccessToken";
|
32 |
|
33 | // We'll want to make sure the bot doesn't have to do an initial sync every
|
34 | // time it restarts, so we need to prepare a storage provider. Here we use
|
35 | // a simple JSON database.
|
36 | const storage = new SimpleFsStorageProvider("hello-bot.json");
|
37 |
|
38 | // Now we can create the client and set it up to automatically join rooms.
|
39 | const client = new MatrixClient(homeserverUrl, accessToken, storage);
|
40 | AutojoinRoomsMixin.setupOnClient(client);
|
41 |
|
42 | // We also want to make sure we can receive events - this is where we will
|
43 | // handle our command.
|
44 | client.on("room.message", handleCommand);
|
45 |
|
46 | // Now that the client is all set up and the event handler is registered, start the
|
47 | // client up. This will start it syncing.
|
48 | client.start().then(() => console.log("Client started!"));
|
49 |
|
50 | // This is our event handler for dealing with the `!hello` command.
|
51 | async function handleCommand(roomId, event, client) {
|
52 | // Don't handle events that don't have contents (they were probably redacted)
|
53 | if (!event["content"]) return;
|
54 |
|
55 | // Don't handle non-text events
|
56 | if (event["content"]["msgtype"] !== "m.text") return;
|
57 |
|
58 | // We never send `m.text` messages so this isn't required, however this is
|
59 | // how you would filter out events sent by the bot itself.
|
60 | if (event["sender"] === await client.getUserId()) return;
|
61 |
|
62 | // Make sure that the event looks like a command we're expecting
|
63 | const body = event["content"]["body"];
|
64 | if (!body || !body.startsWith("!hello")) return;
|
65 |
|
66 | // If we've reached this point, we can safely execute the command. We'll
|
67 | // send a reply to the user's command saying "Hello World!".
|
68 | const replyBody = "Hello World!"; // we don't have any special styling to do.
|
69 | const reply = RichReply.createFor(roomId, event, replyBody, replyBody);
|
70 | reply["msgtype"] = "m.notice";
|
71 | client.sendMessage(roomId, reply);
|
72 | }
|
73 | ```
|
74 |
|
75 | # Usage
|
76 |
|
77 | ```typescript
|
78 | const MatrixClient = require("matrix-bot-sdk").MatrixClient;
|
79 | const AutojoinRoomsMixin = require("matrix-bot-sdk").AutojoinRoomsMixin;
|
80 |
|
81 | const client = new MatrixClient("https://matrix.org", "your_access_token_here");
|
82 | AutojoinRoomsMixin.setupOnClient(client);
|
83 |
|
84 | // To listen for room messages (m.room.message) only:
|
85 | client.on("room.message", (roomId, event) => {
|
86 | if (!event["content"]) return;
|
87 | console.log(event["sender"] + " says " + event["content"]["body"]);
|
88 |
|
89 | client.sendMessage(roomId, {
|
90 | "msgtype": "m.notice",
|
91 | "body": "hello!",
|
92 | });
|
93 |
|
94 | // or...
|
95 | client.sendNotice(roomId, "hello!");
|
96 | });
|
97 |
|
98 | // Or to listen for any event that happens in a room:
|
99 | client.on("room.event", (roomId, event) => {
|
100 | if (!event["content"]) return;
|
101 | console.log(event["sender"] + " sent " + event["type"]);
|
102 | });
|
103 |
|
104 | client.start().then(() => console.log("Client started!"));
|
105 | ```
|
106 |
|
107 | ## Rich replies
|
108 |
|
109 | To automatically process rich replies coming into the client:
|
110 | ```typescript
|
111 | const MatrixClient = require("matrix-bot-sdk").MatrixClient;
|
112 | const RichRepliesPreprocessor = require("matrix-bot-sdk").RichRepliesPreprocessor;
|
113 | const IRichReplyMetadata = require("matrix-bot-sdk").IRichReplyMetadata;
|
114 |
|
115 | const client = new MatrixClient("https://matrix.org", "your_access_token_here");
|
116 |
|
117 | // Set fetchRealEventContents to true to have the preprocessor get the real event
|
118 | client.addPreprocessor(new RichRepliesPreprocessor(fetchRealEventContents: false));
|
119 |
|
120 | // regular client usage here. When you encounter an event:
|
121 | const event = {/* from somewhere, such as on a room message */};
|
122 | if (event["mx_richreply"]) {
|
123 | const reply = <IRichReplyMetadata>event["mx_richreply"];
|
124 | console.log("The original event was " + reply.parentEventId + " and the text was " + reply.fallbackPlainBody);
|
125 | }
|
126 | ```
|
127 |
|
128 | To send a rich reply to an event:
|
129 | ```typescript
|
130 | const MatrixClient = require("matrix-bot-sdk").MatrixClient;
|
131 | const AutojoinRoomsMixin = require("matrix-bot-sdk").AutojoinRoomsMixin;
|
132 | const RichReply = require("matrix-bot-sdk").RichReply;
|
133 |
|
134 | const client = new MatrixClient("https://matrix.org", "your_access_token_here");
|
135 | AutojoinRoomsMixin.setupOnClient(client);
|
136 |
|
137 | client.on("room.message", (roomId, event) => {
|
138 | if (!event["content"]) return;
|
139 |
|
140 | const newEvent = RichReply.createFor(event, "Hello!", "<b>Hello!</b>");
|
141 | newEvent["msgtype"] = "m.notice";
|
142 | client.sendMessage(roomId, newEvent);
|
143 | });
|
144 |
|
145 | client.start().then(() => console.log("Client started!"));
|
146 | ```
|
147 |
|
148 |
|
149 | ### Application Services
|
150 |
|
151 | Application service support is an experimental feature of the SDK. This does things like Intent management, impersonation, and transaction handling on behalf of the application.
|
152 |
|
153 | You'll need to load your registration file from somewhere, however the fastest path is:
|
154 |
|
155 | ```javascript
|
156 | const Appservice = require("matrix-bot-sdk").Appservice;
|
157 |
|
158 | // The registration is of type AppserviceRegistration, also available from the matrix-bot-sdk
|
159 | const registration = {
|
160 | as_token: "YourTokenHere",
|
161 | hs_token: "YourTokenHere",
|
162 | sender_localpart: "_some_bridge",
|
163 | namespaces: {
|
164 | users: [
|
165 | {
|
166 | exclusive: true,
|
167 | regex: "@_some_bridge_.*",
|
168 | },
|
169 | ],
|
170 | rooms: [],
|
171 | aliases: [],
|
172 | },
|
173 | };
|
174 |
|
175 | // The options are of type AppserviceOptions, also available from the matrix-bot-sdk
|
176 | const options = {
|
177 | port: 9000,
|
178 | bindAddress: "0.0.0.0",
|
179 | homeserverName: "matrix.org",
|
180 | homeserverUrl: "https://matrix.org",
|
181 | };
|
182 |
|
183 | const appservice = new Appservice(options, registration);
|
184 | appservice.getIntent("_some_bridge_user").sendText("!somewhere:domain.com", "Hello world!");
|
185 |
|
186 | // or if you don't want to do your own parsing to figure out the user prefix:
|
187 | appservice.getIntentForSuffix("user").sendText("!somewhere:domain.com", "Hello world!");
|
188 | ```
|