2020-01-02 15:13:53 -08:00
import {
readFile as fsReadFile ,
2021-04-30 19:22:15 -07:00
} from 'fs/promises' ;
2020-01-02 15:13:53 -08:00
2019-12-19 14:07:55 -08:00
import { IExecuteFunctions } from 'n8n-core' ;
import {
2020-10-01 05:01:39 -07:00
IExecuteWorkflowInfo ,
2019-12-19 14:07:55 -08:00
INodeExecutionData ,
INodeType ,
INodeTypeDescription ,
2020-01-02 15:13:53 -08:00
IWorkflowBase ,
2021-04-16 09:33:36 -07:00
NodeOperationError ,
2019-12-19 14:07:55 -08:00
} from 'n8n-workflow' ;
export class ExecuteWorkflow implements INodeType {
description : INodeTypeDescription = {
displayName : 'Execute Workflow' ,
name : 'executeWorkflow' ,
icon : 'fa:network-wired' ,
group : [ 'transform' ] ,
version : 1 ,
subtitle : '={{"Workflow: " + $parameter["workflowId"]}}' ,
description : 'Execute another workflow' ,
defaults : {
name : 'Execute Workflow' ,
color : '#ff6d5a' ,
} ,
inputs : [ 'main' ] ,
outputs : [ 'main' ] ,
properties : [
2020-01-02 15:13:53 -08:00
{
displayName : 'Source' ,
name : 'source' ,
type : 'options' ,
options : [
{
name : 'Database' ,
value : 'database' ,
2022-05-06 14:01:25 -07:00
description : 'Load the workflow from the database by ID' ,
2020-01-02 15:13:53 -08:00
} ,
{
name : 'Local File' ,
value : 'localFile' ,
2022-05-06 14:01:25 -07:00
description : 'Load the workflow from a locally saved file' ,
2020-01-02 15:13:53 -08:00
} ,
{
name : 'Parameter' ,
value : 'parameter' ,
2022-05-06 14:01:25 -07:00
description : 'Load the workflow from a parameter' ,
2020-01-02 15:13:53 -08:00
} ,
{
name : 'URL' ,
value : 'url' ,
2022-05-06 14:01:25 -07:00
description : 'Load the workflow from an URL' ,
2020-01-02 15:13:53 -08:00
} ,
] ,
default : 'database' ,
2022-05-06 14:01:25 -07:00
description : 'Where to get the workflow to execute from' ,
2020-01-02 15:13:53 -08:00
} ,
// ----------------------------------
// source:database
// ----------------------------------
2019-12-19 14:07:55 -08:00
{
2020-03-08 14:50:15 -07:00
displayName : 'Workflow ID' ,
2019-12-19 14:07:55 -08:00
name : 'workflowId' ,
2020-03-08 14:50:15 -07:00
type : 'string' ,
2020-01-02 15:13:53 -08:00
displayOptions : {
show : {
source : [
'database' ,
] ,
} ,
} ,
2019-12-19 14:07:55 -08:00
default : '' ,
required : true ,
2022-05-06 14:01:25 -07:00
description : 'The workflow to execute' ,
2019-12-19 14:07:55 -08:00
} ,
2020-01-02 15:13:53 -08:00
// ----------------------------------
// source:localFile
// ----------------------------------
{
displayName : 'Workflow Path' ,
name : 'workflowPath' ,
type : 'string' ,
displayOptions : {
show : {
source : [
'localFile' ,
] ,
} ,
} ,
default : '' ,
placeholder : '/data/workflow.json' ,
required : true ,
2022-05-06 14:01:25 -07:00
description : 'The path to local JSON workflow file to execute' ,
2020-01-02 15:13:53 -08:00
} ,
// ----------------------------------
// source:parameter
// ----------------------------------
{
displayName : 'Workflow JSON' ,
name : 'workflowJson' ,
type : 'string' ,
typeOptions : {
alwaysOpenEditWindow : true ,
2021-12-23 02:41:46 -08:00
editor : 'json' ,
2020-01-02 15:13:53 -08:00
rows : 10 ,
} ,
displayOptions : {
show : {
source : [
'parameter' ,
] ,
} ,
} ,
default : '\n\n\n' ,
required : true ,
2022-05-06 14:01:25 -07:00
description : 'The workflow JSON code to execute' ,
2020-01-02 15:13:53 -08:00
} ,
// ----------------------------------
// source:url
// ----------------------------------
{
displayName : 'Workflow URL' ,
name : 'workflowUrl' ,
type : 'string' ,
displayOptions : {
show : {
source : [
'url' ,
] ,
} ,
} ,
default : '' ,
placeholder : 'https://example.com/workflow.json' ,
required : true ,
2022-05-06 14:01:25 -07:00
description : 'The URL from which to load the workflow from' ,
2020-01-02 15:13:53 -08:00
} ,
2022-04-13 23:51:29 -07:00
{
displayName : 'Any data you pass into this node will be output by the start node of the workflow to be executed. <a href="https://docs.n8n.io/nodes/n8n-nodes-base.executeworkflow/" target="_blank">More info</a>' ,
name : 'executeWorkflowNotice' ,
type : 'notice' ,
default : '' ,
} ,
2020-10-22 06:46:03 -07:00
] ,
2019-12-19 14:07:55 -08:00
} ;
async execute ( this : IExecuteFunctions ) : Promise < INodeExecutionData [ ] [ ] > {
const items = this . getInputData ( ) ;
2020-01-02 15:13:53 -08:00
const source = this . getNodeParameter ( 'source' , 0 ) as string ;
const workflowInfo : IExecuteWorkflowInfo = { } ;
2021-07-19 23:58:54 -07:00
try {
if ( source === 'database' ) {
// Read workflow from database
workflowInfo . id = this . getNodeParameter ( 'workflowId' , 0 ) as string ;
} else if ( source === 'localFile' ) {
// Read workflow from filesystem
const workflowPath = this . getNodeParameter ( 'workflowPath' , 0 ) as string ;
let workflowJson ;
try {
workflowJson = await fsReadFile ( workflowPath , { encoding : 'utf8' } ) as string ;
} catch ( error ) {
if ( error . code === 'ENOENT' ) {
throw new NodeOperationError ( this . getNode ( ) , ` The file " ${ workflowPath } " could not be found. ` ) ;
}
throw error ;
2020-01-02 15:13:53 -08:00
}
2021-07-19 23:58:54 -07:00
workflowInfo . code = JSON . parse ( workflowJson ) as IWorkflowBase ;
} else if ( source === 'parameter' ) {
// Read workflow from parameter
const workflowJson = this . getNodeParameter ( 'workflowJson' , 0 ) as string ;
workflowInfo . code = JSON . parse ( workflowJson ) as IWorkflowBase ;
2020-01-02 15:13:53 -08:00
2021-07-19 23:58:54 -07:00
} else if ( source === 'url' ) {
// Read workflow from url
const workflowUrl = this . getNodeParameter ( 'workflowUrl' , 0 ) as string ;
2020-01-02 15:13:53 -08:00
2021-07-19 23:58:54 -07:00
const requestOptions = {
headers : {
'accept' : 'application/json,text/*;q=0.99' ,
} ,
method : 'GET' ,
uri : workflowUrl ,
json : true ,
gzip : true ,
} ;
2020-01-02 15:13:53 -08:00
2021-07-19 23:58:54 -07:00
const response = await this . helpers . request ( requestOptions ) ;
workflowInfo . code = response ;
2020-01-02 15:13:53 -08:00
2021-07-19 23:58:54 -07:00
}
2020-01-02 15:13:53 -08:00
2021-07-19 23:58:54 -07:00
const receivedData = await this . executeWorkflow ( workflowInfo , items ) ;
2020-01-02 15:13:53 -08:00
2021-07-19 23:58:54 -07:00
return receivedData ;
2019-12-19 14:07:55 -08:00
2021-07-19 23:58:54 -07:00
} catch ( error ) {
if ( this . continueOnFail ( ) ) {
return this . prepareOutputData ( [ { json : { error : error.message } } ] ) ;
}
throw error ;
}
2019-12-19 14:07:55 -08:00
}
}