UNPKG

n8n-nodes-base

Version:

Base nodes of n8n

195 lines 9.08 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.requestAllFiles = requestAllFiles; exports.pollFileUntilAvailable = pollFileUntilAvailable; exports.createAndUploadFile = createAndUploadFile; exports.waitForFileInSession = waitForFileInSession; exports.pushFileToSession = pushFileToSession; exports.triggerFileInput = triggerFileInput; exports.createFileBuffer = createFileBuffer; const pick_1 = __importDefault(require("lodash/pick")); const n8n_workflow_1 = require("n8n-workflow"); const constants_1 = require("../../constants"); const GenericFunctions_1 = require("../../GenericFunctions"); const transport_1 = require("../../transport"); /** * Fetches all files from the Airtop API using pagination * @param this - The execution context providing access to n8n functionality * @param sessionIds - Comma-separated string of session IDs to filter files by * @returns Promise resolving to a response object containing the complete array of files */ async function requestAllFiles(sessionIds) { const endpoint = '/files'; let hasMore = true; let currentOffset = 0; const limit = 100; const files = []; let responseData; while (hasMore) { // request files responseData = (await transport_1.apiRequest.call(this, 'GET', endpoint, {}, { offset: currentOffset, limit, sessionIds })); // add files to the array if (responseData.data?.files && Array.isArray(responseData.data?.files)) { files.push.apply(files, responseData.data.files); } // check if there are more files hasMore = Boolean(responseData.data?.pagination?.hasMore); currentOffset += limit; } return { data: { files, pagination: { hasMore, }, }, }; } /** * Polls the Airtop API until a file reaches "available" status or times out * @param this - The execution context providing access to n8n functionality * @param fileId - The unique identifier of the file to poll * @param timeout - Maximum time in milliseconds to wait before failing (defaults to OPERATION_TIMEOUT) * @param intervalSeconds - Time in seconds to wait between polling attempts (defaults to 1) * @returns Promise resolving to the file ID when the file is available * @throws NodeApiError if the operation times out or API request fails */ async function pollFileUntilAvailable(fileId, timeout = constants_1.OPERATION_TIMEOUT, intervalSeconds = 1) { let fileStatus = ''; const startTime = Date.now(); while (fileStatus !== 'available') { const elapsedTime = Date.now() - startTime; if (elapsedTime >= timeout) { throw new n8n_workflow_1.NodeApiError(this.getNode(), { message: constants_1.ERROR_MESSAGES.TIMEOUT_REACHED, code: 500, }); } const response = await transport_1.apiRequest.call(this, 'GET', `/files/${fileId}`); fileStatus = response.data?.status; // Wait before the next polling attempt await new Promise((resolve) => setTimeout(resolve, intervalSeconds * 1000)); } return fileId; } /** * Creates a file entry in Airtop, uploads the file content, and waits until processing completes * @param this - The execution context providing access to n8n functionality * @param fileName - Name to assign to the uploaded file * @param fileBuffer - Buffer containing the binary file data to upload * @param fileType - Classification of the file in Airtop (e.g., 'customer_upload') * @param pollingFunction - Function to use for checking file availability (defaults to pollFileUntilAvailable) * @returns Promise resolving to the file ID once upload is complete and file is available * @throws NodeApiError if file creation, upload, or polling fails */ async function createAndUploadFile(fileName, fileBuffer, fileType, pollingFunction = pollFileUntilAvailable) { // Create file entry const createResponse = await transport_1.apiRequest.call(this, 'POST', '/files', { fileName, fileType, }); const fileId = createResponse.data?.id; const uploadUrl = createResponse.data?.uploadUrl; if (!fileId || !uploadUrl) { throw new n8n_workflow_1.NodeApiError(this.getNode(), { message: 'Failed to create file entry: missing file ID or upload URL', code: 500, }); } // Upload the file await this.helpers.httpRequest({ method: 'PUT', url: uploadUrl, body: fileBuffer, headers: { 'Content-Type': 'application/octet-stream', }, }); // Poll until the file is available return await pollingFunction.call(this, fileId); } /** * Waits for a file to be ready in a session by polling file's information * @param this - The execution context providing access to n8n functionality * @param sessionId - ID of the session to check for file availability * @param fileId - ID of the file * @param timeout - Maximum time in milliseconds to wait before failing (defaults to OPERATION_TIMEOUT) * @returns Promise that resolves when a file in the session becomes available * @throws NodeApiError if the timeout is reached before a file becomes available */ async function waitForFileInSession(sessionId, fileId, timeout = constants_1.OPERATION_TIMEOUT) { // Wait for a "file_upload_status" event with status "available" or "upload_failed" const condition = (sessionEvent) => { const { event, status } = sessionEvent; return (sessionEvent.fileId === fileId && event === 'file_upload_status' && (status === 'available' || status === 'upload_failed')); }; const event = await GenericFunctions_1.waitForSessionEvent.call(this, sessionId, condition, timeout); if (event.status === 'upload_failed') { const error = new n8n_workflow_1.NodeApiError(this.getNode(), { message: event.eventData?.error ?? `Upload failed for File ID: ${fileId}`, code: 500, }); throw error; } } /** * Associates a file with a session and waits until the file is ready for use * @param this - The execution context providing access to n8n functionality * @param fileId - ID of the file to associate with the session * @param sessionId - ID of the session to add the file to * @param pollingFunction - Function to use for checking file availability in session (defaults to waitForFileInSession) * @returns Promise that resolves when the file is ready for use in the session */ async function pushFileToSession(fileId, sessionId, pollingFunction = waitForFileInSession) { // Push file into session await transport_1.apiRequest.call(this, 'POST', `/files/${fileId}/push`, { sessionIds: [sessionId] }); await pollingFunction.call(this, sessionId, fileId); } /** * Activates a file upload input in a specific window within a session * @param this - The execution context providing access to n8n functionality * @param fileId - ID of the file to use for the input * @param windowId - ID of the window where the file input will be triggered * @param sessionId - ID of the session containing the window * @returns Promise that resolves when the file input has been triggered */ async function triggerFileInput(request) { await transport_1.apiRequest.call(this, 'POST', `/sessions/${request.sessionId}/windows/${request.windowId}/file-input`, (0, pick_1.default)(request, ['fileId', 'elementDescription', 'includeHiddenElements'])); } /** * Creates a file Buffer from either a URL or binary data * This function supports two source types: * - URL: Downloads the file from the specified URL and returns it as a Buffer * - Binary: Retrieves binary data from the workflow's binary data storage * * @param this - The execution context providing access to n8n functionality * @param source - Source type, either 'url' or 'binary' * @param value - Either a URL string or binary data property name depending on source type * @param itemIndex - Index of the workflow item to get binary data from (when source is 'binary') * @returns Promise resolving to a Buffer containing the file data * @throws NodeApiError if the source type is unsupported or retrieval fails */ async function createFileBuffer(source, value, itemIndex) { if (source === 'url') { const buffer = (await this.helpers.httpRequest({ url: value, json: false, encoding: 'arraybuffer', })); return buffer; } if (source === 'binary') { const binaryData = await this.helpers.getBinaryDataBuffer(itemIndex, value); return binaryData; } throw new n8n_workflow_1.NodeApiError(this.getNode(), { message: `Unsupported source type: ${source}. Please use 'url' or 'binary'`, code: 500, }); } //# sourceMappingURL=helpers.js.map