n8n-nodes-feishu-lark
Version:
n8n custom nodes for n8n to interact with Feishu/Lark, including Lark Bot, Lark MCP, and Lark Trigger.
212 lines • 9.42 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const n8n_workflow_1 = require("n8n-workflow");
const wording_1 = require("../../../help/wording");
const streaming_1 = require("../../../help/utils/streaming");
const description_1 = require("../../../help/description");
const RequestUtils_1 = __importDefault(require("../../../help/utils/RequestUtils"));
const GenericFunctions_1 = require("../../GenericFunctions");
exports.default = {
name: wording_1.WORDING.SendStreamMessage,
value: "stream",
order: 100,
options: [
{
displayName: 'Tip: Get a feel with the quick <a href="https://github.com/zhgqthomas/n8n-nodes-feishu-lark/blob/main/README.md#send-streaming-message" target="_blank">tutorial</a> or see an <a href="https://github.com/zhgqthomas/n8n-nodes-feishu-lark/blob/main/demo/send_streaming_message.json" target="_blank">example</a> of how this node works',
name: 'streamMessageStarterCallout',
type: 'callout',
default: '',
},
description_1.DESCRIPTIONS.RECEIVE_ID_TYPE,
{
...description_1.DESCRIPTIONS.MEMBER_ID,
displayName: 'Receive ID(接收 ID)',
name: 'receive_id',
},
{
displayName: 'Webhook URL',
name: 'webhook_url',
type: 'string',
required: true,
hint: 'Webhook node need to use POST method to receive the message',
default: '',
},
description_1.DESCRIPTIONS.REQUEST_BODY,
{
displayName: wording_1.WORDING.Options,
name: 'options',
type: 'collection',
placeholder: wording_1.WORDING.AddField,
default: {},
options: [
{
displayName: 'Bearer Token',
name: 'bearer_token',
type: 'string',
hint: 'Bearer token for authenticating with the webhook',
default: '',
typeOptions: {
password: true,
},
},
{
displayName: 'Initial Message',
name: 'initial_message',
type: 'string',
default: 'Thinking...',
typeOptions: {
rows: 2,
},
description: 'Default messages shown at the start of the chat, one per line',
},
{
displayName: 'Timeout(minutes)',
name: 'timeout',
type: 'number',
default: 10,
typeOptions: {
minValue: 1,
maxValue: 30,
numberPrecision: 0,
},
},
],
},
],
async call(index) {
const receive_id_type = this.getNodeParameter('receive_id_type', index, 'open_id');
const receive_id = this.getNodeParameter('receive_id', index, undefined, {
extractValue: true,
});
const webhookUrl = this.getNodeParameter('webhook_url', index);
const requestBody = this.getNodeParameter('body', index);
const options = this.getNodeParameter('options', index);
const initialMessage = options.initial_message || 'Thinking...';
const bearer_token = options.bearer_token || '';
const { data } = await RequestUtils_1.default.request.call(this, {
method: 'POST',
url: `/open-apis/im/v1/messages`,
qs: {
receive_id_type,
},
body: {
receive_id,
msg_type: 'interactive',
content: JSON.stringify((0, streaming_1.generateStreamingCardMessage)(initialMessage)),
},
});
const { message_id: larkMessageId } = data;
const receivedMessage = null;
const streamingManager = new streaming_1.StreamingMessageManager();
const messages = [];
const headers = {};
if (bearer_token) {
headers['Authorization'] = `Bearer ${bearer_token}`;
}
const handlers = {
onChunk: (chunk, nodeId, runIndex) => {
(0, streaming_1.handleStreamingChunk)(this, chunk, nodeId, streamingManager, receivedMessage, messages, larkMessageId, runIndex);
},
onBeginMessage: (nodeId, runIndex) => {
(0, streaming_1.handleNodeStart)(nodeId, streamingManager, runIndex);
},
onEndMessage: (nodeId, runIndex) => {
(0, streaming_1.handleNodeComplete)(nodeId, streamingManager, runIndex);
},
};
const eventPromise = new Promise(async (resolve, reject) => {
var _a, _b, _c, _d;
try {
const response = await fetch(webhookUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'text/plain',
...headers,
},
body: JSON.stringify((0, GenericFunctions_1.parseJsonParameter)(requestBody, this.getNode(), index)),
});
if (!response.ok) {
const errorText = await response.text();
reject(new n8n_workflow_1.NodeApiError(this.getNode(), {
message: `Error when call webhook api. Error: ${errorText}`,
code: response.status,
}));
return;
}
if (!response.body) {
reject(new n8n_workflow_1.NodeApiError(this.getNode(), {
message: 'Webhook Response body is not readable',
code: 500,
}));
return;
}
const reader = response.body.pipeThrough((0, streaming_1.createLineParser)()).getReader();
let hasReceivedChunks = false;
try {
while (true) {
const { done, value } = await reader.read();
if (done)
break;
const nodeId = ((_a = value.metadata) === null || _a === void 0 ? void 0 : _a.nodeId) || 'unknown';
const runIndex = (_b = value.metadata) === null || _b === void 0 ? void 0 : _b.runIndex;
switch (value.type) {
case 'begin':
handlers.onBeginMessage(nodeId, runIndex);
break;
case 'item':
hasReceivedChunks = true;
handlers.onChunk((_c = value.content) !== null && _c !== void 0 ? _c : '', nodeId, runIndex);
break;
case 'end':
handlers.onEndMessage(nodeId, runIndex);
break;
case 'error':
hasReceivedChunks = true;
handlers.onChunk(`Error: ${(_d = value.content) !== null && _d !== void 0 ? _d : 'Unknown error'}`, nodeId, runIndex);
handlers.onEndMessage(nodeId, runIndex);
break;
}
}
}
finally {
reader.releaseLock();
}
resolve(hasReceivedChunks);
}
catch (error) {
reject(new n8n_workflow_1.NodeApiError(this.getNode(), {
message: `Unexpected error while processing stream: ${error instanceof Error ? error.message : 'Unknown error'}`,
code: 500,
}));
}
});
const timeoutInMinutes = options.timeout || 10;
const timeoutPromise = new Promise((_resolve, reject) => {
setTimeout(() => {
reject(new n8n_workflow_1.NodeApiError(this.getNode(), {
message: 'Timeout reached while waiting for the operation to complete',
code: 500,
}));
}, timeoutInMinutes * 60 * 1000);
});
await Promise.race([eventPromise, timeoutPromise]);
const output = streamingManager
.getAllMessages()
.find((message) => message.id === larkMessageId && message.type === 'text');
if (output) {
await new Promise((resolve) => setTimeout(resolve, 500));
await (0, streaming_1.updateStreamingMessage)(this, larkMessageId, output.text);
return {
output: output.text,
};
}
throw new n8n_workflow_1.NodeOperationError(this.getNode(), {
message: 'No output received',
});
},
};
//# sourceMappingURL=StreamMessage.operation.js.map