2019-06-23 03:35:23 -07:00
import {
IWebhookData ,
WebhookHttpMethod ,
2020-01-22 15:06:43 -08:00
Workflow ,
2019-06-23 03:35:23 -07:00
WorkflowExecuteMode ,
} from 'n8n-workflow' ;
import {
NodeExecuteFunctions ,
} from './' ;
export class ActiveWebhooks {
private workflowWebhooks : {
[ key : string ] : IWebhookData [ ] ;
} = { } ;
private webhookUrls : {
[ key : string ] : IWebhookData ;
} = { } ;
testWebhooks = false ;
/ * *
* Adds a new webhook
*
* @param { IWebhookData } webhookData
* @param { WorkflowExecuteMode } mode
* @returns { Promise < void > }
* @memberof ActiveWebhooks
* /
2020-01-22 15:06:43 -08:00
async add ( workflow : Workflow , webhookData : IWebhookData , mode : WorkflowExecuteMode ) : Promise < void > {
if ( workflow . id === undefined ) {
2019-06-23 03:35:23 -07:00
throw new Error ( 'Webhooks can only be added for saved workflows as an id is needed!' ) ;
}
2020-05-30 16:03:58 -07:00
const webhookKey = this . getWebhookKey ( webhookData . httpMethod , webhookData . path ) ;
//check that there is not a webhook already registed with that path/method
if ( this . webhookUrls [ webhookKey ] !== undefined ) {
2020-05-31 12:13:45 -07:00
throw new Error ( ` Test-Webhook can not be activated because another one with the same method " ${ webhookData . httpMethod } " and path " ${ webhookData . path } " is already active! ` ) ;
2020-05-30 16:03:58 -07:00
}
2020-01-22 15:06:43 -08:00
if ( this . workflowWebhooks [ webhookData . workflowId ] === undefined ) {
this . workflowWebhooks [ webhookData . workflowId ] = [ ] ;
2019-06-23 03:35:23 -07:00
}
// Make the webhook available directly because sometimes to create it successfully
// it gets called
2020-05-30 16:03:58 -07:00
this . webhookUrls [ webhookKey ] = webhookData ;
2019-06-23 03:35:23 -07:00
2020-01-22 15:06:43 -08:00
const webhookExists = await workflow . runWebhookMethod ( 'checkExists' , webhookData , NodeExecuteFunctions , mode , this . testWebhooks ) ;
2019-06-23 03:35:23 -07:00
if ( webhookExists === false ) {
// If webhook does not exist yet create it
2020-01-22 15:06:43 -08:00
await workflow . runWebhookMethod ( 'create' , webhookData , NodeExecuteFunctions , mode , this . testWebhooks ) ;
2019-06-23 03:35:23 -07:00
}
2020-01-22 15:06:43 -08:00
this . workflowWebhooks [ webhookData . workflowId ] . push ( webhookData ) ;
2019-06-23 03:35:23 -07:00
}
/ * *
* Returns webhookData if a webhook with matches is currently registered
*
* @param { WebhookHttpMethod } httpMethod
* @param { string } path
* @returns { ( IWebhookData | undefined ) }
* @memberof ActiveWebhooks
* /
get ( httpMethod : WebhookHttpMethod , path : string ) : IWebhookData | undefined {
const webhookKey = this . getWebhookKey ( httpMethod , path ) ;
if ( this . webhookUrls [ webhookKey ] === undefined ) {
return undefined ;
}
return this . webhookUrls [ webhookKey ] ;
}
2020-01-22 15:06:43 -08:00
/ * *
* Returns the ids of all the workflows which have active webhooks
*
* @returns { string [ ] }
* @memberof ActiveWebhooks
* /
getWorkflowIds ( ) : string [ ] {
return Object . keys ( this . workflowWebhooks ) ;
}
2019-06-23 03:35:23 -07:00
/ * *
* Returns key to uniquely identify a webhook
*
* @param { WebhookHttpMethod } httpMethod
* @param { string } path
* @returns { string }
* @memberof ActiveWebhooks
* /
getWebhookKey ( httpMethod : WebhookHttpMethod , path : string ) : string {
return ` ${ httpMethod } | ${ path } ` ;
}
/ * *
* Removes all webhooks of a workflow
*
2020-01-22 15:06:43 -08:00
* @param { Workflow } workflow
2019-06-23 03:35:23 -07:00
* @returns { boolean }
* @memberof ActiveWebhooks
* /
2020-01-22 15:06:43 -08:00
async removeWorkflow ( workflow : Workflow ) : Promise < boolean > {
const workflowId = workflow . id ! . toString ( ) ;
2019-06-23 03:35:23 -07:00
if ( this . workflowWebhooks [ workflowId ] === undefined ) {
// If it did not exist then there is nothing to remove
return false ;
}
const webhooks = this . workflowWebhooks [ workflowId ] ;
const mode = 'internal' ;
// Go through all the registered webhooks of the workflow and remove them
for ( const webhookData of webhooks ) {
2020-01-22 15:06:43 -08:00
await workflow . runWebhookMethod ( 'delete' , webhookData , NodeExecuteFunctions , mode , this . testWebhooks ) ;
2019-06-23 03:35:23 -07:00
delete this . webhookUrls [ this . getWebhookKey ( webhookData . httpMethod , webhookData . path ) ] ;
}
// Remove also the workflow-webhook entry
delete this . workflowWebhooks [ workflowId ] ;
return true ;
}
/ * *
2020-01-22 15:06:43 -08:00
* Removes all the webhooks of the given workflow
2019-06-23 03:35:23 -07:00
* /
2020-01-22 15:06:43 -08:00
async removeAll ( workflows : Workflow [ ] ) : Promise < void > {
2019-06-23 03:35:23 -07:00
const removePromises = [ ] ;
2020-01-22 15:06:43 -08:00
for ( const workflow of workflows ) {
removePromises . push ( this . removeWorkflow ( workflow ) ) ;
2019-06-23 03:35:23 -07:00
}
await Promise . all ( removePromises ) ;
return ;
}
}