UNPKG

n8n-nodes-feishu-lark

Version:

n8n custom nodes for n8n to interact with Feishu/Lark, including Lark Bot, Lark MCP, and Lark Trigger.

242 lines 8.42 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.StreamingMessageManager = void 0; exports.generateStreamingCardMessage = generateStreamingCardMessage; exports.updateStreamingMessage = updateStreamingMessage; exports.handleStreamingChunk = handleStreamingChunk; exports.handleNodeStart = handleNodeStart; exports.handleNodeComplete = handleNodeComplete; exports.createBotMessage = createBotMessage; exports.updateMessageInArray = updateMessageInArray; exports.createLineParser = createLineParser; const uuid_1 = require("uuid"); const RequestUtils_1 = __importDefault(require("./RequestUtils")); function pThrottle(fn, wait) { let lastTime = 0; return (async (...args) => { const now = Date.now(); if (now - lastTime >= wait) { lastTime = now; return await fn(...args); } else { return Promise.resolve(); } }); } function generateStreamingCardMessage(content) { return { schema: '2.0', config: { update_multi: true, streaming_mode: false, }, body: { direction: 'vertical', padding: '12px 12px 12px 12px', elements: [ { tag: 'markdown', content, text_align: 'left', text_size: 'normal', margin: '0px 0px 0px 0px', }, ], }, }; } async function updateStreamingMessage(context, larkMessageId, message) { return await RequestUtils_1.default.request.call(context, { method: 'PATCH', url: `/open-apis/im/v1/messages/${larkMessageId}`, body: { content: JSON.stringify(generateStreamingCardMessage(message)), }, }); } const throttledUpdateMessage = pThrottle(updateStreamingMessage, 200); async function handleStreamingChunk(context, chunk, nodeId, streamingManager, receivedMessage, messages, larkMessageId, runIndex) { var _a; try { if (chunk === '') { return; } if (!nodeId) { if (!receivedMessage) { receivedMessage = createBotMessage(larkMessageId); messages.push(receivedMessage); } const updatedMessage = { ...receivedMessage, text: receivedMessage.text + chunk, }; updateMessageInArray(messages, receivedMessage.id, updatedMessage); receivedMessage = updatedMessage; } else { let runMessage = streamingManager.getRunMessage(nodeId, runIndex); if (!runMessage) { runMessage = streamingManager.addRunToActive(nodeId, runIndex, larkMessageId); messages.push(runMessage); } const updatedMessage = streamingManager.addChunkToRun(nodeId, chunk, runIndex); if (updatedMessage) { updateMessageInArray(messages, updatedMessage.id, updatedMessage); } } throttledUpdateMessage(context, larkMessageId, (_a = messages.find((message) => message.id === larkMessageId && message.type === 'text')) === null || _a === void 0 ? void 0 : _a.text); } catch (error) { context.logger.error('Error handling stream chunk:', error); } } function handleNodeStart(nodeId, streamingManager, runIndex) { streamingManager.registerRunStart(nodeId, runIndex); } function handleNodeComplete(nodeId, streamingManager, runIndex) { streamingManager.removeRunFromActive(nodeId, runIndex); } function createBotMessage(id) { return { id: id !== null && id !== void 0 ? id : (0, uuid_1.v4)(), type: 'text', text: '', sender: 'bot', }; } function updateMessageInArray(messages, messageId, updatedMessage) { const messageIndex = messages.findIndex((msg) => msg.id === messageId); if (messageIndex === -1) { throw new Error(`Can't update message. No message with id ${messageId} found`); } messages[messageIndex] = updatedMessage; } function createLineParser() { let buffer = ''; const decoder = new TextDecoder(); return new TransformStream({ transform(chunk, controller) { var _a; buffer += decoder.decode(chunk, { stream: true }); const lines = buffer.split('\n'); buffer = (_a = lines.pop()) !== null && _a !== void 0 ? _a : ''; for (const line of lines) { if (line.trim()) { try { const parsed = JSON.parse(line); controller.enqueue(parsed); } catch (error) { controller.enqueue({ type: 'item', content: line, }); } } } }, flush(controller) { if (buffer.trim()) { try { const parsed = JSON.parse(buffer); controller.enqueue(parsed); } catch (error) { controller.enqueue({ type: 'item', content: buffer, }); } } }, }); } class StreamingMessageManager { constructor() { this.nodeRuns = new Map(); this.runOrder = []; this.activeRuns = new Set(); } getRunKey(nodeId, runIndex) { if (runIndex !== undefined) { return `${nodeId}-${runIndex}`; } return nodeId; } initializeRun(nodeId, runIndex, id) { const runKey = this.getRunKey(nodeId, runIndex); if (!this.nodeRuns.has(runKey)) { const message = createBotMessage(id); this.nodeRuns.set(runKey, { content: '', isComplete: false, message, }); this.runOrder.push(runKey); return message; } return this.nodeRuns.get(runKey).message; } registerRunStart(nodeId, runIndex) { const runKey = this.getRunKey(nodeId, runIndex); this.activeRuns.add(runKey); } addRunToActive(nodeId, runIndex, id) { const runKey = this.getRunKey(nodeId, runIndex); this.activeRuns.add(runKey); return this.initializeRun(nodeId, runIndex, id); } removeRunFromActive(nodeId, runIndex) { const runKey = this.getRunKey(nodeId, runIndex); this.activeRuns.delete(runKey); const runData = this.nodeRuns.get(runKey); if (runData) { runData.isComplete = true; } } addChunkToRun(nodeId, chunk, runIndex) { const runKey = this.getRunKey(nodeId, runIndex); const runData = this.nodeRuns.get(runKey); if (runData) { runData.content += chunk; const updatedMessage = { ...runData.message, text: runData.content, }; runData.message = updatedMessage; return updatedMessage; } return null; } getRunMessage(nodeId, runIndex) { var _a; const runKey = this.getRunKey(nodeId, runIndex); const runData = this.nodeRuns.get(runKey); return (_a = runData === null || runData === void 0 ? void 0 : runData.message) !== null && _a !== void 0 ? _a : null; } areAllRunsComplete() { return Array.from(this.nodeRuns.values()).every((data) => data.isComplete); } getRunCount() { return this.runOrder.length; } getActiveRunCount() { return this.activeRuns.size; } getAllMessages() { return this.runOrder .map((key) => { var _a; return (_a = this.nodeRuns.get(key)) === null || _a === void 0 ? void 0 : _a.message; }) .filter((message) => message !== undefined); } reset() { this.nodeRuns.clear(); this.runOrder = []; this.activeRuns.clear(); } } exports.StreamingMessageManager = StreamingMessageManager; //# sourceMappingURL=streaming.js.map