2023-01-27 03:22:44 -08:00
import type { IHookFunctions , IWebhookFunctions } from 'n8n-core' ;
2019-12-03 05:54:30 -08:00
2023-01-27 03:22:44 -08:00
import type {
2023-02-27 19:39:43 -08:00
IDataObject ,
2019-12-03 05:54:30 -08:00
ILoadOptionsFunctions ,
INodePropertyOptions ,
2020-10-01 05:01:39 -07:00
INodeType ,
INodeTypeDescription ,
IWebhookResponseData ,
2023-02-27 19:39:43 -08:00
JsonObject ,
2020-06-30 13:35:31 -07:00
} from 'n8n-workflow' ;
2023-01-27 03:22:44 -08:00
import { NodeApiError } from 'n8n-workflow' ;
2022-08-17 08:50:24 -07:00
import { mailchimpApiRequest } from './GenericFunctions' ;
2019-12-03 05:54:30 -08:00
export class MailchimpTrigger implements INodeType {
description : INodeTypeDescription = {
displayName : 'Mailchimp Trigger' ,
2020-05-12 06:08:19 -07:00
name : 'mailchimpTrigger' ,
2021-03-25 09:10:02 -07:00
icon : 'file:mailchimp.svg' ,
2019-12-03 05:54:30 -08:00
group : [ 'trigger' ] ,
version : 1 ,
description : 'Handle Mailchimp events via webhooks' ,
defaults : {
2020-06-30 13:35:31 -07:00
name : 'Mailchimp Trigger' ,
2019-12-03 05:54:30 -08:00
} ,
inputs : [ ] ,
outputs : [ 'main' ] ,
credentials : [
{
name : 'mailchimpApi' ,
required : true ,
2020-06-04 06:54:39 -07:00
displayOptions : {
show : {
2022-08-17 08:50:24 -07:00
authentication : [ 'apiKey' ] ,
2020-06-04 06:54:39 -07:00
} ,
} ,
} ,
{
name : 'mailchimpOAuth2Api' ,
required : true ,
displayOptions : {
show : {
2022-08-17 08:50:24 -07:00
authentication : [ 'oAuth2' ] ,
2020-06-04 06:54:39 -07:00
} ,
} ,
} ,
2019-12-03 05:54:30 -08:00
] ,
webhooks : [
2019-12-11 15:31:12 -08:00
{
name : 'setup' ,
httpMethod : 'GET' ,
2023-03-03 09:49:19 -08:00
responseMode : 'onReceived' ,
2019-12-11 15:31:12 -08:00
path : 'webhook' ,
} ,
{
name : 'default' ,
httpMethod : 'POST' ,
2023-03-03 09:49:19 -08:00
responseMode : 'onReceived' ,
2019-12-11 15:31:12 -08:00
path : 'webhook' ,
2020-10-22 06:46:03 -07:00
} ,
2019-12-03 05:54:30 -08:00
] ,
properties : [
2020-06-04 06:54:39 -07:00
{
displayName : 'Authentication' ,
name : 'authentication' ,
type : 'options' ,
options : [
{
2020-06-13 19:37:03 -07:00
name : 'API Key' ,
value : 'apiKey' ,
2020-06-04 06:54:39 -07:00
} ,
{
name : 'OAuth2' ,
value : 'oAuth2' ,
} ,
] ,
2020-06-13 19:37:03 -07:00
default : 'apiKey' ,
2020-06-04 06:54:39 -07:00
} ,
2019-12-03 05:54:30 -08:00
{
2022-06-03 10:23:49 -07:00
displayName : 'List Name or ID' ,
2019-12-03 05:54:30 -08:00
name : 'list' ,
type : 'options' ,
required : true ,
2020-01-04 20:19:10 -08:00
default : '' ,
2022-08-17 08:50:24 -07:00
description :
'The list that is gonna fire the event. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.' ,
2019-12-03 05:54:30 -08:00
typeOptions : {
2020-10-22 06:46:03 -07:00
loadOptionsMethod : 'getLists' ,
2019-12-03 05:54:30 -08:00
} ,
options : [ ] ,
} ,
{
displayName : 'Events' ,
name : 'events' ,
type : 'multiOptions' ,
required : true ,
default : [ ] ,
2022-05-06 14:01:25 -07:00
description : 'The events that can trigger the webhook and whether they are enabled' ,
2019-12-03 05:54:30 -08:00
options : [
{
2022-06-20 07:54:01 -07:00
name : 'Campaign Sent' ,
value : 'campaign' ,
description : 'Whether the webhook is triggered when a campaign is sent or cancelled' ,
2019-12-03 05:54:30 -08:00
} ,
{
name : 'Cleaned' ,
value : 'cleaned' ,
2022-08-17 08:50:24 -07:00
description :
"Whether the webhook is triggered when a subscriber's email address is cleaned from the list" ,
2019-12-03 05:54:30 -08:00
} ,
{
name : 'Email Address Updated' ,
value : 'upemail' ,
2022-08-17 08:50:24 -07:00
description :
"Whether the webhook is triggered when a subscriber's email address is changed" ,
2019-12-03 05:54:30 -08:00
} ,
{
2022-06-20 07:54:01 -07:00
name : 'Profile Updated' ,
value : 'profile' ,
2022-08-17 08:50:24 -07:00
description : "Whether the webhook is triggered when a subscriber's profile is updated" ,
2022-06-20 07:54:01 -07:00
} ,
{
name : 'Subscribe' ,
value : 'subscribe' ,
description : 'Whether the webhook is triggered when a list subscriber is added' ,
} ,
{
name : 'Unsubscribe' ,
value : 'unsubscribe' ,
description : 'Whether the webhook is triggered when a list member unsubscribes' ,
2019-12-03 05:54:30 -08:00
} ,
] ,
} ,
{
displayName : 'Sources' ,
name : 'sources' ,
type : 'multiOptions' ,
required : true ,
default : [ ] ,
2022-08-17 08:50:24 -07:00
description :
'The possible sources of any events that can trigger the webhook and whether they are enabled' ,
2019-12-03 05:54:30 -08:00
options : [
{
name : 'User' ,
value : 'user' ,
2022-05-06 14:01:25 -07:00
description : 'Whether the webhook is triggered by subscriber-initiated actions' ,
2019-12-03 05:54:30 -08:00
} ,
{
name : 'Admin' ,
value : 'admin' ,
2022-08-17 08:50:24 -07:00
description :
'Whether the webhook is triggered by admin-initiated actions in the web interface' ,
2019-12-03 05:54:30 -08:00
} ,
{
name : 'API' ,
value : 'api' ,
2022-05-06 14:01:25 -07:00
description : 'Whether the webhook is triggered by actions initiated via the API' ,
2019-12-03 05:54:30 -08:00
} ,
] ,
2020-10-22 06:46:03 -07:00
} ,
2019-12-03 05:54:30 -08:00
] ,
} ;
methods = {
loadOptions : {
// Get all the available lists to display them to user so that he can
// select them easily
async getLists ( this : ILoadOptionsFunctions ) : Promise < INodePropertyOptions [ ] > {
const returnData : INodePropertyOptions [ ] = [ ] ;
2023-02-01 16:00:24 -08:00
const response = await mailchimpApiRequest . call ( this , '/lists' , 'GET' ) ;
const lists = response . lists ;
2019-12-03 05:54:30 -08:00
for ( const list of lists ) {
const listName = list . name ;
const listId = list . id ;
returnData . push ( {
name : listName ,
value : listId ,
} ) ;
}
return returnData ;
} ,
} ,
} ;
// @ts-ignore (because of request)
webhookMethods = {
default : {
async checkExists ( this : IHookFunctions ) : Promise < boolean > {
const webhookData = this . getWorkflowStaticData ( 'node' ) ;
const listId = this . getNodeParameter ( 'list' ) as string ;
if ( webhookData . webhookId === undefined ) {
// No webhook id is set so no webhook can exist
return false ;
}
const endpoint = ` /lists/ ${ listId } /webhooks/ ${ webhookData . webhookId } ` ;
try {
await mailchimpApiRequest . call ( this , endpoint , 'GET' ) ;
2021-04-16 09:33:36 -07:00
} catch ( error ) {
2023-02-01 16:00:24 -08:00
if ( error instanceof NodeApiError && error . cause && 'isAxiosError' in error . cause ) {
if ( error . cause . statusCode === 404 ) {
return false ;
}
throw error ;
2019-12-03 05:54:30 -08:00
}
2023-02-27 19:39:43 -08:00
throw new NodeApiError ( this . getNode ( ) , error as JsonObject ) ;
2019-12-03 05:54:30 -08:00
}
return true ;
} ,
async create ( this : IHookFunctions ) : Promise < boolean > {
let webhook ;
const webhookUrl = this . getNodeWebhookUrl ( 'default' ) ;
const listId = this . getNodeParameter ( 'list' ) as string ;
const events = this . getNodeParameter ( 'events' , [ ] ) as string [ ] ;
const sources = this . getNodeParameter ( 'sources' , [ ] ) as string [ ] ;
const body = {
url : webhookUrl ,
events : events.reduce ( ( object , currentValue ) = > {
// @ts-ignore
object [ currentValue ] = true ;
return object ;
} , { } ) ,
sources : sources.reduce ( ( object , currentValue ) = > {
// @ts-ignore
object [ currentValue ] = true ;
return object ;
} , { } ) ,
} ;
const endpoint = ` /lists/ ${ listId } /webhooks ` ;
try {
webhook = await mailchimpApiRequest . call ( this , endpoint , 'POST' , body ) ;
2021-04-16 09:33:36 -07:00
} catch ( error ) {
throw error ;
2019-12-03 05:54:30 -08:00
}
if ( webhook . id === undefined ) {
return false ;
}
const webhookData = this . getWorkflowStaticData ( 'node' ) ;
webhookData . webhookId = webhook . id as string ;
webhookData . events = events ;
webhookData . sources = sources ;
return true ;
} ,
async delete ( this : IHookFunctions ) : Promise < boolean > {
const webhookData = this . getWorkflowStaticData ( 'node' ) ;
const listId = this . getNodeParameter ( 'list' ) as string ;
if ( webhookData . webhookId !== undefined ) {
const endpoint = ` /lists/ ${ listId } /webhooks/ ${ webhookData . webhookId } ` ;
try {
await mailchimpApiRequest . call ( this , endpoint , 'DELETE' , { } ) ;
2021-04-16 09:33:36 -07:00
} catch ( error ) {
2019-12-03 05:54:30 -08:00
return false ;
}
delete webhookData . webhookId ;
delete webhookData . events ;
delete webhookData . sources ;
}
return true ;
} ,
} ,
} ;
async webhook ( this : IWebhookFunctions ) : Promise < IWebhookResponseData > {
2022-12-02 12:54:28 -08:00
const webhookData = this . getWorkflowStaticData ( 'node' ) ;
2019-12-11 15:31:12 -08:00
const webhookName = this . getWebhookName ( ) ;
if ( webhookName === 'setup' ) {
// Is a create webhook confirmation request
const res = this . getResponseObject ( ) ;
res . status ( 200 ) . end ( ) ;
return {
noWebhookResponse : true ,
} ;
}
2019-12-03 05:54:30 -08:00
const req = this . getRequestObject ( ) ;
if ( req . body . id !== webhookData . id ) {
return { } ;
}
2022-08-17 08:50:24 -07:00
if (
// @ts-ignore
! webhookData . events . includes ( req . body . type ) &&
2020-06-30 13:35:31 -07:00
// @ts-ignore
2022-08-17 08:50:24 -07:00
! webhookData . sources . includes ( req . body . type )
) {
2019-12-03 05:54:30 -08:00
return { } ;
}
return {
2023-02-27 19:39:43 -08:00
workflowData : [ this . helpers . returnJsonArray ( req . body as IDataObject ) ] ,
2019-12-03 05:54:30 -08:00
} ;
}
}