UNPKG

n8n-nodes-message-buffer

Version:
159 lines (158 loc) 6.34 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MessageBuffer = void 0; const ioredis_1 = __importDefault(require("ioredis")); const POLLING_SIGNAL_KEY = '__isPollingSignal__'; function setupRedisClient(credentials) { return new ioredis_1.default({ host: credentials.host, port: credentials.port, tls: credentials.ssl ? {} : undefined, db: credentials.database, username: credentials.user || undefined, password: credentials.password || undefined, showFriendlyErrorStack: true, }); } class MessageBuffer { constructor() { this.description = { displayName: 'Message Buffer', name: 'messageBuffer', icon: 'file:icon.svg', group: ['transform'], version: 1, description: 'Buffers messages for a set time to consolidate them into one. Uses a polling loop. ⚠️ Do not connect anything to the "Discarded" output — it is for internal use only⚠️ .', defaults: { name: 'Message Buffer', }, inputs: ['main'], outputs: ['main', 'main', 'main'], outputNames: ['Message Ready', 'Wait', 'Discarded'], credentials: [ { name: 'redis', required: true, }, ], properties: [ { displayName: 'Conversation Key', name: 'conversationKey', type: 'string', required: true, default: '', description: 'A unique key for the conversation (e.g., userId, chatId). This is crucial to keep conversations separate.', }, { displayName: 'Message Field', name: 'messageField', type: 'string', required: true, default: '', description: 'The field in the incoming JSON that contains the message text to buffer.', }, { displayName: 'Output Field Name', name: 'outputFieldName', type: 'string', default: 'consolidatedMessage', description: 'The name of the new field for the consolidated message.', }, { displayName: 'Wait Time (seconds)', name: 'waitTime', type: 'number', typeOptions: { minValue: 1, }, default: 5, description: 'Time to wait after the last message before consolidating. This value resets with each new message.', }, ], }; } async execute() { const conversationKey = this.getNodeParameter('conversationKey', 0); const messageField = this.getNodeParameter('messageField', 0); const waitTime = this.getNodeParameter('waitTime', 0); const outputFieldName = this.getNodeParameter('outputFieldName', 0, 'consolidatedMessage'); const credentials = await this.getCredentials('redis'); if (!credentials) { throw new Error('Redis credentials are not configured for this node.'); } const redis = setupRedisClient(credentials); const items = this.getInputData(); const returnDataWait = []; const returnDataMessageReady = []; const returnDataDiscarded = []; const dataKey = `msg:${conversationKey}`; const timerKey = `timer:${conversationKey}`; const item = items[0]; try { if (item.json[POLLING_SIGNAL_KEY]) { const timerExists = await redis.exists(timerKey); if (timerExists) { returnDataWait.push(item); } else { const messages = await redis.lrange(dataKey, 0, -1); if (messages.length > 0) { const consolidatedMessage = messages.join(' '); const newJson = { ...item.json }; delete newJson[POLLING_SIGNAL_KEY]; newJson[outputFieldName] = consolidatedMessage; newJson.allMessages = messages; const newItem = { json: newJson, binary: item.binary, }; returnDataMessageReady.push(newItem); await redis.del(dataKey); } else { returnDataDiscarded.push(item); } } } else { if (messageField.trim() !== '') { await redis.rpush(dataKey, messageField); await redis.set(timerKey, '1', 'EX', waitTime); const pollingItem = { json: { ...item.json, [POLLING_SIGNAL_KEY]: true, }, binary: item.binary, }; returnDataWait.push(pollingItem); } else { returnDataDiscarded.push(item); } } } catch (error) { if (this.continueOnFail()) { return this.prepareOutputData(items); } else { const nodeError = error instanceof Error ? error.message : 'Unknown error'; throw nodeError; } } finally { await redis.quit(); } return [ this.helpers.returnJsonArray(returnDataMessageReady), this.helpers.returnJsonArray(returnDataWait), this.helpers.returnJsonArray(returnDataDiscarded), ]; } } exports.MessageBuffer = MessageBuffer;