+ It's recommended to use m.notice for bots because the message will render in a lighter text (at least in Element client) for users to distinguish bot and real user messages.
+
+
+
+
+ Message Format
+
+
Must be a valid MIME Type
@@ -48,34 +62,35 @@
\ No newline at end of file
diff --git a/src/matrix-send-message.js b/src/matrix-send-message.js
index 98eea3d..3d929d0 100644
--- a/src/matrix-send-message.js
+++ b/src/matrix-send-message.js
@@ -7,7 +7,44 @@ module.exports = function(RED) {
this.name = n.name;
this.server = RED.nodes.getNode(n.server);
this.roomId = n.roomId;
- this.htmlMessage = n.htmlMessage;
+ this.messageType = n.messageType;
+ this.messageFormat = n.messageFormat;
+
+ // taken from https://github.com/matrix-org/synapse/blob/master/synapse/push/mailer.py
+ this.allowedTags = [
+ "font", // custom to matrix for IRC-style font coloring
+ "del", // for markdown
+ // deliberately no h1/h2 to stop people shouting.
+ "h3",
+ "h4",
+ "h5",
+ "h6",
+ "blockquote",
+ "p",
+ "a",
+ "ul",
+ "ol",
+ "nl",
+ "li",
+ "b",
+ "i",
+ "u",
+ "strong",
+ "em",
+ "strike",
+ "code",
+ "hr",
+ "br",
+ "div",
+ "table",
+ "thead",
+ "caption",
+ "tbody",
+ "tr",
+ "th",
+ "td",
+ "pre",
+ ];
if (!node.server) {
node.warn("No configuration node");
@@ -25,7 +62,26 @@ module.exports = function(RED) {
});
node.on("input", function (msg) {
- if (! node.server || ! node.server.matrixClient) {
+ let msgType = node.messageType,
+ msgFormat = node.messageFormat;
+
+ if(msgType === 'msg.type') {
+ if(!msg.type) {
+ node.error("Message type is set to be passed in via msg.type but was not defined");
+ return;
+ }
+ msgType = msg.type;
+ }
+
+ if(msgFormat === 'msg.format') {
+ if(!msg.format) {
+ node.error("Message format is set to be passed in via msg.format but was not defined");
+ return;
+ }
+ msgFormat = msg.format;
+ }
+
+ if (!node.server || !node.server.matrixClient) {
node.warn("No matrix server selected");
return;
}
@@ -46,31 +102,27 @@ module.exports = function(RED) {
return;
}
- if(this.htmlMessage) {
- node.server.matrixClient.sendHtmlMessage(msg.roomId, msg.payload.toString(), msg.payload.toString())
- .then(function(e) {
- node.log("Message sent: " + msg.payload);
- msg.eventId = e.eventId;
- node.send([msg, null]);
- })
- .catch(function(e){
- node.warn("Error sending message " + e);
- msg.matrixError = e;
- node.send([null, msg]);
- });
- } else {
- node.server.matrixClient.sendTextMessage(msg.roomId, msg.payload.toString())
- .then(function(e) {
- node.log("Message sent: " + msg.payload);
- msg.eventId = e.eventId;
- node.send([msg, null]);
- })
- .catch(function(e){
- node.warn("Error sending message " + e);
- msg.matrixError = e;
- node.send([null, msg]);
- });
+ let content = {
+ msgtype: msgType,
+ body: msg.payload.toString()
+ };
+
+ if(msgFormat === 'html') {
+ content.format = "org.matrix.custom.html";
+ content.formatted_body = msg.formatted_payload || msg.payload;
}
+
+ node.server.matrixClient.sendMessage(msg.roomId, content)
+ .then(function(e) {
+ node.log("Message sent: " + msg.payload);
+ msg.eventId = e.eventId;
+ node.send([msg, null]);
+ })
+ .catch(function(e){
+ node.warn("Error sending message " + e);
+ msg.error = e;
+ node.send([null, msg]);
+ });
});
}
RED.nodes.registerType("matrix-send-message", MatrixSendImage);
diff --git a/src/matrix-send.html b/src/matrix-send.html
deleted file mode 100644
index eb0de15..0000000
--- a/src/matrix-send.html
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/src/matrix-send.js b/src/matrix-send.js
deleted file mode 100644
index 3cdaa6c..0000000
--- a/src/matrix-send.js
+++ /dev/null
@@ -1,175 +0,0 @@
-module.exports = function(RED) {
- function MatrixSendMessage(n) {
- RED.nodes.createNode(this, n);
-
- var node = this;
-
- this.name = n.name;
- this.server = RED.nodes.getNode(n.matrixServer);
- this.room = n.room;
-
- if (!node.server) {
- node.warn("No configuration 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.matrixClient.joinRoom(node.room, {syncRoom:false}) // should we really skip syncing the room?
- // .then(function(joinedRoom) {
- // node.log("Joined " + node.room);
- // node.room = joinedRoom.roomId;
- // node.updateConnectionState(true);
- // }).catch(function(e) {
- // node.warn("Error joining " + node.room + ": " + e);
- // });
- });
-
- node.on("input", function (msg) {
- if (! node.server || ! node.server.matrixClient) {
- node.warn("No matrix server configuration");
- return;
- }
-
- if(!node.server.isConnected()) {
- node.warn("Matrix server connection is currently closed");
- node.send([null, msg]);
- }
-
- if (msg.payload) {
- node.log("Sending message " + msg.payload);
-
- if(!msg.roomId) {
- msg.roomId = node.room;
- }
-
- if(!msg.roomId) {
- node.warn("Room must be specified in msg.roomId or in configuration");
- return;
- }
-
- // @todo add checks to make sure required properties are filled out instead of throwing an exception
- switch(msg.type || null) {
- case 'react':
- /**
- * React to another event (message)
- * msg.roomId - required
- *
- */
- node.server.matrixClient.sendCompleteEvent(
- msg.roomId,
- {
- type: 'm.reaction',
- content: {
- "m.relates_to": {
- event_id: msg.eventId,
- "key": msg.payload,
- "rel_type": "m.annotation"
- }
- }
- }
- )
- .then(function(e) {
- msg.eventId = e.event_id;
- node.send([msg, null]);
- })
- .catch(function(e){
- msg.matrixError = e;
- node.send([null, msg]);
- });
- break;
-
- case 'image':
- node.server.matrixClient.uploadContent(
- msg.image.content, {
- name: msg.image.filename || null, // Name to give the file on the server.
- rawResponse: (msg.rawResponse || false), // Return the raw body, rather than parsing the JSON.
- type: msg.image.type, // Content-type for the upload. Defaults to file.type, or applicaton/octet-stream.
- onlyContentUri: false // Just return the content URI, rather than the whole body. Defaults to false. Ignored if opts.rawResponse is true.
- }).then(function(file){
- node.server.matrixClient
- .sendImageMessage(msg.roomId, file.content_uri, {}, msg.payload)
- .then(function(imgResp) {
- node.log("Image message sent: " + imgResp);
- msg.eventId = e.eventId;
- node.send([msg, null]);
- })
- .catch(function(e){
- node.warn("Error sending image message " + e);
- msg.matrixError = e;
- node.send([null, msg]);
- });
- }).catch(function(e){
- node.warn("Error uploading image message " + e);
- msg.matrixError = e;
- node.send([null, msg]);
- });
- break;
-
- case 'file':
- if(!msg.file) {
- node.error('msg.file must be defined to send a file');
- }
-
- if(!msg.file.type) {
- node.error('msg.file.type must be set to a valid content-type header (i.e. application/pdf)');
- }
-
- node.server.matrixClient.uploadContent(
- msg.file.content, {
- name: msg.file.filename || null, // Name to give the file on the server.
- rawResponse: (msg.rawResponse || false), // Return the raw body, rather than parsing the JSON.
- type: msg.file.type, // Content-type for the upload. Defaults to file.type, or applicaton/octet-stream.
- onlyContentUri: false // Just return the content URI, rather than the whole body. Defaults to false. Ignored if opts.rawResponse is true.
- }).then(function(file){
- const content = {
- msgtype: 'm.file',
- url: file.content_uri,
- body: msg.payload,
- };
- node.server.matrixClient
- .sendMessage(msg.roomId, content)
- .then(function(imgResp) {
- node.log("File message sent: " + imgResp);
- msg.eventId = e.eventId;
- node.send([msg, null]);
- })
- .catch(function(e){
- node.warn("Error sending file message " + e);
- msg.matrixError = e;
- node.send([null, msg]);
- });
- }).catch(function(e){
- node.warn("Error uploading file message " + e);
- msg.matrixError = e;
- node.send([null, msg]);
- });
- break;
-
- default: // default text message
- node.server.matrixClient.sendTextMessage(msg.roomId, msg.payload.toString())
- .then(function(e) {
- node.log("Message sent: " + msg.payload);
- msg.eventId = e.eventId;
- node.send([msg, null]);
- }).catch(function(e){
- node.warn("Error sending message " + e);
- msg.matrixError = e;
- node.send([null, msg]);
- });
- break;
- }
- } else {
- node.warn("msg.payload is empty");
- }
- });
- }
- RED.nodes.registerType("matrix-send", MatrixSendMessage);
-}
\ No newline at end of file
diff --git a/src/matrix-server-config.js b/src/matrix-server-config.js
index ceb3e9a..8ef7659 100644
--- a/src/matrix-server-config.js
+++ b/src/matrix-server-config.js
@@ -79,7 +79,6 @@ module.exports = function(RED) {
switch (state) {
case "ERROR":
node.error("Connection to Matrix server lost");
- console.log(state, prevState, data);
node.setConnected(false);
break;