@patricktobias86/node-red-telegram-account 1.0.6

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.
@@ -0,0 +1,96 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('delete-message', {
3
+ category: 'telegram-account',
4
+ color: '#FF5733',
5
+ icon: 'tg.png',
6
+ align: 'right',
7
+ defaults: {
8
+ name: { value: '' },
9
+ config: { type: 'config', required: false },
10
+ },
11
+ inputs: 1,
12
+ outputs: 1,
13
+ label: function () {
14
+ return this.name || 'Delete Message';
15
+ },
16
+ });
17
+ </script>
18
+
19
+ <script type="text/html" data-template-name="delete-message">
20
+ <div class="form-row">
21
+ <label for="node-input-name">
22
+ <i class="fa fa-tag"></i> Name
23
+ </label>
24
+ <input
25
+ type="text"
26
+ id="node-input-name"
27
+ placeholder="Name"
28
+ style="width: 60%"
29
+ />
30
+ </div>
31
+ <div class="form-row">
32
+ <label for="node-input-config">
33
+ <i class="fa fa-gear"></i> Config
34
+ </label>
35
+ <input
36
+ type="hidden"
37
+ id="node-input-config"
38
+ placeholder="Config"
39
+ style="width: 60%"
40
+ />
41
+ </div>
42
+ </script>
43
+
44
+
45
+ <script type="text/html" data-help-name="delete-message">
46
+ <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>
47
+
48
+ <h3>Inputs</h3>
49
+ <dl class="message-properties">
50
+ <dt>payload.chatId
51
+ <span class="property-type">string</span>
52
+ </dt>
53
+ <dd>The ID or username of the chat from which the messages will be deleted. Use "me" for personal chats.</dd>
54
+
55
+ <dt>payload.messageIds
56
+ <span class="property-type">number | array</span>
57
+ </dt>
58
+ <dd>The ID or an array of IDs of the messages to be deleted.</dd>
59
+
60
+ <dt>payload.revoke
61
+ <span class="property-type">boolean</span>
62
+ </dt>
63
+ <dd>If true, the messages will be deleted for all participants in the chat (revoke). Defaults to true.</dd>
64
+
65
+ <dt>payload.client
66
+ <span class="property-type">object</span>
67
+ </dt>
68
+ <dd>An optional Telegram client instance if not configured globally.</dd>
69
+ </dl>
70
+
71
+ <h3>Outputs</h3>
72
+ <dl class="message-properties">
73
+ <dt>payload
74
+ <span class="property-type">object</span>
75
+ </dt>
76
+ <dd>The response from the Telegram API, confirming the deletion.</dd>
77
+ </dl>
78
+
79
+ <h3>Details</h3>
80
+ <p>The <b>delete-message</b> node uses the Telegram API to delete messages from a specified chat. It can delete a single message or multiple messages at once. If the <code>revoke</code> parameter is set to true, the messages will be removed for all participants, not just the sender.</p>
81
+
82
+ <h3>Example</h3>
83
+ <pre>
84
+ {
85
+ "payload": {
86
+ "chatId": "@example_user",
87
+ "messageIds": [12345, 12346],
88
+ "revoke": true
89
+ }
90
+ }
91
+ </pre>
92
+ <p>This input deletes the messages with IDs 12345 and 12346 from the chat with the user <code>@example_user</code>, revoking them for all participants.</p>
93
+
94
+ <h3>Configuration</h3>
95
+ <p>The node can use a globally configured Telegram client or a client instance provided in the message payload. Ensure that the client has the necessary permissions to delete messages from the specified chat.</p>
96
+ </script>
@@ -0,0 +1,27 @@
1
+ module.exports = function (RED) {
2
+ function DeleteMessage(config) {
3
+ RED.nodes.createNode(this, config);
4
+ this.config = RED.nodes.getNode(config.config);
5
+ var node = this;
6
+
7
+ this.on('input', async function (msg) {
8
+ const chatId = msg.payload.chatId || config.chatId;
9
+ const messageIds = msg.payload.messageIds || config.messageIds;
10
+ const revoke = msg.payload.revoke || config.revoke || { revoke: true };
11
+ /** @type {TelegramClient} */
12
+ const client = msg.payload?.client ? msg.payload.client : this.config.client;
13
+
14
+ try {
15
+ const response = await client.deleteMessages(chatId, messageIds, revoke);
16
+
17
+ node.send({
18
+ payload: response,
19
+ });
20
+ } catch (err) {
21
+ node.error('Error deleting message: ' + err.message);
22
+ }
23
+ });
24
+ }
25
+
26
+ RED.nodes.registerType('delete-message', DeleteMessage);
27
+ };
@@ -0,0 +1,87 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('get-entity', {
3
+ category: 'telegram-account',
4
+ color: '#229ED9',
5
+ icon: 'tg.png',
6
+ align: "right",
7
+ defaults: {
8
+ name: { value: '' },
9
+ config: { type: 'config', required: false },
10
+ },
11
+ inputs: 1,
12
+ outputs: 1,
13
+ label: function () {
14
+ return this.name || 'Get Entity';
15
+ }
16
+ });
17
+ </script>
18
+
19
+ <script type="text/html" data-template-name="get-entity">
20
+ <div class="form-row">
21
+ <label for="node-input-name">
22
+ <i class="fa fa-tag"></i> Name
23
+ </label>
24
+ <input
25
+ type="text"
26
+ id="node-input-name"
27
+ placeholder="Name"
28
+ style="width: 60%"
29
+ />
30
+ </div>
31
+ <div class="form-row">
32
+ <label for="node-input-config">
33
+ <i class="fa fa-tag"></i> Config
34
+ </label>
35
+ <input
36
+ type="text"
37
+ id="node-input-config"
38
+ placeholder="Config"
39
+ style="width: 60%"
40
+ />
41
+ </div>
42
+ </script>
43
+
44
+ <script type="text/html" data-help-name="get-entity">
45
+ <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>
46
+
47
+ <h3>Inputs</h3>
48
+ <dl class="message-properties">
49
+ <dt>payload.input
50
+ <span class="property-type">string</span>
51
+ </dt>
52
+ <dd>The identifier (username, user ID, chat ID, or channel ID) or URL of the Telegram entity to retrieve. For example, "123456789", "@example_user", or "https://t.me/example_channel".</dd>
53
+
54
+ <dt>payload.client
55
+ <span class="property-type">object</span>
56
+ </dt>
57
+ <dd>An optional Telegram client instance if not configured globally.</dd>
58
+ </dl>
59
+
60
+ <h3>Outputs</h3>
61
+ <dl class="message-properties">
62
+ <dt>payload.input
63
+ <span class="property-type">object</span>
64
+ </dt>
65
+ <dd>The retrieved entity object containing details about the user, chat, or channel.</dd>
66
+ </dl>
67
+
68
+ <h3>Details</h3>
69
+ <p>The <b>get-entity</b> node uses the Telegram API to fetch details about a specified entity. If the input is a Telegram URL (e.g., "https://t.me/example_user"), the node extracts the username or channel name and fetches the corresponding entity. For non-URL inputs, it directly retrieves the entity using the provided identifier.</p>
70
+
71
+ <h3>Example</h3>
72
+ <pre>
73
+ {
74
+ "payload": {
75
+ "input": "https://t.me/example_user"
76
+ }
77
+ }
78
+ </pre>
79
+ <p>This input retrieves the entity information for the Telegram user <code>example_user</code>.</p>
80
+
81
+ <h3>Error Handling</h3>
82
+ <p>If an error occurs while retrieving the entity (e.g., the identifier is invalid or the entity does not exist), the node logs an error and sends a message with <code>payload.input</code> set to <code>null</code>.</p>
83
+
84
+ <h3>Configuration</h3>
85
+ <p>The node can use a globally configured Telegram client or a client instance provided in the message payload. Ensure the client has the necessary permissions to access the requested entity.</p>
86
+ </script>
87
+
@@ -0,0 +1,36 @@
1
+ module.exports = function (RED) {
2
+ function GetEntity(config) {
3
+ RED.nodes.createNode(this, config);
4
+ this.config = RED.nodes.getNode(config.config);
5
+ var node = this;
6
+
7
+ this.on('input', async function (msg) {
8
+ const input = msg.payload.input || config.input;
9
+ /** @type {TelegramClient} */
10
+ const client = msg.payload?.client ? msg.payload.client : this.config.client;
11
+
12
+ try {
13
+ let entity;
14
+
15
+ // Check if the input is a URL
16
+ if (input.includes('https://t.me/')) {
17
+ const username = input.split('/').pop();
18
+ entity = await client.getEntity(username);
19
+ } else {
20
+ entity = await client.getEntity(input);
21
+ }
22
+
23
+ node.send({
24
+ payload: {input:entity},
25
+ });
26
+ } catch (err) {
27
+ node.error('Error getting entity: ' + err.message);
28
+ node.send({
29
+ payload:{ input: null}
30
+ })
31
+ }
32
+ });
33
+ }
34
+
35
+ RED.nodes.registerType('get-entity', GetEntity);
36
+ };
@@ -0,0 +1,212 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('iter-dialogs', {
3
+ category: 'telegram',
4
+ color: '#32a3e0',
5
+ defaults: {
6
+ name: { value: '' },
7
+ config: { type: 'config', required: true },
8
+ limit: { value: "" },
9
+ offsetDate: { value: ""},
10
+ offsetId: { value: "" },
11
+ ignorePinned: { value: false },
12
+ ignoreMigrated: { value: false },
13
+ folder: { value: 0 },
14
+ archived: { value: "" },
15
+ },
16
+ inputs: 1,
17
+ outputs: 1,
18
+ paletteLabel: 'Iterate Dialogs',
19
+ label: function () {
20
+ return this.name || 'Iterate Dialogs';
21
+ },
22
+ });
23
+ </script>
24
+
25
+ <script type="text/html" data-template-name="iter-dialogs">
26
+ <div class="form-row">
27
+ <label for="node-input-name">
28
+ <i class="fa fa-tag"></i> Name
29
+ </label>
30
+ <input
31
+ type="text"
32
+ id="node-input-name"
33
+ placeholder="Name"
34
+ style="width: 60%"
35
+ ng-model="name"
36
+ />
37
+ </div>
38
+ <div class="form-row">
39
+ <label for="node-input-config">
40
+ <i class="fa fa-tag"></i> Config
41
+ </label>
42
+ <input
43
+ type="text"
44
+ id="node-input-config"
45
+ placeholder="Config"
46
+ style="width: 60%"
47
+ ng-model="config"
48
+ />
49
+ </div>
50
+ <div class="form-row">
51
+ <label for="node-input-limit">
52
+ <i class="fa fa-tag"></i> Limit
53
+ </label>
54
+ <input
55
+ type="text"
56
+ id="node-input-limit"
57
+ placeholder="Limit"
58
+ style="width: 60%"
59
+ ng-model="limit"
60
+ />
61
+ </div>
62
+ <div class="form-row">
63
+ <label for="node-input-offsetDate">
64
+ <i class="fa fa-tag"></i> Offset Date
65
+ </label>
66
+ <input
67
+ type="datetime-local"
68
+ id="node-input-offsetDate"
69
+ placeholder="Offset Date"
70
+ style="width: 60%"
71
+ ng-model="offsetDate"
72
+ />
73
+ </div>
74
+ <div class="form-row">
75
+ <label for="node-input-offsetId">
76
+ <i class="fa fa-tag"></i> Offset ID
77
+ </label>
78
+ <input
79
+ type="text"
80
+ id="node-input-offsetId"
81
+ placeholder="Offset ID"
82
+ style="width: 60%"
83
+ ng-model="offsetId"
84
+ />
85
+ </div>
86
+ <div class="form-row">
87
+ <label for="node-input-ignorePinned">
88
+ <i class="fa fa-tag"></i> Ignore Pinned
89
+ </label>
90
+ <input
91
+ type="checkbox"
92
+ id="node-input-ignorePinned"
93
+ ng-model="ignorePinned"
94
+ />
95
+ </div>
96
+ <div class="form-row">
97
+ <label for="node-input-ignoreMigrated">
98
+ <i class="fa fa-tag"></i> Ignore Migrated
99
+ </label>
100
+ <input
101
+ type="checkbox"
102
+ id="node-input-ignoreMigrated"
103
+ ng-model="ignoreMigrated"
104
+ />
105
+ </div>
106
+ <div class="form-row">
107
+ <label for="node-input-folder">
108
+ <i class="fa fa-tag"></i> Folder
109
+ </label>
110
+ <input
111
+ type="text"
112
+ id="node-input-folder"
113
+ placeholder="Folder"
114
+ style="width: 60%"
115
+ ng-model="folder"
116
+ />
117
+ </div>
118
+ <div class="form-row">
119
+ <label for="node-input-archived">
120
+ <i class="fa fa-tag"></i> Archived
121
+ </label>
122
+ <input
123
+ type="checkbox"
124
+ id="node-input-archived"
125
+ ng-model="archived"
126
+ />
127
+ </div>
128
+ </script>
129
+
130
+ <script type="text/html" data-help-name="iter-dialogs">
131
+ <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>
132
+
133
+ <h3>Inputs</h3>
134
+ <dl class="message-properties">
135
+ <dt>payload.client
136
+ <span class="property-type">object</span>
137
+ </dt>
138
+ <dd>An optional Telegram client instance if not configured globally.</dd>
139
+
140
+ <dt>payload.limit
141
+ <span class="property-type">number</span>
142
+ </dt>
143
+ <dd>Limits the number of dialogs to retrieve. Default is no limit.</dd>
144
+
145
+ <dt>payload.offsetDate
146
+ <span class="property-type">string | number</span>
147
+ </dt>
148
+ <dd>Fetch dialogs starting from this date. Provide a UNIX timestamp or a date string.</dd>
149
+
150
+ <dt>payload.offsetId
151
+ <span class="property-type">number</span>
152
+ </dt>
153
+ <dd>Fetch dialogs starting from this message ID.</dd>
154
+
155
+ <dt>payload.offsetPeer
156
+ <span class="property-type">object</span>
157
+ </dt>
158
+ <dd>The peer object to start retrieving dialogs from.</dd>
159
+
160
+ <dt>payload.ignorePinned
161
+ <span class="property-type">boolean</span>
162
+ </dt>
163
+ <dd>Ignores pinned dialogs if set to <code>true</code>. Default is <code>false</code>.</dd>
164
+
165
+ <dt>payload.ignoreMigrated
166
+ <span class="property-type">boolean</span>
167
+ </dt>
168
+ <dd>Ignores migrated chats if set to <code>true</code>. Default is <code>false</code>.</dd>
169
+
170
+ <dt>payload.folder
171
+ <span class="property-type">number</span>
172
+ </dt>
173
+ <dd>Retrieves dialogs from a specific folder by folder ID.</dd>
174
+
175
+ <dt>payload.archived
176
+ <span class="property-type">boolean</span>
177
+ </dt>
178
+ <dd>Includes archived dialogs if set to <code>true</code>. Default is <code>false</code>.</dd>
179
+ </dl>
180
+
181
+ <h3>Outputs</h3>
182
+ <dl class="message-properties">
183
+ <dt>payload.dialogs
184
+ <span class="property-type">object</span>
185
+ </dt>
186
+ <dd>An object containing dialogs, where keys are dialog IDs and values are dialog details.</dd>
187
+ </dl>
188
+
189
+ <h3>Details</h3>
190
+ <p>The <b>iter-dialogs</b> node uses the Telegram API to iterate over all available dialogs. It allows filtering by various parameters, such as the number of dialogs to retrieve (<code>limit</code>), starting date or message (<code>offsetDate</code>, <code>offsetId</code>), and additional flags like <code>ignorePinned</code> or <code>archived</code>.</p>
191
+
192
+ <p>It supports advanced configurations such as folder-specific retrieval and skipping migrated chats, providing granular control over the dialogs to be processed.</p>
193
+
194
+ <h3>Example</h3>
195
+ <pre>
196
+ {
197
+ "payload": {
198
+ "limit": 10,
199
+ "offsetDate": "2023-12-01T00:00:00Z",
200
+ "archived": true
201
+ }
202
+ }
203
+ </pre>
204
+ <p>This input retrieves up to 10 archived dialogs starting from December 1, 2023.</p>
205
+
206
+ <h3>Error Handling</h3>
207
+ <p>If an error occurs during dialog retrieval (e.g., invalid parameters or API limitations), the node logs an error message and does not return a payload.</p>
208
+
209
+ <h3>Configuration</h3>
210
+ <p>The node can use a globally configured Telegram client or a client instance provided in the message payload. Ensure the client has sufficient permissions to access the dialogs.</p>
211
+ </script>
212
+
@@ -0,0 +1,54 @@
1
+ const { TelegramClient } = require("telegram");
2
+
3
+ module.exports = function (RED) {
4
+ function IterDialogs(config) {
5
+ RED.nodes.createNode(this, config);
6
+ this.config = RED.nodes.getNode(config.config);
7
+ var node = this;
8
+
9
+ this.on('input', async function (msg) {
10
+
11
+ /** @type {TelegramClient} */
12
+ const client = msg.payload?.client ? msg.payload.client : this.config.client;
13
+ const limit = msg.payload.limit || config.limit;
14
+ const offsetDate = msg.payload.offsetDate || config.offsetDate;
15
+ const offsetId = msg.payload.offsetId || config.offsetId;
16
+ const offsetPeer = msg.payload?.offsetPeer || undefined;
17
+ const ignorePinned = msg.payload.ignorePinned || config.ignorePinned;
18
+ const ignoreMigrated = msg.payload.ignoreMigrated || config.ignoreMigrated;
19
+ const folder = msg.payload.folder || config.folder;
20
+ const archived = msg.payload.archived || config.archived;
21
+
22
+ const params = {
23
+ limit: limit !== ""? parseInt(limit) : undefined,
24
+ offsetDate: offsetDate !== "" ? offsetDate:undefined,
25
+ offsetId: offsetId !== "" ? parseInt(offsetId):undefined,
26
+ offsetPeer: offsetPeer,
27
+ ignorePinned: ignorePinned,
28
+ ignoreMigrated: ignoreMigrated,
29
+ folder: folder !== "" ? parseInt(folder):undefined,
30
+ archived: archived,
31
+ }
32
+
33
+ if (offsetDate) {
34
+ params.offsetDate = new Date(offsetDate).getTime() / 1000;
35
+ }
36
+
37
+ try {
38
+ const dialogs = {};
39
+ for await (const dialog of client.iterDialogs(params)){
40
+ dialogs[dialog.id] = dialog;
41
+ console.log(`${dialog.id}: ${dialog.title}`);
42
+ }
43
+ node.send({
44
+ payload: { dialogs },
45
+ });
46
+ } catch (err) {
47
+ node.error('Error iter dialogs: ' + err.message);
48
+ }
49
+
50
+ });
51
+ }
52
+
53
+ RED.nodes.registerType('iter-dialogs', IterDialogs);
54
+ };