n8n-nodes-ume-v4 4.5.23 → 4.5.24

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.
@@ -7,7 +7,9 @@ exports.getDynamicProperties = getDynamicProperties;
7
7
  exports.extractIdFromUrl = extractIdFromUrl;
8
8
  exports.generateAutoNote = generateAutoNote;
9
9
  exports.processCommentList = processCommentList;
10
+ exports.getServerDetails = getServerDetails;
10
11
  const services_data_json_1 = __importDefault(require("./services-data.json"));
12
+
11
13
  function getServerDetails(serviceData, serverId) {
12
14
  if (!serviceData || !serviceData.servers) {
13
15
  return "Không có thông tin chi tiết";
@@ -127,10 +129,10 @@ function getDynamicProperties() {
127
129
  ...parameter,
128
130
  name: `count_${serverOption.value}`,
129
131
  displayName: `Số lượng (${serverOption.name})`,
130
- default: serverInfo?.minQuantity || parameter.default || 50,
132
+ default: serverInfo?.min_quantity || serverInfo?.minQuantity || parameter.default || 50,
131
133
  typeOptions: {
132
- minValue: serverInfo?.minQuantity || parameter.typeOptions?.minValue || 1,
133
- maxValue: serverInfo?.maxQuantity || parameter.typeOptions?.maxValue || 999999999
134
+ minValue: serverInfo?.min_quantity || serverInfo?.minQuantity || parameter.typeOptions?.minValue || 1,
135
+ maxValue: serverInfo?.max_quantity || serverInfo?.maxQuantity || parameter.typeOptions?.maxValue || 999999999
134
136
  },
135
137
  displayOptions: {
136
138
  show: {
@@ -139,7 +141,7 @@ function getDynamicProperties() {
139
141
  server: [serverOption.value]
140
142
  },
141
143
  },
142
- description: `Số lượng cần tăng (${serverOption.name}: ${serverInfo?.minQuantity || 'N/A'} - ${serverInfo?.maxQuantity || 'N/A'})`,
144
+ description: `Số lượng cần tăng (${serverOption.name}: ${serverInfo?.min_quantity || serverInfo?.minQuantity || 'N/A'} - ${serverInfo?.max_quantity || serverInfo?.maxQuantity || 'N/A'})`,
143
145
  };
144
146
  serviceParameters.push(serverSpecificCount);
145
147
  });
@@ -174,6 +176,7 @@ function getDynamicProperties() {
174
176
  }
175
177
  return properties;
176
178
  }
