Add additional helper functions to webhook functionality

This commit is contained in:
Jan Oberhauser 2019-07-12 11:33:18 +02:00
parent 5f471c2ab3
commit 1e0d2cbf1e
4 changed files with 86 additions and 38 deletions

View file

@ -135,7 +135,7 @@ export function getWorkflowWebhooks(workflow: Workflow, additionalData: IWorkflo
try { try {
// Run the webhook function to see what should be returned and if // Run the webhook function to see what should be returned and if
// the workflow should be executed or not // the workflow should be executed or not
const webhookResultData = await webhookData.workflow.runWebhook(workflowStartNode, additionalData, NodeExecuteFunctions, executionMode); const webhookResultData = await webhookData.workflow.runWebhook(webhookData, workflowStartNode, additionalData, NodeExecuteFunctions, executionMode);
if (webhookResultData.noWebhookResponse === true) { if (webhookResultData.noWebhookResponse === true) {
// The response got already send // The response got already send

View file

@ -22,6 +22,7 @@ import {
IRunExecutionData, IRunExecutionData,
ITaskDataConnections, ITaskDataConnections,
ITriggerFunctions, ITriggerFunctions,
IWebhookData,
IWebhookDescription, IWebhookDescription,
IWebhookFunctions, IWebhookFunctions,
IWorkflowExecuteAdditionalData, IWorkflowExecuteAdditionalData,
@ -226,6 +227,38 @@ export function getNodeParameter(workflow: Workflow, runExecutionData: IRunExecu
/**
* Returns the webhook URL of the webhook with the given name
*
* @export
* @param {string} name
* @param {Workflow} workflow
* @param {INode} node
* @param {IWorkflowExecuteAdditionalData} additionalData
* @param {boolean} [isTest]
* @returns {(string | undefined)}
*/
export function getNodeWebhookUrl(name: string, workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, isTest?: boolean): string | undefined {
let baseUrl = additionalData.webhookBaseUrl;
if (isTest === true) {
baseUrl = additionalData.webhookTestBaseUrl;
}
const webhookDescription = getWebhookDescription(name, workflow, node);
if (webhookDescription === undefined) {
return undefined;
}
const path = workflow.getWebhookParameterValue(node, webhookDescription, 'path');
if (path === undefined) {
return undefined;
}
return NodeHelpers.getNodeWebhookUrl(baseUrl, workflow.id!, node, path);
}
/** /**
* Returns the timezone for the workflow * Returns the timezone for the workflow
* *
@ -243,6 +276,34 @@ export function getTimezone(workflow: Workflow, additionalData: IWorkflowExecute
/**
* Returns the full webhook description of the webhook with the given name
*
* @export
* @param {string} name
* @param {Workflow} workflow
* @param {INode} node
* @returns {(IWebhookDescription | undefined)}
*/
export function getWebhookDescription(name: string, workflow: Workflow, node: INode): IWebhookDescription | undefined {
const nodeType = workflow.nodeTypes.getByName(node.type) as INodeType;
if (nodeType.description.webhooks === undefined) {
// Node does not have any webhooks so return
return undefined;
}
for (const webhookDescription of nodeType.description.webhooks) {
if (webhookDescription.name === name) {
return webhookDescription;
}
}
return undefined;
}
/** /**
* Returns the execute functions the trigger nodes have access to. * Returns the execute functions the trigger nodes have access to.
* *
@ -496,7 +557,7 @@ export function getLoadOptionsFunctions(workflow: Workflow, node: INode, additio
* @param {WorkflowExecuteMode} mode * @param {WorkflowExecuteMode} mode
* @returns {IHookFunctions} * @returns {IHookFunctions}
*/ */
export function getExecuteHookFunctions(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode, isTest?: boolean): IHookFunctions { export function getExecuteHookFunctions(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode, isTest?: boolean, webhookData?: IWebhookData): IHookFunctions {
return ((workflow: Workflow, node: INode) => { return ((workflow: Workflow, node: INode) => {
const that = { const that = {
getCredentials(type: string): ICredentialDataDecryptedObject | undefined { getCredentials(type: string): ICredentialDataDecryptedObject | undefined {
@ -514,41 +575,19 @@ export function getExecuteHookFunctions(workflow: Workflow, node: INode, additio
return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, fallbackValue); return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, fallbackValue);
}, },
getNodeWebhookUrl: (name: string): string | undefined => { getNodeWebhookUrl: (name: string): string | undefined => {
let baseUrl = additionalData.webhookBaseUrl; return getNodeWebhookUrl(name, workflow, node, additionalData, isTest);
if (isTest === true) {
baseUrl = additionalData.webhookTestBaseUrl;
}
const webhookDescription = that.getWebhookDescription(name);
if (webhookDescription === undefined) {
return undefined;
}
const path = workflow.getWebhookParameterValue(node, webhookDescription, 'path');
if (path === undefined) {
return undefined;
}
return NodeHelpers.getNodeWebhookUrl(baseUrl, workflow.id!, node, path);
}, },
getTimezone: (): string => { getTimezone: (): string => {
return getTimezone(workflow, additionalData); return getTimezone(workflow, additionalData);
}, },
getWebhookName(): string {
if (webhookData === undefined) {
throw new Error('Is only supported in webhook functions!');
}
return webhookData.webhookDescription.name;
},
getWebhookDescription(name: string): IWebhookDescription | undefined { getWebhookDescription(name: string): IWebhookDescription | undefined {
const nodeType = workflow.nodeTypes.getByName(node.type) as INodeType; return getWebhookDescription(name, workflow, node);
if (nodeType.description.webhooks === undefined) {
// Node does not have any webhooks so return
return undefined;
}
for (const webhookDescription of nodeType.description.webhooks) {
if (webhookDescription.name === name) {
return webhookDescription;
}
}
return undefined;
}, },
getWorkflowStaticData(type: string): IDataObject { getWorkflowStaticData(type: string): IDataObject {
return workflow.getStaticData(type, node); return workflow.getStaticData(type, node);
@ -574,7 +613,7 @@ export function getExecuteHookFunctions(workflow: Workflow, node: INode, additio
* @param {WorkflowExecuteMode} mode * @param {WorkflowExecuteMode} mode
* @returns {IWebhookFunctions} * @returns {IWebhookFunctions}
*/ */
export function getExecuteWebhookFunctions(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode): IWebhookFunctions { export function getExecuteWebhookFunctions(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode, webhookData: IWebhookData): IWebhookFunctions {
return ((workflow: Workflow, node: INode) => { return ((workflow: Workflow, node: INode) => {
return { return {
getBodyData(): IDataObject { getBodyData(): IDataObject {
@ -621,12 +660,18 @@ export function getExecuteWebhookFunctions(workflow: Workflow, node: INode, addi
} }
return additionalData.httpResponse; return additionalData.httpResponse;
}, },
getNodeWebhookUrl: (name: string): string | undefined => {
return getNodeWebhookUrl(name, workflow, node, additionalData);
},
getTimezone: (): string => { getTimezone: (): string => {
return getTimezone(workflow, additionalData); return getTimezone(workflow, additionalData);
}, },
getWorkflowStaticData(type: string): IDataObject { getWorkflowStaticData(type: string): IDataObject {
return workflow.getStaticData(type, node); return workflow.getStaticData(type, node);
}, },
getWebhookName(): string {
return webhookData.webhookDescription.name;
},
prepareOutputData: NodeHelpers.prepareOutputData, prepareOutputData: NodeHelpers.prepareOutputData,
helpers: { helpers: {
prepareBinaryData, prepareBinaryData,

View file

@ -167,6 +167,7 @@ export interface IHookFunctions {
getNodeParameter(parameterName: string, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object; //tslint:disable-line:no-any getNodeParameter(parameterName: string, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object; //tslint:disable-line:no-any
getTimezone(): string; getTimezone(): string;
getWebhookDescription(name: string): IWebhookDescription | undefined; getWebhookDescription(name: string): IWebhookDescription | undefined;
getWebhookName(): string;
getWorkflowStaticData(type: string): IDataObject; getWorkflowStaticData(type: string): IDataObject;
helpers: { helpers: {
[key: string]: (...args: any[]) => any //tslint:disable-line:no-any [key: string]: (...args: any[]) => any //tslint:disable-line:no-any
@ -191,10 +192,12 @@ export interface IWebhookFunctions {
getHeaderData(): object; getHeaderData(): object;
getMode(): WorkflowExecuteMode; getMode(): WorkflowExecuteMode;
getNodeParameter(parameterName: string, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object; //tslint:disable-line:no-any getNodeParameter(parameterName: string, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object; //tslint:disable-line:no-any
getNodeWebhookUrl: (name: string) => string | undefined;
getQueryData(): object; getQueryData(): object;
getRequestObject(): express.Request; getRequestObject(): express.Request;
getResponseObject(): express.Response; getResponseObject(): express.Response;
getTimezone(): string; getTimezone(): string;
getWebhookName(): string;
getWorkflowStaticData(type: string): IDataObject; getWorkflowStaticData(type: string): IDataObject;
prepareOutputData(outputData: INodeExecutionData[], outputIndex?: number): Promise<INodeExecutionData[][]>; prepareOutputData(outputData: INodeExecutionData[], outputIndex?: number): Promise<INodeExecutionData[][]>;
helpers: { helpers: {
@ -247,8 +250,8 @@ export interface INodeExecuteFunctions {
getExecuteTriggerFunctions(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode): ITriggerFunctions; getExecuteTriggerFunctions(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode): ITriggerFunctions;
getExecuteFunctions(workflow: Workflow, runExecutionData: IRunExecutionData, runIndex: number, connectionInputData: INodeExecutionData[], inputData: ITaskDataConnections, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode): IExecuteFunctions; getExecuteFunctions(workflow: Workflow, runExecutionData: IRunExecutionData, runIndex: number, connectionInputData: INodeExecutionData[], inputData: ITaskDataConnections, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode): IExecuteFunctions;
getExecuteSingleFunctions(workflow: Workflow, runExecutionData: IRunExecutionData, runIndex: number, connectionInputData: INodeExecutionData[], inputData: ITaskDataConnections, node: INode, itemIndex: number, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode): IExecuteSingleFunctions; getExecuteSingleFunctions(workflow: Workflow, runExecutionData: IRunExecutionData, runIndex: number, connectionInputData: INodeExecutionData[], inputData: ITaskDataConnections, node: INode, itemIndex: number, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode): IExecuteSingleFunctions;
getExecuteHookFunctions(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode, isTest?: boolean): IHookFunctions; getExecuteHookFunctions(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode, isTest?: boolean, webhookData?: IWebhookData): IHookFunctions;
getExecuteWebhookFunctions(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode): IWebhookFunctions; getExecuteWebhookFunctions(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode, webhookData: IWebhookData): IWebhookFunctions;
} }

View file

@ -896,7 +896,7 @@ export class Workflow {
return; return;
} }
const thisArgs = nodeExecuteFunctions.getExecuteHookFunctions(this, node, webhookData.workflowExecuteAdditionalData, mode, isTest); const thisArgs = nodeExecuteFunctions.getExecuteHookFunctions(this, node, webhookData.workflowExecuteAdditionalData, mode, isTest, webhookData);
return nodeType.webhookMethods[webhookData.webhookDescription.name][method]!.call(thisArgs); return nodeType.webhookMethods[webhookData.webhookDescription.name][method]!.call(thisArgs);
} }
@ -956,7 +956,7 @@ export class Workflow {
* @returns {Promise<IWebhookResonseData>} * @returns {Promise<IWebhookResonseData>}
* @memberof Workflow * @memberof Workflow
*/ */
async runWebhook(node: INode, additionalData: IWorkflowExecuteAdditionalData, nodeExecuteFunctions: INodeExecuteFunctions, mode: WorkflowExecuteMode): Promise<IWebhookResonseData> { async runWebhook(webhookData: IWebhookData, node: INode, additionalData: IWorkflowExecuteAdditionalData, nodeExecuteFunctions: INodeExecuteFunctions, mode: WorkflowExecuteMode): Promise<IWebhookResonseData> {
const nodeType = this.nodeTypes.getByName(node.type); const nodeType = this.nodeTypes.getByName(node.type);
if (nodeType === undefined) { if (nodeType === undefined) {
throw new Error(`The type of the webhook node "${node.name}" is not known.`); throw new Error(`The type of the webhook node "${node.name}" is not known.`);
@ -964,7 +964,7 @@ export class Workflow {
throw new Error(`The node "${node.name}" does not have any webhooks defined.`); throw new Error(`The node "${node.name}" does not have any webhooks defined.`);
} }
const thisArgs = nodeExecuteFunctions.getExecuteWebhookFunctions(this, node, additionalData, mode); const thisArgs = nodeExecuteFunctions.getExecuteWebhookFunctions(this, node, additionalData, mode, webhookData);
return nodeType.webhook.call(thisArgs); return nodeType.webhook.call(thisArgs);
} }