diff --git a/examples/README.md b/examples/README.md
index 95de200..5eaf8cf 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -15,6 +15,8 @@ Build something cool with these nodes? Feel free to submit a pull request to sha
- [Respond to "image" with an uploaded image](#respond-to-image-with-an-uploaded-image)
- [Respond to "file" with an uploaded file](#respond-to-file-with-an-uploaded-file)
- [Respond to "react" with a reaction](#respond-to-react-with-a-reaction)
+- [Accept room invites from specific user](#accept-room-invites-from-specific-user)
+- [Leave room when someone says "bye"](#leave-room-when-someone-says-bye)
- [Remove messages containing "delete"](#remove-messages-containing-delete)
- [Respond to "users" with full list of server users](#respond-to-users-with-full-list-of-server-users)
- [Respond to "newroom" by creating new room and inviting user](#respond-to-newroom-by-creating-new-room-and-inviting-user)
@@ -113,6 +115,26 @@ Give a 👍 reaction when someone says "react"
+### Accept room invites from specific user
+
+[View JSON](accept-room-invites.json)
+
+Accept room invites from specific user.
+
+
+
+
+
+### Leave room when someone says bye
+
+[View JSON](leave-room-bye.json)
+
+Leave room when someone says "bye".
+
+
+
+
+
### Remove messages containing "delete"
[View JSON](delete-event.json)
diff --git a/examples/accept-room-invites.json b/examples/accept-room-invites.json
new file mode 100644
index 0000000..d853c6e
--- /dev/null
+++ b/examples/accept-room-invites.json
@@ -0,0 +1,94 @@
+[
+ {
+ "id": "64f76474ff7a3727",
+ "type": "matrix-room-invite",
+ "z": "f025a8b9fbd1b054",
+ "name": "",
+ "server": "8da0ef83f77f8e24",
+ "roomId": null,
+ "x": 270,
+ "y": 2380,
+ "wires": [
+ [
+ "22f6056fa5bc5bd0"
+ ]
+ ]
+ },
+ {
+ "id": "6d6f304a0a6342b8",
+ "type": "matrix-join-room",
+ "z": "f025a8b9fbd1b054",
+ "name": "",
+ "server": "8da0ef83f77f8e24",
+ "x": 770,
+ "y": 2380,
+ "wires": [
+ [
+ "1409ebb4a0e65663"
+ ],
+ [
+ "1409ebb4a0e65663"
+ ]
+ ]
+ },
+ {
+ "id": "22f6056fa5bc5bd0",
+ "type": "switch",
+ "z": "f025a8b9fbd1b054",
+ "name": "msg.userId == @skylord123:skylar.tech",
+ "property": "userId",
+ "propertyType": "msg",
+ "rules": [
+ {
+ "t": "eq",
+ "v": "@skylord123:skylar.tech",
+ "vt": "str"
+ }
+ ],
+ "checkall": "true",
+ "repair": false,
+ "outputs": 1,
+ "x": 520,
+ "y": 2380,
+ "wires": [
+ [
+ "6d6f304a0a6342b8"
+ ]
+ ]
+ },
+ {
+ "id": "043f74e6d76b1eb0",
+ "type": "comment",
+ "z": "f025a8b9fbd1b054",
+ "name": "Only accept room invites from specific user",
+ "info": "",
+ "x": 360,
+ "y": 2340,
+ "wires": []
+ },
+ {
+ "id": "1409ebb4a0e65663",
+ "type": "debug",
+ "z": "f025a8b9fbd1b054",
+ "name": "",
+ "active": true,
+ "tosidebar": true,
+ "console": false,
+ "tostatus": false,
+ "complete": "true",
+ "targetType": "full",
+ "statusVal": "",
+ "statusType": "auto",
+ "x": 910,
+ "y": 2380,
+ "wires": []
+ },
+ {
+ "id": "8da0ef83f77f8e24",
+ "type": "matrix-server-config",
+ "name": null,
+ "autoAcceptRoomInvites": false,
+ "enableE2ee": true,
+ "global": true
+ }
+]
\ No newline at end of file
diff --git a/examples/accept-room-invites.png b/examples/accept-room-invites.png
new file mode 100644
index 0000000..9ba8369
Binary files /dev/null and b/examples/accept-room-invites.png differ
diff --git a/examples/leave-room-bye.json b/examples/leave-room-bye.json
new file mode 100644
index 0000000..ba054a6
--- /dev/null
+++ b/examples/leave-room-bye.json
@@ -0,0 +1,103 @@
+[
+ {
+ "id": "997c354038202dba",
+ "type": "comment",
+ "z": "f025a8b9fbd1b054",
+ "name": "Leave room when someone says \"bye\"",
+ "info": "",
+ "x": 350,
+ "y": 2520,
+ "wires": []
+ },
+ {
+ "id": "69c4ea189be94feb",
+ "type": "matrix-receive",
+ "z": "f025a8b9fbd1b054",
+ "name": "",
+ "server": "8da0ef83f77f8e24",
+ "roomId": "",
+ "acceptText": true,
+ "acceptEmotes": true,
+ "acceptStickers": true,
+ "acceptReactions": true,
+ "acceptFiles": true,
+ "acceptAudio": true,
+ "acceptImages": true,
+ "acceptLocations": true,
+ "x": 280,
+ "y": 2560,
+ "wires": [
+ [
+ "19e1d64b63ae8a1f"
+ ]
+ ]
+ },
+ {
+ "id": "19e1d64b63ae8a1f",
+ "type": "switch",
+ "z": "f025a8b9fbd1b054",
+ "name": "msg.payload == bye",
+ "property": "payload",
+ "propertyType": "msg",
+ "rules": [
+ {
+ "t": "eq",
+ "v": "bye",
+ "vt": "str"
+ }
+ ],
+ "checkall": "true",
+ "repair": false,
+ "outputs": 1,
+ "x": 480,
+ "y": 2560,
+ "wires": [
+ [
+ "db0e51f8e7793f92"
+ ]
+ ]
+ },
+ {
+ "id": "db0e51f8e7793f92",
+ "type": "matrix-leave-room",
+ "z": "f025a8b9fbd1b054",
+ "name": "",
+ "server": "8da0ef83f77f8e24",
+ "roomId": null,
+ "x": 670,
+ "y": 2560,
+ "wires": [
+ [
+ "3791f551bf0e4fc4"
+ ],
+ [
+ "3791f551bf0e4fc4"
+ ]
+ ]
+ },
+ {
+ "id": "3791f551bf0e4fc4",
+ "type": "debug",
+ "z": "f025a8b9fbd1b054",
+ "name": "",
+ "active": true,
+ "tosidebar": true,
+ "console": false,
+ "tostatus": false,
+ "complete": "true",
+ "targetType": "full",
+ "statusVal": "",
+ "statusType": "auto",
+ "x": 810,
+ "y": 2560,
+ "wires": []
+ },
+ {
+ "id": "8da0ef83f77f8e24",
+ "type": "matrix-server-config",
+ "name": null,
+ "autoAcceptRoomInvites": false,
+ "enableE2ee": true,
+ "global": true
+ }
+]
\ No newline at end of file
diff --git a/examples/leave-room-bye.png b/examples/leave-room-bye.png
new file mode 100644
index 0000000..7ad5cdf
Binary files /dev/null and b/examples/leave-room-bye.png differ
diff --git a/package.json b/package.json
index fe6ba09..789f9a5 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,9 @@
"matrix-react": "src/matrix-react.js",
"matrix-create-room": "src/matrix-create-room.js",
"matrix-invite-room": "src/matrix-invite-room.js",
+ "matrix-room-invite": "src/matrix-room-invite.js",
"matrix-join-room": "src/matrix-join-room.js",
+ "matrix-leave-room": "src/matrix-leave-room.js",
"matrix-crypt-file": "src/matrix-crypt-file.js",
"matrix-room-kick": "src/matrix-room-kick.js",
"matrix-room-ban": "src/matrix-room-ban.js",
diff --git a/src/matrix-invite-room.html b/src/matrix-invite-room.html
index 1294d16..20f49d1 100644
--- a/src/matrix-invite-room.html
+++ b/src/matrix-invite-room.html
@@ -12,9 +12,9 @@
roomId: { value: null },
},
label: function() {
- return this.name || "Room Invite";
+ return this.name || "Invite to Room";
},
- paletteLabel: 'Room Invite'
+ paletteLabel: 'Invite to Room'
});
diff --git a/src/matrix-leave-room.html b/src/matrix-leave-room.html
new file mode 100644
index 0000000..4795c66
--- /dev/null
+++ b/src/matrix-leave-room.html
@@ -0,0 +1,63 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/matrix-leave-room.js b/src/matrix-leave-room.js
new file mode 100644
index 0000000..f69877d
--- /dev/null
+++ b/src/matrix-leave-room.js
@@ -0,0 +1,54 @@
+module.exports = function(RED) {
+ function MatrixLeaveRoom(n) {
+ RED.nodes.createNode(this, n);
+
+ let node = this;
+
+ this.name = n.name;
+ this.server = RED.nodes.getNode(n.server);
+ this.roomId = n.roomId;
+
+ node.status({ fill: "red", shape: "ring", text: "disconnected" });
+
+ if (!node.server) {
+ node.error("No configuration node");
+ return;
+ }
+
+ node.server.on("disconnected", function(){
+ node.status({ fill: "red", shape: "ring", text: "disconnected" });
+ });
+
+ node.server.on("connected", function() {
+ node.status({ fill: "green", shape: "ring", text: "connected" });
+ });
+
+ node.on('input', function(msg) {
+ if (! node.server || ! node.server.matrixClient) {
+ node.error("No matrix server selected");
+ return;
+ }
+
+ if(!msg.topic) {
+ node.error('No room provided in msg.topic');
+ return;
+ }
+
+ if(!node.server.isConnected()) {
+ node.error("Matrix server connection is currently closed");
+ node.send([null, msg]);
+ }
+
+ try {
+ node.log("Leaving room " + msg.topic);
+ node.server.matrixClient.leave(msg.topic);
+ node.send([msg, null]);
+ } catch(e) {
+ node.error("Failed to leave room " + msg.topic + ": " + e);
+ msg.payload = e;
+ node.send([null, msg]);
+ }
+ });
+ }
+ RED.nodes.registerType("matrix-leave-room", MatrixLeaveRoom);
+}
\ No newline at end of file
diff --git a/src/matrix-receive.js b/src/matrix-receive.js
index 27c7ce9..f69225b 100644
--- a/src/matrix-receive.js
+++ b/src/matrix-receive.js
@@ -32,12 +32,6 @@ module.exports = function(RED) {
node.status({ fill: "green", shape: "ring", text: "connected" });
});
-
- node.server.on("Room.invite", async function(msg) {
- node.send(msg);
- });
-
-
node.server.on("Room.timeline", async function(event, room, toStartOfTimeline, removed, data, msg) {
// if node has a room ID set we only listen on that room
if(node.roomIds.length && node.roomIds.indexOf(room.roomId) === -1) {
diff --git a/src/matrix-room-invite.html b/src/matrix-room-invite.html
new file mode 100644
index 0000000..79c9c39
--- /dev/null
+++ b/src/matrix-room-invite.html
@@ -0,0 +1,80 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/matrix-room-invite.js b/src/matrix-room-invite.js
new file mode 100644
index 0000000..9c7edf5
--- /dev/null
+++ b/src/matrix-room-invite.js
@@ -0,0 +1,31 @@
+module.exports = function(RED) {
+ function MatrixRoomInvite(n) {
+ RED.nodes.createNode(this, n);
+
+ let node = this;
+
+ this.name = n.name;
+ this.server = RED.nodes.getNode(n.server);
+ this.roomId = n.roomId;
+
+ if(!this.server) {
+ node.error('Server must be configured on the node.');
+ return;
+ }
+
+ node.status({ fill: "red", shape: "ring", text: "disconnected" });
+
+ node.server.on("disconnected", function(){
+ node.status({ fill: "red", shape: "ring", text: "disconnected" });
+ });
+
+ node.server.on("connected", function() {
+ node.status({ fill: "green", shape: "ring", text: "connected" });
+ });
+
+ node.server.on("Room.invite", async function(msg) {
+ node.send(msg);
+ });
+ }
+ RED.nodes.registerType("matrix-room-invite", MatrixRoomInvite);
+}
\ No newline at end of file
diff --git a/src/matrix-server-config.js b/src/matrix-server-config.js
index 61ea712..0bf3e30 100644
--- a/src/matrix-server-config.js
+++ b/src/matrix-server-config.js
@@ -251,23 +251,30 @@ module.exports = function(RED) {
// handle auto-joining rooms
node.matrixClient.on(RoomMemberEvent.Membership, async function(event, member) {
+ if(node.initializedAt > event.getDate()) {
+ return; // skip events that occurred before our client initialized
+ }
+
if (member.membership === "invite" && member.userId === node.userId) {
+ node.log("Got invite to join room " + member.roomId);
+ console.log(event);
if(node.autoAcceptRoomInvites) {
node.matrixClient.joinRoom(member.roomId).then(function() {
node.log("Automatically accepted invitation to join room " + member.roomId);
}).catch(function(e) {
node.warn("Cannot join room (could be from being kicked/banned) " + member.roomId + ": " + e);
});
- } else {
- node.log("Got invite to join room " + member.roomId);
- let msg = {
- type : 'r.invite',
- payload : 'Invitation',
- userId : member.userId,
- topic : member.roomId
- };
- node.emit("Room.invite", msg);
}
+
+ let room = node.matrixClient.getRoom(event.getRoomId());
+ node.emit("Room.invite", {
+ type : 'm.room.member',
+ userId : event.getSender(),
+ topic : event.getRoomId(),
+ topicName : (room ? room.name : null) || null,
+ event : event,
+ eventId : event.getId(),
+ });
}
});