179
+
177
180
  function getGeneralNote(platform, serviceName) {
178
181
  const servicesData = require('./services-data.json');
179
182
  const platformData = servicesData[platform];
@@ -215,9 +218,6 @@ function getGeneralNote(platform, serviceName) {
215
218
  • Kiểm tra kỹ trước khi đặt đơn số lượng lớn`;
216
219
  }
217
220
 
218
-
219
-
220
-
221
221
  function getServiceDisplayName(platform, serviceName) {
222
222
  const servicesData = require('./services-data.json');
223
223
  const platformData = servicesData[platform];
@@ -231,7 +231,6 @@ function getServiceDisplayName(platform, serviceName) {
231
231
  return serviceName.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
232
232
  }
233
233
 
234
-
235
234
  function getPlatformDisplayName(platform) {
236
235
  const platformNames = {
237
236
  'facebook': 'Facebook',
@@ -460,4 +459,4 @@ function generateAutoNote(serviceName, platform, inputData) {
460
459
  note += `\n🆔 Order ID: AUTO-${Date.now()}`;
461
460
 
462
461
  return note;
463
- }
462
+ }
@@ -0,0 +1,463 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getDynamicProperties = getDynamicProperties;
7
+ exports.extractIdFromUrl = extractIdFromUrl;
8
+ exports.generateAutoNote = generateAutoNote;
9
+ exports.processCommentList = processCommentList;
10
+ const services_data_json_1 = __importDefault(require("./services-data.json"));
11
+ function getServerDetails(serviceData, serverId) {
12
+ if (!serviceData || !serviceData.servers) {
13
+ return "Không có thông tin chi tiết";
14
+ }
15
+
16
+ const server = serviceData.servers.find(s => s.id === serverId || s.server_id === serverId);
17
+ if (!server) {
18
+ return "Không tìm thấy thông tin server";
19
+ }
20
+
21
+ let details = [];
22
+
23
+ // Only show features, not price/quantity/status
24
+ if (server.features && server.features.length > 0) {
25
+ details.push("Features:");
26
+ server.features.forEach(feature => {
27
+ // Remove bullet points and add proper formatting
28
+ const cleanFeature = feature.replace(/^[-*]\s*/, '').trim();
29
+ details.push(`• ${cleanFeature}`);
30
+ });
31
+ } else {
32
+ details.push("Không có features đặc biệt");
33
+ }
34
+
35
+ return details.join('\n');
36
+ }
37
+
38
+ function getDynamicProperties() {
39
+ var _a, _b, _c;
40
+ const properties = [];
41
+ // Generate service options for each platform
42
+ for (const [platformKey, platformData] of Object.entries(services_data_json_1.default)) {
43
+ const platformServices = platformData;
44
+ const serviceOptions = Object.keys(platformServices).map(serviceName => ({
45
+ name: getServiceDisplayName(platformKey, serviceName),
46
+ value: serviceName,
47
+ }));
48
+ properties.push({
49
+ displayName: "Dịch vụ",
50
+ name: "service",
51
+ type: "options",
52
+ noDataExpression: true,
53
+ options: serviceOptions,
54
+ default: ((_a = serviceOptions[0]) === null || _a === void 0 ? void 0 : _a.value) || "",
55
+ displayOptions: {
56
+ show: {
57
+ platform: [platformKey],
58
+ },
59
+ },
60
+ description: `Chọn dịch vụ ${getPlatformDisplayName(platformKey)} cần sử dụng`,
61
+ });
62
+ // Add service-specific parameters
63
+ for (const [serviceName, serviceData] of Object.entries(platformServices)) {
64
+ const serviceParameters = [];
65
+ // Add server options from services data
66
+ const serverParam = (_b = serviceData.parameters) === null || _b === void 0 ? void 0 : _b.find((p) => p.name === 'server');
67
+ if (serverParam === null || serverParam === void 0 ? void 0 : serverParam.options) {
68
+ serviceParameters.push({
69
+ displayName: "Server",
70
+ name: "server",
71
+ type: "options",
72
+ default: serverParam.default || ((_c = serverParam.options[0]) === null || _c === void 0 ? void 0 : _c.value) || "",
73
+ options: serverParam.options,
74
+ displayOptions: {
75
+ show: {
76
+ platform: [platformKey],
77
+ service: [serviceName],
78
+ },
79
+ },
80
+ description: "Chọn server để sử dụng dịch vụ",
81
+ });
82
+ // Add server-specific details for each server
83
+ serverParam.options.forEach((serverOption) => {
84
+ serviceParameters.push({
85
+ displayName: `Chi tiết ${serverOption.name}`,
86
+ name: `server_details_${serverOption.value}`,
87
+ type: "string",
88
+ default: getServerDetails(serviceData, serverOption.value),
89
+ typeOptions: {
90
+ rows: 8,
91
+ },
92
+ displayOptions: {
93
+ show: {
94
+ platform: [platformKey],
95
+ service: [serviceName],
96
+ server: [serverOption.value],
97
+ },
98
+ },
99
+ description: "Thông tin chi tiết về server đã chọn",
100
+ noDataExpression: true,
101
+ });
102
+ });
103
+ }
104
+ // Add all service parameters except server (which we already added)
105
+ const serviceParametersData = serviceData.parameters || [];
106
+ for (const parameter of serviceParametersData) {
107
+ if (parameter.name !== 'server') {
108
+ const paramProperty = {
109
+ ...parameter,
110
+ displayOptions: {
111
+ show: {
112
+ platform: [platformKey],
113
+ service: [serviceName],
114
+ },
115
+ },
116
+ };
117
+
118
+ // Add server-specific count parameters (one for each server)
119
+ if (parameter.name === 'count' && serverParam && serverParam.options) {
120
+ // Instead of one count parameter, create server-specific ones
121
+ serverParam.options.forEach((serverOption) => {
122
+ const serverInfo = serviceData.servers?.find(s =>
123
+ s.id === serverOption.value || s.server_id === serverOption.value
124
+ );
125
+
126
+ const serverSpecificCount = {
127
+ ...parameter,
128
+ name: `count_${serverOption.value}`,
129
+ displayName: `Số lượng (${serverOption.name})`,
130
+ default: serverInfo?.minQuantity || parameter.default || 50,
131
+ typeOptions: {
132
+ minValue: serverInfo?.minQuantity || parameter.typeOptions?.minValue || 1,
133
+ maxValue: serverInfo?.maxQuantity || parameter.typeOptions?.maxValue || 999999999
134
+ },
135
+ displayOptions: {
136
+ show: {
137
+ platform: [platformKey],
138
+ service: [serviceName],
139
+ server: [serverOption.value]
140
+ },
141
+ },
142
+ description: `Số lượng cần tăng (${serverOption.name}: ${serverInfo?.minQuantity || 'N/A'} - ${serverInfo?.maxQuantity || 'N/A'})`,
143
+ };
144
+ serviceParameters.push(serverSpecificCount);
145
+ });
146
+
147
+ // Skip adding the original count parameter
148
+ continue;
149
+ }
150
+
151
+ serviceParameters.push(paramProperty);
152
+ }
153
+ }
154
+ // Add general note if available
155
+ serviceParameters.push({
156
+ displayName: "Lưu ý chung",
157
+ name: `${serviceName}_general_note`,
158
+ type: "string",
159
+ default: getGeneralNote(platformKey, serviceName),
160
+ typeOptions: {
161
+ rows: 10,
162
+ },
163
+ displayOptions: {
164
+ show: {
165
+ platform: [platformKey],
166
+ service: [serviceName],
167
+ },
168
+ },
169
+ description: "Lưu ý quan trọng khi sử dụng dịch vụ",
170
+ noDataExpression: true,
171
+ });
172
+ properties.push(...serviceParameters);
173
+ }
174
+ }
175
+ return properties;
176
+ }
177
+ function getGeneralNote(platform, serviceName) {
178
+ const servicesData = require('./services-data.json');
179
+ const platformData = servicesData[platform];
180
+ const serviceData = platformData && platformData[serviceName];
181
+
182
+ if (serviceData && serviceData.warnings && serviceData.warnings.length > 0) {
183
+ return serviceData.warnings.map((warning, index) => (index + 1) + '. ' + warning).join('\n');
184
+ }
185
+
186
+ // Fallback for services without specific warnings
187
+ if (platform === 'facebook') {
188
+ return `Lưu ý khi sử dụng dịch vụ Facebook:
189
+
190
+ • Hướng dẫn lấy link - Một số lỗi phổ biến:
191
+ - Link avatar, bìa (và nhớ bật nút Like)
192
+ - Link dạng post cho video (link chứa từ "post")
193
+ - Link bài chia sẻ (share bài viết và share video)
194
+
195
+ • Mỗi UID có thể mua tối đa 30-60 lần tùy server
196
+
197
+ • Nếu tăng video trong album, vui lòng sử dụng server thích hợp
198
+
199
+ • Tất cả server không bảo hành tương tác khi bị tụt
200
+
201
+ • Các trường hợp hủy gói và không lên tương tác:
202
+ - Bài viết là avatar hoặc ảnh bìa
203
+ - Tương tác group công khai, video và livestream
204
+ - Bài viết có link sai hoặc tag người dùng bị chặn
205
+ - Các UID bị lỗi do không công khai hoặc chưa bật nút Like`;
206
+ }
207
+
208
+ // Default note for other platforms
209
+ return `Lưu ý khi sử dụng dịch vụ:
210
+
211
+ • Chỉ hỗ trợ link/dữ liệu công khai
212
+
213
+ • Đảm bảo link/dữ liệu hợp lệ và hoạt động
214
+
215
+ • Kiểm tra kỹ trước khi đặt đơn số lượng lớn`;
216
+ }
217
+
218
+
219
+
220
+
221
+ function getServiceDisplayName(platform, serviceName) {
222
+ const servicesData = require('./services-data.json');
223
+ const platformData = servicesData[platform];
224
+ const serviceData = platformData && platformData[serviceName];
225
+
226
+ if (serviceData && serviceData.displayName) {
227
+ return serviceData.displayName;
228
+ }
229
+
230
+ // Fallback for services without display names
231
+ return serviceName.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
232
+ }
233
+
234
+
235
+ function getPlatformDisplayName(platform) {
236
+ const platformNames = {
237
+ 'facebook': 'Facebook',
238
+ 'instagram': 'Instagram',
239
+ 'tiktok': 'TikTok',
240
+ 'youtube': 'YouTube',
241
+ 'telegram': 'Telegram',
242
+ 'twitter': 'Twitter/X',
243
+ 'threads': 'Threads',
244
+ 'shopee': 'Shopee',
245
+ };
246
+ return platformNames[platform] || platform.toUpperCase();
247
+ }
248
+
249
+ // List of service keys that require UID (URL-to-ID conversion applies)
250
+ const UID_REQUIRED_SERVICES = [
251
+ 'like_speed',
252
+ 'reactions',
253
+ 'follow',
254
+ 'like_page',
255
+ 'like_comment',
256
+ 'comment',
257
+ 'share',
258
+ 'buff_group',
259
+ 'share_group',
260
+ 'review',
261
+ 'view_100k_reel',
262
+ 'like',
263
+ 'share',
264
+ 'favorite',
265
+ 'like_comment',
266
+ 'retweet',
267
+ 'follow'
268
+ ];
269
+
270
+ // Extract ID from various platform URLs - ONLY for services that need UID
271
+ function extractIdFromUrl(url, serviceKey) {
272
+ if (!url || typeof url !== 'string') {
273
+ return url; // Return as-is if not a valid URL
274
+ }
275
+
276
+ // Only apply URL-to-ID conversion for services that require UID
277
+ if (!UID_REQUIRED_SERVICES.includes(serviceKey)) {
278
+ return url; // Return original URL for services that need URL
279
+ }
280
+
281
+ // Facebook URLs
282
+ if (url.includes('facebook.com')) {
283
+ // Special handling for Facebook Like Comment service
284
+ if (serviceKey === 'like_comment') {
285
+ // Extract pfbid and comment_id from URL with comment_id parameter
286
+ const pfbidMatch = url.match(/pfbid([a-zA-Z0-9]+)/);
287
+ const commentIdMatch = url.match(/comment_id=([a-zA-Z0-9]+)/);
288
+
289
+ if (pfbidMatch && commentIdMatch) {
290
+ // Return format: pfbid[postId]_[commentId]
291
+ return 'pfbid' + pfbidMatch[1] + '_' + commentIdMatch[1];
292
+ }
293
+
294
+ // Extract post ID and comment_id
295
+ const postMatch = url.match(/\/posts\/([a-zA-Z0-9]+)/);
296
+ if (postMatch && commentIdMatch) {
297
+ return postMatch[1] + '_' + commentIdMatch[1];
298
+ }
299
+ }
300
+
301
+ // Extract pfbid from posts (for other services)
302
+ const pfbidMatch = url.match(/pfbid([a-zA-Z0-9]+)/);
303
+ if (pfbidMatch) return 'pfbid' + pfbidMatch[1];
304
+
305
+ // Extract post ID
306
+ const postMatch = url.match(/\/posts\/([a-zA-Z0-9]+)/);
307
+ if (postMatch) return postMatch[1];
308
+
309
+ // Extract video ID
310
+ const videoMatch = url.match(/\/videos\/([a-zA-Z0-9]+)/);
311
+ if (videoMatch) return videoMatch[1];
312
+
313
+ // Extract story ID
314
+ const storyMatch = url.match(/\/stories\/[^\/]+\/([a-zA-Z0-9]+)/);
315
+ if (storyMatch) return storyMatch[1];
316
+
317
+ // Extract from permalink
318
+ const permalinkMatch = url.match(/permalink\/([a-zA-Z0-9]+)/);
319
+ if (permalinkMatch) return permalinkMatch[1];
320
+
321
+ // Extract numeric ID from username/profile
322
+ const profileMatch = url.match(/facebook\.com\/([^\/\?]+)/);
323
+ if (profileMatch && !profileMatch[1].includes('pages')) {
324
+ return profileMatch[1];
325
+ }
326
+ }
327
+
328
+ // Instagram URLs
329
+ if (url.includes('instagram.com')) {
330
+ // Extract post ID from /p/ or /reel/
331
+ const postMatch = url.match(/instagram\.com\/(p|reel)\/([a-zA-Z0-9-_]+)/);
332
+ if (postMatch) return postMatch[2];
333
+
334
+ // Extract username from profile
335
+ const profileMatch = url.match(/instagram\.com\/([^\/\?]+)/);
336
+ if (profileMatch) return profileMatch[1];
337
+ }
338
+
339
+ // TikTok URLs
340
+ if (url.includes('tiktok.com')) {
341
+ // Extract video ID
342
+ const videoMatch = url.match(/\/video\/([a-zA-Z0-9]+)/);
343
+ if (videoMatch) return videoMatch[1];
344
+
345
+ // Extract username
346
+ const profileMatch = url.match(/tiktok\.com\/@([^\/\?]+)/);
347
+ if (profileMatch) return profileMatch[1];
348
+ }
349
+
350
+ // YouTube URLs
351
+ if (url.includes('youtube.com') || url.includes('youtu.be')) {
352
+ // Extract video ID from youtu.be
353
+ const shortMatch = url.match(/youtu\.be\/([a-zA-Z0-9_-]+)/);
354
+ if (shortMatch) return shortMatch[1];
355
+
356
+ // Extract video ID from youtube.com/watch
357
+ const watchMatch = url.match(/[?&]v=([a-zA-Z0-9_-]+)/);
358
+ if (watchMatch) return watchMatch[1];
359
+
360
+ // Extract channel ID or custom name
361
+ const channelMatch = url.match(/youtube\.com\/(?:channel\/|c\/|@)?([^\/\?]+)/);
362
+ if (channelMatch) return channelMatch[1];
363
+ }
364
+
365
+ // Twitter/X URLs
366
+ if (url.includes('twitter.com') || url.includes('x.com')) {
367
+ // Extract tweet ID
368
+ const tweetMatch = url.match(/\/status\/([a-zA-Z0-9]+)/);
369
+ if (tweetMatch) return tweetMatch[1];
370
+
371
+ // Extract username
372
+ const profileMatch = url.match(/(?:twitter|x)\.com\/([^\/\?]+)/);
373
+ if (profileMatch) return profileMatch[1];
374
+ }
375
+
376
+ // Threads URLs
377
+ if (url.includes('threads.net')) {
378
+ // Extract post ID
379
+ const postMatch = url.match(/\/post\/([a-zA-Z0-9]+)/);
380
+ if (postMatch) return postMatch[1];
381
+
382
+ // Extract username
383
+ const profileMatch = url.match(/threads\.net\/@([^\/\?]+)/);
384
+ if (profileMatch) return profileMatch[1];
385
+ }
386
+
387
+ // Telegram URLs
388
+ if (url.includes('t.me')) {
389
+ // Extract post ID
390
+ const postMatch = url.match(/t\.me\/[^\/]+\/([a-zA-Z0-9]+)/);
391
+ if (postMatch) return postMatch[1];
392
+
393
+ // Extract channel/group name
394
+ const channelMatch = url.match(/t\.me\/([^\/\?]+)/);
395
+ if (channelMatch) return channelMatch[1];
396
+ }
397
+
398
+ // Shopee URLs
399
+ if (url.includes('shopee.vn')) {
400
+ // Extract product ID
401
+ const productMatch = url.match(/product\/([a-zA-Z0-9]+)/);
402
+ if (productMatch) return productMatch[1];
403
+
404
+ // Extract shop ID
405
+ const shopMatch = url.match(/shopee\.vn\/([^\/\?]+)/);
406
+ if (shopMatch) return shopMatch[1];
407
+ }
408
+
409
+ // Return original URL if no pattern matches
410
+ return url;
411
+ }
412
+
413
+ // Process comment list - convert multiline input to API format
414
+ function processCommentList(commentList) {
415
+ if (!commentList || typeof commentList !== 'string') {
416
+ return commentList;
417
+ }
418
+
419
+ // Split by newlines and filter empty lines
420
+ const comments = commentList
421
+ .split('\n')
422
+ .map(line => line.trim())
423
+ .filter(line => line.length > 0);
424
+
425
+ // If only one comment, return as is
426
+ if (comments.length === 1) {
427
+ return comments[0];
428
+ }
429
+
430
+ // If multiple comments, join with newline for API that supports it
431
+ // or return first comment for APIs that only accept single comment
432
+ return comments.join('\n');
433
+ }
434
+
435
+ // Generate auto note from n8n execution context
436
+ function generateAutoNote(serviceName, platform, inputData) {
437
+ const timestamp = new Date().toISOString();
438
+ const date = new Date().toLocaleDateString('vi-VN');
439
+ const time = new Date().toLocaleTimeString('vi-VN');
440
+
441
+ let note = `🤖 Generated from n8n UME node\n`;
442
+ note += `📅 ${date} ${time}\n`;
443
+ note += `🌐 Platform: ${platform}\n`;
444
+ note += `⚡ Service: ${serviceName}`;
445
+
446
+ // Add relevant info based on input data
447
+ if (inputData.uid) {
448
+ note += `\n📍 Target: ${inputData.uid}`;
449
+ }
450
+ if (inputData.count) {
451
+ note += `\n🔢 Quantity: ${inputData.count}`;
452
+ }
453
+ if (inputData.server) {
454
+ note += `\n🖥️ Server: ${inputData.server}`;
455
+ }
456
+ if (inputData.reaction) {
457
+ note += `\n❤️ Reaction: ${inputData.reaction}`;
458
+ }
459
+
460
+ note += `\n🆔 Order ID: AUTO-${Date.now()}`;
461
+
462
+ return note;
463
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-ume-v4",
3
- "version": "4.5.23",
3
+ "version": "4.5.24",
4
4
  "description": "UME Social Seeding Services for n8n - Version 4 with updated features",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",