Add additional external workflow hooks

This commit is contained in:
Jan Oberhauser 2020-05-06 00:59:58 +02:00
parent 0387671cae
commit 6e1254fd54
6 changed files with 65 additions and 34 deletions

View file

@ -1,23 +1,28 @@
import {
Db,
IExternalHookFunctions,
IExternalHooks,
IExternalHooksFunctions,
IExternalHooksClass,
} from './';
import * as config from '../config';
// export EXTERNAL_HOOK_FILES=/data/packages/cli/dist/src/externalHooksTemp/test-hooks.js
class ExternalHooksClass implements IExternalHooks {
class ExternalHooksClass implements IExternalHooksClass {
externalHooks: {
[key: string]: Array<() => {}>
} = {};
initDidRun = false;
async init(): Promise<void> {
console.log('ExternalHooks.init');
if (this.initDidRun === true) {
return;
}
const externalHookFiles = config.get('externalHookFiles').split(':');
console.log('externalHookFiles');
@ -48,13 +53,15 @@ class ExternalHooksClass implements IExternalHooks {
}
}
}
this.initDidRun = true;
}
async run(hookName: string, hookParameters?: any[]): Promise<void> { // tslint:disable-line:no-any
console.log('RUN NOW: ' + hookName);
const externalHookFunctions: IExternalHookFunctions = {
DbCollections: Db.collections,
const externalHookFunctions: IExternalHooksFunctions = {
dbCollections: Db.collections,
};
if (this.externalHooks[hookName] === undefined) {

View file

@ -188,11 +188,26 @@ export interface IExecutingWorkflowData {
workflowExecution?: PCancelable<IRun>;
}
export interface IExternalHookFunctions {
DbCollections: IDatabaseCollections;
export interface IExternalHooks {
credentials?: {
create?: Array<{ (this: IExternalHooksFunctions, credentialsData: ICredentialsEncrypted): Promise<void>; }>
delete?: Array<{ (this: IExternalHooksFunctions, credentialId: string): Promise<void>; }>
update?: Array<{ (this: IExternalHooksFunctions, credentialsData: ICredentialsDb): Promise<void>; }>
};
workflow?: {
activate?: Array<{ (this: IExternalHooksFunctions, workflowData: IWorkflowDb): Promise<void>; }>
create?: Array<{ (this: IExternalHooksFunctions, workflowData: IWorkflowBase): Promise<void>; }>
delete?: Array<{ (this: IExternalHooksFunctions, workflowId: string): Promise<void>; }>
execute?: Array<{ (this: IExternalHooksFunctions, workflowData: IWorkflowDb, mode: WorkflowExecuteMode): Promise<void>; }>
update?: Array<{ (this: IExternalHooksFunctions, workflowData: IWorkflowDb): Promise<void>; }>
};
}
export interface IExternalHooks {
export interface IExternalHooksFunctions {
dbCollections: IDatabaseCollections;
}
export interface IExternalHooksClass {
init(): Promise<void>;
run(hookName: string, hookParameters?: any[]): Promise<void>; // tslint:disable-line:no-any
}

View file

@ -48,7 +48,6 @@ import {
WorkflowCredentials,
WebhookHelpers,
WorkflowExecuteAdditionalData,
WorkflowHelpers,
WorkflowRunner,
GenericHelpers,
} from './';
@ -477,6 +476,8 @@ class App {
if (responseData.active === true) {
// When the workflow is supposed to be active add it again
try {
await this.externalHooks.run('workflow.activate', [responseData]);
await this.activeWorkflowRunner.add(id);
} catch (error) {
// If workflow could not be activated set it again to inactive
@ -680,8 +681,6 @@ class App {
nodeAccess.date = this.getCurrentDate();
}
await this.externalHooks.run('credentials.create');
const encryptionKey = await UserSettings.getEncryptionKey();
if (encryptionKey === undefined) {
throw new Error('No encryption key got found to encrypt the credentials!');
@ -709,6 +708,8 @@ class App {
credentials.setData(incomingData.data, encryptionKey);
const newCredentialsData = credentials.getDataToSave() as ICredentialsDb;
await this.externalHooks.run('credentials.create', [newCredentialsData]);
// Add special database related data
newCredentialsData.createdAt = this.getCurrentDate();
newCredentialsData.updatedAt = this.getCurrentDate();
@ -730,8 +731,6 @@ class App {
const id = req.params.id;
await this.externalHooks.run('credentials.update', [id]);
if (incomingData.name === '') {
throw new Error('Credentials have to have a name set!');
}
@ -770,6 +769,8 @@ class App {
// Add special database related data
newCredentialsData.updatedAt = this.getCurrentDate();
await this.externalHooks.run('credentials.update', [newCredentialsData]);
// Update the credentials in DB
await Db.collections.Credentials!.update(id, newCredentialsData);

View file

@ -1,5 +1,6 @@
import {
Db,
ExternalHooks,
IExecutionDb,
IExecutionFlattedDb,
IPushDataExecutionFinished,
@ -302,6 +303,10 @@ export async function executeWorkflow(workflowInfo: IExecuteWorkflowInfo, additi
workflowData = workflowInfo.code;
}
const externalHooks = ExternalHooks();
await externalHooks.init();
await externalHooks.run('workflow.execute', [workflowData, mode]);
const nodeTypes = NodeTypes();
const workflowName = workflowData ? workflowData.name : undefined;

View file

@ -1,5 +1,6 @@
import {
ActiveExecutions,
ExternalHooks,
IProcessMessageDataHook,
ITransferNodeTypes,
IWorkflowExecutionDataProcess,
@ -94,6 +95,9 @@ export class WorkflowRunner {
* @memberof WorkflowRunner
*/
async run(data: IWorkflowExecutionDataProcess, loadStaticData?: boolean): Promise<string> {
const externalHooks = ExternalHooks();
await externalHooks.run('workflow.execute', [data.workflowData, data.executionMode]);
const executionsProcess = config.get('executions.process') as string;
if (executionsProcess === 'main') {
return this.runMainProcess(data, loadStaticData);

View file

@ -1,45 +1,44 @@
import {
IExternalHookFunctions,
WorkflowExecuteMode,
} from 'n8n-workflow';
import {
IExternalHooks,
IExternalHooksFunctions,
IWorkflowBase,
IWorkflowDb,
} from '../';
// TODO: Move that to interfaces
interface IExternalHooks {
credentials?: {
create?: Array<{ (this: IExternalHookFunctions): Promise<void>; }>
delete?: Array<{ (this: IExternalHookFunctions, credentialId: string): Promise<void>; }>
update?: Array<{ (this: IExternalHookFunctions, credentialId: string): Promise<void>; }>
};
workflow?: {
create?: Array<{ (this: IExternalHookFunctions, workflowData: IWorkflowBase): Promise<void>; }>
delete?: Array<{ (this: IExternalHookFunctions, workflowId: string): Promise<void>; }>
update?: Array<{ (this: IExternalHookFunctions, workflowData: IWorkflowBase): Promise<void>; }>
};
}
export = {
credentials: {
create: [
async function (this: IExternalHookFunctions) {
// console.log(this.DbCollections.Workflow);
async function (this: IExternalHooksFunctions) {
// Here any additional code can run or the creation blocked
throw new Error('No additional credentials can be created.');
// throw new Error('No additional credentials can be created.');
},
],
},
workflow: {
execute: [
async function (this: IExternalHooksFunctions, workflowData: IWorkflowDb, mode: WorkflowExecuteMode) {
console.log('execute: ' + mode);
// if (mode === 'integrated') {
// throw new Error('Workflow can not be executed.');
// }
}
],
update: [
async function (this: IExternalHookFunctions, workflowData: IWorkflowBase) {
async function (this: IExternalHooksFunctions, workflowData: IWorkflowBase) {
console.log('update workflow hook');
// const responseData = await this.DbCollections.Workflow!.findOne(workflowData.id);
// const responseData = await this.dbCollections.Workflow!.findOne(workflowData.id);
// console.log('workflowData');
// console.log(responseData);
// console.log(workflowData);
// Here any additional code can run or the creation blocked
throw new Error('Workflow can not be updated.');
// throw new Error('Workflow can not be updated.');
},
],
},