UNPKG

n8n-nodes-feishu-lark

Version:

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

244 lines 11.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.LarkTrigger = void 0; const n8n_workflow_1 = require("n8n-workflow"); const ws_client_1 = require("../lark-sdk/ws-client"); const event_handler_1 = require("../lark-sdk/handler/event-handler"); const properties_1 = require("../help/utils/properties"); const wording_1 = require("../help/wording"); const consts_1 = require("../lark-sdk/consts"); const RequestUtils_1 = __importDefault(require("../help/utils/RequestUtils")); class LarkTrigger { constructor() { this.description = { displayName: 'Lark Trigger', name: 'larkTrigger', icon: 'file:lark_icon.svg', group: ['trigger'], version: [1, 2], defaultVersion: 2, subtitle: '=Events: {{$parameter["events"].join(", ")}}', description: 'Starts the workflow on Lark events', defaults: { name: 'Lark Trigger', }, inputs: [], outputs: [n8n_workflow_1.NodeConnectionTypes.Main], credentials: [ { name: "larkApi", required: true, displayOptions: { show: { authentication: ["larkApi"], }, }, }, ], properties: [ { displayName: 'Authentication', name: 'authentication', type: 'options', default: `${"larkApi"}`, options: [ { name: 'Tenant Access Token', value: "larkApi", }, ], }, { displayName: 'This trigger only supports Feishu China. And due to Lark API limitations, you can use just one Lark trigger for each lark bot at a time.', name: 'LarkTriggerNotice', type: 'notice', default: '', }, properties_1.triggerEventProperty, { displayName: wording_1.WORDING.Options, name: 'options', type: 'collection', placeholder: wording_1.WORDING.AddField, default: {}, options: [ { displayName: 'Subscription Docs Event(订阅云文档事件)', name: 'subscriptionEventsUi', placeholder: 'Add New Subscription', type: 'fixedCollection', default: {}, typeOptions: { multipleValues: true, }, options: [ { name: 'eventValues', displayName: 'New Subscription', values: [ { displayName: 'File Type(文件类型)', name: 'type', type: 'options', required: true, default: 'bitable', options: [ { name: 'Bitable(多维表格)', value: "bitable", }, { name: 'Docx(新版文档类型)', value: "docx", }, { name: 'Folder(文件夹)', value: "folder", }, { name: 'File(文件)', value: "file", }, { name: 'Slides(幻灯片)', value: "slides", }, ], }, { displayName: 'File Token(文件唯一标识)', name: 'fileId', required: true, type: 'string', default: '', description: 'Document token. For details, <a target="_blank" href="https://open.feishu.cn/document/server-docs/docs/drive-v1/faq">check documentation</a>.', }, ], }, ], }, { displayName: 'Unsubscribe on Deactivate | 停用时取消订阅', name: 'unsubscribeOnDeactivate', type: 'boolean', default: false, description: 'Whether to unsubscribe the events on deactivation', }, { displayName: 'Callback Toast | 回调提示', name: 'callbackToast', type: 'string', default: '', description: 'Set the toast message displayed to users when the callback is triggered. If not set, no toast will be shown.', }, ], }, { displayName: 'Before adding this event, please ensure that you have add the subscription in the options field. <a target="_blank" href="https://open.feishu.cn/document/server-docs/docs/drive-v1/event/subscribe">Open Documentation</a>', name: 'subscriptionNotice', type: 'notice', default: '', displayOptions: { show: { events: [ consts_1.ANY_EVENT, 'drive.file.bitable_field_changed_v1', 'drive.file.bitable_record_changed_v1', ], }, }, }, ], }; } async trigger() { const credentials = await this.getCredentials("larkApi"); if (!(credentials.appid && credentials.appsecret && credentials.baseUrl)) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Missing required Lark credentials'); } const options = this.getNodeParameter('options', {}); const callbackToast = options.callbackToast || undefined; const handleSubscribeEvents = async (cmd) => { const unsubscribeOnDeactivate = options.unsubscribeOnDeactivate || false; if (cmd === 'delete_subscribe' && !unsubscribeOnDeactivate) { return; } if (options.subscriptionEventsUi) { const subscriptionEvents = options.subscriptionEventsUi .eventValues; const subscriptionPromises = subscriptionEvents.map(async (subscription) => { const { type, fileId } = subscription; return RequestUtils_1.default.request.call(this, { method: cmd === 'subscribe' ? 'POST' : 'DELETE', url: `/open-apis/drive/v1/files/${fileId}/${cmd}`, qs: { file_type: type, ...(type === "folder" && { event_type: 'file.created_in_folder_v1' }), }, }); }); await Promise.all(subscriptionPromises); } }; const appId = credentials['appid']; const appSecret = credentials['appsecret']; const baseUrl = credentials['baseUrl']; const wsClient = new ws_client_1.WSClient({ appId, appSecret, domain: `${baseUrl}`, logger: this.logger, helpers: this.helpers, }); const closeFunction = async () => { await wsClient.stop(); await handleSubscribeEvents('delete_subscribe'); }; const startWsClient = async () => { const events = this.getNodeParameter('events', []); const isAnyEvent = events.includes('any_event'); const handlers = {}; for (const event of events) { handlers[event] = async (data) => { let donePromise = undefined; donePromise = this.helpers.createDeferredPromise(); this.emit([this.helpers.returnJsonArray(data)], undefined, donePromise); this.logger.info(`Handled event: ${event}`); if (callbackToast) { return { toast: { type: 'info', content: callbackToast, }, }; } return {}; }; } const eventDispatcher = new event_handler_1.EventDispatcher({ logger: this.logger, isAnyEvent }).register(handlers); await wsClient.start({ eventDispatcher }); }; if (this.getMode() !== 'manual') { await handleSubscribeEvents('subscribe'); await startWsClient(); return { closeFunction, }; } else { const manualTriggerFunction = async () => { await handleSubscribeEvents('subscribe'); await startWsClient(); }; return { closeFunction, manualTriggerFunction, }; } } } exports.LarkTrigger = LarkTrigger; //# sourceMappingURL=LarkTrigger.node.js.map