UNPKG

n8n-nodes-zalo-nnt

Version:

Unofficial Zalo integration for n8n - Send messages, manage groups, user operations with QR login. No API key required, works via browser simulation.

334 lines 13 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.parseUrls = parseUrls; exports.parseLocalPaths = parseLocalPaths; exports.validateLocalFile = validateLocalFile; exports.processUrl = processUrl; exports.processLocalPath = processLocalPath; exports.processLocalPaths = processLocalPaths; exports.processUrls = processUrls; exports.processAttachments = processAttachments; exports.cleanupFiles = cleanupFiles; const path = __importStar(require("path")); const fs = __importStar(require("fs")); const os = __importStar(require("os")); const helper_1 = require("../../utils/helper"); const IMAGE_UPLOAD_PIPELINE_EXTS = ['.jpg', '.jpeg', '.png', '.webp']; function parseUrls(input) { if (!input || input.trim() === '') { return []; } const trimmed = input.trim(); if (trimmed.startsWith('[')) { try { const parsed = JSON.parse(trimmed); if (Array.isArray(parsed)) { return parsed.filter(url => url && typeof url === 'string'); } } catch { } } if (trimmed.includes(',')) { return trimmed .split(',') .map(url => url.trim()) .filter(url => url); } return [trimmed]; } function parseLocalPaths(input) { if (!input || input.trim() === '') { return []; } const trimmed = input.trim(); if (trimmed.startsWith('[')) { try { const parsed = JSON.parse(trimmed); if (Array.isArray(parsed)) { return parsed.filter(p => p && typeof p === 'string'); } } catch { } } if (trimmed.includes(',')) { return trimmed .split(',') .map(p => p.trim()) .filter(p => p); } return [trimmed]; } function validateLocalFile(filePath) { try { let absolutePath = filePath; const searchPaths = []; if (!path.isAbsolute(filePath)) { const n8nUserFolder = process.env.N8N_USER_FOLDER || path.join(os.homedir(), '.n8n'); const n8nPath = path.join(n8nUserFolder, filePath); searchPaths.push(n8nPath); const cwdPath = path.resolve(filePath); searchPaths.push(cwdPath); console.log(`[validateLocalFile] Searching for relative path: ${filePath}`); console.log(`[validateLocalFile] N8N_USER_FOLDER: ${n8nUserFolder}`); console.log(`[validateLocalFile] Current working directory: ${process.cwd()}`); let found = false; for (const testPath of searchPaths) { console.log(`[validateLocalFile] Testing: ${testPath}`); if (fs.existsSync(testPath)) { absolutePath = testPath; found = true; console.log(`[validateLocalFile] ✓ Found at: ${absolutePath}`); break; } } if (!found) { const errorMsg = `File not found: ${filePath}. Searched in: ${searchPaths.join(', ')}`; console.error(`[validateLocalFile] ${errorMsg}`); return { valid: false, error: errorMsg, }; } } else { console.log(`[validateLocalFile] Using absolute path: ${absolutePath}`); } if (!fs.existsSync(absolutePath)) { const errorMsg = `File not found: ${absolutePath}`; console.error(`[validateLocalFile] ${errorMsg}`); return { valid: false, error: errorMsg, }; } const stats = fs.statSync(absolutePath); if (!stats.isFile()) { const errorMsg = `Path is not a file: ${absolutePath}`; console.error(`[validateLocalFile] ${errorMsg}`); return { valid: false, error: errorMsg, }; } fs.accessSync(absolutePath, fs.constants.R_OK); const ext = path.extname(absolutePath).toLowerCase(); if (!IMAGE_UPLOAD_PIPELINE_EXTS.includes(ext)) { console.log(`[validateLocalFile] ${ext} will be sent as a generic file attachment (not the image pipeline): ${absolutePath}`); } console.log(`[validateLocalFile] ✓ File validated successfully: ${absolutePath}`); return { valid: true, absolutePath, }; } catch (error) { const errorMsg = `Cannot read file ${filePath}: ${error.message}`; console.error(`[validateLocalFile] ${errorMsg}`); return { valid: false, error: errorMsg, }; } } async function processUrl(url, logger) { try { logger.info(`Processing URL: ${url}`); console.log(`[AttachmentProcessor] Processing URL: ${url}`); const fileData = await (0, helper_1.saveFile)(url); if (!fileData) { const error = `Failed to download file from URL: ${url}`; logger.error(error); console.error(`[AttachmentProcessor] ${error}`); return { filePath: null, error }; } const ext = path.extname(fileData).toLowerCase(); console.log(`[AttachmentProcessor] Downloaded file: ${fileData}, extension: ${ext}`); if (IMAGE_UPLOAD_PIPELINE_EXTS.includes(ext)) { logger.info(`Successfully downloaded image: ${fileData}`); } else { logger.info(`Downloaded ${ext} file, will send as a generic file attachment: ${fileData}`); } return { filePath: fileData, error: null }; } catch (error) { const errorMsg = `Error processing URL ${url}: ${error.message}`; logger.error(errorMsg); console.error(`[AttachmentProcessor] ${errorMsg}`); return { filePath: null, error: errorMsg }; } } async function processLocalPath(filePath, logger) { try { logger.info(`Processing local file: ${filePath}`); console.log(`[AttachmentProcessor] Processing local file: ${filePath}`); const validation = validateLocalFile(filePath); if (!validation.valid) { logger.error(validation.error); console.error(`[AttachmentProcessor] ${validation.error}`); return { filePath: null, error: validation.error || 'Unknown error', isConverted: false }; } const absolutePath = validation.absolutePath; const ext = path.extname(absolutePath).toLowerCase(); if (ext === '.heic' || ext === '.heif') { console.log(`[AttachmentProcessor] HEIC/HEIF file detected: ${absolutePath}`); const tempDir = path.dirname(absolutePath); const tempFileName = `temp-${Date.now()}${ext}`; const tempPath = path.join(tempDir, tempFileName); try { fs.copyFileSync(absolutePath, tempPath); console.log(`[AttachmentProcessor] Created temp copy: ${tempPath}`); const helperModule = await Promise.resolve().then(() => __importStar(require('../../utils/helper'))); const convertedPath = await helperModule.convertHeicToJpeg(tempPath); if (convertedPath) { logger.info(`HEIC converted to: ${convertedPath}`); console.log(`[AttachmentProcessor] HEIC converted to: ${convertedPath}`); return { filePath: convertedPath, error: null, isConverted: true }; } else { logger.warn(`HEIC conversion failed, using original: ${absolutePath}`); if (fs.existsSync(tempPath)) { fs.unlinkSync(tempPath); } } } catch (conversionError) { logger.error(`HEIC conversion error: ${conversionError.message}`); if (fs.existsSync(tempPath)) { fs.unlinkSync(tempPath); } } } logger.info(`Local file validated: ${absolutePath}`); console.log(`[AttachmentProcessor] Local file validated: ${absolutePath}`); return { filePath: absolutePath, error: null, isConverted: false }; } catch (error) { const errorMsg = `Error processing local file ${filePath}: ${error.message}`; logger.error(errorMsg); console.error(`[AttachmentProcessor] ${errorMsg}`); return { filePath: null, error: errorMsg, isConverted: false }; } } async function processLocalPaths(paths, logger) { const localFiles = []; const downloadedFiles = []; const errors = []; const results = await Promise.all(paths.map(p => processLocalPath(p, logger))); for (const result of results) { if (result.filePath) { if (result.isConverted) { downloadedFiles.push(result.filePath); } else { localFiles.push(result.filePath); } } if (result.error) { errors.push(result.error); } } return { localFiles, downloadedFiles, errors }; } async function processUrls(urls, logger) { const filePaths = []; const errors = []; const results = await Promise.all(urls.map(url => processUrl(url, logger))); for (const result of results) { if (result.filePath) { filePaths.push(result.filePath); } if (result.error) { errors.push(result.error); } } return { filePaths, errors }; } async function processAttachments(attachments, logger) { if (!attachments || !attachments.attachment || attachments.attachment.length === 0) { return { downloadedFiles: [], localFiles: [], errors: [] }; } const allDownloadedFiles = []; const allLocalFiles = []; const allErrors = []; for (const attachment of attachments.attachment) { const type = attachment.type; if (type === 'url' || type === 'urlArray') { let urls = []; if (type === 'url') { urls = parseUrls(attachment.imageUrl); } else if (type === 'urlArray') { urls = parseUrls(attachment.imageUrls); } const result = await processUrls(urls, logger); allDownloadedFiles.push(...result.filePaths); allErrors.push(...result.errors); } else if (type === 'localPath' || type === 'localPaths') { let paths = []; if (type === 'localPath') { paths = parseLocalPaths(attachment.filePath); } else if (type === 'localPaths') { paths = parseLocalPaths(attachment.filePaths); } const result = await processLocalPaths(paths, logger); allLocalFiles.push(...result.localFiles); allDownloadedFiles.push(...result.downloadedFiles); allErrors.push(...result.errors); } } return { downloadedFiles: allDownloadedFiles, localFiles: allLocalFiles, errors: allErrors }; } async function cleanupFiles(filePaths, logger) { for (const filePath of filePaths) { try { logger.info(`Removing attachment: ${filePath}`); await (0, helper_1.removeFile)(filePath); } catch (error) { logger.warn(`Failed to cleanup file ${filePath}: ${error.message}`); } } } //# sourceMappingURL=attachmentProcessor.js.map