mirror of
https://github.com/Skylar-Tech/node-red-contrib-matrix-chat.git
synced 2025-04-19 12:33:06 -06:00
commit
00bc14e1c7
BIN
@matrix-org_olm-3.2.8.tgz
Normal file
BIN
@matrix-org_olm-3.2.8.tgz
Normal file
Binary file not shown.
@ -15,6 +15,7 @@ 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 "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 "file" with an uploaded file](#respond-to-file-with-an-uploaded-file)
|
||||||
- [Respond to "react" with a reaction](#respond-to-react-with-a-reaction)
|
- [Respond to "react" with a reaction](#respond-to-react-with-a-reaction)
|
||||||
|
- [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 "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)
|
- [Respond to "newroom" by creating new room and inviting user](#respond-to-newroom-by-creating-new-room-and-inviting-user)
|
||||||
- [Respond to "joinroom <room_id_or_alias>" by joining mentioned room](#respond-to-joinroom-room_id_or_alias-by-joining-mentioned-room)
|
- [Respond to "joinroom <room_id_or_alias>" by joining mentioned room](#respond-to-joinroom-room_id_or_alias-by-joining-mentioned-room)
|
||||||
@ -52,7 +53,7 @@ Allows an administrator to create or modify a user account with a specified `msg
|
|||||||
|
|
||||||
[View JSON](custom-redact-function-node.json)
|
[View JSON](custom-redact-function-node.json)
|
||||||
|
|
||||||
If we do not have a node for something you want to do (such as redacting events/messages) you can do this manually with a function node.
|
If we do not have a node for something you want to do you can do this manually with a function node. We now have a node for removing events but this is still a good example.
|
||||||
|
|
||||||
**Note:** You should make sure to catch any errors in your function node otherwise you could cause Node-RED to crash.
|
**Note:** You should make sure to catch any errors in your function node otherwise you could cause Node-RED to crash.
|
||||||
|
|
||||||
@ -60,6 +61,8 @@ To view what sort of functions you have access to check out the `client.ts` file
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Respond to "ping" with "pong"
|
### Respond to "ping" with "pong"
|
||||||
|
|
||||||
[View JSON](respond-ping-pong.json)
|
[View JSON](respond-ping-pong.json)
|
||||||
@ -110,6 +113,16 @@ Give a 👍 reaction when someone says "react"
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Remove messages containing "delete"
|
||||||
|
|
||||||
|
[View JSON](delete-event.json)
|
||||||
|
|
||||||
|
Any messages containing "delete" will try to be removed by the client.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Respond to "users" with full list of server users
|
### Respond to "users" with full list of server users
|
||||||
|
|
||||||
[View JSON](respond-users-list.json)
|
[View JSON](respond-users-list.json)
|
||||||
|
73
examples/delete-event.json
Normal file
73
examples/delete-event.json
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "fed9197df27197a4",
|
||||||
|
"type": "matrix-receive",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"acceptText": true,
|
||||||
|
"acceptEmotes": true,
|
||||||
|
"acceptStickers": true,
|
||||||
|
"acceptReactions": true,
|
||||||
|
"acceptFiles": true,
|
||||||
|
"acceptImages": true,
|
||||||
|
"x": 340,
|
||||||
|
"y": 1560,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"b289bb4fed9fa166"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b289bb4fed9fa166",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"property": "payload",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "cont",
|
||||||
|
"v": "delete",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 490,
|
||||||
|
"y": 1560,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"48766b632ab2e6a1"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "48766b632ab2e6a1",
|
||||||
|
"type": "matrix-delete-event",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"reason": "Requested deletion",
|
||||||
|
"x": 630,
|
||||||
|
"y": 1560,
|
||||||
|
"wires": [
|
||||||
|
[],
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "11f9cbbed7b95c83",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Delete messages containing \"delete\"",
|
||||||
|
"info": "",
|
||||||
|
"x": 480,
|
||||||
|
"y": 1520,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
BIN
examples/delete-event.png
Normal file
BIN
examples/delete-event.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
924
package-lock.json
generated
924
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "node-red-contrib-matrix-chat",
|
"name": "node-red-contrib-matrix-chat",
|
||||||
"version": "0.4.6",
|
"version": "0.5.8",
|
||||||
"description": "Matrix chat server client for Node-RED",
|
"description": "Matrix chat server client for Node-RED",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.1",
|
||||||
"got": "^12.0.1",
|
"got": "^12.0.2",
|
||||||
"isomorphic-webcrypto": "^2.3.8",
|
"isomorphic-webcrypto": "^2.3.8",
|
||||||
"matrix-js-sdk": "^15.5.0",
|
"matrix-js-sdk": "^16.0.0",
|
||||||
"node-localstorage": "^2.2.1",
|
"node-localstorage": "^2.2.1",
|
||||||
"olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz",
|
"olm": "https://gitlab.matrix.org/matrix-org/olm/-/package_files/271/download",
|
||||||
"utf8": "^3.0.0"
|
"utf8": "^3.0.0"
|
||||||
},
|
},
|
||||||
"node-red": {
|
"node-red": {
|
||||||
@ -17,6 +17,7 @@
|
|||||||
"matrix-server-config": "src/matrix-server-config.js",
|
"matrix-server-config": "src/matrix-server-config.js",
|
||||||
"matrix-receive": "src/matrix-receive.js",
|
"matrix-receive": "src/matrix-receive.js",
|
||||||
"matrix-send-message": "src/matrix-send-message.js",
|
"matrix-send-message": "src/matrix-send-message.js",
|
||||||
|
"matrix-delete-event": "src/matrix-delete-event.js",
|
||||||
"matrix-send-file": "src/matrix-send-file.js",
|
"matrix-send-file": "src/matrix-send-file.js",
|
||||||
"matrix-send-image": "src/matrix-send-image.js",
|
"matrix-send-image": "src/matrix-send-image.js",
|
||||||
"matrix-react": "src/matrix-react.js",
|
"matrix-react": "src/matrix-react.js",
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-create-room">
|
<script type="text/html" data-template-name="matrix-create-room">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -18,14 +18,14 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-decrypt-file">
|
<script type="text/html" data-template-name="matrix-decrypt-file">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" data-help-name="matrix-decrypt-file">
|
<script type="text/html" data-help-name="matrix-decrypt-file">
|
||||||
<h3>Details</h3>
|
<h3>Details</h3>
|
||||||
<p>Files sent in an encrypted room are themselves encrypted. Use this node to encrypt/decrypt files. Note: This node will download the encrypted file so be cautious of large downloads.</p>
|
<p>Files sent in an encrypted room are themselves encrypted. Use this node to decrypt files. Note: This node will download the encrypted file so be cautious of large downloads.</p>
|
||||||
|
|
||||||
<h3>Inputs</h3>
|
<h3>Inputs</h3>
|
||||||
<dl class="message-properties">
|
<dl class="message-properties">
|
||||||
|
96
src/matrix-delete-event.html
Normal file
96
src/matrix-delete-event.html
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<script type="text/javascript">
|
||||||
|
RED.nodes.registerType('matrix-delete-event',{
|
||||||
|
category: 'matrix',
|
||||||
|
color: '#00b7ca',
|
||||||
|
icon: "matrix.png",
|
||||||
|
outputLabels: ["success", "error"],
|
||||||
|
inputs:1,
|
||||||
|
outputs:2,
|
||||||
|
defaults: {
|
||||||
|
name: { value: null },
|
||||||
|
server: { value: "", type: "matrix-server-config" },
|
||||||
|
roomId: { value: null },
|
||||||
|
reason: { value: "" },
|
||||||
|
},
|
||||||
|
label: function() {
|
||||||
|
return this.name||"Delete Event";
|
||||||
|
},
|
||||||
|
paletteLabel: 'Delete Event'
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/html" data-template-name="matrix-delete-event">
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-server"><i class="fa fa-user"></i> Matrix Server Config</label>
|
||||||
|
<input type="text" id="node-input-server">
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-roomId"><i class="fa fa-comments"></i> Room ID</label>
|
||||||
|
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
||||||
|
<pre class="form-tips" id="node-input-roomId-error" style="color: #721c24;background-color: #f8d7da;border-color: #f5c6cb;margin-bottom: 12px;margin-top: 12px;display:none;"></pre>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-reason"><i class="fa fa-sticky-note"></i> Reason</label>
|
||||||
|
<input type="text" id="node-input-reason" placeholder="msg.reason">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function(){
|
||||||
|
$("#node-input-roomId").on("keyup", function() {
|
||||||
|
if($(this).val() && !$(this).val().startsWith("!")) {
|
||||||
|
$("#node-input-roomId-error").html(`Room IDs start with exclamation point "!"<br />Example: !OGEhHVWSdvArJzumhm:matrix.org`).show();
|
||||||
|
} else {
|
||||||
|
$("#node-input-roomId-error").hide();
|
||||||
|
}
|
||||||
|
}).trigger('keyup');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/html" data-help-name="matrix-delete-event">
|
||||||
|
<h3>Details</h3>
|
||||||
|
<p>Delete an event in a room</p>
|
||||||
|
|
||||||
|
<dl class="message-properties">
|
||||||
|
<dt>msg.topic
|
||||||
|
<span class="property-type">string</span>
|
||||||
|
</dt>
|
||||||
|
<dd> Room ID from where the event should be deleted from. Optional if configured on the node. If configured on the node this input will be overridden.</dd>
|
||||||
|
<dt>msg.eventId
|
||||||
|
<span class="property-type">string</span>
|
||||||
|
</dt>
|
||||||
|
<dd>Event ID of the Event which should be deleted.</dd>
|
||||||
|
<dt>msg.reason
|
||||||
|
<span class="property-type">string</span>
|
||||||
|
</dt>
|
||||||
|
<dd>Reason why the event is deleted. Default an empty string</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<h3>Outputs</h3>
|
||||||
|
<ol class="node-ports">
|
||||||
|
<li>Success
|
||||||
|
<dl class="message-properties">
|
||||||
|
<dt>msg.eventId <span class="property-type">string</span></dt>
|
||||||
|
<dd>the eventId from the deleted event.</dd>
|
||||||
|
</dl>
|
||||||
|
<dl class="message-properties">
|
||||||
|
<dt>msg.deleted <span class="property-type">boolean</span></dt>
|
||||||
|
<dd>True, if the event is deleted</dd>
|
||||||
|
</dl>
|
||||||
|
</li>
|
||||||
|
<li>Error
|
||||||
|
<dl class="message-properties">
|
||||||
|
<dt>msg.error <span class="property-type">string</span></dt>
|
||||||
|
<dd>the error that occurred.</dd>
|
||||||
|
<dl class="message-properties">
|
||||||
|
<dt>msg.deleted <span class="property-type">boolean</span></dt>
|
||||||
|
<dd>False, if the event is not deleted</dd>
|
||||||
|
</dl>
|
||||||
|
</dl>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</script>
|
75
src/matrix-delete-event.js
Normal file
75
src/matrix-delete-event.js
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
module.exports = function(RED) {
|
||||||
|
function MatrixDeleteEvent(n) {
|
||||||
|
RED.nodes.createNode(this,n);
|
||||||
|
|
||||||
|
var node = this;
|
||||||
|
|
||||||
|
this.name = n.name;
|
||||||
|
this.server = RED.nodes.getNode(n.server);
|
||||||
|
this.roomId = n.roomId;
|
||||||
|
this.reason = n.reason
|
||||||
|
|
||||||
|
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.on('input', function(msg) {
|
||||||
|
|
||||||
|
if(!msg.eventId) {
|
||||||
|
node.error("eventId is missing");
|
||||||
|
node.send([null, msg])
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!node.server || !node.server.matrixClient) {
|
||||||
|
node.warn("No matrix server selected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!node.server.isConnected()) {
|
||||||
|
node.error("Matrix server connection is currently closed");
|
||||||
|
node.send([null, msg]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.topic = node.roomId || msg.topic;
|
||||||
|
if(!msg.topic) {
|
||||||
|
node.warn("Room must be specified in msg.topic or in configuration");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.reason = node.reason || msg.reason;
|
||||||
|
|
||||||
|
if(!msg.reason) {
|
||||||
|
msg.reason = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
node.server.matrixClient.redactEvent(msg.topic, msg.eventId, undefined,{
|
||||||
|
reason: msg.reason
|
||||||
|
})
|
||||||
|
|
||||||
|
.then(function(e) {
|
||||||
|
msg.deleted = true
|
||||||
|
node.send([msg, null]);
|
||||||
|
})
|
||||||
|
.catch(function(e){
|
||||||
|
node.warn("Error deleting event " + e);
|
||||||
|
msg.error = e;
|
||||||
|
msg.deleted = false
|
||||||
|
node.send([null, msg]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
RED.nodes.registerType("matrix-delete-event",MatrixDeleteEvent);
|
||||||
|
}
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-invite-room">
|
<script type="text/html" data-template-name="matrix-invite-room">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -30,9 +30,21 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-roomId"><i class="fa fa-user"></i> Room ID</label>
|
<label for="node-input-roomId"><i class="fa fa-comments"></i> Room ID</label>
|
||||||
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
||||||
|
<pre class="form-tips" id="node-input-roomId-error" style="color: #721c24;background-color: #f8d7da;border-color: #f5c6cb;margin-bottom: 12px;margin-top: 12px;display:none;"></pre>
|
||||||
</div>
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function(){
|
||||||
|
$("#node-input-roomId").on("keyup", function() {
|
||||||
|
if($(this).val() && !$(this).val().startsWith("!")) {
|
||||||
|
$("#node-input-roomId-error").html(`Room IDs start with exclamation point "!"<br />Example: !OGEhHVWSdvArJzumhm:matrix.org`).show();
|
||||||
|
} else {
|
||||||
|
$("#node-input-roomId-error").hide();
|
||||||
|
}
|
||||||
|
}).trigger('keyup');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" data-help-name="matrix-invite-room">
|
<script type="text/html" data-help-name="matrix-invite-room">
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-join-room">
|
<script type="text/html" data-template-name="matrix-join-room">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
defaults: {
|
defaults: {
|
||||||
name: { value: null },
|
name: { value: null },
|
||||||
server: { value: "", type: "matrix-server-config" },
|
server: { value: "", type: "matrix-server-config" },
|
||||||
roomId: { value: null }
|
roomId: { value: null },
|
||||||
|
reaction: { value: null }
|
||||||
},
|
},
|
||||||
label: function() {
|
label: function() {
|
||||||
return this.name || "React";
|
return this.name || "React";
|
||||||
@ -20,7 +21,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-react">
|
<script type="text/html" data-template-name="matrix-react">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@ -28,9 +29,25 @@
|
|||||||
<input type="text" id="node-input-server">
|
<input type="text" id="node-input-server">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-roomId"><i class="fa fa-user"></i> Room ID</label>
|
<label for="node-input-roomId"><i class="fa fa-comments"></i> Room ID</label>
|
||||||
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
||||||
|
<pre class="form-tips" id="node-input-roomId-error" style="color: #721c24;background-color: #f8d7da;border-color: #f5c6cb;margin-bottom: 12px;margin-top: 12px;display:none;"></pre>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-reaction"><i class="fa fa-thumbs-up"></i> Reaction</label>
|
||||||
|
<input type="text" id="node-input-reaction" placeholder="msg.payload">
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function(){
|
||||||
|
$("#node-input-roomId").on("keyup", function() {
|
||||||
|
if($(this).val() && !$(this).val().startsWith("!")) {
|
||||||
|
$("#node-input-roomId-error").html(`Room IDs start with exclamation point "!"<br />Example: !OGEhHVWSdvArJzumhm:matrix.org`).show();
|
||||||
|
} else {
|
||||||
|
$("#node-input-roomId-error").hide();
|
||||||
|
}
|
||||||
|
}).trigger('keyup');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" data-help-name="matrix-react">
|
<script type="text/html" data-help-name="matrix-react">
|
||||||
@ -42,7 +59,7 @@
|
|||||||
<dt>msg.payload
|
<dt>msg.payload
|
||||||
<span class="property-type">string</span>
|
<span class="property-type">string</span>
|
||||||
</dt>
|
</dt>
|
||||||
<dd> Usually an emoji but can also be text. </dd>
|
<dd> Usually an emoji but can also be text. If configured on the node this is ignored otherwise it required. </dd>
|
||||||
|
|
||||||
<dt>msg.topic
|
<dt>msg.topic
|
||||||
<span class="property-type">string | null</span>
|
<span class="property-type">string | null</span>
|
||||||
|
@ -7,6 +7,7 @@ module.exports = function(RED) {
|
|||||||
this.name = n.name;
|
this.name = n.name;
|
||||||
this.server = RED.nodes.getNode(n.server);
|
this.server = RED.nodes.getNode(n.server);
|
||||||
this.roomId = n.roomId;
|
this.roomId = n.roomId;
|
||||||
|
this.reaction = n.reaction;
|
||||||
|
|
||||||
if (!node.server) {
|
if (!node.server) {
|
||||||
node.warn("No configuration node");
|
node.warn("No configuration node");
|
||||||
@ -40,8 +41,9 @@ module.exports = function(RED) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!msg.payload) {
|
let payload = n.reaction || msg.payload;
|
||||||
node.error('msg.payload is required');
|
if(!payload) {
|
||||||
|
node.error('msg.payload must be defined or the reaction configured on the node.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +61,7 @@ module.exports = function(RED) {
|
|||||||
{
|
{
|
||||||
"m.relates_to": {
|
"m.relates_to": {
|
||||||
event_id: eventId,
|
event_id: eventId,
|
||||||
key: msg.payload,
|
key: payload,
|
||||||
rel_type: "m.annotation"
|
rel_type: "m.annotation"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,9 @@
|
|||||||
<input type="text" id="node-input-server">
|
<input type="text" id="node-input-server">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-roomId"><i class="fa fa-user"></i> Room ID</label>
|
<label for="node-input-roomId"><i class="fa fa-comments"></i> Room ID</label>
|
||||||
<input type="text" id="node-input-roomId">
|
<input type="text" id="node-input-roomId">
|
||||||
|
<pre class="form-tips" id="node-input-roomId-error" style="color: #721c24;background-color: #f8d7da;border-color: #f5c6cb;margin-bottom: 12px;margin-top: 12px;display:none;"></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-tips">Enter a single room, comma separated list of rooms, or leave blank to get from all</div>
|
<div class="form-tips">Enter a single room, comma separated list of rooms, or leave blank to get from all</div>
|
||||||
<div class="form-row" style="margin-left: 100px;margin-top:10px;font-weight:bold;">
|
<div class="form-row" style="margin-left: 100px;margin-top:10px;font-weight:bold;">
|
||||||
@ -101,6 +102,17 @@
|
|||||||
Accept images <code>m.image</code>
|
Accept images <code>m.image</code>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function(){
|
||||||
|
$("#node-input-roomId").on("keyup", function() {
|
||||||
|
if($(this).val() && !$(this).val().startsWith("!")) {
|
||||||
|
$("#node-input-roomId-error").html(`Room IDs start with exclamation point "!"<br />Example: !OGEhHVWSdvArJzumhm:matrix.org`).show();
|
||||||
|
} else {
|
||||||
|
$("#node-input-roomId-error").hide();
|
||||||
|
}
|
||||||
|
}).trigger('keyup');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" data-help-name="matrix-receive">
|
<script type="text/html" data-help-name="matrix-receive">
|
||||||
@ -116,6 +128,11 @@
|
|||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
<dl class="message-properties">
|
||||||
|
<dt>msg.isDM <span class="property-type">bool</span></dt>
|
||||||
|
<dd> returns true if message is from a direct message room.</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
<dl class="message-properties">
|
<dl class="message-properties">
|
||||||
<dt>msg.encrypted <span class="property-type">bool</span></dt>
|
<dt>msg.encrypted <span class="property-type">bool</span></dt>
|
||||||
<dd> returns true if message was encrypted (e2ee).</dd>
|
<dd> returns true if message was encrypted (e2ee).</dd>
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
defaults: {
|
defaults: {
|
||||||
name: { value: null },
|
name: { value: null },
|
||||||
server: { value: "", type: "matrix-server-config" },
|
server: { value: "", type: "matrix-server-config" },
|
||||||
roomId: { value: null }
|
roomId: { value: null },
|
||||||
|
reason: { value: null }
|
||||||
},
|
},
|
||||||
label: function() {
|
label: function() {
|
||||||
return this.name || "Room Ban";
|
return this.name || "Room Ban";
|
||||||
@ -20,7 +21,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-room-ban">
|
<script type="text/html" data-template-name="matrix-room-ban">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@ -28,9 +29,25 @@
|
|||||||
<input type="text" id="node-input-server">
|
<input type="text" id="node-input-server">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-roomId"><i class="fa fa-user"></i> Room ID</label>
|
<label for="node-input-roomId"><i class="fa fa-comments"></i> Room ID</label>
|
||||||
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
||||||
|
<pre class="form-tips" id="node-input-roomId-error" style="color: #721c24;background-color: #f8d7da;border-color: #f5c6cb;margin-bottom: 12px;margin-top: 12px;display:none;"></pre>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-reason"><i class="fa fa-comment"></i> Reason</label>
|
||||||
|
<input type="text" id="node-input-reason" placeholder="msg.topic">
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function(){
|
||||||
|
$("#node-input-roomId").on("keyup", function() {
|
||||||
|
if($(this).val() && !$(this).val().startsWith("!")) {
|
||||||
|
$("#node-input-roomId-error").html(`Room IDs start with exclamation point "!"<br />Example: !OGEhHVWSdvArJzumhm:matrix.org`).show();
|
||||||
|
} else {
|
||||||
|
$("#node-input-roomId-error").hide();
|
||||||
|
}
|
||||||
|
}).trigger('keyup');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" data-help-name="matrix-room-ban">
|
<script type="text/html" data-help-name="matrix-room-ban">
|
||||||
@ -52,7 +69,7 @@
|
|||||||
<dt class="optional">msg.reason
|
<dt class="optional">msg.reason
|
||||||
<span class="property-type">string</span>
|
<span class="property-type">string</span>
|
||||||
</dt>
|
</dt>
|
||||||
<dd> Reason for banning the user.</dd>
|
<dd> Reason for banning the user. If configured on the node it will overwrite this input</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<h3>Outputs</h3>
|
<h3>Outputs</h3>
|
||||||
|
@ -7,6 +7,7 @@ module.exports = function(RED) {
|
|||||||
this.name = n.name;
|
this.name = n.name;
|
||||||
this.server = RED.nodes.getNode(n.server);
|
this.server = RED.nodes.getNode(n.server);
|
||||||
this.roomId = n.roomId;
|
this.roomId = n.roomId;
|
||||||
|
this.reason = n.reason;
|
||||||
|
|
||||||
if (!node.server) {
|
if (!node.server) {
|
||||||
node.warn("No configuration node");
|
node.warn("No configuration node");
|
||||||
@ -45,7 +46,7 @@ module.exports = function(RED) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
node.server.matrixClient.ban(msg.topic, msg.userId, msg.reason || undefined)
|
node.server.matrixClient.ban(msg.topic, msg.userId, n.reason || msg.reason || undefined)
|
||||||
.then(function(e) {
|
.then(function(e) {
|
||||||
node.log("Successfully banned " + msg.userId + " from " + msg.topic);
|
node.log("Successfully banned " + msg.userId + " from " + msg.topic);
|
||||||
msg.eventId = e.event_id;
|
msg.eventId = e.event_id;
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
defaults: {
|
defaults: {
|
||||||
name: { value: null },
|
name: { value: null },
|
||||||
server: { value: "", type: "matrix-server-config" },
|
server: { value: "", type: "matrix-server-config" },
|
||||||
roomId: { value: null }
|
roomId: { value: null },
|
||||||
|
reason: { value: null }
|
||||||
},
|
},
|
||||||
label: function() {
|
label: function() {
|
||||||
return this.name || "Room Kick";
|
return this.name || "Room Kick";
|
||||||
@ -20,7 +21,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-room-kick">
|
<script type="text/html" data-template-name="matrix-room-kick">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@ -28,9 +29,25 @@
|
|||||||
<input type="text" id="node-input-server">
|
<input type="text" id="node-input-server">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-roomId"><i class="fa fa-user"></i> Room ID</label>
|
<label for="node-input-roomId"><i class="fa fa-comments"></i> Room ID</label>
|
||||||
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
||||||
|
<pre class="form-tips" id="node-input-roomId-error" style="color: #721c24;background-color: #f8d7da;border-color: #f5c6cb;margin-bottom: 12px;margin-top: 12px;display:none;"></pre>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-reason"><i class="fa fa-comment"></i> Reason</label>
|
||||||
|
<input type="text" id="node-input-reason" placeholder="msg.topic">
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function(){
|
||||||
|
$("#node-input-roomId").on("keyup", function() {
|
||||||
|
if($(this).val() && !$(this).val().startsWith("!")) {
|
||||||
|
$("#node-input-roomId-error").html(`Room IDs start with exclamation point "!"<br />Example: !OGEhHVWSdvArJzumhm:matrix.org`).show();
|
||||||
|
} else {
|
||||||
|
$("#node-input-roomId-error").hide();
|
||||||
|
}
|
||||||
|
}).trigger('keyup');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" data-help-name="matrix-room-kick">
|
<script type="text/html" data-help-name="matrix-room-kick">
|
||||||
@ -52,7 +69,7 @@
|
|||||||
<dt class="optional">msg.reason
|
<dt class="optional">msg.reason
|
||||||
<span class="property-type">string</span>
|
<span class="property-type">string</span>
|
||||||
</dt>
|
</dt>
|
||||||
<dd> Reason for kicking the user.</dd>
|
<dd> Reason for kicking the user. If configured on the node it will overwrite this input</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<h3>Outputs</h3>
|
<h3>Outputs</h3>
|
||||||
|
@ -7,6 +7,7 @@ module.exports = function(RED) {
|
|||||||
this.name = n.name;
|
this.name = n.name;
|
||||||
this.server = RED.nodes.getNode(n.server);
|
this.server = RED.nodes.getNode(n.server);
|
||||||
this.roomId = n.roomId;
|
this.roomId = n.roomId;
|
||||||
|
this.reason = n.reason;
|
||||||
|
|
||||||
if (!node.server) {
|
if (!node.server) {
|
||||||
node.warn("No configuration node");
|
node.warn("No configuration node");
|
||||||
@ -45,7 +46,7 @@ module.exports = function(RED) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
node.server.matrixClient.kick(msg.topic, msg.userId, msg.reason || undefined)
|
node.server.matrixClient.kick(msg.topic, msg.userId, n.reason || msg.reason || undefined)
|
||||||
.then(function(e) {
|
.then(function(e) {
|
||||||
node.log("Successfully kicked " + msg.userId + " from " + msg.topic);
|
node.log("Successfully kicked " + msg.userId + " from " + msg.topic);
|
||||||
msg.eventId = e.event_id;
|
msg.eventId = e.event_id;
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-room-users">
|
<script type="text/html" data-template-name="matrix-room-users">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@ -30,7 +30,19 @@
|
|||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-server"><i class="fa fa-user"></i> Room Id</label>
|
<label for="node-input-server"><i class="fa fa-user"></i> Room Id</label>
|
||||||
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
||||||
|
<pre class="form-tips" id="node-input-roomId-error" style="color: #721c24;background-color: #f8d7da;border-color: #f5c6cb;margin-bottom: 12px;margin-top: 12px;display:none;"></pre>
|
||||||
</div>
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function(){
|
||||||
|
$("#node-input-roomId").on("keyup", function() {
|
||||||
|
if($(this).val() && !$(this).val().startsWith("!")) {
|
||||||
|
$("#node-input-roomId-error").html(`Room IDs start with exclamation point "!"<br />Example: !OGEhHVWSdvArJzumhm:matrix.org`).show();
|
||||||
|
} else {
|
||||||
|
$("#node-input-roomId-error").hide();
|
||||||
|
}
|
||||||
|
}).trigger('keyup');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" data-help-name="matrix-room-users">
|
<script type="text/html" data-help-name="matrix-room-users">
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-send-file">
|
<script type="text/html" data-template-name="matrix-send-file">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@ -29,8 +29,9 @@
|
|||||||
<input type="text" id="node-input-server">
|
<input type="text" id="node-input-server">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-roomId"><i class="fa fa-user"></i> Room ID</label>
|
<label for="node-input-roomId"><i class="fa fa-comments"></i> Room ID</label>
|
||||||
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
||||||
|
<pre class="form-tips" id="node-input-roomId-error" style="color: #721c24;background-color: #f8d7da;border-color: #f5c6cb;margin-bottom: 12px;margin-top: 12px;display:none;"></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-contentType"><i class="fa fa-user"></i> Content-Type</label>
|
<label for="node-input-contentType"><i class="fa fa-user"></i> Content-Type</label>
|
||||||
@ -39,6 +40,17 @@
|
|||||||
<div class="form-tips">
|
<div class="form-tips">
|
||||||
Must be a valid <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types" target="_blank">MIME Type</a> (ex: application/pdf) or left empty
|
Must be a valid <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types" target="_blank">MIME Type</a> (ex: application/pdf) or left empty
|
||||||
</div>
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function(){
|
||||||
|
$("#node-input-roomId").on("keyup", function() {
|
||||||
|
if($(this).val() && !$(this).val().startsWith("!")) {
|
||||||
|
$("#node-input-roomId-error").html(`Room IDs start with exclamation point "!"<br />Example: !OGEhHVWSdvArJzumhm:matrix.org`).show();
|
||||||
|
} else {
|
||||||
|
$("#node-input-roomId-error").hide();
|
||||||
|
}
|
||||||
|
}).trigger('keyup');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" data-help-name="matrix-send-file">
|
<script type="text/html" data-help-name="matrix-send-file">
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-send-image">
|
<script type="text/html" data-template-name="matrix-send-image">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@ -29,8 +29,9 @@
|
|||||||
<input type="text" id="node-input-server">
|
<input type="text" id="node-input-server">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-roomId"><i class="fa fa-user"></i> Room ID</label>
|
<label for="node-input-roomId"><i class="fa fa-comments"></i> Room ID</label>
|
||||||
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
||||||
|
<pre class="form-tips" id="node-input-roomId-error" style="color: #721c24;background-color: #f8d7da;border-color: #f5c6cb;margin-bottom: 12px;margin-top: 12px;display:none;"></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-contentType"><i class="fa fa-user"></i> Content-Type</label>
|
<label for="node-input-contentType"><i class="fa fa-user"></i> Content-Type</label>
|
||||||
@ -39,6 +40,17 @@
|
|||||||
<div class="form-tips">
|
<div class="form-tips">
|
||||||
Must be a valid <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types" target="_blank">MIME Type</a> (ex: image/png) or left empty
|
Must be a valid <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types" target="_blank">MIME Type</a> (ex: image/png) or left empty
|
||||||
</div>
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function(){
|
||||||
|
$("#node-input-roomId").on("keyup", function() {
|
||||||
|
if($(this).val() && !$(this).val().startsWith("!")) {
|
||||||
|
$("#node-input-roomId-error").html(`Room IDs start with exclamation point "!"<br />Example: !OGEhHVWSdvArJzumhm:matrix.org`).show();
|
||||||
|
} else {
|
||||||
|
$("#node-input-roomId-error").hide();
|
||||||
|
}
|
||||||
|
}).trigger('keyup');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" data-help-name="matrix-send-image">
|
<script type="text/html" data-help-name="matrix-send-image">
|
||||||
|
@ -10,8 +10,10 @@
|
|||||||
name: { value: null },
|
name: { value: null },
|
||||||
server: { value: "", type: "matrix-server-config" },
|
server: { value: "", type: "matrix-server-config" },
|
||||||
roomId: { value: null },
|
roomId: { value: null },
|
||||||
|
message: { value: null },
|
||||||
messageType: { value: 'm.text' },
|
messageType: { value: 'm.text' },
|
||||||
messageFormat: { value: '' },
|
messageFormat: { value: '' },
|
||||||
|
replaceMessage : { value: false }
|
||||||
},
|
},
|
||||||
label: function() {
|
label: function() {
|
||||||
return this.name || "Send Message";
|
return this.name || "Send Message";
|
||||||
@ -22,7 +24,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-send-message">
|
<script type="text/html" data-template-name="matrix-send-message">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -32,8 +34,25 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-roomId"><i class="fa fa-user"></i> Room ID</label>
|
<label for="node-input-roomId"><i class="fa fa-comments"></i> Room ID</label>
|
||||||
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
||||||
|
<pre class="form-tips" id="node-input-roomId-error" style="color: #721c24;background-color: #f8d7da;border-color: #f5c6cb;margin-bottom: 12px;margin-top: 12px;display:none;"></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-message"><i class="fa fa-comment"></i> Message</label>
|
||||||
|
<textarea id="node-input-message" placeholder="msg.payload" style="width: 70%;"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="node-input-replaceMessage"
|
||||||
|
style="width: auto; margin-left: 105px; vertical-align: top"
|
||||||
|
/>
|
||||||
|
<label for="node-input-replaceMessage" style="width: auto;max-width:50%;">
|
||||||
|
Update existing message if <code>msg.eventId</code> is set
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@ -60,6 +79,17 @@
|
|||||||
<option value="msg.format">msg.format input</option>
|
<option value="msg.format">msg.format input</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function(){
|
||||||
|
$("#node-input-roomId").on("keyup", function() {
|
||||||
|
if($(this).val() && !$(this).val().startsWith("!")) {
|
||||||
|
$("#node-input-roomId-error").html(`Room IDs start with exclamation point "!"<br />Example: !OGEhHVWSdvArJzumhm:matrix.org`).show();
|
||||||
|
} else {
|
||||||
|
$("#node-input-roomId-error").hide();
|
||||||
|
}
|
||||||
|
}).trigger('keyup');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" data-help-name="matrix-send-message">
|
<script type="text/html" data-help-name="matrix-send-message">
|
||||||
@ -76,12 +106,17 @@
|
|||||||
<dt>msg.payload
|
<dt>msg.payload
|
||||||
<span class="property-type">string</span>
|
<span class="property-type">string</span>
|
||||||
</dt>
|
</dt>
|
||||||
<dd> the message text. </dd>
|
<dd> the message text. If configured on the node this is ignored otherwise it required. </dd>
|
||||||
|
|
||||||
|
<dt>msg.replace
|
||||||
|
<span class="property-type">bool</span>
|
||||||
|
</dt>
|
||||||
|
<dd> If true and <code>msg.eventId</code> is present it will update an existing message. Posts a new message if false or <code>msg.eventId</code> is missing. </dd>
|
||||||
|
|
||||||
<dt class="optional">msg.formatted_payload
|
<dt class="optional">msg.formatted_payload
|
||||||
<span class="property-type">string</span>
|
<span class="property-type">string</span>
|
||||||
</dt>
|
</dt>
|
||||||
<dd> the formatted HTML message (uses msg.payload if not defined). This only affects HTML messages.</dd>
|
<dd> the formatted HTML message (uses <code>msg.payload</code> if not defined). This only affects HTML messages.</dd>
|
||||||
|
|
||||||
<dt class="optional">msg.type
|
<dt class="optional">msg.type
|
||||||
<span class="property-type">string | null</span>
|
<span class="property-type">string | null</span>
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
const {RelationType} = require("matrix-js-sdk");
|
||||||
|
|
||||||
module.exports = function(RED) {
|
module.exports = function(RED) {
|
||||||
function MatrixSendImage(n) {
|
function MatrixSendImage(n) {
|
||||||
RED.nodes.createNode(this, n);
|
RED.nodes.createNode(this, n);
|
||||||
@ -9,6 +11,8 @@ module.exports = function(RED) {
|
|||||||
this.roomId = n.roomId;
|
this.roomId = n.roomId;
|
||||||
this.messageType = n.messageType;
|
this.messageType = n.messageType;
|
||||||
this.messageFormat = n.messageFormat;
|
this.messageFormat = n.messageFormat;
|
||||||
|
this.replaceMessage = n.replaceMessage;
|
||||||
|
this.message = n.message;
|
||||||
|
|
||||||
// taken from https://github.com/matrix-org/synapse/blob/master/synapse/push/mailer.py
|
// taken from https://github.com/matrix-org/synapse/blob/master/synapse/push/mailer.py
|
||||||
this.allowedTags = [
|
this.allowedTags = [
|
||||||
@ -98,14 +102,15 @@ module.exports = function(RED) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!msg.payload) {
|
let payload = n.message || msg.payload;
|
||||||
node.error('msg.payload is required');
|
if(!payload) {
|
||||||
|
node.error('msg.payload must be defined or the message configured on the node.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let content = {
|
let content = {
|
||||||
msgtype: msgType,
|
msgtype: msgType,
|
||||||
body: msg.payload.toString()
|
body: payload.toString()
|
||||||
};
|
};
|
||||||
|
|
||||||
if(msgFormat === 'html') {
|
if(msgFormat === 'html') {
|
||||||
@ -113,12 +118,31 @@ module.exports = function(RED) {
|
|||||||
content.formatted_body =
|
content.formatted_body =
|
||||||
(typeof msg.formatted_payload !== 'undefined' && msg.formatted_payload)
|
(typeof msg.formatted_payload !== 'undefined' && msg.formatted_payload)
|
||||||
? msg.formatted_payload.toString()
|
? msg.formatted_payload.toString()
|
||||||
: msg.payload.toString();
|
: payload.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if((node.replaceMessage || msg.replace) && msg.eventId) {
|
||||||
|
content['m.new_content'] = {
|
||||||
|
msgtype: content.msgtype,
|
||||||
|
body: content.body
|
||||||
|
};
|
||||||
|
if('format' in content) {
|
||||||
|
content['m.new_content']['format'] = content['format'];
|
||||||
|
}
|
||||||
|
if('formatted_body' in content) {
|
||||||
|
content['m.new_content']['formatted_body'] = content['formatted_body'];
|
||||||
|
}
|
||||||
|
|
||||||
|
content['m.relates_to'] = {
|
||||||
|
rel_type: RelationType.Replace,
|
||||||
|
event_id: msg.eventId
|
||||||
|
};
|
||||||
|
content['body'] = ' * ' + content['body'];
|
||||||
}
|
}
|
||||||
|
|
||||||
node.server.matrixClient.sendMessage(msg.topic, content)
|
node.server.matrixClient.sendMessage(msg.topic, content)
|
||||||
.then(function(e) {
|
.then(function(e) {
|
||||||
node.log("Message sent: " + msg.payload);
|
node.log("Message sent: " + payload);
|
||||||
msg.eventId = e.event_id;
|
msg.eventId = e.event_id;
|
||||||
node.send([msg, null]);
|
node.send([msg, null]);
|
||||||
})
|
})
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
deviceLabel: { type: "text", required: false },
|
deviceLabel: { type: "text", required: false },
|
||||||
accessToken: { type: "password", required: true },
|
accessToken: { type: "password", required: true },
|
||||||
deviceId: { type: "text", required: false },
|
deviceId: { type: "text", required: false },
|
||||||
url: { type: "text", required: true }
|
url: { type: "text", required: true },
|
||||||
},
|
},
|
||||||
defaults: {
|
defaults: {
|
||||||
name: { value: null },
|
name: { value: null },
|
||||||
|
@ -4,6 +4,9 @@ const sdk = require("matrix-js-sdk");
|
|||||||
const { resolve } = require('path');
|
const { resolve } = require('path');
|
||||||
const { LocalStorage } = require('node-localstorage');
|
const { LocalStorage } = require('node-localstorage');
|
||||||
const { LocalStorageCryptoStore } = require('matrix-js-sdk/lib/crypto/store/localStorage-crypto-store');
|
const { LocalStorageCryptoStore } = require('matrix-js-sdk/lib/crypto/store/localStorage-crypto-store');
|
||||||
|
const {RoomEvent, RoomMemberEvent, HttpApiEvent, ClientEvent} = require("matrix-js-sdk");
|
||||||
|
const {deriveKey} = require("matrix-js-sdk/lib/crypto/key_passphrase");
|
||||||
|
const {encryptAES} = require("matrix-js-sdk/lib/crypto/aes");
|
||||||
|
|
||||||
module.exports = function(RED) {
|
module.exports = function(RED) {
|
||||||
function MatrixFolderNameFromUserId(name) {
|
function MatrixFolderNameFromUserId(name) {
|
||||||
@ -29,8 +32,8 @@ module.exports = function(RED) {
|
|||||||
this.deviceId = this.credentials.deviceId || null;
|
this.deviceId = this.credentials.deviceId || null;
|
||||||
this.url = this.credentials.url;
|
this.url = this.credentials.url;
|
||||||
this.autoAcceptRoomInvites = n.autoAcceptRoomInvites;
|
this.autoAcceptRoomInvites = n.autoAcceptRoomInvites;
|
||||||
this.enableE2ee = n.enableE2ee || false;
|
this.e2ee = n.enableE2ee || false;
|
||||||
this.e2ee = (this.enableE2ee && this.deviceId);
|
|
||||||
this.globalAccess = n.global;
|
this.globalAccess = n.global;
|
||||||
this.initializedAt = new Date();
|
this.initializedAt = new Date();
|
||||||
|
|
||||||
@ -50,7 +53,7 @@ module.exports = function(RED) {
|
|||||||
} else if(!this.url) {
|
} else if(!this.url) {
|
||||||
node.error("Matrix connection failed: missing server URL in configuration.");
|
node.error("Matrix connection failed: missing server URL in configuration.");
|
||||||
} else {
|
} else {
|
||||||
node.setConnected = function(connected, cb) {
|
node.setConnected = async function(connected, cb) {
|
||||||
if (node.connected !== connected) {
|
if (node.connected !== connected) {
|
||||||
node.connected = connected;
|
node.connected = connected;
|
||||||
if(typeof cb === 'function') {
|
if(typeof cb === 'function') {
|
||||||
@ -64,6 +67,10 @@ module.exports = function(RED) {
|
|||||||
// store Device ID internally
|
// store Device ID internally
|
||||||
let stored_device_id = getStoredDeviceId(localStorage),
|
let stored_device_id = getStoredDeviceId(localStorage),
|
||||||
device_id = this.matrixClient.getDeviceId();
|
device_id = this.matrixClient.getDeviceId();
|
||||||
|
|
||||||
|
if(!device_id && node.enableE2ee) {
|
||||||
|
node.error("Failed to auto detect deviceId for this auth token. You will need to manually specify one. You may need to login to create a new deviceId.")
|
||||||
|
} else {
|
||||||
if(!stored_device_id || stored_device_id !== device_id) {
|
if(!stored_device_id || stored_device_id !== device_id) {
|
||||||
node.log(`Saving Device ID (old:${stored_device_id} new:${device_id})`);
|
node.log(`Saving Device ID (old:${stored_device_id} new:${device_id})`);
|
||||||
storeDeviceId(localStorage, device_id);
|
storeDeviceId(localStorage, device_id);
|
||||||
@ -91,6 +98,7 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
initialSetup = true;
|
initialSetup = true;
|
||||||
}
|
}
|
||||||
@ -113,7 +121,8 @@ module.exports = function(RED) {
|
|||||||
sessionStore: new sdk.WebStorageSessionStore(localStorage),
|
sessionStore: new sdk.WebStorageSessionStore(localStorage),
|
||||||
cryptoStore: new LocalStorageCryptoStore(localStorage),
|
cryptoStore: new LocalStorageCryptoStore(localStorage),
|
||||||
userId: this.userId,
|
userId: this.userId,
|
||||||
deviceId: (this.deviceId || getStoredDeviceId(localStorage)) || undefined
|
deviceId: (this.deviceId || getStoredDeviceId(localStorage)) || undefined,
|
||||||
|
// verificationMethods: ["m.sas.v1"]
|
||||||
});
|
});
|
||||||
|
|
||||||
// set globally if configured to do so
|
// set globally if configured to do so
|
||||||
@ -141,7 +150,7 @@ module.exports = function(RED) {
|
|||||||
return node.connected;
|
return node.connected;
|
||||||
};
|
};
|
||||||
|
|
||||||
node.matrixClient.on("Room.timeline", async function(event, room, toStartOfTimeline, removed, data) {
|
node.matrixClient.on(RoomEvent.Timeline, async function(event, room, toStartOfTimeline, removed, data) {
|
||||||
if (toStartOfTimeline) {
|
if (toStartOfTimeline) {
|
||||||
return; // ignore paginated results
|
return; // ignore paginated results
|
||||||
}
|
}
|
||||||
@ -162,16 +171,32 @@ module.exports = function(RED) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isDmRoom = (room) => {
|
||||||
|
// Find out if this is a direct message room.
|
||||||
|
let isDM = !!room.getDMInviter();
|
||||||
|
const allMembers = room.currentState.getMembers();
|
||||||
|
if (!isDM && allMembers.length <= 2) {
|
||||||
|
// if not a DM, but there are 2 users only
|
||||||
|
// double check DM (needed because getDMInviter works only if you were invited, not if you invite)
|
||||||
|
// hence why we check for each member
|
||||||
|
if (allMembers.some((m) => m.getDMInviter())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allMembers.length <= 2 && isDM;
|
||||||
|
};
|
||||||
|
|
||||||
let msg = {
|
let msg = {
|
||||||
encrypted : event.isEncrypted(),
|
encrypted : event.isEncrypted(),
|
||||||
redacted : event.isRedacted(),
|
redacted : event.isRedacted(),
|
||||||
content : event.getContent(),
|
content : event.getContent(),
|
||||||
type : (event.getContent()['msgtype'] || event.getType()) || null,
|
type : (event.getContent()['msgtype'] || event.getType()) || null,
|
||||||
payload : (event.getContent()['body'] || event.getContent()) || null,
|
payload : (event.getContent()['body'] || event.getContent()) || null,
|
||||||
|
isDM : isDmRoom(room),
|
||||||
userId : event.getSender(),
|
userId : event.getSender(),
|
||||||
topic : event.getRoomId(),
|
topic : event.getRoomId(),
|
||||||
eventId : event.getId(),
|
eventId : event.getId(),
|
||||||
event : event,
|
event : event
|
||||||
};
|
};
|
||||||
|
|
||||||
node.log("Received" + (msg.encrypted ? ' encrypted' : '') +" timeline event [" + msg.type + "]: (" + room.name + ") " + event.getSender() + " :: " + msg.content.body + (toStartOfTimeline ? ' [PAGINATED]' : ''));
|
node.log("Received" + (msg.encrypted ? ' encrypted' : '') +" timeline event [" + msg.type + "]: (" + room.name + ") " + event.getSender() + " :: " + msg.content.body + (toStartOfTimeline ? ' [PAGINATED]' : ''));
|
||||||
@ -184,9 +209,9 @@ module.exports = function(RED) {
|
|||||||
*
|
*
|
||||||
* @event module:client~MatrixClient#"crypto.suggestKeyRestore"
|
* @event module:client~MatrixClient#"crypto.suggestKeyRestore"
|
||||||
*/
|
*/
|
||||||
node.matrixClient.on("crypto.suggestKeyRestore", function(){
|
// node.matrixClient.on("crypto.suggestKeyRestore", function(){
|
||||||
|
//
|
||||||
});
|
// });
|
||||||
|
|
||||||
// node.matrixClient.on("RoomMember.typing", async function(event, member) {
|
// node.matrixClient.on("RoomMember.typing", async function(event, member) {
|
||||||
// let isTyping = member.typing;
|
// let isTyping = member.typing;
|
||||||
@ -205,7 +230,8 @@ module.exports = function(RED) {
|
|||||||
// });
|
// });
|
||||||
|
|
||||||
// handle auto-joining rooms
|
// handle auto-joining rooms
|
||||||
node.matrixClient.on("RoomMember.membership", async function(event, member) {
|
|
||||||
|
node.matrixClient.on(RoomMemberEvent.Membership, async function(event, member) {
|
||||||
if (member.membership === "invite" && member.userId === node.userId) {
|
if (member.membership === "invite" && member.userId === node.userId) {
|
||||||
if(node.autoAcceptRoomInvites) {
|
if(node.autoAcceptRoomInvites) {
|
||||||
node.matrixClient.joinRoom(member.roomId).then(function() {
|
node.matrixClient.joinRoom(member.roomId).then(function() {
|
||||||
@ -219,7 +245,7 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
node.matrixClient.on("sync", async function(state, prevState, data) {
|
node.matrixClient.on(ClientEvent.Sync, async function(state, prevState, data) {
|
||||||
node.debug("SYNC [STATE=" + state + "] [PREVSTATE=" + prevState + "]");
|
node.debug("SYNC [STATE=" + state + "] [PREVSTATE=" + prevState + "]");
|
||||||
if(prevState === null && state === "PREPARED" ) {
|
if(prevState === null && state === "PREPARED" ) {
|
||||||
// Occurs when the initial sync is completed first time.
|
// Occurs when the initial sync is completed first time.
|
||||||
@ -287,7 +313,8 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
node.matrixClient.on("Session.logged_out", async function(errorObj){
|
|
||||||
|
node.matrixClient.on(HttpApiEvent.SessionLoggedOut, async function(errorObj){
|
||||||
// Example if user auth token incorrect:
|
// Example if user auth token incorrect:
|
||||||
// {
|
// {
|
||||||
// errcode: 'M_UNKNOWN_TOKEN',
|
// errcode: 'M_UNKNOWN_TOKEN',
|
||||||
@ -326,9 +353,29 @@ module.exports = function(RED) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
node.matrixClient.getAccountDataFromServer()
|
/**
|
||||||
|
* We do a /whoami request before starting for a few reasons:
|
||||||
|
* - validate our auth token
|
||||||
|
* - make sure auth token belongs to provided node.userId
|
||||||
|
* - fetch device_id if possible (only available on Synapse >= v1.40.0 under MSC2033)
|
||||||
|
*/
|
||||||
|
node.matrixClient.whoami()
|
||||||
.then(
|
.then(
|
||||||
function() {
|
function(data) {
|
||||||
|
if((typeof data['device_id'] === undefined || !data['device_id']) && !node.deviceId && !getStoredDeviceId(localStorage)) {
|
||||||
|
node.error("/whoami request did not return device_id. You will need to manually set one in your configuration because this cannot be automatically fetched.");
|
||||||
|
}
|
||||||
|
if('device_id' in data && data['device_id'] && !node.deviceId) {
|
||||||
|
// if we have no device_id configured lets use the one
|
||||||
|
// returned by /whoami for this access_token
|
||||||
|
node.matrixClient.deviceId = data['device_id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure our userId matches the access token's
|
||||||
|
if(data['user_id'].toLowerCase() !== node.userId.toLowerCase()) {
|
||||||
|
node.error(`User ID provided is ${node.userId} but token belongs to ${data['user_id']}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
run().catch((error) => node.error(error));
|
run().catch((error) => node.error(error));
|
||||||
},
|
},
|
||||||
function(err) {
|
function(err) {
|
||||||
@ -436,10 +483,18 @@ module.exports = function(RED) {
|
|||||||
* If a device ID is stored we will use that for the client
|
* If a device ID is stored we will use that for the client
|
||||||
*/
|
*/
|
||||||
function getStoredDeviceId(localStorage) {
|
function getStoredDeviceId(localStorage) {
|
||||||
return localStorage.getItem('my_device_id');
|
let deviceId = localStorage.getItem('my_device_id');
|
||||||
|
if(deviceId === "null" || !deviceId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return deviceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function storeDeviceId(localStorage, deviceId) {
|
function storeDeviceId(localStorage, deviceId) {
|
||||||
|
if(!deviceId) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
localStorage.setItem('my_device_id', deviceId);
|
localStorage.setItem('my_device_id', deviceId);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-synapse-create-edit-user">
|
<script type="text/html" data-template-name="matrix-synapse-create-edit-user">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-synapse-deactivate-user">
|
<script type="text/html" data-template-name="matrix-synapse-deactivate-user">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-synapse-join-room">
|
<script type="text/html" data-template-name="matrix-synapse-join-room">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -30,13 +30,25 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-roomId"><i class="fa fa-user"></i> Room ID</label>
|
<label for="node-input-roomId"><i class="fa fa-comments"></i> Room ID</label>
|
||||||
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
||||||
|
<pre class="form-tips" id="node-input-roomId-error" style="color: #721c24;background-color: #f8d7da;border-color: #f5c6cb;margin-bottom: 12px;margin-top: 12px;display:none;"></pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-tips" style="margin-bottom: 12px;">
|
<div class="form-tips" style="margin-bottom: 12px;">
|
||||||
User must be an admin to use this endpoint.
|
User must be an admin to use this endpoint.
|
||||||
</div>
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function(){
|
||||||
|
$("#node-input-roomId").on("keyup", function() {
|
||||||
|
if($(this).val() && !$(this).val().startsWith("!")) {
|
||||||
|
$("#node-input-roomId-error").html(`Room IDs start with exclamation point "!"<br />Example: !OGEhHVWSdvArJzumhm:matrix.org`).show();
|
||||||
|
} else {
|
||||||
|
$("#node-input-roomId-error").hide();
|
||||||
|
}
|
||||||
|
}).trigger('keyup');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" data-help-name="matrix-synapse-join-room">
|
<script type="text/html" data-help-name="matrix-synapse-join-room">
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-synapse-register">
|
<script type="text/html" data-template-name="matrix-synapse-register">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-synapse-users">
|
<script type="text/html" data-template-name="matrix-synapse-users">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="matrix-whois-user">
|
<script type="text/html" data-template-name="matrix-whois-user">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user