Issue #97 Room Settings

- Can set room name, topic, and avatar
- Can get name, topic, avatar, encrypted, power_levels, aliases, guest_access, join_rule, and join_allow_rules
This commit is contained in:
Skylar Sadlier 2023-10-15 04:17:12 -06:00
parent 0e755bc350
commit c833a40a84
3 changed files with 234 additions and 2 deletions

View File

@ -32,13 +32,14 @@
"matrix-crypt-file": "src/matrix-crypt-file.js", "matrix-crypt-file": "src/matrix-crypt-file.js",
"matrix-room-kick": "src/matrix-room-kick.js", "matrix-room-kick": "src/matrix-room-kick.js",
"matrix-room-ban": "src/matrix-room-ban.js", "matrix-room-ban": "src/matrix-room-ban.js",
"matrix-room-users": "src/matrix-room-users.js",
"matrix-room-settings": "src/matrix-room-settings.js",
"matrix-synapse-users": "src/matrix-synapse-users.js", "matrix-synapse-users": "src/matrix-synapse-users.js",
"matrix-synapse-register": "src/matrix-synapse-register.js", "matrix-synapse-register": "src/matrix-synapse-register.js",
"matrix-synapse-create-edit-user": "src/matrix-synapse-create-edit-user.js", "matrix-synapse-create-edit-user": "src/matrix-synapse-create-edit-user.js",
"matrix-synapse-deactivate-user": "src/matrix-synapse-deactivate-user.js", "matrix-synapse-deactivate-user": "src/matrix-synapse-deactivate-user.js",
"matrix-synapse-join-room": "src/matrix-synapse-join-room.js", "matrix-synapse-join-room": "src/matrix-synapse-join-room.js",
"matrix-whois-user": "src/matrix-whois-user.js", "matrix-whois-user": "src/matrix-whois-user.js"
"matrix-room-users": "src/matrix-room-users.js"
} }
}, },
"engines": { "engines": {

View File

@ -0,0 +1,115 @@
<script type="text/javascript">
RED.nodes.registerType('matrix-room-settings',{
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: null },
returnValues: { value: true }
},
label: function() {
return this.name || "Room Settings";
},
paletteLabel: 'Room Settings'
});
</script>
<script type="text/html" data-template-name="matrix-room-settings">
<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">
<input
type="checkbox"
id="node-input-returnValues"
style="width: auto; margin-left: 105px; vertical-align: top"
/>
<label for="node-input-returnValues" style="width: auto">
Return current name, topic, and avatar in <code style="white-space: normal;">msg.payload</code>
</label>
<div class="form-tips" style="margin-bottom: 12px;">
You can set the payload to <code style="white-space: normal;">null</code>, <code style="white-space: normal;">undefined</code>, or <code style="white-space: normal;">false</code> to just get the current settings without changing them.
</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 type="text/html" data-help-name="matrix-room-settings">
<h3>Details</h3>
<p>
Set or get room name, topic, and avatar.
</p>
<h3>Inputs</h3>
<dl class="message-properties">
<dt class="optional">msg.topic
<span class="property-type">string | null</span>
</dt>
<dd> The room to set/get settings for.</dd>
<dt class="optional">msg.payload.name
<span class="property-type">string</span>
</dt>
<dd> New name for the room</dd>
<dt class="optional">msg.payload.topic
<span class="property-type">string</span>
</dt>
<dd> New topic for the room</dd>
<dt class="optional">msg.payload.avatar
<span class="property-type">string</span>
</dt>
<dd> MXC URL for the new room avatar (ex: mxc://localhost/JWEIFJgwEIhweiWJE)</dd>
</dl>
<h3>Outputs</h3>
<ol class="node-ports">
<li>Success
<dl class="message-properties">
<dt>msg <span class="property-type">object</span></dt>
<dd>Original message object.</dd>
</dl>
</li>
<li>Error
<dl class="message-properties">
<dt>msg.error.name <span class="property-type">string</span></dt>
<dd>Error if name failed to set on room.</dd>
</dl>
<dl class="message-properties">
<dt>msg.error.topic <span class="property-type">string</span></dt>
<dd>Error if topic failed to set on room.</dd>
</dl>
<dl class="message-properties">
<dt>msg.error.avatar <span class="property-type">string</span></dt>
<dd>Error if avatar failed to set on room.</dd>
</dl>
</li>
</ol>
</script>

116
src/matrix-room-settings.js Normal file
View File

@ -0,0 +1,116 @@
module.exports = function(RED) {
function MatrixRoomSettings(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.returnValues = n.returnValues;
if (!node.server) {
node.warn("No configuration node");
return;
}
node.server.register(node);
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", async function (msg) {
if (! node.server || ! node.server.matrixClient) {
msg.error = "No matrix server selected";
node.error(msg.error, msg);
node.send([null, msg]);
return;
}
if(!node.server.isConnected()) {
msg.error = "Matrix server connection is currently closed";
node.error(msg.error, msg);
node.send([null, msg]);
return;
}
msg.topic = node.roomId || msg.topic;
if(!msg.topic) {
msg.error = "Room must be specified in msg.topic or in configuration";
node.error(msg.error, msg);
node.send([null, msg]);
return;
}
let errors = {},
payload = {};
if(msg.payload?.name) {
try {
await node.server.matrixClient.setRoomName(msg.topic, msg.payload.name);
} catch(e) {
node.error("Set room name failed: " + e.message, msg);
errors.name = e.message;
}
}
if(msg.payload?.topic) {
try {
await node.server.matrixClient.setRoomTopic(msg.topic, msg.payload.topic);
} catch(e) {
node.error("Set room topic failed: " + e.message, msg);
errors.topic = e.message;
}
}
if(msg.payload?.avatar) {
try {
await node.server.matrixClient.sendStateEvent(
msg.topic,
"m.room.avatar",
{
"info": msg.payload?.avatar_info || undefined,
"url": msg.payload.avatar
},
"");
} catch(e) {
node.error("Set room avatar failed: " + e.message, msg);
errors.topic = e.message;
}
}
if(Object.keys(errors).length) {
msg.errors = errors;
}
if(node.returnValues) {
// return current settings
let join_rules = await node.server.matrixClient.getStateEvent(msg.topic, "m.room.join_rules", "");
msg.payload = {
"name": (await node.server.matrixClient.getStateEvent(msg.topic, "m.room.name", ""))?.name,
"topic": (await node.server.matrixClient.getStateEvent(msg.topic, "m.room.topic", ""))?.topic,
"avatar": (await node.server.matrixClient.getStateEvent(msg.topic, "m.room.avatar", ""))?.url,
"encrypted": node.server.matrixClient.isRoomEncrypted(msg.topic),
"power_levels": await node.server.matrixClient.getStateEvent(msg.topic, "m.room.power_levels", ""),
"aliases": (await node.server.matrixClient.getLocalAliases(msg.topic))?.aliases,
"guest_access": (await node.server.matrixClient.getStateEvent(msg.topic, "m.room.guest_access", ""))?.guest_access,
"join_rule": join_rules?.join_rule,
"join_allow_rules": join_rules?.allow_rules
};
}
node.send([msg, null]);
});
node.on("close", function() {
node.server.deregister(node);
});
}
RED.nodes.registerType("matrix-room-settings", MatrixRoomSettings);
}