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
JavaScript
;
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