@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,365 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('iter-messages', {
3
+ category: 'telegram',
4
+ color: '#32a3e0',
5
+ defaults: {
6
+ name: { value: '' },
7
+ config: { type: 'config', required: true },
8
+ chatId: { value: '', required: false },
9
+ limit: { value: '', required: false },
10
+ offsetDate: { value: '', required: false },
11
+ offsetId: { value: '', required: false },
12
+ maxId: { value: '', required: false },
13
+ minId: { value: '', required: false },
14
+ addOffset: { value: '', required: false },
15
+ search: { value: '', required: false },
16
+ filter: { value: '', required: false },
17
+ fromUser: { value: '', required: false },
18
+ waitTime: { value: '', required: false },
19
+ messageIds: { value: '', required: false },
20
+ reverse: { value: '', required: false },
21
+ replyTo: { value: '', required: false },
22
+ scheduled: { value: '', required: false }
23
+ },
24
+ inputs: 1,
25
+ outputs: 1,
26
+ paletteLabel: 'Iterate Messages',
27
+ label: function () {
28
+ return this.name || 'Iterate Messages';
29
+ },
30
+ oneditprepare: function(){
31
+ const node = this;
32
+ $("#node-input-messageIds").val((node.messageIds || []).join(","))
33
+ },
34
+ oneditsave:function(){
35
+ const node = this;
36
+ const messageIds = $("#node-input-messageIds").val();
37
+ if(messageIds){
38
+ node.messageIds = messageIds.split(",").map(id => parseInt(id))
39
+ }
40
+ },
41
+ });
42
+ </script>
43
+
44
+ <script type="text/html" data-template-name="iter-messages">
45
+ <div class="form-row">
46
+ <label for="node-input-name">
47
+ <i class="fa fa-tag"></i> Name
48
+ </label>
49
+ <input
50
+ type="text"
51
+ id="node-input-name"
52
+ placeholder="Name"
53
+ style="width: 60%"
54
+ ng-model="name"
55
+ />
56
+ </div>
57
+ <div class="form-row">
58
+ <label for="node-input-config">
59
+ <i class="fa fa-tag"></i> Config
60
+ </label>
61
+ <input
62
+ type="text"
63
+ id="node-input-config"
64
+ placeholder="Config"
65
+ style="width: 60%"
66
+ ng-model="config"
67
+ />
68
+ </div>
69
+ <div class="form-row">
70
+ <label for="node-input-chatId">
71
+ <i class="fa fa-tag"></i> Chat ID
72
+ </label>
73
+ <input
74
+ type="text"
75
+ id="node-input-chatId"
76
+ placeholder="Chat ID"
77
+ style="width: 60%"
78
+ ng-model="chatId"
79
+ />
80
+ </div>
81
+ <div class="form-row">
82
+ <label for="node-input-limit">
83
+ <i class="fa fa-tag"></i> Limit
84
+ </label>
85
+ <input
86
+ type="number"
87
+ id="node-input-limit"
88
+ placeholder="Limit"
89
+ style="width: 60%"
90
+ ng-model="limit"
91
+ />
92
+ </div>
93
+ <div class="form-row">
94
+ <label for="node-input-offsetDate">
95
+ <i class="fa fa-tag"></i> Offset Date
96
+ </label>
97
+ <input
98
+ type="datetime-local"
99
+ id="node-input-offsetDate"
100
+ placeholder="Offset Date"
101
+ style="width: 60%"
102
+ ng-model="offsetDate"
103
+ />
104
+ </div>
105
+ <div class="form-row">
106
+ <label for="node-input-offsetId">
107
+ <i class="fa fa-tag"></i> Offset ID
108
+ </label>
109
+ <input
110
+ type="number"
111
+ id="node-input-offsetId"
112
+ placeholder="Offset ID"
113
+ style="width: 60%"
114
+ ng-model="offsetId"
115
+ />
116
+ </div>
117
+ <div class="form-row">
118
+ <label for="node-input-maxId">
119
+ <i class="fa fa-tag"></i> Max ID
120
+ </label>
121
+ <input
122
+ type="number"
123
+ id="node-input-maxId"
124
+ placeholder="Max ID"
125
+ style="width: 60%"
126
+ ng-model="maxId"
127
+ />
128
+ </div>
129
+ <div class="form-row">
130
+ <label for="node-input-minId">
131
+ <i class="fa fa-tag"></i> Min ID
132
+ </label>
133
+ <input
134
+ type="number"
135
+ id="node-input-minId"
136
+ placeholder="Min ID"
137
+ style="width: 60%"
138
+ ng-model="minId"
139
+ />
140
+ </div>
141
+ <div class="form-row">
142
+ <label for="node-input-addOffset">
143
+ <i class="fa fa-tag"></i> Add Offset
144
+ </label>
145
+ <input
146
+ type="number"
147
+ id="node-input-addOffset"
148
+ placeholder="Add Offset"
149
+ style="width: 60%"
150
+ ng-model="addOffset"
151
+ />
152
+ </div>
153
+ <div class="form-row">
154
+ <label for="node-input-search">
155
+ <i class="fa fa-tag"></i> Search
156
+ </label>
157
+ <input
158
+ type="text"
159
+ id="node-input-search"
160
+ placeholder="Search"
161
+ style="width: 60%"
162
+ ng-model="search"
163
+ />
164
+ </div>
165
+ <div class="form-row">
166
+ <label for="node-input-filter">
167
+ <i class="fa fa-tag"></i> Filter
168
+ </label>
169
+ <input type="checkbox" name="filter" value="InputMessagesFilterEmpty">Empty<br>
170
+ <input type="checkbox" name="filter" value="InputMessagesFilterPhotos">Photos<br>
171
+ <input type="checkbox" name="filter" value="InputMessagesFilterVideo">Video<br>
172
+ <input type="checkbox" name="filter" value="InputMessagesFilterPhotoVideo">Photo and Video<br>
173
+ <input type="checkbox" name="filter" value="InputMessagesFilterDocument">Document<br>
174
+ <input type="checkbox" name="filter" value="InputMessagesFilterUrl">URL<br>
175
+ <input type="checkbox" name="filter" value="InputMessagesFilterGif">GIF<br>
176
+ <input type="checkbox" name="filter" value="InputMessagesFilterVoice">Voice<br>
177
+ <input type="checkbox" name="filter" value="InputMessagesFilterMusic">Music<br>
178
+ <input type="checkbox" name="filter" value="InputMessagesFilterChatPhotos">Chat Photos<br>
179
+ <input type="checkbox" name="filter" value="InputMessagesFilterPhoneCalls">Phone Calls<br>
180
+ <input type="checkbox" name="filter" value="InputMessagesFilterRoundVoice">Round Voice<br>
181
+ <input type="checkbox" name="filter" value="InputMessagesFilterRoundVideo">Round Video<br>
182
+ <input type="checkbox" name="filter" value="InputMessagesFilterMyMentions">My Mentions<br>
183
+ <input type="checkbox" name="filter" value="InputMessagesFilterGeo">Geo<br>
184
+ <input type="checkbox" name="filter" value="InputMessagesFilterContacts">Contacts<br>
185
+ <input type="checkbox" name="filter" value="InputMessagesFilterPinned">Pinned<br>
186
+
187
+ </div>
188
+ <div class="form-row">
189
+ <label for="node-input-fromUser">
190
+ <i class="fa fa-tag"></i> From User
191
+ </label>
192
+ <input
193
+ type="text"
194
+ id="node-input-fromUser"
195
+ placeholder="From User"
196
+ style="width: 60%"
197
+ ng-model="fromUser"
198
+ />
199
+ </div>
200
+ <div class="form-row">
201
+ <label for="node-input-waitTime">
202
+ <i class="fa fa-tag"></i> Wait Time
203
+ </label>
204
+ <input
205
+ type="number"
206
+ id="node-input-waitTime"
207
+ placeholder="Wait Time"
208
+ style="width: 60%"
209
+ ng-model="waitTime"
210
+ />
211
+ </div>
212
+ <div class="form-row">
213
+ <label for="node-input-messageIds">
214
+ <i class="fa fa-tag"></i> Message IDs
215
+ </label>
216
+ <input
217
+ type="text"
218
+ id="node-input-messageIds"
219
+ placeholder="123,1245"
220
+ style="width: 60%"
221
+ ng-model="messageIds"
222
+ />
223
+ </div>
224
+ <div class="form-row">
225
+ <label for="node-input-reverse">
226
+ <i class="fa fa-tag"></i> Reverse
227
+ </label>
228
+ <input
229
+ type="checkbox"
230
+ id="node-input-reverse"
231
+ ng-model="reverse"
232
+ />
233
+ </div>
234
+ <div class="form-row">
235
+ <label for="node-input-replyTo">
236
+ <i class="fa fa-tag"></i> Reply To
237
+ </label>
238
+ <input
239
+ type="number"
240
+ id="node-input-replyTo"
241
+ placeholder="Reply To"
242
+ style="width: 60%"
243
+ ng-model="replyTo"
244
+ />
245
+ </div>
246
+ <div class="form-row">
247
+ <label for="node-input-scheduled">
248
+ <i class="fa fa-tag"></i> Scheduled
249
+ </label>
250
+ <input
251
+ type="checkbox"
252
+ id="node-input-scheduled"
253
+ ng-model="scheduled"
254
+ />
255
+ </div>
256
+ </script>
257
+
258
+ <script type="text/html" data-help-name="iter-messages">
259
+ <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>
260
+
261
+ <h3>Inputs</h3>
262
+ <dl class="message-properties">
263
+ <dt>payload.client
264
+ <span class="property-type">object</span>
265
+ </dt>
266
+ <dd>An optional Telegram client instance if not configured globally.</dd>
267
+
268
+ <dt>payload.chatId
269
+ <span class="property-type">string</span>
270
+ </dt>
271
+ <dd>The ID or username of the chat or user to retrieve messages from. Use "me" for personal messages.</dd>
272
+
273
+ <dt>payload.limit
274
+ <span class="property-type">number</span>
275
+ </dt>
276
+ <dd>Maximum number of messages to retrieve.</dd>
277
+
278
+ <dt>payload.offsetDate
279
+ <span class="property-type">string | number</span>
280
+ </dt>
281
+ <dd>Fetch messages starting from this date. Accepts a UNIX timestamp or a date string.</dd>
282
+
283
+ <dt>payload.offsetId
284
+ <span class="property-type">number</span>
285
+ </dt>
286
+ <dd>Fetch messages starting from this message ID.</dd>
287
+
288
+ <dt>payload.maxId
289
+ <span class="property-type">number</span>
290
+ </dt>
291
+ <dd>Fetch messages with IDs less than or equal to this value.</dd>
292
+
293
+ <dt>payload.minId
294
+ <span class="property-type">number</span>
295
+ </dt>
296
+ <dd>Fetch messages with IDs greater than or equal to this value.</dd>
297
+
298
+ <dt>payload.addOffset
299
+ <span class="property-type">number</span>
300
+ </dt>
301
+ <dd>An additional offset to apply when retrieving messages.</dd>
302
+
303
+ <dt>payload.search
304
+ <span class="property-type">string</span>
305
+ </dt>
306
+ <dd>Filters messages containing the specified search term.</dd>
307
+
308
+ <dt>payload.filter
309
+ <span class="property-type">object</span>
310
+ </dt>
311
+ <dd>Applies a specific message filter (e.g., photos, videos, documents).</dd>
312
+
313
+ <dt>payload.filters
314
+ <span class="property-type">array</span>
315
+ </dt>
316
+ <dd>Applies multiple message filters using Telegram API filter classes (e.g., <code>Api.InputMessagesFilterPhotos</code>).</dd>
317
+
318
+ <dt>payload.reverse
319
+ <span class="property-type">boolean</span>
320
+ </dt>
321
+ <dd>Retrieves messages in reverse order if set to <code>true</code>. Default is <code>false</code>.</dd>
322
+
323
+ <dt>payload.replyTo
324
+ <span class="property-type">number</span>
325
+ </dt>
326
+ <dd>Fetches messages replying to the specified message ID.</dd>
327
+
328
+ <dt>payload.scheduled
329
+ <span class="property-type">boolean</span>
330
+ </dt>
331
+ <dd>Includes scheduled messages if set to <code>true</code>.</dd>
332
+ </dl>
333
+
334
+ <h3>Outputs</h3>
335
+ <dl class="message-properties">
336
+ <dt>payload.messages
337
+ <span class="property-type">object</span>
338
+ </dt>
339
+ <dd>An object containing messages, where keys are message IDs and values are message details.</dd>
340
+ </dl>
341
+
342
+ <h3>Details</h3>
343
+ <p>The <b>iter-messages</b> node provides a flexible way to retrieve messages from a Telegram chat or user. It allows advanced configurations such as filtering messages by type, searching for specific terms, and paginating results using offsets and IDs.</p>
344
+
345
+ <p>The node also handles cases where a chat username needs to be resolved into an entity or peer ID. It supports using multiple filters in conjunction, enabling precise control over the messages to process.</p>
346
+
347
+ <h3>Example</h3>
348
+ <pre>
349
+ {
350
+ "payload": {
351
+ "chatId": "@examplechannel",
352
+ "limit": 50,
353
+ "search": "announcement",
354
+ "filters": ["InputMessagesFilterPhotos"]
355
+ }
356
+ }
357
+ </pre>
358
+ <p>This input retrieves up to 50 messages containing the term "announcement" and filters them to include only photos from the specified channel.</p>
359
+
360
+ <h3>Error Handling</h3>
361
+ <p>If an error occurs during message retrieval (e.g., invalid chat ID or API errors), the node logs an error message and does not return a payload.</p>
362
+
363
+ <h3>Configuration</h3>
364
+ <p>The node can use a globally configured Telegram client or a client instance provided in the message payload. Ensure the client has access to the specified chat or user.</p>
365
+ </script>
@@ -0,0 +1,94 @@
1
+ const { TelegramClient, utils, Api } = require("telegram");
2
+
3
+ module.exports = function (RED) {
4
+ function IterMessages(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 chatId = msg.payload?.chatId ? msg.payload.chatId : config.chatId;
14
+ let peerId = chatId === "me" ? chatId : utils.parseID(chatId);
15
+
16
+ // Получаем параметры из входного сообщения или из конфигурации узла
17
+ const limit = msg.payload?.limit || config.limit;
18
+ const offsetDate = msg.payload?.offsetDate || config.offsetDate;
19
+ const offsetId = msg.payload?.offsetId || config.offsetId;
20
+ const maxId = msg.payload?.maxId || config.maxId;
21
+ const minId = msg.payload?.minId || config.minId;
22
+ const addOffset = msg.payload?.addOffset || config.addOffset;
23
+ const search = msg.payload?.search || config.search;
24
+ const filter = msg.payload?.filter || config.filter;
25
+ const fromUser = msg.payload?.fromUser || config.fromUser;
26
+ const waitTime = msg.payload?.waitTime || config.waitTime;
27
+ const messageIds = msg.payload?.messageIds || config.messageIds;
28
+ const reverse = msg.payload?.reverse || config.reverse;
29
+ const replyTo = msg.payload?.replyTo || config.replyTo;
30
+ const scheduled = msg.payload?.scheduled || config.scheduled;
31
+
32
+ try {
33
+
34
+ const params = {
35
+ limit: limit !== ""? parseInt(limit) : undefined,
36
+ offsetDate: offsetDate !== "" ? offsetDate:undefined,
37
+ offsetId: offsetId !== "" ? parseInt(offsetId):undefined,
38
+ maxId: maxId,
39
+ minId: minId,
40
+ addOffset: addOffset,
41
+ search: search !== "" ? search : undefined,
42
+ filter: filter,
43
+ // fromUser: fromUser,
44
+ waitTime: waitTime,
45
+ ids: messageIds,
46
+ reverse: reverse,
47
+ replyTo: replyTo,
48
+ scheduled: scheduled,
49
+ };
50
+
51
+ if (offsetDate) {
52
+ params.offsetDate = new Date(offsetDate).getTime() / 1000;
53
+ }
54
+
55
+ if (chatId[0] === "@") {
56
+ peerId = await client.getEntity(chatId);
57
+ }
58
+ const messages = {};
59
+
60
+ const filters = msg.payload?.filters || config.filters || [];
61
+
62
+ // Обработка выбранных фильтров
63
+ if (filters.length > 0) {
64
+ params.filter = [];
65
+ filters.forEach((filter) => {
66
+ params.filter.push( Api[filter]);
67
+ });
68
+ }
69
+
70
+ try {
71
+ for await (const message of client.iterMessages(peerId, params)){
72
+ messages[message.id] = message;
73
+ console.log(message.id, message.text);
74
+ }
75
+ } catch (error) {
76
+ const entity = await client.getInputEntity(peerId)
77
+ for await (const message of client.iterMessages(entity, params)){
78
+ messages[message.id] = message;
79
+ console.log(message.id, message.text);
80
+ }
81
+ }
82
+
83
+ node.send({
84
+ payload: { messages },
85
+ });
86
+ } catch (err) {
87
+ node.error('Error iter messages: ' + err.message);
88
+ }
89
+
90
+ });
91
+ }
92
+
93
+ RED.nodes.registerType('iter-messages', IterMessages);
94
+ };
@@ -0,0 +1,24 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('promote-admin', {
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
+ chatId: { value: '' },
11
+ userId: { value: '' },
12
+ rank: { value: 'Admin' },
13
+ adminRights: { value: '' }, // JSON string of ChatAdminRights
14
+ },
15
+ inputs: 1,
16
+ outputs: 1,
17
+ label: function () {
18
+ return this.name || 'Promote Admin';
19
+ },
20
+ oneditprepare: function () {
21
+ // Nothing special here yet — could validate JSON if needed
22
+ }
23
+ });
24
+ </script>
@@ -0,0 +1,55 @@
1
+ const { TelegramClient } = require("telegram");
2
+ const { parseID } = require("telegram/Utils");
3
+ const { Api } = require("telegram");
4
+
5
+ module.exports = function (RED) {
6
+ function PromoteAdmin(config) {
7
+ RED.nodes.createNode(this, config);
8
+ this.config = RED.nodes.getNode(config.config);
9
+ var node = this;
10
+
11
+ this.on('input', async function (msg) {
12
+ let chatId = msg.payload.chatId || config.chatId;
13
+ let userId = msg.payload.userId || config.userId;
14
+ let rank = msg.payload.rank || config.rank || "Admin";
15
+ const customRights = msg.payload.adminRights || config.adminRights;
16
+
17
+ /** @type {TelegramClient} */
18
+ const client = msg.payload?.client ? msg.payload.client : this.config.client;
19
+ let group, user;
20
+
21
+ try {
22
+ group = chatId[0] === "@" ? await client.getEntity(chatId) : parseID(chatId);
23
+ user = userId[0] === "@" ? await client.getEntity(userId) : parseID(userId);
24
+
25
+ const adminRights = customRights || new Api.ChatAdminRights({
26
+ changeInfo: true,
27
+ postMessages: true,
28
+ editMessages: true,
29
+ deleteMessages: true,
30
+ banUsers: true,
31
+ inviteUsers: true,
32
+ pinMessages: true,
33
+ addAdmins: true,
34
+ manageCall: true,
35
+ anonymous: false,
36
+ manageTopics: true,
37
+ });
38
+
39
+ const result = await client.invoke(new Api.channels.EditAdmin({
40
+ channel: group,
41
+ userId: user,
42
+ adminRights,
43
+ rank,
44
+ }));
45
+
46
+ node.send({ payload: result });
47
+
48
+ } catch (err) {
49
+ node.error('Error promoting admin: ' + err.message);
50
+ }
51
+ });
52
+ }
53
+
54
+ RED.nodes.registerType('promote-admin', PromoteAdmin);
55
+ };
@@ -0,0 +1,128 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('receiver', {
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
+ ignore: { value:""}
11
+ },
12
+ inputs: 1,
13
+ outputs: 1,
14
+ label: function () {
15
+ return this.name || 'Receiver';
16
+ },
17
+
18
+ });
19
+ </script>
20
+
21
+ <script type="text/html" data-template-name="receiver">
22
+ <div class="form-row">
23
+ <label for="node-input-name">
24
+ <i class="fa fa-tag"></i> Name
25
+ </label>
26
+ <input
27
+ type="text"
28
+ id="node-input-name"
29
+ placeholder="Name"
30
+ style="width: 60%"
31
+ />
32
+ </div>
33
+ <div class="form-row">
34
+ <label for="node-input-config">
35
+ <i class="fa fa-tag"></i> Config
36
+ </label>
37
+ <input
38
+ type="text"
39
+ id="node-input-config"
40
+ placeholder="Config"
41
+ style="width: 60%"
42
+ />
43
+ </div>
44
+ <div class="form-row">
45
+ <label for="node-input-ignore">
46
+ <i class="fa fa-tag"></i> Config
47
+ </label>
48
+ <textarea
49
+ type="text"
50
+ id="node-input-ignore"
51
+ placeholder="Config"
52
+ style="width: 60%"
53
+ ></textarea>
54
+ </div>
55
+ </script>
56
+
57
+ <script type="text/html" data-help-name="receiver">
58
+ <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>
59
+
60
+ <h3>Inputs</h3>
61
+ <p>This node does not take any direct inputs. It listens to all incoming messages from the configured Telegram client.</p>
62
+
63
+ <h3>Outputs</h3>
64
+ <dl class="message-properties">
65
+ <dt>payload.update
66
+ <span class="property-type">object</span>
67
+ </dt>
68
+ <dd>The raw Telegram update object containing details about the incoming message, sender, chat, and metadata.</dd>
69
+ </dl>
70
+
71
+ <h3>Configuration</h3>
72
+ <dl class="message-properties">
73
+ <dt>Telegram Configuration
74
+ <span class="property-type">node</span>
75
+ </dt>
76
+ <dd>A configured Telegram client node to receive messages. Ensure the client is authenticated and has necessary permissions.</dd>
77
+
78
+ <dt>Ignore List
79
+ <span class="property-type">string</span>
80
+ </dt>
81
+ <dd>A newline-separated list of user IDs to ignore. Messages from these users will not trigger the output.</dd>
82
+ </dl>
83
+
84
+ <h3>Details</h3>
85
+ <p>The <b>receiver</b> node uses the Telegram client to listen for all new messages in real-time. It emits a message to the next connected Node-RED node whenever a new Telegram message is received, provided the sender's user ID is not in the ignore list.</p>
86
+
87
+ <h3>Example</h3>
88
+ <pre>
89
+ {
90
+ "payload": {
91
+ "update": {
92
+ "message": {
93
+ "message": "Hello, bot!",
94
+ "sender": {
95
+ "id": 123456789,
96
+ "username": "exampleuser"
97
+ },
98
+ "chat": {
99
+ "id": 987654321,
100
+ "type": "private"
101
+ }
102
+ }
103
+ }
104
+ }
105
+ }
106
+ </pre>
107
+ <p>In this example, the node outputs the raw Telegram update object when a user sends the message "Hello, bot!" to the Telegram bot.</p>
108
+
109
+ <h3>Error Handling</h3>
110
+ <p>If the Telegram client encounters an authentication issue or configuration error, the node logs an error message and stops listening for messages.</p>
111
+
112
+ <h3>Advanced Usage</h3>
113
+ <p>By configuring the <b>Ignore List</b>, you can filter out messages from specific users. For example:</p>
114
+ <pre>
115
+ 123456789
116
+ 987654321
117
+ </pre>
118
+ <p>In this case, messages from user IDs <code>123456789</code> and <code>987654321</code> will be ignored.</p>
119
+
120
+ <h3>Notes</h3>
121
+ <ul>
122
+ <li>Ensure the Telegram bot has sufficient permissions to receive messages in the configured chat or channel.</li>
123
+ <li>The <b>Ignore List</b> only filters messages based on the sender's user ID.</li>
124
+ <li>For advanced filtering based on message content, consider chaining this node with additional processing nodes in Node-RED.</li>
125
+ </ul>
126
+ </script>
127
+
128
+