189 lines
3.6 KiB
JavaScript
189 lines
3.6 KiB
JavaScript
// wrapper around matrix-js-sdk for easier bot development
|
|
// inspired by discord.js
|
|
|
|
const EventEmitter = require("events");
|
|
const sdk = require("matrix-js-sdk");
|
|
|
|
class User {
|
|
constructor(client, id) {
|
|
this._client = client;
|
|
this.id = id;
|
|
}
|
|
|
|
get avatar() {
|
|
return this._client.getUser(this.id).avatarUrl;
|
|
}
|
|
|
|
get name() {
|
|
return this._client.getUser(this.id).displayName;
|
|
}
|
|
}
|
|
|
|
class Member extends User {
|
|
constructor(client, id, room) {
|
|
super(client, id);
|
|
this._room = room;
|
|
}
|
|
|
|
get room() {
|
|
return new Room(this._client, this._room);
|
|
}
|
|
|
|
get membership() {
|
|
return this.room._state.members[this.id].membership;
|
|
}
|
|
|
|
kick(reason) {
|
|
return this._client.kick(this._room, this.id, reason);
|
|
}
|
|
|
|
ban(reason) {
|
|
return this._client.ban(this._room, this.id, reason);
|
|
}
|
|
|
|
unban() {
|
|
return this._client.unban(this._room, this.id);
|
|
}
|
|
|
|
getPower() {
|
|
return this.room._state.members[this.id].powerLevel;
|
|
}
|
|
|
|
setPower(level) {
|
|
const event = this.room._state.getStateEvents('m.room.power_levels')[0];
|
|
return this._client.setPowerLevel(this.room.id, this.id, level, event);
|
|
}
|
|
}
|
|
|
|
class Room {
|
|
constructor(client, id) {
|
|
this._client = client;
|
|
this.id = id;
|
|
}
|
|
|
|
get _state() {
|
|
return this._client.getRoom(this.id).currentState;
|
|
}
|
|
|
|
get name() {
|
|
return this._client.getRoom(this.id).name;
|
|
}
|
|
|
|
send(content) {
|
|
return this._client.sendMessage(this.id, null, {
|
|
body: content,
|
|
});
|
|
}
|
|
|
|
invite(who) {
|
|
return this._client.invite(this.id, who instanceof User ? who.id : who);
|
|
}
|
|
|
|
join() {
|
|
return this._client.joinRoom(this.id);
|
|
}
|
|
|
|
setName(name) {
|
|
return this._client.setRoomName(this.id, name);
|
|
}
|
|
}
|
|
|
|
class Event {
|
|
constructor(client, event) {
|
|
this._client = client;
|
|
this._event = event;
|
|
}
|
|
|
|
get id() {
|
|
return this._event.getId();
|
|
}
|
|
|
|
get room() {
|
|
return new Room(this._client, this._event.getRoomId());
|
|
}
|
|
|
|
get author() {
|
|
return new Member(this._client, this._event.getSender(), this._event.getRoomId());
|
|
}
|
|
}
|
|
|
|
class Message extends Event {
|
|
constructor(client, event) {
|
|
super(client, event);
|
|
}
|
|
|
|
get content() {
|
|
return this._event.getContent().body;
|
|
}
|
|
|
|
redact() {
|
|
return this._client.redactEvent(this.room.id, this.id);
|
|
}
|
|
|
|
reply(content) {
|
|
return this._client.sendMessage(this.room.id, null, {
|
|
body: content,
|
|
"m.relates_to": { "m.in_reply_to": { event_id: this.id } },
|
|
});
|
|
}
|
|
|
|
relations() {
|
|
return this._client.fetchRelations(this.room.id, this.id);
|
|
}
|
|
}
|
|
|
|
class Bot extends EventEmitter {
|
|
constructor(options) {
|
|
super();
|
|
|
|
this._client = sdk.createClient(options);
|
|
this._ready = false;
|
|
|
|
this._client.on("Room.timeline", (event, room, toStartOfTimeline) => {
|
|
if (!this._ready) return;
|
|
if (toStartOfTimeline) return;
|
|
switch (event.getType()) {
|
|
case "m.room.message":
|
|
return this.emit("message", new Message(this._client, event));
|
|
};
|
|
});
|
|
|
|
this._client.on("Room.redaction", (event) => {
|
|
if (!this._ready) return;
|
|
return this.emit("redact", new Message(this._client, event));
|
|
});
|
|
|
|
this._client.on("RoomMember.membership", (event, member) => {
|
|
if (!this._ready) return;
|
|
return this.emit(member.membership, new Member(this._client, member.userId, member.roomId), new Room(this._client, member.roomId));
|
|
});
|
|
}
|
|
|
|
get id() {
|
|
return this._client.getUserId();
|
|
}
|
|
|
|
getRooms() {
|
|
return this._client
|
|
.getRooms()
|
|
.map(room => new Room(this._client, room.roomId));
|
|
}
|
|
|
|
getRoom(id) {
|
|
return new Room(this._client, id));
|
|
}
|
|
|
|
async start() {
|
|
this._client.once("sync", (state) => {
|
|
if(state === 'PREPARED') {
|
|
this._ready = true;
|
|
this.emit("ready");
|
|
} else {
|
|
throw "failed to start: " + state;
|
|
}
|
|
});
|
|
this._client.startClient({ initialSyncLimit: 0 });
|
|
}
|
|
}
|
|
|
|
module.exports = Bot;
|