Add Webhook response node (#2254)
* ✨ Add Webhook-Response-Node * ⚡ Replace callback function with promise * ✨ Add support for Bull and binary-data * ✨ Add string response option * ⚡ Remove some comments * ✨ Make more generically possible & fix issue multi call in queue mode * ⚡ Fix startup and eslint issues * ⚡ Improvements to webhook response node and functionality * ⚡ Replace data with more generic type * ⚡ Make statusMessage optional * ⚡ Change parameter order * ⚡ Move Response Code underneath options * ⚡ Hide Response Code on Webhook node if mode responseNode got selected * ⚡ Minor improvements * ⚡ Add missing file and fix lint issue * ⚡ Fix some node linting issues * ⚡ Apply feedback * ⚡ Minor improvements
This commit is contained in:
@@ -15,6 +15,8 @@ import { IProcessMessage, WorkflowExecute } from 'n8n-core';
|
||||
|
||||
import {
|
||||
ExecutionError,
|
||||
IDeferredPromise,
|
||||
IExecuteResponsePromiseData,
|
||||
IRun,
|
||||
LoggerProxy as Logger,
|
||||
Workflow,
|
||||
@@ -41,9 +43,7 @@ import {
|
||||
IBullJobResponse,
|
||||
ICredentialsOverwrite,
|
||||
ICredentialsTypeData,
|
||||
IExecutionDb,
|
||||
IExecutionFlattedDb,
|
||||
IExecutionResponse,
|
||||
IProcessMessageDataHook,
|
||||
ITransferNodeTypes,
|
||||
IWorkflowExecutionDataProcess,
|
||||
@@ -51,6 +51,7 @@ import {
|
||||
NodeTypes,
|
||||
Push,
|
||||
ResponseHelper,
|
||||
WebhookHelpers,
|
||||
WorkflowExecuteAdditionalData,
|
||||
WorkflowHelpers,
|
||||
} from '.';
|
||||
@@ -146,6 +147,7 @@ export class WorkflowRunner {
|
||||
loadStaticData?: boolean,
|
||||
realtime?: boolean,
|
||||
executionId?: string,
|
||||
responsePromise?: IDeferredPromise<IExecuteResponsePromiseData>,
|
||||
): Promise<string> {
|
||||
const executionsProcess = config.get('executions.process') as string;
|
||||
const executionsMode = config.get('executions.mode') as string;
|
||||
@@ -153,11 +155,17 @@ export class WorkflowRunner {
|
||||
if (executionsMode === 'queue' && data.executionMode !== 'manual') {
|
||||
// Do not run "manual" executions in bull because sending events to the
|
||||
// frontend would not be possible
|
||||
executionId = await this.runBull(data, loadStaticData, realtime, executionId);
|
||||
executionId = await this.runBull(
|
||||
data,
|
||||
loadStaticData,
|
||||
realtime,
|
||||
executionId,
|
||||
responsePromise,
|
||||
);
|
||||
} else if (executionsProcess === 'main') {
|
||||
executionId = await this.runMainProcess(data, loadStaticData, executionId);
|
||||
executionId = await this.runMainProcess(data, loadStaticData, executionId, responsePromise);
|
||||
} else {
|
||||
executionId = await this.runSubprocess(data, loadStaticData, executionId);
|
||||
executionId = await this.runSubprocess(data, loadStaticData, executionId, responsePromise);
|
||||
}
|
||||
|
||||
const postExecutePromise = this.activeExecutions.getPostExecutePromise(executionId);
|
||||
@@ -200,6 +208,7 @@ export class WorkflowRunner {
|
||||
data: IWorkflowExecutionDataProcess,
|
||||
loadStaticData?: boolean,
|
||||
restartExecutionId?: string,
|
||||
responsePromise?: IDeferredPromise<IExecuteResponsePromiseData>,
|
||||
): Promise<string> {
|
||||
if (loadStaticData === true && data.workflowData.id) {
|
||||
data.workflowData.staticData = await WorkflowHelpers.getStaticDataById(
|
||||
@@ -256,6 +265,15 @@ export class WorkflowRunner {
|
||||
executionId,
|
||||
true,
|
||||
);
|
||||
|
||||
additionalData.hooks.hookFunctions.sendResponse = [
|
||||
async (response: IExecuteResponsePromiseData): Promise<void> => {
|
||||
if (responsePromise) {
|
||||
responsePromise.resolve(response);
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
additionalData.sendMessageToUI = WorkflowExecuteAdditionalData.sendMessageToUI.bind({
|
||||
sessionId: data.sessionId,
|
||||
});
|
||||
@@ -341,11 +359,15 @@ export class WorkflowRunner {
|
||||
loadStaticData?: boolean,
|
||||
realtime?: boolean,
|
||||
restartExecutionId?: string,
|
||||
responsePromise?: IDeferredPromise<IExecuteResponsePromiseData>,
|
||||
): Promise<string> {
|
||||
// TODO: If "loadStaticData" is set to true it has to load data new on worker
|
||||
|
||||
// Register the active execution
|
||||
const executionId = await this.activeExecutions.add(data, undefined, restartExecutionId);
|
||||
if (responsePromise) {
|
||||
this.activeExecutions.attachResponsePromise(executionId, responsePromise);
|
||||
}
|
||||
|
||||
const jobData: IBullJobData = {
|
||||
executionId,
|
||||
@@ -545,6 +567,7 @@ export class WorkflowRunner {
|
||||
data: IWorkflowExecutionDataProcess,
|
||||
loadStaticData?: boolean,
|
||||
restartExecutionId?: string,
|
||||
responsePromise?: IDeferredPromise<IExecuteResponsePromiseData>,
|
||||
): Promise<string> {
|
||||
let startedAt = new Date();
|
||||
const subprocess = fork(pathJoin(__dirname, 'WorkflowRunnerProcess.js'));
|
||||
@@ -653,6 +676,10 @@ export class WorkflowRunner {
|
||||
} else if (message.type === 'end') {
|
||||
clearTimeout(executionTimeout);
|
||||
this.activeExecutions.remove(executionId, message.data.runData);
|
||||
} else if (message.type === 'sendResponse') {
|
||||
if (responsePromise) {
|
||||
responsePromise.resolve(WebhookHelpers.decodeWebhookResponse(message.data.response));
|
||||
}
|
||||
} else if (message.type === 'sendMessageToUI') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
WorkflowExecuteAdditionalData.sendMessageToUI.bind({ sessionId: data.sessionId })(
|
||||
|
||||
Reference in New Issue
Block a user