n8n自定义节点如何实现类似S3的主节点含多操作节点结构?
解决n8n自定义节点合并为单一主节点带多操作的问题
问题根源
你之前在package.json中把两个独立的节点文件(authenticate.node.js、uploadFile.node.js)都配置到main数组里,n8n会将它们识别为两个独立核心节点,这就导致搜索时出现两个节点,同时每个节点内又保留了操作下拉框的冗余结构。
正确实现步骤
1. 修正package.json节点配置
只保留一个主节点文件的路径,让n8n识别为单一核心节点:
"nodes": { "main": [ "dist/nodes/main/company.node.js" ] }
2. 整合节点代码到单一文件(company.node.ts)
你现有的Company类已经定义了操作选项和对应的参数显示规则,只需要补充execute方法,根据选中的操作执行对应逻辑即可。完整代码示例:
import { INodeType, INodeTypeDescription, IExecuteFunctions } from 'n8n-core'; export class Company implements INodeType { description: INodeTypeDescription = { displayName: 'Company', name: 'company', icon: 'file:Company.png', group: ['transform'], version: 1, description: 'Create a project and translate a file in this node.', defaults: { name: 'Company', color: '#4B8BBE', }, inputs: ['main'], outputs: ['main'], properties: [ { displayName: 'Operation', name: 'operation', type: 'options', options: [ { displayName: 'Authenticate', name: 'authenticate', value: 'authenticate', description: 'Authenticate your account', }, { displayName: 'Upload File', name: 'uploadFile', value: 'uploadFile', description: 'Upload a file in Company', }, ], default: 'authenticate', description: 'Select the operation', }, { displayName: 'Username', name: 'username', type: 'string', default: '', displayOptions: { show: { operation: ['authenticate'], }, }, description: 'The username for authentication', required: true, }, { displayName: 'Password', name: 'password', type: 'string', typeOptions: { password: true, }, displayOptions: { show: { operation: ['authenticate'], }, }, default: '', description: 'The password for authentication', required: true, }, { displayName: 'Project Name', name: 'projectName', type: 'string', displayOptions: { show: { operation: ['uploadFile'], }, }, default: '', description: 'Name of the project to create.', }, { displayName: 'Source Language', name: 'sourceLanguage', type: 'string', displayOptions: { show: { operation: ['uploadFile'], }, }, default: '', description: 'Source language of the project.', }, { displayName: 'Target Language', name: 'targetLanguage', type: 'string', displayOptions: { show: { operation: ['uploadFile'], }, }, default: '', description: 'Target language of the project.', }, { displayName: 'File Input', name: 'fileInput', type: 'string', displayOptions: { show: { operation: ['uploadFile'], }, }, default: '', placeholder: 'Select file...', typeOptions: { multipleValues: false, multipleValueButtonText: 'Add File', }, required: true, description: 'The file to be processed.', }, ], }; async execute(this: IExecuteFunctions): Promise<void> { const items = this.getInputData(); const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { try { if (operation === 'authenticate') { // 执行认证逻辑 const username = this.getNodeParameter('username', i) as string; const password = this.getNodeParameter('password', i) as string; // 替换为实际认证API调用逻辑 const authResult = { success: true, message: 'Authentication successful' }; this.appendOutputData([{ json: authResult }]); } else if (operation === 'uploadFile') { // 执行文件上传逻辑 const projectName = this.getNodeParameter('projectName', i) as string; const sourceLang = this.getNodeParameter('sourceLanguage', i) as string; const targetLang = this.getNodeParameter('targetLanguage', i) as string; const fileInput = this.getNodeParameter('fileInput', i) as string; // 替换为实际文件上传API调用逻辑 const uploadResult = { success: true, project: projectName, sourceLanguage: sourceLang, targetLanguage: targetLang, file: fileInput }; this.appendOutputData([{ json: uploadResult }]); } } catch (error) { if (this.continueOnFail()) { this.appendOutputData([{ json: { error: error.message }, pairedItem: { item: i } }]); continue; } throw error; } } } }
3. 关键说明
- 操作与参数联动:通过
displayOptions.show.operation配置,让不同操作只显示对应参数,和S3节点逻辑一致。 - 单一节点文件:所有操作逻辑都放在同一个
Company类中,n8n会将其识别为一个主节点,搜索时仅显示"Company",选中后通过顶部下拉框切换操作。 - 分支执行逻辑:在
execute方法中根据选中的operation参数,执行对应业务逻辑,确保不同操作功能正常运行。
内容的提问来源于stack exchange,提问作者Tomás Da Mota
相关产品推荐
相关产品推荐

