@patricktobias86/node-red-telegram-account 1.1.7 → 1.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/README.md +4 -2
- package/docs/NODES.md +4 -2
- package/nodes/auth.html +9 -1
- package/nodes/auth.js +16 -6
- package/nodes/command.html +10 -2
- package/nodes/command.js +26 -13
- package/nodes/config.html +5 -0
- package/nodes/config.js +13 -0
- package/nodes/delete-message.html +9 -1
- package/nodes/delete-message.js +10 -3
- package/nodes/get-entity.html +8 -0
- package/nodes/get-entity.js +15 -6
- package/nodes/iter-dialogs.html +8 -0
- package/nodes/iter-dialogs.js +10 -3
- package/nodes/iter-messages.html +8 -0
- package/nodes/iter-messages.js +10 -3
- package/nodes/promote-admin.html +6 -0
- package/nodes/promote-admin.js +10 -1
- package/nodes/receiver.html +10 -2
- package/nodes/receiver.js +24 -12
- package/nodes/resolve-userid.html +12 -4
- package/nodes/resolve-userid.js +15 -2
- package/nodes/send-file.html +8 -0
- package/nodes/send-file.js +10 -3
- package/nodes/send-message.html +8 -0
- package/nodes/send-message.js +10 -3
- package/package.json +1 -1
- package/test/command.test.js +43 -0
- package/test/debug-option.test.js +44 -0
- package/test/receiver.test.js +43 -0
package/CHANGELOG.md
CHANGED
|
@@ -9,3 +9,7 @@ All notable changes to this project will be documented in this file.
|
|
|
9
9
|
### Changed
|
|
10
10
|
- Session management now tracks active clients in a `Map` for safer reuse.
|
|
11
11
|
|
|
12
|
+
## [1.1.8] - 2025-07-22
|
|
13
|
+
### Fixed
|
|
14
|
+
- Receiver and Command nodes now remove their event listeners when closed to prevent duplicate messages after redeploys.
|
|
15
|
+
|
package/README.md
CHANGED
|
@@ -18,8 +18,8 @@ See [docs/NODES.md](docs/NODES.md) for a detailed description of every node. Bel
|
|
|
18
18
|
|
|
19
19
|
- **config** – stores your API credentials and caches sessions for reuse.
|
|
20
20
|
- **auth** – interactive login that outputs a `stringSession`.
|
|
21
|
-
- **receiver** – emits messages for every incoming update (with optional ignore list).
|
|
22
|
-
- **command** – triggers when an incoming message matches a command or regex.
|
|
21
|
+
- **receiver** – emits messages for every incoming update (with optional ignore list). Event listeners are cleaned up on node close so redeploys won't duplicate messages.
|
|
22
|
+
- **command** – triggers when an incoming message matches a command or regex. Event listeners are removed on redeploy to prevent duplicates.
|
|
23
23
|
- **send-message** – sends text or media messages with rich options.
|
|
24
24
|
- **send-files** – uploads one or more files with captions and buttons.
|
|
25
25
|
- **get-entity** – resolves usernames, IDs or t.me links into Telegram entities.
|
|
@@ -29,6 +29,8 @@ See [docs/NODES.md](docs/NODES.md) for a detailed description of every node. Bel
|
|
|
29
29
|
- **promote-admin** – promotes a user to admin with configurable rights.
|
|
30
30
|
- **resolve-userid** – converts a username to a numeric user ID.
|
|
31
31
|
|
|
32
|
+
All nodes include a <code>Debug</code> option that logs incoming and outgoing messages to the Node-RED log when enabled.
|
|
33
|
+
|
|
32
34
|
## Session management
|
|
33
35
|
|
|
34
36
|
Connections to Telegram are cached by the configuration node. A Map keyed by the `stringSession` tracks each client together with a reference count and the connection promise. If a node is created while another one is still connecting, it waits for that promise and then reuses the same client.
|
package/docs/NODES.md
CHANGED
|
@@ -8,8 +8,8 @@ Below is a short description of each node. For a full list of configuration opti
|
|
|
8
8
|
|------|-------------|
|
|
9
9
|
| **config** | Configuration node storing API credentials and connection options. Other nodes reference this to share a Telegram client and reuse the session. Connections are tracked in a Map with a reference count so multiple nodes can wait for the same connection. |
|
|
10
10
|
| **auth** | Starts an interactive login flow. Produces a `stringSession` that can be reused with the `config` node. |
|
|
11
|
-
| **receiver** | Emits an output message for every incoming Telegram message. Can ignore specific user IDs. |
|
|
12
|
-
| **command** | Listens for new messages and triggers when a message matches a configured command or regular expression. |
|
|
11
|
+
| **receiver** | Emits an output message for every incoming Telegram message. Can ignore specific user IDs. Event handlers are automatically removed when the node is closed. |
|
|
12
|
+
| **command** | Listens for new messages and triggers when a message matches a configured command or regular expression. The event listener is cleaned up on node close to avoid duplicates. |
|
|
13
13
|
| **send-message** | Sends text messages or media files to a chat. Supports parse mode, buttons, scheduling, and more. |
|
|
14
14
|
| **send-files** | Uploads one or more files to a chat with optional caption, thumbnails and other parameters. |
|
|
15
15
|
| **get-entity** | Resolves a username, user ID or t.me URL into a Telegram entity object. |
|
|
@@ -20,3 +20,5 @@ Below is a short description of each node. For a full list of configuration opti
|
|
|
20
20
|
| **resolve-userid** | Converts a Telegram username to its numeric user ID. |
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
All nodes provide a **Debug** checkbox. When enabled the node will log its input and output messages to aid troubleshooting.
|
|
24
|
+
|
package/nodes/auth.html
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
api_id: { value: "" },
|
|
8
8
|
api_hash: { value: "" },
|
|
9
9
|
phoneNumber: { value: "" },
|
|
10
|
-
password: { value: "" }
|
|
10
|
+
password: { value: "" },
|
|
11
|
+
debug: { value: false }
|
|
11
12
|
},
|
|
12
13
|
inputs: 1,
|
|
13
14
|
outputs: 1,
|
|
@@ -70,6 +71,12 @@
|
|
|
70
71
|
</label>
|
|
71
72
|
<input type="password" id="node-input-password" placeholder="Enter your password (if any)">
|
|
72
73
|
</div>
|
|
74
|
+
<div class="form-row">
|
|
75
|
+
<label for="node-input-debug">
|
|
76
|
+
<i class="fa fa-bug"></i> Debug
|
|
77
|
+
</label>
|
|
78
|
+
<input type="checkbox" id="node-input-debug">
|
|
79
|
+
</div>
|
|
73
80
|
|
|
74
81
|
<p>
|
|
75
82
|
<strong>Note:</strong> These values are used to create a Telegram session string.
|
|
@@ -78,6 +85,7 @@
|
|
|
78
85
|
|
|
79
86
|
<script type="text/html" data-help-name="auth">
|
|
80
87
|
<p>The <b>auth</b> node facilitates Telegram API authentication using the <code>telegram</code> (GramJS) library. It allows users to authenticate a session and retrieve a <code>stringSession</code> for reuse with other Telegram clients.</p>
|
|
88
|
+
<p>Enable <b>Debug</b> to log the incoming credentials and returned session.</p>
|
|
81
89
|
|
|
82
90
|
<h3>Inputs</h3>
|
|
83
91
|
<dl class="message-properties">
|
package/nodes/auth.js
CHANGED
|
@@ -5,8 +5,13 @@ module.exports = function (RED) {
|
|
|
5
5
|
function TelegramClientConfig(config) {
|
|
6
6
|
RED.nodes.createNode(this, config);
|
|
7
7
|
const node = this;
|
|
8
|
+
this.debugEnabled = config.debug;
|
|
8
9
|
|
|
9
10
|
this.on("input", async (msg) => {
|
|
11
|
+
const debug = node.debugEnabled || msg.debug;
|
|
12
|
+
if (debug) {
|
|
13
|
+
node.log('auth input: ' + JSON.stringify(msg));
|
|
14
|
+
}
|
|
10
15
|
|
|
11
16
|
const payload = (msg && typeof msg.payload === "object") ? msg.payload : {};
|
|
12
17
|
|
|
@@ -53,22 +58,27 @@ module.exports = function (RED) {
|
|
|
53
58
|
]
|
|
54
59
|
});
|
|
55
60
|
|
|
56
|
-
|
|
61
|
+
const out = {
|
|
57
62
|
topic: "auth_success",
|
|
58
63
|
payload: {
|
|
59
64
|
stringSession,
|
|
60
65
|
message: "Authorization successful!"
|
|
61
66
|
}
|
|
62
|
-
}
|
|
67
|
+
};
|
|
68
|
+
node.send(out);
|
|
69
|
+
if (debug) {
|
|
70
|
+
node.log('auth output: ' + JSON.stringify(out));
|
|
71
|
+
}
|
|
63
72
|
|
|
64
73
|
node.status({ fill: "green", shape: "dot", text: "Authenticated" });
|
|
65
74
|
|
|
66
75
|
} catch (err) {
|
|
67
76
|
node.error("Authentication failed: " + err.message);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
77
|
+
const out = { topic: "auth_error", payload: { error: err.message } };
|
|
78
|
+
node.send(out);
|
|
79
|
+
if (debug) {
|
|
80
|
+
node.log('auth output: ' + JSON.stringify(out));
|
|
81
|
+
}
|
|
72
82
|
node.status({ fill: "red", shape: "ring", text: "Failed" });
|
|
73
83
|
}
|
|
74
84
|
});
|
package/nodes/command.html
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
name: { value: '' },
|
|
8
8
|
config: { type: 'config', required: false },
|
|
9
9
|
command: { value: "", required: true },
|
|
10
|
-
regex: { value: false }
|
|
10
|
+
regex: { value: false },
|
|
11
|
+
debug: { value: false }
|
|
11
12
|
},
|
|
12
13
|
inputs: 1,
|
|
13
14
|
outputs: 1,
|
|
@@ -41,6 +42,12 @@
|
|
|
41
42
|
style="width: 60%"
|
|
42
43
|
/>
|
|
43
44
|
</div>
|
|
45
|
+
<div class="form-row">
|
|
46
|
+
<label for="node-input-debug">
|
|
47
|
+
<i class="fa fa-bug"></i> Debug
|
|
48
|
+
</label>
|
|
49
|
+
<input type="checkbox" id="node-input-debug">
|
|
50
|
+
</div>
|
|
44
51
|
|
|
45
52
|
<div class="form-row">
|
|
46
53
|
<label for="node-input-command">
|
|
@@ -57,8 +64,9 @@
|
|
|
57
64
|
</div>
|
|
58
65
|
</script>
|
|
59
66
|
|
|
60
|
-
|
|
67
|
+
<script type="text/html" data-help-name="command">
|
|
61
68
|
<p>The <b>command</b> node listens for specific commands or patterns in Telegram messages and triggers further processing when a match is found. It supports both exact matches and regex-based pattern matching.</p>
|
|
69
|
+
<p>Enable <b>Debug</b> to log matching updates and outputs.</p>
|
|
62
70
|
|
|
63
71
|
<h3>Inputs</h3>
|
|
64
72
|
<p>This node does not take any direct inputs. Instead, it listens for incoming messages from the Telegram bot or user.</p>
|
package/nodes/command.js
CHANGED
|
@@ -5,48 +5,61 @@ module.exports = function (RED) {
|
|
|
5
5
|
function Command(config) {
|
|
6
6
|
RED.nodes.createNode(this, config);
|
|
7
7
|
this.config = RED.nodes.getNode(config.config);
|
|
8
|
+
this.debugEnabled = config.debug;
|
|
8
9
|
var node = this;
|
|
9
10
|
/** @type {TelegramClient} */
|
|
10
11
|
const client = this.config.client;
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const event = new NewMessage();
|
|
14
|
+
const handler = (update) => {
|
|
15
|
+
const debug = node.debugEnabled;
|
|
16
|
+
const message = update.message.message;
|
|
17
|
+
if (debug) {
|
|
18
|
+
node.log('command update: ' + JSON.stringify(update));
|
|
19
|
+
}
|
|
17
20
|
if (message) {
|
|
18
21
|
if (config.regex) {
|
|
19
22
|
const regex = new RegExp(config.command);
|
|
20
23
|
|
|
21
24
|
if (regex.test(message)) {
|
|
22
|
-
|
|
23
25
|
var msg = {
|
|
24
26
|
payload: {
|
|
25
27
|
update
|
|
26
28
|
}
|
|
27
29
|
};
|
|
28
|
-
|
|
29
|
-
|
|
30
30
|
node.send(msg);
|
|
31
|
+
if (debug) {
|
|
32
|
+
node.log('command output: ' + JSON.stringify(msg));
|
|
33
|
+
}
|
|
31
34
|
}
|
|
32
35
|
} else if (message === config.command) {
|
|
33
|
-
|
|
34
36
|
var msg = {
|
|
35
37
|
payload: {
|
|
36
38
|
update
|
|
37
39
|
}
|
|
38
40
|
};
|
|
39
|
-
|
|
40
|
-
|
|
41
41
|
node.send(msg);
|
|
42
|
+
if (debug) {
|
|
43
|
+
node.log('command output: ' + JSON.stringify(msg));
|
|
44
|
+
}
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
client.addEventHandler(handler, event);
|
|
46
51
|
} catch (err) {
|
|
47
52
|
node.error('Authorization error: ' + err.message);
|
|
48
53
|
}
|
|
49
54
|
|
|
55
|
+
this.on('close', () => {
|
|
56
|
+
try {
|
|
57
|
+
client.removeEventHandler(handler, event);
|
|
58
|
+
} catch (err) {
|
|
59
|
+
node.error('Handler removal error: ' + err.message);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
50
63
|
}
|
|
51
64
|
|
|
52
65
|
RED.nodes.registerType('command', Command);
|
package/nodes/config.html
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
api_id: {value:"", required:true},
|
|
7
7
|
api_hash: {value:"", required:true},
|
|
8
8
|
session: {value:"", required:true},
|
|
9
|
+
debug: {value:false},
|
|
9
10
|
useIPV6: {value: undefined},
|
|
10
11
|
timeout: {value: undefined},
|
|
11
12
|
requestRetries: {value: undefined},
|
|
@@ -52,6 +53,10 @@
|
|
|
52
53
|
<label for="node-config-input-session"><i class="icon-tasks"></i> Session</label>
|
|
53
54
|
<input type="text" id="node-config-input-session" placeholder="Enter Session" style="width:70%" ng-model="node.session">
|
|
54
55
|
</div>
|
|
56
|
+
<div class="form-row">
|
|
57
|
+
<label for="node-config-input-debug"><i class="icon-bug"></i> Debug</label>
|
|
58
|
+
<input type="checkbox" id="node-config-input-debug" ng-model="node.debug">
|
|
59
|
+
</div>
|
|
55
60
|
<div class="form-row">
|
|
56
61
|
<label for="node-config-input-useIPV6"><i class="icon-tasks"></i> Use IPV6</label>
|
|
57
62
|
<input type="checkbox" id="node-config-input-useIPV6" ng-model="node.useIPV6">
|
package/nodes/config.js
CHANGED
|
@@ -6,6 +6,7 @@ const activeClients = new Map(); // Cache: session string → { client, refCount
|
|
|
6
6
|
module.exports = function (RED) {
|
|
7
7
|
function TelegramClientConfig(config) {
|
|
8
8
|
RED.nodes.createNode(this, config);
|
|
9
|
+
this.debugEnabled = config.debug;
|
|
9
10
|
|
|
10
11
|
const sessionStr = config.session;
|
|
11
12
|
const apiId = parseInt(config.api_id);
|
|
@@ -21,6 +22,9 @@ module.exports = function (RED) {
|
|
|
21
22
|
const record = activeClients.get(sessionStr);
|
|
22
23
|
this.client = record.client;
|
|
23
24
|
record.refCount += 1;
|
|
25
|
+
if (this.debugEnabled) {
|
|
26
|
+
node.log('config: reusing existing client');
|
|
27
|
+
}
|
|
24
28
|
if (record.connecting) {
|
|
25
29
|
node.status({ fill: "yellow", shape: "dot", text: "Waiting for connection" });
|
|
26
30
|
record.connecting.then(() => {
|
|
@@ -31,6 +35,9 @@ module.exports = function (RED) {
|
|
|
31
35
|
}
|
|
32
36
|
} else {
|
|
33
37
|
// Create and connect new client
|
|
38
|
+
if (this.debugEnabled) {
|
|
39
|
+
node.log('config: creating new client');
|
|
40
|
+
}
|
|
34
41
|
this.client = new TelegramClient(this.session, apiId, apiHash, {
|
|
35
42
|
connectionRetries: config.connectionRetries || 5,
|
|
36
43
|
autoReconnect: config.autoReconnect !== false,
|
|
@@ -49,6 +56,9 @@ module.exports = function (RED) {
|
|
|
49
56
|
})
|
|
50
57
|
.then(() => {
|
|
51
58
|
node.status({ fill: "green", shape: "dot", text: "Connected" });
|
|
59
|
+
if (this.debugEnabled) {
|
|
60
|
+
node.log('config: connected');
|
|
61
|
+
}
|
|
52
62
|
record.connecting = null;
|
|
53
63
|
})
|
|
54
64
|
.catch(err => {
|
|
@@ -65,6 +75,9 @@ module.exports = function (RED) {
|
|
|
65
75
|
if (record && record.client === this.client) {
|
|
66
76
|
record.refCount -= 1;
|
|
67
77
|
if (record.refCount <= 0) {
|
|
78
|
+
if (this.debugEnabled) {
|
|
79
|
+
node.log('config: disconnecting client');
|
|
80
|
+
}
|
|
68
81
|
try {
|
|
69
82
|
await this.client.disconnect();
|
|
70
83
|
} catch (err) {
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
defaults: {
|
|
8
8
|
name: { value: '' },
|
|
9
9
|
config: { type: 'config', required: false },
|
|
10
|
+
debug: { value: false },
|
|
10
11
|
},
|
|
11
12
|
inputs: 1,
|
|
12
13
|
outputs: 1,
|
|
@@ -40,11 +41,18 @@
|
|
|
40
41
|
style="width: 60%"
|
|
41
42
|
/>
|
|
42
43
|
</div>
|
|
44
|
+
<div class="form-row">
|
|
45
|
+
<label for="node-input-debug">
|
|
46
|
+
<i class="fa fa-bug"></i> Debug
|
|
47
|
+
</label>
|
|
48
|
+
<input type="checkbox" id="node-input-debug">
|
|
49
|
+
</div>
|
|
43
50
|
</script>
|
|
44
51
|
|
|
45
52
|
|
|
46
|
-
|
|
53
|
+
<script type="text/html" data-help-name="delete-message">
|
|
47
54
|
<p>The <b>delete-message</b> node allows you to delete messages from a Telegram chat. It supports deleting multiple messages at once and provides an option to revoke messages for all chat participants.</p>
|
|
55
|
+
<p>Enable <b>Debug</b> to log the input and output.</p>
|
|
48
56
|
|
|
49
57
|
<h3>Inputs</h3>
|
|
50
58
|
<dl class="message-properties">
|
package/nodes/delete-message.js
CHANGED
|
@@ -2,9 +2,14 @@ module.exports = function (RED) {
|
|
|
2
2
|
function DeleteMessage(config) {
|
|
3
3
|
RED.nodes.createNode(this, config);
|
|
4
4
|
this.config = RED.nodes.getNode(config.config);
|
|
5
|
+
this.debugEnabled = config.debug;
|
|
5
6
|
var node = this;
|
|
6
7
|
|
|
7
8
|
this.on('input', async function (msg) {
|
|
9
|
+
const debug = node.debugEnabled || msg.debug;
|
|
10
|
+
if (debug) {
|
|
11
|
+
node.log('delete-message input: ' + JSON.stringify(msg));
|
|
12
|
+
}
|
|
8
13
|
const chatId = msg.payload.chatId || config.chatId;
|
|
9
14
|
const messageIds = msg.payload.messageIds || config.messageIds;
|
|
10
15
|
const revoke = msg.payload.revoke || config.revoke || { revoke: true };
|
|
@@ -14,9 +19,11 @@ module.exports = function (RED) {
|
|
|
14
19
|
try {
|
|
15
20
|
const response = await client.deleteMessages(chatId, messageIds, revoke);
|
|
16
21
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
const out = { payload: response };
|
|
23
|
+
node.send(out);
|
|
24
|
+
if (debug) {
|
|
25
|
+
node.log('delete-message output: ' + JSON.stringify(out));
|
|
26
|
+
}
|
|
20
27
|
} catch (err) {
|
|
21
28
|
node.error('Error deleting message: ' + err.message);
|
|
22
29
|
}
|
package/nodes/get-entity.html
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
defaults: {
|
|
8
8
|
name: { value: '' },
|
|
9
9
|
config: { type: 'config', required: false },
|
|
10
|
+
debug: { value: false },
|
|
10
11
|
},
|
|
11
12
|
inputs: 1,
|
|
12
13
|
outputs: 1,
|
|
@@ -40,10 +41,17 @@
|
|
|
40
41
|
style="width: 60%"
|
|
41
42
|
/>
|
|
42
43
|
</div>
|
|
44
|
+
<div class="form-row">
|
|
45
|
+
<label for="node-input-debug">
|
|
46
|
+
<i class="fa fa-bug"></i> Debug
|
|
47
|
+
</label>
|
|
48
|
+
<input type="checkbox" id="node-input-debug" />
|
|
49
|
+
</div>
|
|
43
50
|
</script>
|
|
44
51
|
|
|
45
52
|
<script type="text/html" data-help-name="get-entity">
|
|
46
53
|
<p>The <b>get-entity</b> node retrieves information about a Telegram entity (e.g., user, chat, or channel) using its identifier or URL.</p>
|
|
54
|
+
<p>Enable <b>Debug</b> to print incoming and outgoing messages to the log.</p>
|
|
47
55
|
|
|
48
56
|
<h3>Inputs</h3>
|
|
49
57
|
<dl class="message-properties">
|
package/nodes/get-entity.js
CHANGED
|
@@ -2,9 +2,14 @@ module.exports = function (RED) {
|
|
|
2
2
|
function GetEntity(config) {
|
|
3
3
|
RED.nodes.createNode(this, config);
|
|
4
4
|
this.config = RED.nodes.getNode(config.config);
|
|
5
|
+
this.debugEnabled = config.debug;
|
|
5
6
|
var node = this;
|
|
6
7
|
|
|
7
8
|
this.on('input', async function (msg) {
|
|
9
|
+
const debug = node.debugEnabled || msg.debug;
|
|
10
|
+
if (debug) {
|
|
11
|
+
node.log('get-entity input: ' + JSON.stringify(msg));
|
|
12
|
+
}
|
|
8
13
|
const input = msg.payload.input || config.input;
|
|
9
14
|
/** @type {TelegramClient} */
|
|
10
15
|
const client = msg.payload?.client ? msg.payload.client : this.config.client;
|
|
@@ -20,14 +25,18 @@ module.exports = function (RED) {
|
|
|
20
25
|
entity = await client.getEntity(input);
|
|
21
26
|
}
|
|
22
27
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
const out = { payload: { input: entity } };
|
|
29
|
+
node.send(out);
|
|
30
|
+
if (debug) {
|
|
31
|
+
node.log('get-entity output: ' + JSON.stringify(out));
|
|
32
|
+
}
|
|
26
33
|
} catch (err) {
|
|
27
34
|
node.error('Error getting entity: ' + err.message);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
const out = { payload: { input: null } };
|
|
36
|
+
node.send(out);
|
|
37
|
+
if (debug) {
|
|
38
|
+
node.log('get-entity output: ' + JSON.stringify(out));
|
|
39
|
+
}
|
|
31
40
|
}
|
|
32
41
|
});
|
|
33
42
|
}
|
package/nodes/iter-dialogs.html
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
defaults: {
|
|
8
8
|
name: { value: '' },
|
|
9
9
|
config: { type: 'config', required: true },
|
|
10
|
+
debug: { value: false },
|
|
10
11
|
limit: { value: "" },
|
|
11
12
|
offsetDate: { value: ""},
|
|
12
13
|
offsetId: { value: "" },
|
|
@@ -49,6 +50,12 @@
|
|
|
49
50
|
ng-model="config"
|
|
50
51
|
/>
|
|
51
52
|
</div>
|
|
53
|
+
<div class="form-row">
|
|
54
|
+
<label for="node-input-debug">
|
|
55
|
+
<i class="fa fa-bug"></i> Debug
|
|
56
|
+
</label>
|
|
57
|
+
<input type="checkbox" id="node-input-debug" ng-model="debug" />
|
|
58
|
+
</div>
|
|
52
59
|
<div class="form-row">
|
|
53
60
|
<label for="node-input-limit">
|
|
54
61
|
<i class="fa fa-tag"></i> Limit
|
|
@@ -131,6 +138,7 @@
|
|
|
131
138
|
|
|
132
139
|
<script type="text/html" data-help-name="iter-dialogs">
|
|
133
140
|
<p>The <b>iter-dialogs</b> node retrieves a list of Telegram dialogs (chats, channels, or groups) by iterating through them using the Telegram API.</p>
|
|
141
|
+
<p>Enable <b>Debug</b> to log the request and resulting dialogs.</p>
|
|
134
142
|
|
|
135
143
|
<h3>Inputs</h3>
|
|
136
144
|
<dl class="message-properties">
|
package/nodes/iter-dialogs.js
CHANGED
|
@@ -4,9 +4,14 @@ module.exports = function (RED) {
|
|
|
4
4
|
function IterDialogs(config) {
|
|
5
5
|
RED.nodes.createNode(this, config);
|
|
6
6
|
this.config = RED.nodes.getNode(config.config);
|
|
7
|
+
this.debugEnabled = config.debug;
|
|
7
8
|
var node = this;
|
|
8
9
|
|
|
9
10
|
this.on('input', async function (msg) {
|
|
11
|
+
const debug = node.debugEnabled || msg.debug;
|
|
12
|
+
if (debug) {
|
|
13
|
+
node.log('iter-dialogs input: ' + JSON.stringify(msg));
|
|
14
|
+
}
|
|
10
15
|
|
|
11
16
|
/** @type {TelegramClient} */
|
|
12
17
|
const client = msg.payload?.client ? msg.payload.client : this.config.client;
|
|
@@ -40,9 +45,11 @@ module.exports = function (RED) {
|
|
|
40
45
|
dialogs[dialog.id] = dialog;
|
|
41
46
|
console.log(`${dialog.id}: ${dialog.title}`);
|
|
42
47
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
const out = { payload: { dialogs } };
|
|
49
|
+
node.send(out);
|
|
50
|
+
if (debug) {
|
|
51
|
+
node.log('iter-dialogs output: ' + JSON.stringify(out));
|
|
52
|
+
}
|
|
46
53
|
} catch (err) {
|
|
47
54
|
node.error('Error iter dialogs: ' + err.message);
|
|
48
55
|
}
|
package/nodes/iter-messages.html
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
defaults: {
|
|
8
8
|
name: { value: '' },
|
|
9
9
|
config: { type: 'config', required: true },
|
|
10
|
+
debug: { value: false },
|
|
10
11
|
chatId: { value: '', required: false },
|
|
11
12
|
limit: { value: '', required: false },
|
|
12
13
|
offsetDate: { value: '', required: false },
|
|
@@ -68,6 +69,12 @@
|
|
|
68
69
|
ng-model="config"
|
|
69
70
|
/>
|
|
70
71
|
</div>
|
|
72
|
+
<div class="form-row">
|
|
73
|
+
<label for="node-input-debug">
|
|
74
|
+
<i class="fa fa-bug"></i> Debug
|
|
75
|
+
</label>
|
|
76
|
+
<input type="checkbox" id="node-input-debug" ng-model="debug" />
|
|
77
|
+
</div>
|
|
71
78
|
<div class="form-row">
|
|
72
79
|
<label for="node-input-chatId">
|
|
73
80
|
<i class="fa fa-tag"></i> Chat ID
|
|
@@ -259,6 +266,7 @@
|
|
|
259
266
|
|
|
260
267
|
<script type="text/html" data-help-name="iter-messages">
|
|
261
268
|
<p>The <b>iter-messages</b> node retrieves messages from a specified chat or user using the Telegram API. It supports a wide range of filtering and pagination options, allowing for efficient message iteration.</p>
|
|
269
|
+
<p>When <b>Debug</b> is enabled, incoming parameters and results are logged.</p>
|
|
262
270
|
|
|
263
271
|
<h3>Inputs</h3>
|
|
264
272
|
<dl class="message-properties">
|
package/nodes/iter-messages.js
CHANGED
|
@@ -4,9 +4,14 @@ module.exports = function (RED) {
|
|
|
4
4
|
function IterMessages(config) {
|
|
5
5
|
RED.nodes.createNode(this, config);
|
|
6
6
|
this.config = RED.nodes.getNode(config.config);
|
|
7
|
+
this.debugEnabled = config.debug;
|
|
7
8
|
var node = this;
|
|
8
9
|
|
|
9
10
|
this.on('input', async function (msg) {
|
|
11
|
+
const debug = node.debugEnabled || msg.debug;
|
|
12
|
+
if (debug) {
|
|
13
|
+
node.log('iter-messages input: ' + JSON.stringify(msg));
|
|
14
|
+
}
|
|
10
15
|
|
|
11
16
|
/** @type {TelegramClient} */
|
|
12
17
|
const client = msg.payload?.client ? msg.payload.client : this.config.client;
|
|
@@ -80,9 +85,11 @@ module.exports = function (RED) {
|
|
|
80
85
|
}
|
|
81
86
|
}
|
|
82
87
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
88
|
+
const out = { payload: { messages } };
|
|
89
|
+
node.send(out);
|
|
90
|
+
if (debug) {
|
|
91
|
+
node.log('iter-messages output: ' + JSON.stringify(out));
|
|
92
|
+
}
|
|
86
93
|
} catch (err) {
|
|
87
94
|
node.error('Error iter messages: ' + err.message);
|
|
88
95
|
}
|
package/nodes/promote-admin.html
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
defaults: {
|
|
8
8
|
name: { value: '' },
|
|
9
9
|
config: { type: 'config', required: false },
|
|
10
|
+
debug: { value: false },
|
|
10
11
|
chatId: { value: '' },
|
|
11
12
|
userId: { value: '' },
|
|
12
13
|
rank: { value: 'admin' },
|
|
@@ -43,6 +44,10 @@
|
|
|
43
44
|
<label for="node-input-config"><i class="fa fa-gear"></i> Config</label>
|
|
44
45
|
<input type="hidden" id="node-input-config">
|
|
45
46
|
</div>
|
|
47
|
+
<div class="form-row">
|
|
48
|
+
<label for="node-input-debug"><i class="fa fa-bug"></i> Debug</label>
|
|
49
|
+
<input type="checkbox" id="node-input-debug">
|
|
50
|
+
</div>
|
|
46
51
|
|
|
47
52
|
<div class="form-row">
|
|
48
53
|
<label for="node-input-chatId"><i class="fa fa-users"></i> Chat ID</label>
|
|
@@ -193,6 +198,7 @@
|
|
|
193
198
|
</script>
|
|
194
199
|
<script type="text/html" data-help-name="promote-admin">
|
|
195
200
|
<p><b>Promote Admin</b> lets you promote a user to admin in a Telegram group or channel using the Telegram MTProto API (via GramJS).</p>
|
|
201
|
+
<p>With <b>Debug</b> enabled the node logs its request and the response from Telegram.</p>
|
|
196
202
|
|
|
197
203
|
<h3>Inputs</h3>
|
|
198
204
|
<dl class="message-properties">
|
package/nodes/promote-admin.js
CHANGED
|
@@ -6,9 +6,14 @@ module.exports = function (RED) {
|
|
|
6
6
|
function PromoteAdmin(config) {
|
|
7
7
|
RED.nodes.createNode(this, config);
|
|
8
8
|
this.config = RED.nodes.getNode(config.config);
|
|
9
|
+
this.debugEnabled = config.debug;
|
|
9
10
|
var node = this;
|
|
10
11
|
|
|
11
12
|
this.on('input', async function (msg) {
|
|
13
|
+
const debug = node.debugEnabled || msg.debug;
|
|
14
|
+
if (debug) {
|
|
15
|
+
node.log('promote-admin input: ' + JSON.stringify(msg));
|
|
16
|
+
}
|
|
12
17
|
const client = msg.payload?.client || this.config.client;
|
|
13
18
|
const chatId = msg.payload.chatId || config.chatId;
|
|
14
19
|
const userId = msg.payload.userId || config.userId;
|
|
@@ -39,7 +44,11 @@ module.exports = function (RED) {
|
|
|
39
44
|
rank: rank,
|
|
40
45
|
}));
|
|
41
46
|
|
|
42
|
-
|
|
47
|
+
const out = { payload: { response: result } };
|
|
48
|
+
node.send(out);
|
|
49
|
+
if (debug) {
|
|
50
|
+
node.log('promote-admin output: ' + JSON.stringify(out));
|
|
51
|
+
}
|
|
43
52
|
} catch (err) {
|
|
44
53
|
node.error("Error promoting admin: " + err.message);
|
|
45
54
|
}
|
package/nodes/receiver.html
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
defaults: {
|
|
7
7
|
name: { value: '' },
|
|
8
8
|
config: { type: 'config', required: false },
|
|
9
|
-
ignore: { value:""}
|
|
9
|
+
ignore: { value:""},
|
|
10
|
+
debug: { value: false }
|
|
10
11
|
},
|
|
11
12
|
inputs: 1,
|
|
12
13
|
outputs: 1,
|
|
@@ -40,6 +41,12 @@
|
|
|
40
41
|
style="width: 60%"
|
|
41
42
|
/>
|
|
42
43
|
</div>
|
|
44
|
+
<div class="form-row">
|
|
45
|
+
<label for="node-input-debug">
|
|
46
|
+
<i class="fa fa-bug"></i> Debug
|
|
47
|
+
</label>
|
|
48
|
+
<input type="checkbox" id="node-input-debug">
|
|
49
|
+
</div>
|
|
43
50
|
<div class="form-row">
|
|
44
51
|
<label for="node-input-ignore">
|
|
45
52
|
<i class="fa fa-tag"></i> Config
|
|
@@ -53,8 +60,9 @@
|
|
|
53
60
|
</div>
|
|
54
61
|
</script>
|
|
55
62
|
|
|
56
|
-
|
|
63
|
+
<script type="text/html" data-help-name="receiver">
|
|
57
64
|
<p>The <b>receiver</b> node listens for incoming Telegram messages and forwards them as output messages in Node-RED. It supports filtering messages based on sender IDs to ignore specific users.</p>
|
|
65
|
+
<p>Turn on <b>Debug</b> to log received updates and the emitted messages.</p>
|
|
58
66
|
|
|
59
67
|
<h3>Inputs</h3>
|
|
60
68
|
<p>This node does not take any direct inputs. It listens to all incoming messages from the configured Telegram client.</p>
|
package/nodes/receiver.js
CHANGED
|
@@ -4,28 +4,40 @@ module.exports = function (RED) {
|
|
|
4
4
|
function Receiver(config) {
|
|
5
5
|
RED.nodes.createNode(this, config);
|
|
6
6
|
this.config = RED.nodes.getNode(config.config);
|
|
7
|
+
this.debugEnabled = config.debug;
|
|
7
8
|
var node = this;
|
|
8
9
|
const client = this.config.client;
|
|
9
10
|
const ignore = config.ignore.split(/\n/);
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
if
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
const event = new NewMessage();
|
|
13
|
+
const handler = (update) => {
|
|
14
|
+
const debug = node.debugEnabled;
|
|
15
|
+
if (debug) {
|
|
16
|
+
node.log('receiver update: ' + JSON.stringify(update));
|
|
17
|
+
}
|
|
18
|
+
if (update.message.fromId != null && !ignore.includes(update.message.fromId.userId.toString())) {
|
|
19
|
+
const out = { payload: { update } };
|
|
20
|
+
node.send(out);
|
|
21
|
+
if (debug) {
|
|
22
|
+
node.log('receiver output: ' + JSON.stringify(out));
|
|
19
23
|
}
|
|
20
|
-
} )
|
|
21
24
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
client.addEventHandler(handler, event);
|
|
25
29
|
} catch (err) {
|
|
26
30
|
node.error('Authorization error: ' + err.message);
|
|
27
31
|
}
|
|
28
32
|
|
|
33
|
+
this.on('close', () => {
|
|
34
|
+
try {
|
|
35
|
+
client.removeEventHandler(handler, event);
|
|
36
|
+
} catch (err) {
|
|
37
|
+
node.error('Handler removal error: ' + err.message);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
29
41
|
}
|
|
30
42
|
|
|
31
43
|
RED.nodes.registerType('receiver', Receiver);
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
defaults: {
|
|
8
8
|
name: { value: '' },
|
|
9
9
|
config: { type: 'config', required: false },
|
|
10
|
-
username: { value: '' }
|
|
10
|
+
username: { value: '' },
|
|
11
|
+
debug: { value: false }
|
|
11
12
|
},
|
|
12
13
|
inputs: 1,
|
|
13
14
|
outputs: 1,
|
|
@@ -25,11 +26,17 @@
|
|
|
25
26
|
</label>
|
|
26
27
|
<input type="text" id="node-input-name" placeholder="Name" style="width: 60%" />
|
|
27
28
|
</div>
|
|
29
|
+
<div class="form-row">
|
|
30
|
+
<label for="node-input-config">
|
|
31
|
+
<i class="fa fa-gear"></i> Config
|
|
32
|
+
</label>
|
|
33
|
+
<input type="text" id="node-input-config" placeholder="Config" style="width: 60%" />
|
|
34
|
+
</div>
|
|
28
35
|
<div class="form-row">
|
|
29
|
-
<label for="node-input-
|
|
30
|
-
<i class="fa fa-
|
|
36
|
+
<label for="node-input-debug">
|
|
37
|
+
<i class="fa fa-bug"></i> Debug
|
|
31
38
|
</label>
|
|
32
|
-
<input type="
|
|
39
|
+
<input type="checkbox" id="node-input-debug" />
|
|
33
40
|
</div>
|
|
34
41
|
<div class="form-row">
|
|
35
42
|
<label for="node-input-username">
|
|
@@ -41,6 +48,7 @@
|
|
|
41
48
|
|
|
42
49
|
<script type="text/html" data-help-name="resolve-userid">
|
|
43
50
|
<p>The <b>resolve-userid</b> node converts a Telegram username into a numeric user ID.</p>
|
|
51
|
+
<p>Select <b>Debug</b> to log lookups and results.</p>
|
|
44
52
|
<h3>Inputs</h3>
|
|
45
53
|
<dl class="message-properties">
|
|
46
54
|
<dt>payload.username <span class="property-type">string</span></dt>
|
package/nodes/resolve-userid.js
CHANGED
|
@@ -2,9 +2,14 @@ module.exports = function(RED) {
|
|
|
2
2
|
function ResolveUserId(config) {
|
|
3
3
|
RED.nodes.createNode(this, config);
|
|
4
4
|
this.config = RED.nodes.getNode(config.config);
|
|
5
|
+
this.debugEnabled = config.debug;
|
|
5
6
|
var node = this;
|
|
6
7
|
|
|
7
8
|
this.on('input', async function(msg) {
|
|
9
|
+
const debug = node.debugEnabled || msg.debug;
|
|
10
|
+
if (debug) {
|
|
11
|
+
node.log('resolve-userid input: ' + JSON.stringify(msg));
|
|
12
|
+
}
|
|
8
13
|
const username = msg.payload?.username || config.username;
|
|
9
14
|
const client = msg.payload?.client ? msg.payload.client : node.config?.client;
|
|
10
15
|
|
|
@@ -25,10 +30,18 @@ module.exports = function(RED) {
|
|
|
25
30
|
} else if (entity?.userId) {
|
|
26
31
|
userId = entity.userId;
|
|
27
32
|
}
|
|
28
|
-
|
|
33
|
+
const out = { payload: { userId } };
|
|
34
|
+
node.send(out);
|
|
35
|
+
if (debug) {
|
|
36
|
+
node.log('resolve-userid output: ' + JSON.stringify(out));
|
|
37
|
+
}
|
|
29
38
|
} catch (err) {
|
|
30
39
|
node.error('Error resolving username: ' + err.message);
|
|
31
|
-
|
|
40
|
+
const out = { payload: { userId: null } };
|
|
41
|
+
node.send(out);
|
|
42
|
+
if (debug) {
|
|
43
|
+
node.log('resolve-userid output: ' + JSON.stringify(out));
|
|
44
|
+
}
|
|
32
45
|
}
|
|
33
46
|
});
|
|
34
47
|
}
|
package/nodes/send-file.html
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
name: { value: '' },
|
|
7
7
|
config: { type: 'config', required: true },
|
|
8
8
|
chatId: { value: '', required: true },
|
|
9
|
+
debug: { value: false },
|
|
9
10
|
files: { value: '', required: true },
|
|
10
11
|
caption: { value: '' },
|
|
11
12
|
forceDocument: { value: false },
|
|
@@ -64,6 +65,12 @@
|
|
|
64
65
|
ng-model="config"
|
|
65
66
|
/>
|
|
66
67
|
</div>
|
|
68
|
+
<div class="form-row">
|
|
69
|
+
<label for="node-input-debug">
|
|
70
|
+
<i class="fa fa-bug"></i> Debug
|
|
71
|
+
</label>
|
|
72
|
+
<input type="checkbox" id="node-input-debug" ng-model="debug" />
|
|
73
|
+
</div>
|
|
67
74
|
<div class="form-row">
|
|
68
75
|
<label for="node-input-chatId">
|
|
69
76
|
<i class="fa fa-tag"></i> Chat ID
|
|
@@ -318,6 +325,7 @@
|
|
|
318
325
|
|
|
319
326
|
<script type="text/html" data-help-name="send-files">
|
|
320
327
|
<p>The <b>send-files</b> node allows you to send files to a Telegram chat or user using the Telegram API. It supports a wide range of parameters, including file attributes, captions, buttons, and scheduling options.</p>
|
|
328
|
+
<p>When the <b>Debug</b> option is enabled the node logs incoming and outgoing messages.</p>
|
|
321
329
|
|
|
322
330
|
<h3>Inputs</h3>
|
|
323
331
|
<dl class="message-properties">
|
package/nodes/send-file.js
CHANGED
|
@@ -2,9 +2,14 @@ module.exports = function (RED) {
|
|
|
2
2
|
function SendFile(config) {
|
|
3
3
|
RED.nodes.createNode(this, config);
|
|
4
4
|
this.config = RED.nodes.getNode(config.config);
|
|
5
|
+
this.debugEnabled = config.debug;
|
|
5
6
|
var node = this;
|
|
6
7
|
|
|
7
8
|
this.on('input', async function (msg) {
|
|
9
|
+
const debug = node.debugEnabled || msg.debug;
|
|
10
|
+
if (debug) {
|
|
11
|
+
node.log('send-files input: ' + JSON.stringify(msg));
|
|
12
|
+
}
|
|
8
13
|
const chatId = msg.payload.chatId || config.chatId;
|
|
9
14
|
const files = msg.payload.files || config.files.split(',').map(file => file.trim());
|
|
10
15
|
const caption = msg.payload.caption || config.caption;
|
|
@@ -59,9 +64,11 @@ module.exports = function (RED) {
|
|
|
59
64
|
|
|
60
65
|
// Send files
|
|
61
66
|
const response = await client.sendFile(chatId, params);
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
const out = { payload: response };
|
|
68
|
+
node.send(out);
|
|
69
|
+
if (debug) {
|
|
70
|
+
node.log('send-files output: ' + JSON.stringify(out));
|
|
71
|
+
}
|
|
65
72
|
} catch (err) {
|
|
66
73
|
node.error('Error sending files: ' + err.message);
|
|
67
74
|
}
|
package/nodes/send-message.html
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
chatId: { value: '' },
|
|
10
10
|
message: { value: '' },
|
|
11
11
|
config: { type: 'config', required: false },
|
|
12
|
+
debug: { value: false },
|
|
12
13
|
parseMode: { value: 'md' }, // Default parse mode is Markdown
|
|
13
14
|
schedule: { value: '' }, // Default schedule is empty
|
|
14
15
|
replyTo: { value: '' }, // Reply to a message
|
|
@@ -100,6 +101,12 @@
|
|
|
100
101
|
</label>
|
|
101
102
|
<input type="hidden" id="node-input-config">
|
|
102
103
|
</div>
|
|
104
|
+
<div class="form-row">
|
|
105
|
+
<label for="node-input-debug">
|
|
106
|
+
<i class="fa fa-bug"></i> Debug
|
|
107
|
+
</label>
|
|
108
|
+
<input type="checkbox" id="node-input-debug">
|
|
109
|
+
</div>
|
|
103
110
|
|
|
104
111
|
<div class="form-row">
|
|
105
112
|
<label for="node-input-chatId">
|
|
@@ -214,6 +221,7 @@
|
|
|
214
221
|
|
|
215
222
|
<script type="text/html" data-help-name="send-message">
|
|
216
223
|
<p>The <b>send-message</b> node allows sending messages via Telegram using the <code>telegram</code> library. It supports various message types, formatting options, and additional features like scheduling and silent messages.</p>
|
|
224
|
+
<p>Enable the <b>Debug</b> option to log incoming and outgoing messages to the Node-RED log.</p>
|
|
217
225
|
|
|
218
226
|
<h3>Inputs</h3>
|
|
219
227
|
<dl class="message-properties">
|
package/nodes/send-message.js
CHANGED
|
@@ -5,9 +5,14 @@ module.exports = function (RED) {
|
|
|
5
5
|
function SendMessage(config) {
|
|
6
6
|
RED.nodes.createNode(this, config);
|
|
7
7
|
this.config = RED.nodes.getNode(config.config);
|
|
8
|
+
this.debugEnabled = config.debug;
|
|
8
9
|
var node = this;
|
|
9
10
|
|
|
10
11
|
this.on('input', async function (msg) {
|
|
12
|
+
const debug = node.debugEnabled || msg.debug;
|
|
13
|
+
if (debug) {
|
|
14
|
+
node.log('send-message input: ' + JSON.stringify(msg));
|
|
15
|
+
}
|
|
11
16
|
let chatId = msg.payload.chatId || config.chatId;
|
|
12
17
|
const message = msg.payload.message || config.message;
|
|
13
18
|
const parseMode = msg.payload.parseMode || config.parseMode;
|
|
@@ -68,9 +73,11 @@ module.exports = function (RED) {
|
|
|
68
73
|
await client.sendMessage(entity, params);
|
|
69
74
|
}
|
|
70
75
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
const out = { payload: { response } };
|
|
77
|
+
node.send(out);
|
|
78
|
+
if (debug) {
|
|
79
|
+
node.log('send-message output: ' + JSON.stringify(out));
|
|
80
|
+
}
|
|
74
81
|
} catch (err) {
|
|
75
82
|
node.error('Error send message: ' + err.message);
|
|
76
83
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const assert = require('assert');
|
|
2
|
+
const proxyquire = require('proxyquire').noPreserveCache();
|
|
3
|
+
|
|
4
|
+
function load() {
|
|
5
|
+
const addCalls = [];
|
|
6
|
+
const removeCalls = [];
|
|
7
|
+
class TelegramClientStub {
|
|
8
|
+
addEventHandler(fn, event) { addCalls.push({fn, event}); }
|
|
9
|
+
removeEventHandler(fn, event) { removeCalls.push({fn, event}); }
|
|
10
|
+
}
|
|
11
|
+
class NewMessageStub {}
|
|
12
|
+
|
|
13
|
+
let NodeCtor;
|
|
14
|
+
const configNode = { client: new TelegramClientStub() };
|
|
15
|
+
const RED = {
|
|
16
|
+
nodes: {
|
|
17
|
+
createNode(node) {
|
|
18
|
+
node._events = {};
|
|
19
|
+
node.on = (e, fn) => { node._events[e] = fn; };
|
|
20
|
+
},
|
|
21
|
+
registerType(name, ctor) { NodeCtor = ctor; },
|
|
22
|
+
getNode() { return configNode; }
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
proxyquire('../nodes/command.js', {
|
|
27
|
+
'telegram/events': { NewMessage: NewMessageStub }
|
|
28
|
+
})(RED);
|
|
29
|
+
|
|
30
|
+
return { NodeCtor, addCalls, removeCalls };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
describe('Command node', function() {
|
|
34
|
+
it('removes event handler on close', function() {
|
|
35
|
+
const { NodeCtor, addCalls, removeCalls } = load();
|
|
36
|
+
const node = new NodeCtor({config:'c', command:'cmd', regex:false});
|
|
37
|
+
assert.strictEqual(addCalls.length, 1);
|
|
38
|
+
node._events.close();
|
|
39
|
+
assert.strictEqual(removeCalls.length, 1);
|
|
40
|
+
assert.strictEqual(removeCalls[0].fn, addCalls[0].fn);
|
|
41
|
+
assert.strictEqual(removeCalls[0].event, addCalls[0].event);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const assert = require('assert');
|
|
2
|
+
const proxyquire = require('proxyquire').noPreserveCache();
|
|
3
|
+
|
|
4
|
+
function load() {
|
|
5
|
+
const addCalls = [];
|
|
6
|
+
const logs = [];
|
|
7
|
+
class TelegramClientStub {
|
|
8
|
+
addEventHandler(fn, event) { addCalls.push({fn, event}); }
|
|
9
|
+
removeEventHandler() {}
|
|
10
|
+
}
|
|
11
|
+
class NewMessageStub {}
|
|
12
|
+
|
|
13
|
+
let NodeCtor;
|
|
14
|
+
const configNode = { client: new TelegramClientStub() };
|
|
15
|
+
const RED = {
|
|
16
|
+
nodes: {
|
|
17
|
+
createNode(node) {
|
|
18
|
+
node._events = {};
|
|
19
|
+
node.on = (e, fn) => { node._events[e] = fn; };
|
|
20
|
+
node.log = (msg) => logs.push(msg);
|
|
21
|
+
node.send = () => {};
|
|
22
|
+
},
|
|
23
|
+
registerType(name, ctor) { NodeCtor = ctor; },
|
|
24
|
+
getNode() { return configNode; }
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
proxyquire('../nodes/command.js', {
|
|
29
|
+
'telegram/events': { NewMessage: NewMessageStub }
|
|
30
|
+
})(RED);
|
|
31
|
+
|
|
32
|
+
return { NodeCtor, addCalls, logs };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
describe('Debug option', function() {
|
|
36
|
+
it('logs update and output when enabled', function() {
|
|
37
|
+
const { NodeCtor, addCalls, logs } = load();
|
|
38
|
+
const node = new NodeCtor({config:'c', command:'cmd', regex:false, debug:true});
|
|
39
|
+
const handler = addCalls[0].fn;
|
|
40
|
+
handler({ message: { message:'cmd', fromId:{userId:1} } });
|
|
41
|
+
assert(logs.some(l => l.includes('command update')));
|
|
42
|
+
assert(logs.some(l => l.includes('command output')));
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const assert = require('assert');
|
|
2
|
+
const proxyquire = require('proxyquire').noPreserveCache();
|
|
3
|
+
|
|
4
|
+
function load() {
|
|
5
|
+
const addCalls = [];
|
|
6
|
+
const removeCalls = [];
|
|
7
|
+
class TelegramClientStub {
|
|
8
|
+
addEventHandler(fn, event) { addCalls.push({fn, event}); }
|
|
9
|
+
removeEventHandler(fn, event) { removeCalls.push({fn, event}); }
|
|
10
|
+
}
|
|
11
|
+
class NewMessageStub {}
|
|
12
|
+
|
|
13
|
+
let NodeCtor;
|
|
14
|
+
const configNode = { client: new TelegramClientStub() };
|
|
15
|
+
const RED = {
|
|
16
|
+
nodes: {
|
|
17
|
+
createNode(node) {
|
|
18
|
+
node._events = {};
|
|
19
|
+
node.on = (e, fn) => { node._events[e] = fn; };
|
|
20
|
+
},
|
|
21
|
+
registerType(name, ctor) { NodeCtor = ctor; },
|
|
22
|
+
getNode() { return configNode; }
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
proxyquire('../nodes/receiver.js', {
|
|
27
|
+
'telegram/events': { NewMessage: NewMessageStub }
|
|
28
|
+
})(RED);
|
|
29
|
+
|
|
30
|
+
return { NodeCtor, addCalls, removeCalls };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
describe('Receiver node', function() {
|
|
34
|
+
it('removes event handler on close', function() {
|
|
35
|
+
const { NodeCtor, addCalls, removeCalls } = load();
|
|
36
|
+
const node = new NodeCtor({config:'c', ignore:''});
|
|
37
|
+
assert.strictEqual(addCalls.length, 1);
|
|
38
|
+
node._events.close();
|
|
39
|
+
assert.strictEqual(removeCalls.length, 1);
|
|
40
|
+
assert.strictEqual(removeCalls[0].fn, addCalls[0].fn);
|
|
41
|
+
assert.strictEqual(removeCalls[0].event, addCalls[0].event);
|
|
42
|
+
});
|
|
43
|
+
});
|