Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 00bc14e1c7 | |||
| 9f41b67174 | |||
| 4e93b7253e | |||
| ecb4427217 | |||
| 3e70369cae | |||
| 2ce80e2906 | |||
| 0c657caf5f | |||
| 848fd0ec9d | |||
| fef40f4ea9 | |||
| 595fbca3df | |||
| 487f17a439 | |||
| 68cb5a026e | |||
| d01733c647 | |||
| ed146e98d8 | |||
| 3dc6363a88 | |||
| 380e548425 | |||
| 27dd4d81a2 | |||
| de3c58044f | |||
| db1901ed1e | |||
| ac68060825 | |||
| d304cb95f6 | |||
| 85764c08d3 | |||
| 050be29d64 | |||
| 33823dea25 | |||
| d826c58b51 | |||
| d0ba671452 | |||
| 282c8ffc80 | |||
| 6dd2ec75f0 | |||
| ae386b90a6 |
@@ -1 +0,0 @@
|
|||||||
@matrix-org:registry=https://gitlab.matrix.org/api/v4/packages/npm/
|
|
||||||
@@ -15,7 +15,16 @@ 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 "joinroom <room_id_or_alias>" by joining mentioned room](#respond-to-joinroom-room_id_or_alias-by-joining-mentioned-room)
|
||||||
|
- [Respond to "rooms <user_id>" with user's rooms (list server's rooms if <user_id> is left blank)](#respond-to-rooms-user_id-with-users-rooms-list-servers-rooms-if-user_id-is-left-blank)
|
||||||
|
- [Respond to "whois <user_id>" with information about the user's session](#respond-to-whois-user_id-with-information-about-the-users-session)
|
||||||
|
- [Respond to "room_users" with current room's users](#respond-to-room_users-with-current-rooms-users)
|
||||||
|
- [Download & store all received files/images](#download--store-all-received-filesimages)
|
||||||
|
- [Kick/Ban user from room](#kickban-user-from-room)
|
||||||
|
- [Deactivate user](#deactivate-user)
|
||||||
|
|
||||||
|
|
||||||
### Create user with Shared Secret Registration
|
### Create user with Shared Secret Registration
|
||||||
@@ -28,7 +37,7 @@ Edit the object on the inject node to the user/pass combo you want to create and
|
|||||||
|
|
||||||
**Note:** This only works on Synapse servers.
|
**Note:** This only works on Synapse servers.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
### Create/Edit Synapse User
|
### Create/Edit Synapse User
|
||||||
@@ -37,20 +46,22 @@ Edit the object on the inject node to the user/pass combo you want to create and
|
|||||||
|
|
||||||
Allows an administrator to create or modify a user account with a specified `msg.userId`.
|
Allows an administrator to create or modify a user account with a specified `msg.userId`.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
### Use function node to run any command
|
### Use function node to run any command
|
||||||
|
|
||||||
[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.
|
||||||
|
|
||||||
To view what sort of functions you have access to check out the `client.ts` file from `matrix-js-sdk` [here](https://github.com/matrix-org/matrix-js-sdk/blob/master/src/client.ts).
|
To view what sort of functions you have access to check out the `client.ts` file from `matrix-js-sdk` [here](https://github.com/matrix-org/matrix-js-sdk/blob/master/src/client.ts).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Respond to "ping" with "pong"
|
### Respond to "ping" with "pong"
|
||||||
|
|
||||||
@@ -58,7 +69,7 @@ To view what sort of functions you have access to check out the `client.ts` file
|
|||||||
|
|
||||||
Use this flow to respond to anyone that says "ping" with "pong" into the same room.
|
Use this flow to respond to anyone that says "ping" with "pong" into the same room.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -68,7 +79,7 @@ Use this flow to respond to anyone that says "ping" with "pong" into the same ro
|
|||||||
|
|
||||||
Use this flow to respond to anyone that says "html" with an example HTML message. This shows how easy it is to send HTML.
|
Use this flow to respond to anyone that says "html" with an example HTML message. This shows how easy it is to send HTML.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -78,7 +89,7 @@ Use this flow to respond to anyone that says "html" with an example HTML message
|
|||||||
|
|
||||||
You will need an image on the machine running Node-RED. In this case example.png exists inside the Node-RED directory.
|
You will need an image on the machine running Node-RED. In this case example.png exists inside the Node-RED directory.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -88,7 +99,7 @@ You will need an image on the machine running Node-RED. In this case example.png
|
|||||||
|
|
||||||
You will need a file on the machine running Node-RED. In this case sample.pdf exists inside the Node-RED directory.
|
You will need a file on the machine running Node-RED. In this case sample.pdf exists inside the Node-RED directory.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -98,7 +109,17 @@ You will need a file on the machine running Node-RED. In this case sample.pdf ex
|
|||||||
|
|
||||||
Give a 👍 reaction when someone says "react"
|
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.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -106,8 +127,109 @@ Give a 👍 reaction when someone says "react"
|
|||||||
|
|
||||||
[View JSON](respond-users-list.json)
|
[View JSON](respond-users-list.json)
|
||||||
|
|
||||||
When someone sends the text "users" they get a HTML message back containing all the current users on the server.
|
When someone sends the text "users" they get a HTML message back containing all the current users on the server. If your server has a lot of users this paginates and sends a message with 25 users per message.
|
||||||
|
|
||||||
This requires admin privileges.
|
This requires admin privileges.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
### Respond to "newroom" by creating new room and inviting user
|
||||||
|
|
||||||
|
[View JSON](respond-users-list.json)
|
||||||
|
|
||||||
|
When someone sends "newroom" a new room will be created and the user that said the message will be invited. The client will also send a welcome message into the new room.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
### Respond to "joinroom <room_id_or_alias>" by joining mentioned room
|
||||||
|
|
||||||
|
[View JSON](respond-joinroom.json)
|
||||||
|
|
||||||
|
When someone sends "newroom" a new room will be created and the user that said the message will be invited. The client will also send a welcome message into the new room.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Respond to "rooms <user_id>" with user's rooms (list server's rooms if <user_id> is left blank)
|
||||||
|
|
||||||
|
[View JSON](respond-rooms.json)
|
||||||
|
|
||||||
|
Responds to "rooms <user_id>" with that user's rooms. If the message is just "rooms" it responds with a list of all rooms the server is participating in.
|
||||||
|
|
||||||
|
Note: If there are a lot of rooms this may fail to send the message as it is too large. This also only works for user's that are on the current server.
|
||||||
|
|
||||||
|
This requires admin privileges.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
### Respond to "whois <user_id>" with information about the user's session
|
||||||
|
|
||||||
|
[View JSON](respond-whois.json)
|
||||||
|
|
||||||
|
This lists out the user's session info. Each session contains the IP address, when it was last seen, and the user agent. Useful to find out more about a specific user on your server.
|
||||||
|
|
||||||
|
Note: If there are a lot of sessions this may fail to send the message as it is too large. This also only works for user's that are on the current server.
|
||||||
|
|
||||||
|
This requires admin privileges.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
### Respond to "room_users" with current room's users
|
||||||
|
|
||||||
|
[View JSON](respond-room-users.json)
|
||||||
|
|
||||||
|
List out the users participating in a room.
|
||||||
|
|
||||||
|
Note: If there are a lot of users in the room this will fail to send due to a large message error.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
### Download & store all received files/images
|
||||||
|
|
||||||
|
[View JSON](store-received-files.json)
|
||||||
|
|
||||||
|
Download received files/images. If the file is encrypted it will decrypt it for you. The decrypt node downloads the file for you otherwise you need to use a HTTP Request node to download the file.
|
||||||
|
|
||||||
|
Note: You may need to edit the storage directory for this to work. Default action is to create a `downloads` folder in the Node-RED directory and places files in that but there is a good chance your Node-RED instance doesn't have access to write to this directory.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
### Kick/Ban user from room
|
||||||
|
|
||||||
|
[View JSON](room-kick-ban.json)
|
||||||
|
|
||||||
|
If you say "kick @test:example.com" the bot will kick @test:example.com from the current room.
|
||||||
|
|
||||||
|
If you say "ban @test:example.com" the bot will ban @test:example.com from the current room.
|
||||||
|
|
||||||
|
Note: This requires the bot to have permissions to kick/ban in the current room.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
### Deactivate user
|
||||||
|
|
||||||
|
[View JSON](deactivate-user.json)
|
||||||
|
|
||||||
|
If you say "deactivate_user @test:example.com" the bot will deactivate the @test:example.com account on the server.
|
||||||
|
|
||||||
|
Note: This requires the bot to be a server admin.
|
||||||
|
|
||||||
|
WARNING: Accounts that are deleted cannot be restored. If you want to temp-disable edit the user instead.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Force user to join room
|
||||||
|
|
||||||
|
[View JSON](force-join-room.json)
|
||||||
|
|
||||||
|
If you say "force_join @test:example.com !320j90mf0394f:example.com" the bot will force the user `@test:example.com` into room `!320j90mf0394f:example.com`
|
||||||
|
|
||||||
|
Note: This requires the bot to be a server admin. This also only works for rooms on the same server.
|
||||||
|
|
||||||
|

|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "843c48978ab1b0a0",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "is from me",
|
||||||
|
"property": "userId",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "eq",
|
||||||
|
"v": "@skylord123:skylar.tech",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 590,
|
||||||
|
"y": 3260,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"b77d071077487ddc"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "93ea76ce5e65a250",
|
||||||
|
"type": "matrix-receive",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"acceptText": true,
|
||||||
|
"acceptEmotes": false,
|
||||||
|
"acceptStickers": false,
|
||||||
|
"acceptReactions": false,
|
||||||
|
"acceptFiles": false,
|
||||||
|
"acceptImages": false,
|
||||||
|
"x": 420,
|
||||||
|
"y": 3260,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"843c48978ab1b0a0"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d6795b522954bccd",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Respond to \"deactivate_user <user_id>\" by deactivating the user on the server",
|
||||||
|
"info": "",
|
||||||
|
"x": 590,
|
||||||
|
"y": 3220,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b77d071077487ddc",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "msg.payload filter",
|
||||||
|
"property": "payload",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "regex",
|
||||||
|
"v": "^deactivate_user",
|
||||||
|
"vt": "str",
|
||||||
|
"case": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 770,
|
||||||
|
"y": 3260,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"3c0e1e130e91206e"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3c0e1e130e91206e",
|
||||||
|
"type": "function",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"func": "let matches = msg.payload.match(/^deactivate_user ?(\\@.*)?/);\nmsg.userId = matches[1].trim() ? matches[1].trim() : null;\nif(!msg.userId) {\n return null;\n}\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 420,
|
||||||
|
"y": 3320,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"1f4870b7171cc70f"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1f4870b7171cc70f",
|
||||||
|
"type": "matrix-synapse-deactivate-user",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"x": 610,
|
||||||
|
"y": 3320,
|
||||||
|
"wires": [
|
||||||
|
[],
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
After Width: | Height: | Size: 24 KiB |
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,117 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "897b8de477d7d0df",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "is from me",
|
||||||
|
"property": "userId",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "eq",
|
||||||
|
"v": "@skylord123:skylar.tech",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 470,
|
||||||
|
"y": 3460,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"1f73f36092a9536b"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "973b2caeb68f3a60",
|
||||||
|
"type": "matrix-receive",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"acceptText": true,
|
||||||
|
"acceptEmotes": false,
|
||||||
|
"acceptStickers": false,
|
||||||
|
"acceptReactions": false,
|
||||||
|
"acceptFiles": false,
|
||||||
|
"acceptImages": false,
|
||||||
|
"x": 300,
|
||||||
|
"y": 3460,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"897b8de477d7d0df"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "be5c7290e6223b7b",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Say \"force_join <user_id> <room_id_or_alias>\" to force a user into a room",
|
||||||
|
"info": "",
|
||||||
|
"x": 460,
|
||||||
|
"y": 3420,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1f73f36092a9536b",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "msg.payload filter",
|
||||||
|
"property": "payload",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "regex",
|
||||||
|
"v": "^deactivate_user",
|
||||||
|
"vt": "str",
|
||||||
|
"case": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 650,
|
||||||
|
"y": 3460,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"6a2a73bc9dfdaece"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6a2a73bc9dfdaece",
|
||||||
|
"type": "function",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"func": "let matches = msg.payload.match(/^force_join (\\@.*) (.*)/);\nmsg.userId = matches[1].trim() ? matches[1].trim() : null;\nif(!msg.userId) {\n return null;\n}\nmsg.topic = matches[2].trim() ? matches[2].trim() : null;\nif(!msg.topic) {\n return null;\n}\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 300,
|
||||||
|
"y": 3520,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"212e060e320918d3"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "212e060e320918d3",
|
||||||
|
"type": "matrix-synapse-join-room",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"x": 490,
|
||||||
|
"y": 3520,
|
||||||
|
"wires": [
|
||||||
|
[],
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1,90 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "9a737b0c57b35063",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "is from me",
|
||||||
|
"property": "userId",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "eq",
|
||||||
|
"v": "@skylord123:skylar.tech",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 430,
|
||||||
|
"y": 2020,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"2a44927d9317a4b4"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f377ad37af7dc49e",
|
||||||
|
"type": "matrix-receive",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"acceptText": true,
|
||||||
|
"acceptEmotes": true,
|
||||||
|
"acceptStickers": true,
|
||||||
|
"acceptReactions": true,
|
||||||
|
"acceptFiles": true,
|
||||||
|
"acceptImages": true,
|
||||||
|
"x": 260,
|
||||||
|
"y": 2020,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"9a737b0c57b35063"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f7112a1d2808cfbb",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Respond to \"joinroom <room_id_or_alias>\" by joining the mentioned room",
|
||||||
|
"info": "",
|
||||||
|
"x": 440,
|
||||||
|
"y": 1980,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2a44927d9317a4b4",
|
||||||
|
"type": "function",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "msg.payload == \"joinroom\"",
|
||||||
|
"func": "if(!msg.payload.startsWith(\"joinroom\")) {\n return null;\n}\n\nlet split = msg.payload.split(\" \");\nif(split.length < 2) {\n return; // no room provided\n}\n\nmsg.topic = split[1];\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 640,
|
||||||
|
"y": 2020,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"a34d05c3b6f6bd27"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a34d05c3b6f6bd27",
|
||||||
|
"type": "matrix-join-room",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"x": 850,
|
||||||
|
"y": 2020,
|
||||||
|
"wires": [
|
||||||
|
[],
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
After Width: | Height: | Size: 17 KiB |
@@ -0,0 +1,157 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "ea0921f33b58e337",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "msg.payload is \"newroom\"",
|
||||||
|
"property": "payload",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "eq",
|
||||||
|
"v": "newroom",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 640,
|
||||||
|
"y": 1820,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"d7ce5027bc1e2eee"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9f9a24376b94c977",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "is from me",
|
||||||
|
"property": "userId",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "eq",
|
||||||
|
"v": "@skylord123:skylar.tech",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 430,
|
||||||
|
"y": 1820,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"ea0921f33b58e337"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3bce23488138c013",
|
||||||
|
"type": "matrix-receive",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"acceptText": true,
|
||||||
|
"acceptEmotes": true,
|
||||||
|
"acceptStickers": true,
|
||||||
|
"acceptReactions": true,
|
||||||
|
"acceptFiles": true,
|
||||||
|
"acceptImages": true,
|
||||||
|
"x": 260,
|
||||||
|
"y": 1820,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"9f9a24376b94c977"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d7ce5027bc1e2eee",
|
||||||
|
"type": "matrix-create-room",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"x": 250,
|
||||||
|
"y": 1880,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"735b9d9fd1401e96"
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "735b9d9fd1401e96",
|
||||||
|
"type": "matrix-invite-room",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"x": 410,
|
||||||
|
"y": 1880,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"089f2a7f0c079b6b"
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "222ee3c08028c1df",
|
||||||
|
"type": "matrix-send-message",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"messageType": "m.text",
|
||||||
|
"messageFormat": "",
|
||||||
|
"x": 760,
|
||||||
|
"y": 1880,
|
||||||
|
"wires": [
|
||||||
|
[],
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "089f2a7f0c079b6b",
|
||||||
|
"type": "change",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "set",
|
||||||
|
"p": "payload",
|
||||||
|
"pt": "msg",
|
||||||
|
"to": "Welcome to my new room!",
|
||||||
|
"tot": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"action": "",
|
||||||
|
"property": "",
|
||||||
|
"from": "",
|
||||||
|
"to": "",
|
||||||
|
"reg": false,
|
||||||
|
"x": 580,
|
||||||
|
"y": 1880,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"222ee3c08028c1df"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "48a1fd26227f277e",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Respond to \"newroom\" by creating new room and inviting person that said it then send welcome message",
|
||||||
|
"info": "",
|
||||||
|
"x": 520,
|
||||||
|
"y": 1780,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
After Width: | Height: | Size: 28 KiB |
@@ -0,0 +1,134 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "a7581a6224cbd24d",
|
||||||
|
"type": "matrix-room-users",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"x": 440,
|
||||||
|
"y": 2800,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"3e37b5fded58782d"
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2764620d2d514996",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "is from me",
|
||||||
|
"property": "userId",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "eq",
|
||||||
|
"v": "@skylord123:skylar.tech",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 610,
|
||||||
|
"y": 2740,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"f487951ea1b22a95"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7ed8fc36ba75298a",
|
||||||
|
"type": "matrix-receive",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"acceptText": true,
|
||||||
|
"acceptEmotes": true,
|
||||||
|
"acceptStickers": true,
|
||||||
|
"acceptReactions": true,
|
||||||
|
"acceptFiles": true,
|
||||||
|
"acceptImages": true,
|
||||||
|
"x": 440,
|
||||||
|
"y": 2740,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"2764620d2d514996"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f487951ea1b22a95",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "msg.payload filter",
|
||||||
|
"property": "payload",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "eq",
|
||||||
|
"v": "room_users",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 790,
|
||||||
|
"y": 2740,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"a7581a6224cbd24d"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3e37b5fded58782d",
|
||||||
|
"type": "function",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Room List (for user or all)",
|
||||||
|
"func": "let payload = null;\nif(!msg.payload || !msg.payload.joined) {\n payload = 'No users in room.';\n} else {\n payload = `Room ${msg.topic} users:`;\n payload += '<ul>';\n for(let user_id in msg.payload.joined) {\n payload += `<li>${msg.payload.joined[user_id].display_name} - ${user_id}</li>`;\n }\n payload += '</ul>'\n}\n\nif(payload){\n msg.payload = payload;\n}\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 650,
|
||||||
|
"y": 2800,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"86a4895c4fe46657"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "86a4895c4fe46657",
|
||||||
|
"type": "matrix-send-message",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Send HTML Message",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"messageType": "m.text",
|
||||||
|
"messageFormat": "html",
|
||||||
|
"x": 880,
|
||||||
|
"y": 2800,
|
||||||
|
"wires": [
|
||||||
|
[],
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cae1a37fe034b8f8",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Respond to \"room_users\" with that room's users",
|
||||||
|
"info": "",
|
||||||
|
"x": 600,
|
||||||
|
"y": 2700,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
After Width: | Height: | Size: 26 KiB |
@@ -0,0 +1,151 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "2eb2dd1b5dbdd03b",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Response to \"rooms\" with all rooms",
|
||||||
|
"info": "",
|
||||||
|
"x": 580,
|
||||||
|
"y": 2500,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f3415a10f124d586",
|
||||||
|
"type": "function",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"func": "let matches = msg.payload.match(/^rooms ?(\\@.*)?/);\nmsg.userId = matches[1] ? matches[1] : null;\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 420,
|
||||||
|
"y": 2620,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"2cae98732747989d"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2cae98732747989d",
|
||||||
|
"type": "function",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Room List (for user or all)",
|
||||||
|
"func": "let matrixClient = global.get(\"matrixClient['@bot:example.com']\"),\n matrixOnline = global.get(\"matrixClientOnline['@bot:example.com']\");\n\nif(!matrixOnline) {\n msg.payload = 'Matrix client not connected.';\n return [null, msg];\n}\n\nif(msg.userId) {\n matrixClient.http\n .authedRequest(\n undefined,\n 'GET',\n `/_synapse/admin/v1/users/${msg.userId}/joined_rooms`,\n {}, // query params\n undefined,\n { prefix: '' }\n ).then(function(e){\n msg.payload = e;\n if(!e.joined_rooms) {\n msg.payload = 'User is not part of any rooms.';\n } else {\n msg.payload = `${msg.userId}'s rooms:`;\n msg.payload += '<ul>';\n e.joined_rooms.forEach(function(room_id){\n msg.payload += `<li>${room_id}</li>`;\n });\n msg.payload += '</ul>'\n }\n node.send([msg, null]);\n }).catch(function(e){\n node.warn(\"Error fetching server user list \" + e);\n msg.payload = e;\n node.send([null, msg]);\n });\n} else {\n matrixClient.http\n .authedRequest(\n undefined,\n 'GET',\n `/_synapse/admin/v1/rooms`,\n {}, // query params\n undefined,\n { prefix: '' }\n ).then(function(e){\n msg.payload = e;\n if(!e.rooms) {\n msg.payload = 'Server has no rooms.';\n } else {\n msg.payload = `Server rooms:`;\n msg.payload += '<ul>';\n e.rooms.forEach(function(room){\n msg.payload += `<li>${room.name} - ${room.room_id} (members: ${room.joined_members} | creator: ${room.creator})</li>`;\n });\n msg.payload += '</ul>'\n }\n node.send([msg, null]);\n }).catch(function(e){\n node.warn(\"Error fetching server user list \" + e);\n msg.payload = e;\n node.send([null, msg]);\n });\n}",
|
||||||
|
"outputs": 2,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 610,
|
||||||
|
"y": 2620,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"d7508993ec1ce895"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"d7508993ec1ce895"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2f8c696ec0dc8f6d",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Respond to \"rooms <user_id>\" with that user's rooms",
|
||||||
|
"info": "",
|
||||||
|
"x": 590,
|
||||||
|
"y": 2540,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d7508993ec1ce895",
|
||||||
|
"type": "matrix-send-message",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Send HTML Message",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"messageType": "m.text",
|
||||||
|
"messageFormat": "html",
|
||||||
|
"x": 840,
|
||||||
|
"y": 2620,
|
||||||
|
"wires": [
|
||||||
|
[],
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "13a9a0331352338a",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "is from me",
|
||||||
|
"property": "userId",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "eq",
|
||||||
|
"v": "@skylord123:skylar.tech",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 590,
|
||||||
|
"y": 2580,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"afe88b8e115f661f"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e261cc12da739901",
|
||||||
|
"type": "matrix-receive",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"acceptText": true,
|
||||||
|
"acceptEmotes": true,
|
||||||
|
"acceptStickers": true,
|
||||||
|
"acceptReactions": true,
|
||||||
|
"acceptFiles": true,
|
||||||
|
"acceptImages": true,
|
||||||
|
"x": 420,
|
||||||
|
"y": 2580,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"13a9a0331352338a"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "afe88b8e115f661f",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "msg.payload filter",
|
||||||
|
"property": "payload",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "regex",
|
||||||
|
"v": "^rooms",
|
||||||
|
"vt": "str",
|
||||||
|
"case": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 770,
|
||||||
|
"y": 2580,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"f3415a10f124d586"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
After Width: | Height: | Size: 27 KiB |
@@ -1,27 +1,257 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"id": "a9b412957063b06c",
|
"id": "49e4b3a1ee3e9e1e",
|
||||||
"type": "matrix-receive",
|
"type": "matrix-synapse-users",
|
||||||
"z": "f025a8b9fbd1b054",
|
"z": "f025a8b9fbd1b054",
|
||||||
"name": "",
|
"name": "",
|
||||||
"roomId": "",
|
"server": null,
|
||||||
"ignoreText": false,
|
"x": 610,
|
||||||
"ignoreReactions": false,
|
"y": 2240,
|
||||||
"ignoreFiles": false,
|
|
||||||
"ignoreImages": false,
|
|
||||||
"x": 460,
|
|
||||||
"y": 120,
|
|
||||||
"wires": [
|
"wires": [
|
||||||
[
|
[
|
||||||
"4aa45cd8653ba898"
|
"d4978f7c2dad7ecf"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"da9d25c324cb727e"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "4aa45cd8653ba898",
|
"id": "e199d3db1ea6757c",
|
||||||
|
"type": "matrix-send-message",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Send HTML Notice",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"messageType": "m.notice",
|
||||||
|
"messageFormat": "html",
|
||||||
|
"x": 970,
|
||||||
|
"y": 2240,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"e248881d6749ba70"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"da9d25c324cb727e"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d4978f7c2dad7ecf",
|
||||||
|
"type": "function",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"func": "msg.next_token = msg.payload.next_token || false;\nlet new_payload = '<ul>';\nmsg.payload.users.forEach(function(user, index){\n if(msg.guests == 'false' && user.is_guest) {\n return;\n }\n new_payload += '<li>'+ JSON.stringify(user, null, 2).replace(/(?:\\r\\n|\\r|\\n)/g, \"\\n<br>\"); + '</li>'\n});\nmsg.payload = new_payload + '</ul>';\n\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 800,
|
||||||
|
"y": 2240,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"e199d3db1ea6757c"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "880cac7307d9a786",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Response to \"users\" with full server user list (excluding guests)",
|
||||||
|
"info": "",
|
||||||
|
"x": 620,
|
||||||
|
"y": 2160,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "469d2ebd9995747a",
|
||||||
|
"type": "matrix-send-message",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"messageType": "m.notice",
|
||||||
|
"messageFormat": "",
|
||||||
|
"x": 600,
|
||||||
|
"y": 2300,
|
||||||
|
"wires": [
|
||||||
|
[],
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "da9d25c324cb727e",
|
||||||
|
"type": "change",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "set",
|
||||||
|
"p": "payload",
|
||||||
|
"pt": "msg",
|
||||||
|
"to": "error",
|
||||||
|
"tot": "msg"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"action": "",
|
||||||
|
"property": "",
|
||||||
|
"from": "",
|
||||||
|
"to": "",
|
||||||
|
"reg": false,
|
||||||
|
"x": 420,
|
||||||
|
"y": 2300,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"469d2ebd9995747a"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "86577e484ca26aca",
|
||||||
|
"type": "change",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "set",
|
||||||
|
"p": "guests",
|
||||||
|
"pt": "msg",
|
||||||
|
"to": "false",
|
||||||
|
"tot": "str"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "set",
|
||||||
|
"p": "limit",
|
||||||
|
"pt": "msg",
|
||||||
|
"to": "25",
|
||||||
|
"tot": "num"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "set",
|
||||||
|
"p": "order_by",
|
||||||
|
"pt": "msg",
|
||||||
|
"to": "creation_ts",
|
||||||
|
"tot": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"action": "",
|
||||||
|
"property": "",
|
||||||
|
"from": "",
|
||||||
|
"to": "",
|
||||||
|
"reg": false,
|
||||||
|
"x": 420,
|
||||||
|
"y": 2240,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"49e4b3a1ee3e9e1e"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e248881d6749ba70",
|
||||||
"type": "switch",
|
"type": "switch",
|
||||||
"z": "f025a8b9fbd1b054",
|
"z": "f025a8b9fbd1b054",
|
||||||
"name": "msg.payload == \"users\"",
|
"name": "More to paginate?",
|
||||||
|
"property": "next_token",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "istype",
|
||||||
|
"v": "string",
|
||||||
|
"vt": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 1190,
|
||||||
|
"y": 2240,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"11d7fcf6335bc75b"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "11d7fcf6335bc75b",
|
||||||
|
"type": "change",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "set",
|
||||||
|
"p": "from",
|
||||||
|
"pt": "msg",
|
||||||
|
"to": "next_token",
|
||||||
|
"tot": "msg"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"action": "",
|
||||||
|
"property": "",
|
||||||
|
"from": "",
|
||||||
|
"to": "",
|
||||||
|
"reg": false,
|
||||||
|
"x": 1370,
|
||||||
|
"y": 2240,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"49e4b3a1ee3e9e1e"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8b48e27a118999ec",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "is from me",
|
||||||
|
"property": "userId",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "eq",
|
||||||
|
"v": "@skylord123:skylar.tech",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 590,
|
||||||
|
"y": 2200,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"7a64319e26e8b689"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "553da6dd77e5e03b",
|
||||||
|
"type": "matrix-receive",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"acceptText": true,
|
||||||
|
"acceptEmotes": true,
|
||||||
|
"acceptStickers": true,
|
||||||
|
"acceptReactions": true,
|
||||||
|
"acceptFiles": true,
|
||||||
|
"acceptImages": true,
|
||||||
|
"x": 420,
|
||||||
|
"y": 2200,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"8b48e27a118999ec"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7a64319e26e8b689",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "msg.payload filter",
|
||||||
"property": "payload",
|
"property": "payload",
|
||||||
"propertyType": "msg",
|
"propertyType": "msg",
|
||||||
"rules": [
|
"rules": [
|
||||||
@@ -34,70 +264,12 @@
|
|||||||
"checkall": "true",
|
"checkall": "true",
|
||||||
"repair": false,
|
"repair": false,
|
||||||
"outputs": 1,
|
"outputs": 1,
|
||||||
"x": 670,
|
"x": 770,
|
||||||
"y": 120,
|
"y": 2200,
|
||||||
"wires": [
|
"wires": [
|
||||||
[
|
[
|
||||||
"b95a674179d93416"
|
"86577e484ca26aca"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "b95a674179d93416",
|
|
||||||
"type": "matrix-synapse-users",
|
|
||||||
"z": "f025a8b9fbd1b054",
|
|
||||||
"name": "",
|
|
||||||
"x": 890,
|
|
||||||
"y": 120,
|
|
||||||
"wires": [
|
|
||||||
[
|
|
||||||
"19b654e5f28d93c4"
|
|
||||||
],
|
|
||||||
[]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "8720c66e867f89f6",
|
|
||||||
"type": "matrix-send-message",
|
|
||||||
"z": "f025a8b9fbd1b054",
|
|
||||||
"name": "Send HTML Notice",
|
|
||||||
"roomId": "",
|
|
||||||
"messageType": "m.notice",
|
|
||||||
"messageFormat": "html",
|
|
||||||
"x": 1230,
|
|
||||||
"y": 120,
|
|
||||||
"wires": [
|
|
||||||
[],
|
|
||||||
[]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "19b654e5f28d93c4",
|
|
||||||
"type": "function",
|
|
||||||
"z": "f025a8b9fbd1b054",
|
|
||||||
"name": "",
|
|
||||||
"func": "let new_payload = '<ul>';\nmsg.payload.users.forEach(function(user, index){\n new_payload += '<li>'+ JSON.stringify(user, null, 2).replace(/(?:\\r\\n|\\r|\\n)/g, \"\\n<br>\"); + '</li>'\n});\nmsg.payload = new_payload + '</ul>';\n\nreturn msg;",
|
|
||||||
"outputs": 1,
|
|
||||||
"noerr": 0,
|
|
||||||
"initialize": "",
|
|
||||||
"finalize": "",
|
|
||||||
"libs": [],
|
|
||||||
"x": 1060,
|
|
||||||
"y": 120,
|
|
||||||
"wires": [
|
|
||||||
[
|
|
||||||
"8720c66e867f89f6"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "563da45ab1747c2b",
|
|
||||||
"type": "comment",
|
|
||||||
"z": "f025a8b9fbd1b054",
|
|
||||||
"name": "Response to \"users\" with full server user list",
|
|
||||||
"info": "",
|
|
||||||
"x": 550,
|
|
||||||
"y": 80,
|
|
||||||
"wires": []
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 44 KiB |
@@ -0,0 +1,153 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "93df869346a728d3",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Response to \"whois <user_id>\" with user information",
|
||||||
|
"info": "",
|
||||||
|
"x": 610,
|
||||||
|
"y": 2360,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "656ed1e444fd2e0a",
|
||||||
|
"type": "function",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"func": "let matches = msg.payload.match(/^whois ?(\\@.*)?/);\nmsg.userId = matches[1].trim() ? matches[1].trim() : msg.userId;\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 440,
|
||||||
|
"y": 2440,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"4869676dab929d20"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4869676dab929d20",
|
||||||
|
"type": "matrix-whois-user",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"x": 590,
|
||||||
|
"y": 2440,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"a894fcabf9e41dca"
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a894fcabf9e41dca",
|
||||||
|
"type": "function",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"func": "try { \n var sessions = msg.payload.devices[\"\"].sessions || null;\n} catch (error) { \n var sessions = null;\n}\nlet html = \"whois (session) information for <strong>\" + msg.userId + \"</strong>\\n<ol>\";\nfor(let session of sessions) {\n try { \n var connections = session.connections;\n } catch (error) { \n var connections = null;\n }\n for(let connection of connections) {\n html += \"\\n<li><pre><code>\"+JSON.stringify(connection, null, 2)+\"</code></pre></li>\"\n }\n}\nhtml += \"</ol>\"\nmsg.payload = html;\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 740,
|
||||||
|
"y": 2440,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"898b8974f2b24861"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "898b8974f2b24861",
|
||||||
|
"type": "matrix-send-message",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Send HTML Notice",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"messageType": "m.notice",
|
||||||
|
"messageFormat": "html",
|
||||||
|
"x": 910,
|
||||||
|
"y": 2440,
|
||||||
|
"wires": [
|
||||||
|
[],
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "c8855c79f194796e",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "is from me",
|
||||||
|
"property": "userId",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "eq",
|
||||||
|
"v": "@skylord123:skylar.tech",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 590,
|
||||||
|
"y": 2400,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"ae1537a16b9e3b4c"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "39109d4f02d241ca",
|
||||||
|
"type": "matrix-receive",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"acceptText": true,
|
||||||
|
"acceptEmotes": true,
|
||||||
|
"acceptStickers": true,
|
||||||
|
"acceptReactions": true,
|
||||||
|
"acceptFiles": true,
|
||||||
|
"acceptImages": true,
|
||||||
|
"x": 420,
|
||||||
|
"y": 2400,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"c8855c79f194796e"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ae1537a16b9e3b4c",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "msg.payload filter",
|
||||||
|
"property": "payload",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "regex",
|
||||||
|
"v": "^whois",
|
||||||
|
"vt": "str",
|
||||||
|
"case": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 770,
|
||||||
|
"y": 2400,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"656ed1e444fd2e0a"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,211 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "d78dd157085ed843",
|
||||||
|
"type": "matrix-room-kick",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"x": 570,
|
||||||
|
"y": 2980,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"44d49fcaad67790c"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"44d49fcaad67790c"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "32a99c44b50fe3f3",
|
||||||
|
"type": "matrix-room-ban",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"x": 570,
|
||||||
|
"y": 3080,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"04628a976e7acf1b"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"04628a976e7acf1b"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5e786bbae3b1a368",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "is from me",
|
||||||
|
"property": "userId",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "eq",
|
||||||
|
"v": "@skylord123:skylar.tech",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 230,
|
||||||
|
"y": 3020,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"5b3ddae8335383e7"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ca278a6ffc3b9d6b",
|
||||||
|
"type": "matrix-receive",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"acceptText": true,
|
||||||
|
"acceptEmotes": false,
|
||||||
|
"acceptStickers": false,
|
||||||
|
"acceptReactions": false,
|
||||||
|
"acceptFiles": false,
|
||||||
|
"acceptImages": false,
|
||||||
|
"x": 220,
|
||||||
|
"y": 2960,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"5e786bbae3b1a368"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b6830f430157be4e",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Respond to \"room_ban <user_id>\" by banning user from room",
|
||||||
|
"info": "",
|
||||||
|
"x": 580,
|
||||||
|
"y": 3040,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8bffe425d3c1bf24",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Respond to \"room_kick <user_id>\" by kicking user from room",
|
||||||
|
"info": "",
|
||||||
|
"x": 580,
|
||||||
|
"y": 2940,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5b3ddae8335383e7",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Kick or Ban",
|
||||||
|
"property": "payload",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "regex",
|
||||||
|
"v": "^room_kick",
|
||||||
|
"vt": "str",
|
||||||
|
"case": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "regex",
|
||||||
|
"v": "^room_ban",
|
||||||
|
"vt": "str",
|
||||||
|
"case": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 2,
|
||||||
|
"x": 230,
|
||||||
|
"y": 3060,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"a19b38afd7b52834"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"925c59f485bf7247"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "925c59f485bf7247",
|
||||||
|
"type": "function",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"func": "let matches = msg.payload.match(/^room_ban ?(\\@.*)?/);\nmsg.userId = matches[1].trim() ? matches[1].trim() : null;\nif(!msg.userId) {\n return null;\n}\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 420,
|
||||||
|
"y": 3080,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"32a99c44b50fe3f3"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a19b38afd7b52834",
|
||||||
|
"type": "function",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"func": "let matches = msg.payload.match(/^room_kick ?(\\@.*)?/);\nmsg.userId = matches[1].trim() ? matches[1].trim() : null;\nif(!msg.userId) {\n return null;\n}\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 420,
|
||||||
|
"y": 2980,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"d78dd157085ed843"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "04628a976e7acf1b",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "true",
|
||||||
|
"targetType": "full",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 710,
|
||||||
|
"y": 3080,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "44d49fcaad67790c",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "true",
|
||||||
|
"targetType": "full",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 710,
|
||||||
|
"y": 2980,
|
||||||
|
"wires": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
After Width: | Height: | Size: 36 KiB |
@@ -0,0 +1,166 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "d7573ed76980dc64",
|
||||||
|
"type": "matrix-receive",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"server": null,
|
||||||
|
"roomId": "",
|
||||||
|
"acceptText": false,
|
||||||
|
"acceptEmotes": false,
|
||||||
|
"acceptStickers": false,
|
||||||
|
"acceptReactions": false,
|
||||||
|
"acceptFiles": true,
|
||||||
|
"acceptImages": true,
|
||||||
|
"x": 1740,
|
||||||
|
"y": 600,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"4d4e992ed895413f"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "addcccdfea9935b1",
|
||||||
|
"type": "comment",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "Download & store received files/images and decrypt if necessary",
|
||||||
|
"info": "",
|
||||||
|
"x": 1970,
|
||||||
|
"y": 560,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4d4e992ed895413f",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"property": "encrypted",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "true"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "else"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 2,
|
||||||
|
"x": 1890,
|
||||||
|
"y": 600,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"660782188696fc62"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"857bce169036e3cb"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "660782188696fc62",
|
||||||
|
"type": "matrix-decrypt-file",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": null,
|
||||||
|
"x": 2050,
|
||||||
|
"y": 600,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"cdbaf88f6631322e"
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b62db6caf4697242",
|
||||||
|
"type": "file",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"filename": "",
|
||||||
|
"appendNewline": true,
|
||||||
|
"createDir": false,
|
||||||
|
"overwriteFile": "true",
|
||||||
|
"encoding": "none",
|
||||||
|
"x": 2240,
|
||||||
|
"y": 660,
|
||||||
|
"wires": [
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "857bce169036e3cb",
|
||||||
|
"type": "http request",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"method": "GET",
|
||||||
|
"ret": "bin",
|
||||||
|
"paytoqs": "ignore",
|
||||||
|
"url": "",
|
||||||
|
"tls": "",
|
||||||
|
"persist": false,
|
||||||
|
"proxy": "",
|
||||||
|
"authType": "",
|
||||||
|
"senderr": false,
|
||||||
|
"x": 1910,
|
||||||
|
"y": 660,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"7d0be52f8c3f1b54"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7d0be52f8c3f1b54",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "",
|
||||||
|
"property": "statusCode",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "eq",
|
||||||
|
"v": "200",
|
||||||
|
"vt": "num"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 2050,
|
||||||
|
"y": 660,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"cdbaf88f6631322e"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cdbaf88f6631322e",
|
||||||
|
"type": "change",
|
||||||
|
"z": "f025a8b9fbd1b054",
|
||||||
|
"name": "set directory",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "set",
|
||||||
|
"p": "filename",
|
||||||
|
"pt": "msg",
|
||||||
|
"to": "\"downloads/\" & msg.filename",
|
||||||
|
"tot": "jsonata"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"action": "",
|
||||||
|
"property": "",
|
||||||
|
"from": "",
|
||||||
|
"to": "",
|
||||||
|
"reg": false,
|
||||||
|
"x": 2230,
|
||||||
|
"y": 600,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"b62db6caf4697242"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
After Width: | Height: | Size: 24 KiB |
@@ -1,22 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "node-red-contrib-matrix-chat",
|
"name": "node-red-contrib-matrix-chat",
|
||||||
"version": "0.4.0",
|
"version": "0.5.8",
|
||||||
"description": "Matrix chat server client for Node-RED",
|
"description": "Matrix chat server client for Node-RED",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@matrix-org/olm": "^3.2.8",
|
"fs-extra": "^10.0.1",
|
||||||
"fs-extra": "^9.1.0",
|
"got": "^12.0.2",
|
||||||
"got": "^11.8.2",
|
|
||||||
"isomorphic-webcrypto": "^2.3.8",
|
"isomorphic-webcrypto": "^2.3.8",
|
||||||
"matrix-js-sdk": "^15.3.0",
|
"matrix-js-sdk": "^16.0.0",
|
||||||
"node-localstorage": "^2.2.1",
|
"node-localstorage": "^2.2.1",
|
||||||
"process": "^0.11.10",
|
"olm": "https://gitlab.matrix.org/matrix-org/olm/-/package_files/271/download",
|
||||||
"utf8": "^3.0.0"
|
"utf8": "^3.0.0"
|
||||||
},
|
},
|
||||||
"node-red": {
|
"node-red": {
|
||||||
|
"version": ">=1.3.0",
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"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",
|
||||||
@@ -35,6 +36,9 @@
|
|||||||
"matrix-room-users": "src/matrix-room-users.js"
|
"matrix-room-users": "src/matrix-room-users.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"node-red",
|
"node-red",
|
||||||
"matrix",
|
"matrix",
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
module.exports = function(RED) {
|
module.exports = function(RED) {
|
||||||
const got = require('got');
|
|
||||||
const crypto = require('isomorphic-webcrypto');
|
const crypto = require('isomorphic-webcrypto');
|
||||||
|
|
||||||
function MatrixDecryptFile(n) {
|
function MatrixDecryptFile(n) {
|
||||||
@@ -10,6 +9,8 @@ module.exports = function(RED) {
|
|||||||
this.name = n.name;
|
this.name = n.name;
|
||||||
|
|
||||||
node.on("input", async function (msg) {
|
node.on("input", async function (msg) {
|
||||||
|
const { got } = await import('got');
|
||||||
|
|
||||||
if(!msg.type) {
|
if(!msg.type) {
|
||||||
node.error('msg.type is required.');
|
node.error('msg.type is required.');
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -204,6 +221,11 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li><code>msg.type</code> == '<strong>m.file</strong>'
|
<li><code>msg.type</code> == '<strong>m.file</strong>'
|
||||||
|
<dl class="message-properties">
|
||||||
|
<dt>msg.filename <span class="property-type">string</span></dt>
|
||||||
|
<dd>the file's parsed filename</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
<dl class="message-properties">
|
<dl class="message-properties">
|
||||||
<dt>msg.url <span class="property-type">string</span></dt>
|
<dt>msg.url <span class="property-type">string</span></dt>
|
||||||
<dd>the file's URL</dd>
|
<dd>the file's URL</dd>
|
||||||
@@ -216,6 +238,11 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li><code>msg.type</code> == '<strong>m.image</strong>'
|
<li><code>msg.type</code> == '<strong>m.image</strong>'
|
||||||
|
<dl class="message-properties">
|
||||||
|
<dt>msg.filename <span class="property-type">string</span></dt>
|
||||||
|
<dd>the image's parsed filename</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
<dl class="message-properties">
|
<dl class="message-properties">
|
||||||
<dt>msg.url <span class="property-type">string</span></dt>
|
<dt>msg.url <span class="property-type">string</span></dt>
|
||||||
<dd>the image's URL</dd>
|
<dd>the image's URL</dd>
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ module.exports = function(RED) {
|
|||||||
|
|
||||||
case 'm.file':
|
case 'm.file':
|
||||||
if(!node.acceptFiles) return;
|
if(!node.acceptFiles) return;
|
||||||
|
msg.filename = msg.content.filename || msg.content.body;
|
||||||
if(msg.encrypted) {
|
if(msg.encrypted) {
|
||||||
msg.url = node.server.matrixClient.mxcUrlToHttp(msg.content.file.url);
|
msg.url = node.server.matrixClient.mxcUrlToHttp(msg.content.file.url);
|
||||||
msg.mxc_url = msg.content.file.url;
|
msg.mxc_url = msg.content.file.url;
|
||||||
@@ -73,7 +74,7 @@ module.exports = function(RED) {
|
|||||||
|
|
||||||
case 'm.image':
|
case 'm.image':
|
||||||
if(!node.acceptImages) return;
|
if(!node.acceptImages) return;
|
||||||
|
msg.filename = msg.content.filename || msg.content.body;
|
||||||
if(msg.encrypted) {
|
if(msg.encrypted) {
|
||||||
msg.url = node.server.matrixClient.mxcUrlToHttp(msg.content.file.url);
|
msg.url = node.server.matrixClient.mxcUrlToHttp(msg.content.file.url);
|
||||||
msg.mxc_url = msg.content.file.url;
|
msg.mxc_url = msg.content.file.url;
|
||||||
|
|||||||
@@ -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,10 +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>
|
||||||
<div class="form-tips">
|
<script type="text/javascript">
|
||||||
This only works on Synapse servers. The user also must be an administrator.
|
$(function(){
|
||||||
</div>
|
$("#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,11 +40,22 @@
|
|||||||
<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">
|
||||||
<h3>Details</h3>
|
<h3>Details</h3>
|
||||||
<p>This node will send an image to a Matrix chat room. Supports direct linking to a File In node.</p>
|
<p>This node will send an image to a Matrix chat room. Supports direct linking to a File In node. It's recommended you set <code>msg.contentType</code> so the client knows how to render the image (otherwise the image could show blank).</p>
|
||||||
|
|
||||||
<h3>Inputs</h3>
|
<h3>Inputs</h3>
|
||||||
<dl class="message-properties">
|
<dl class="message-properties">
|
||||||
|
|||||||
@@ -72,20 +72,28 @@ module.exports = function(RED) {
|
|||||||
})
|
})
|
||||||
.then(function(file){
|
.then(function(file){
|
||||||
node.server.matrixClient
|
node.server.matrixClient
|
||||||
.sendImageMessage(msg.topic, file.content_uri, {}, (msg.body || msg.filename) || "")
|
.sendImageMessage(
|
||||||
|
msg.topic,
|
||||||
|
file.content_uri,
|
||||||
|
{},
|
||||||
|
(msg.body || msg.filename) || null,
|
||||||
|
null
|
||||||
|
)
|
||||||
.then(function(e) {
|
.then(function(e) {
|
||||||
node.log("Image message sent: " + e);
|
node.log("Image message sent: " + e);
|
||||||
msg.eventId = e.event_id;
|
msg.eventId = e.event_id;
|
||||||
|
msg.content_uri_mxc = file.content_uri;
|
||||||
|
msg.content_uri = node.server.matrixClient.mxcUrlToHttp(file.content_uri);
|
||||||
node.send([msg, null]);
|
node.send([msg, null]);
|
||||||
})
|
})
|
||||||
.catch(function(e){
|
.catch(function(e){
|
||||||
node.warn("Error sending image message " + e);
|
node.warn("Error sending image message: " + e);
|
||||||
msg.error = e;
|
msg.error = e;
|
||||||
node.send([null, msg]);
|
node.send([null, msg]);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(function(e){
|
.catch(function(e){
|
||||||
node.warn("Error uploading image message " + e);
|
node.warn("Error uploading image message: " + e);
|
||||||
msg.error = e;
|
msg.error = e;
|
||||||
node.send([null, msg]);
|
node.send([null, msg]);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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 },
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
style="width: auto; margin-left: 125px; vertical-align: top"
|
style="width: auto; margin-left: 125px; vertical-align: top"
|
||||||
/>
|
/>
|
||||||
<label for="node-config-input-enableE2ee" style="width: auto;max-width:50%;">
|
<label for="node-config-input-enableE2ee" style="width: auto;max-width:50%;">
|
||||||
Enable end-to-end encryption (requires a Device ID to be set.)
|
Enable end-to-end encryption
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
global.Olm = require('@matrix-org/olm');
|
global.Olm = require('olm');
|
||||||
const fs = require("fs-extra");
|
const fs = require("fs-extra");
|
||||||
const sdk = require("matrix-js-sdk");
|
const sdk = require("matrix-js-sdk");
|
||||||
|
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) {
|
||||||
@@ -10,19 +14,17 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function MatrixServerNode(n) {
|
function MatrixServerNode(n) {
|
||||||
let storageDir = './matrix-client-storage';
|
let node = this,
|
||||||
|
storageDir = RED.settings.userDir + '/matrix-client-storage';
|
||||||
RED.nodes.createNode(this, n);
|
RED.nodes.createNode(this, n);
|
||||||
|
node.setMaxListeners(1000);
|
||||||
|
|
||||||
let node = this;
|
|
||||||
node.log("Initializing Matrix Server Config node");
|
node.log("Initializing Matrix Server Config node");
|
||||||
|
|
||||||
if(!this.credentials) {
|
if(!this.credentials) {
|
||||||
this.credentials = {};
|
this.credentials = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
node.setMaxListeners(1000);
|
|
||||||
|
|
||||||
this.connected = null;
|
this.connected = null;
|
||||||
this.name = n.name;
|
this.name = n.name;
|
||||||
this.userId = this.credentials.userId;
|
this.userId = this.credentials.userId;
|
||||||
@@ -30,10 +32,16 @@ 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();
|
||||||
|
|
||||||
|
if(!this.userId) {
|
||||||
|
node.log("Matrix connection failed: missing user ID in configuration.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let localStorageDir = storageDir + '/' + MatrixFolderNameFromUserId(this.userId),
|
let localStorageDir = storageDir + '/' + MatrixFolderNameFromUserId(this.userId),
|
||||||
localStorage = new LocalStorage(localStorageDir),
|
localStorage = new LocalStorage(localStorageDir),
|
||||||
initialSetup = false;
|
initialSetup = false;
|
||||||
@@ -41,13 +49,11 @@ module.exports = function(RED) {
|
|||||||
let retryStartTimeout = null;
|
let retryStartTimeout = null;
|
||||||
|
|
||||||
if(!this.credentials.accessToken) {
|
if(!this.credentials.accessToken) {
|
||||||
node.log("Matrix connection failed: missing access token.");
|
node.error("Matrix connection failed: missing access token in configuration.");
|
||||||
} else if(!this.url) {
|
} else if(!this.url) {
|
||||||
node.log("Matrix connection failed: missing server URL.");
|
node.error("Matrix connection failed: missing server URL in configuration.");
|
||||||
} else if(!this.userId) {
|
|
||||||
node.log("Matrix connection failed: missing user ID.");
|
|
||||||
} 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') {
|
||||||
@@ -61,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);
|
||||||
@@ -88,6 +98,7 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
initialSetup = true;
|
initialSetup = true;
|
||||||
}
|
}
|
||||||
@@ -110,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
|
||||||
@@ -138,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
|
||||||
}
|
}
|
||||||
@@ -159,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]' : ''));
|
||||||
@@ -181,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;
|
||||||
@@ -202,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() {
|
||||||
@@ -216,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.
|
||||||
@@ -284,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',
|
||||||
@@ -296,7 +326,6 @@ module.exports = function(RED) {
|
|||||||
// httpStatus: 401
|
// httpStatus: 401
|
||||||
// }
|
// }
|
||||||
|
|
||||||
console.log("Authentication failure: ", errorObj);
|
|
||||||
node.error("Authentication failure: " + errorObj);
|
node.error("Authentication failure: " + errorObj);
|
||||||
stopClient();
|
stopClient();
|
||||||
});
|
});
|
||||||
@@ -324,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) {
|
||||||
@@ -392,7 +441,8 @@ module.exports = function(RED) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function upgradeDirectoryIfNecessary(node, storageDir) {
|
function upgradeDirectoryIfNecessary(node, storageDir) {
|
||||||
let oldStorageDir = './matrix-local-storage';
|
let oldStorageDir = './matrix-local-storage',
|
||||||
|
oldStorageDir2 = './matrix-client-storage';
|
||||||
|
|
||||||
// if the old storage location exists lets move it to it's new location
|
// if the old storage location exists lets move it to it's new location
|
||||||
if(fs.pathExistsSync(oldStorageDir)){
|
if(fs.pathExistsSync(oldStorageDir)){
|
||||||
@@ -415,16 +465,36 @@ module.exports = function(RED) {
|
|||||||
node.log("archiving old config folder '" + oldStorageDir + "' to '" + oldStorageDir + "-backup");
|
node.log("archiving old config folder '" + oldStorageDir + "' to '" + oldStorageDir + "-backup");
|
||||||
fs.renameSync(oldStorageDir, oldStorageDir + "-backup");
|
fs.renameSync(oldStorageDir, oldStorageDir + "-backup");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(RED.settings.userDir !== resolve('./')) {
|
||||||
|
// user directory does not match running directory
|
||||||
|
// check if we stored stuff in wrong directory and move it
|
||||||
|
if(fs.pathExistsSync(oldStorageDir2)){
|
||||||
|
fs.ensureDirSync(storageDir);
|
||||||
|
node.log("found old '" + oldStorageDir2 + "' path, copying to new location '" + storageDir);
|
||||||
|
fs.copySync(oldStorageDir2, storageDir);
|
||||||
|
// rename folder to keep as a backup (and so we don't run again)
|
||||||
|
fs.renameSync(oldStorageDir2, oldStorageDir2 + "-backup");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
module.exports = function(RED) {
|
module.exports = function(RED) {
|
||||||
const got = require("got");
|
|
||||||
const utf8 = require('utf8');
|
const utf8 = require('utf8');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
|
|
||||||
@@ -22,7 +21,8 @@ module.exports = function(RED) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
node.on("input", function (msg) {
|
node.on("input", async function (msg) {
|
||||||
|
const { got } = await import('got');
|
||||||
|
|
||||||
if(!msg.payload.username) {
|
if(!msg.payload.username) {
|
||||||
node.error("msg.payload.username is required");
|
node.error("msg.payload.username is required");
|
||||||
@@ -34,7 +34,7 @@ module.exports = function(RED) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(async () => {
|
await (async () => {
|
||||||
try {
|
try {
|
||||||
var response = await got.get(this.server + '/_synapse/admin/v1/register', {
|
var response = await got.get(this.server + '/_synapse/admin/v1/register', {
|
||||||
responseType: 'json'
|
responseType: 'json'
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||