UNPKG

n8n-nodes-mautic-advanced

Version:

Enhanced n8n node for Mautic with comprehensive API coverage including tags, campaigns, categories, and advanced contact management

598 lines (597 loc) 30.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MauticAdvanced = void 0; const n8n_workflow_1 = require("n8n-workflow"); const ContactOperations_1 = require("./operations/ContactOperations"); const CompanyOperations_1 = require("./operations/CompanyOperations"); const CampaignOperations_1 = require("./operations/CampaignOperations"); const FieldOperations_1 = require("./operations/FieldOperations"); const NoteOperations_1 = require("./operations/NoteOperations"); const NotificationOperations_1 = require("./operations/NotificationOperations"); const SegmentOperations_1 = require("./operations/SegmentOperations"); const EmailOperations_1 = require("./operations/EmailOperations"); const ThemeOperations_1 = require("./operations/ThemeOperations"); const MiscellaneousOperations_1 = require("./operations/MiscellaneousOperations"); const UserOperations_1 = require("./operations/UserOperations"); const RoleOperations_1 = require("./operations/RoleOperations"); const StatsOperations_1 = require("./operations/StatsOperations"); const CampaignContactDescription_1 = require("./CampaignContactDescription"); const CampaignDescription_1 = require("./CampaignDescription"); const CategoryDescription_1 = require("./CategoryDescription"); const CompanyContactDescription_1 = require("./CompanyContactDescription"); const CompanyDescription_1 = require("./CompanyDescription"); const ContactDescription_1 = require("./ContactDescription"); const ContactSegmentDescription_1 = require("./ContactSegmentDescription"); const EmailDescription_1 = require("./EmailDescription"); const FieldDescription_1 = require("./FieldDescription"); const GenericFunctions_1 = require("./GenericFunctions"); const loadOptionsCache_1 = require("./utils/loadOptionsCache"); const NoteDescription_1 = require("./NoteDescription"); const NotificationDescription_1 = require("./NotificationDescription"); const SegmentEmailDescription_1 = require("./SegmentEmailDescription"); const SegmentDescription_1 = require("./SegmentDescription"); const TagDescription_1 = require("./TagDescription"); const ThemeDescription_1 = require("./ThemeDescription"); const UserDescription_1 = require("./UserDescription"); const RoleDescription_1 = require("./RoleDescription"); const StatsDescription_1 = require("./StatsDescription"); class MauticAdvanced { constructor() { this.description = { displayName: 'Mautic Advanced', name: 'mauticAdvanced', icon: 'file:MauticAdvancedIcon.svg', group: ['output'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', description: 'Consume Mautic API with advanced features', defaults: { name: 'Mautic Advanced', }, usableAsTool: true, inputs: ['main'], outputs: ['main'], credentials: [ { name: 'mauticAdvancedApi', required: true, displayOptions: { show: { authentication: ['credentials'], }, }, }, { name: 'mauticAdvancedOAuth2Api', required: true, displayOptions: { show: { authentication: ['oAuth2'], }, }, }, ], properties: [ { displayName: 'Authentication', name: 'authentication', type: 'options', options: [ { name: 'Credentials', value: 'credentials', }, { name: 'OAuth2', value: 'oAuth2', }, ], default: 'credentials', }, { displayName: 'Resource', name: 'resource', type: 'options', noDataExpression: true, options: [ { name: 'Campaign', value: 'campaign', description: 'Create, update, and retrieve campaigns', }, { name: 'Campaign Contact', value: 'campaignContact', description: 'Add/remove contacts to/from a campaign', }, { name: 'Category', value: 'category', description: 'Create, update, and retrieve categories', }, { name: 'Company', value: 'company', description: 'Create or modify a company', }, { name: 'Company Contact', value: 'companyContact', description: 'Add/remove contacts to/from a company', }, { name: 'Contact', value: 'contact', description: 'Create & modify contacts', }, { name: 'Contact Segment', value: 'contactSegment', description: 'Add/remove contacts to/from a segment', }, { name: 'Email', value: 'email', description: 'Create, update, and retrieve emails', }, { name: 'Field', value: 'field', description: 'Manage custom fields for contacts and companies', }, { name: 'Note', value: 'note', description: 'Create, update, and retrieve contact notes', }, { name: 'Notification', value: 'notification', description: 'Create, update, and retrieve notifications', }, { name: 'Role', value: 'role', description: 'Create, update, and retrieve roles', }, { name: 'Segment', value: 'segment', description: 'Create, update, and retrieve segments', }, { name: 'Segment Email', value: 'segmentEmail', description: 'Send an email', }, { name: 'Stats', value: 'stats', description: 'Get statistical data from Mautic tables', }, { name: 'Tag', value: 'tag', description: 'Create, update, and retrieve tags', }, { name: 'Theme', value: 'theme', description: 'Create, update, and retrieve themes', }, { name: 'User', value: 'user', description: 'Create, update, and retrieve users', }, ], default: 'contact', }, ...CompanyDescription_1.companyOperations, ...CompanyDescription_1.companyFields, ...ContactDescription_1.contactOperations, ...ContactDescription_1.contactFields, ...ContactSegmentDescription_1.contactSegmentOperations, ...ContactSegmentDescription_1.contactSegmentFields, ...CampaignDescription_1.campaignOperations, ...CampaignDescription_1.campaignFields, ...CampaignContactDescription_1.campaignContactOperations, ...CampaignContactDescription_1.campaignContactFields, ...CompanyContactDescription_1.companyContactOperations, ...CompanyContactDescription_1.companyContactFields, ...EmailDescription_1.emailOperations, ...EmailDescription_1.emailFields, ...FieldDescription_1.fieldOperations, ...FieldDescription_1.fieldFields, ...NoteDescription_1.noteOperations, ...NoteDescription_1.noteFields, ...NotificationDescription_1.notificationOperations, ...NotificationDescription_1.notificationFields, ...SegmentEmailDescription_1.segmentEmailOperations, ...SegmentEmailDescription_1.segmentEmailFields, ...TagDescription_1.tagOperations, ...TagDescription_1.tagFields, ...CategoryDescription_1.categoryOperations, ...CategoryDescription_1.categoryFields, ...SegmentDescription_1.segmentOperations, ...SegmentDescription_1.segmentFields, ...ThemeDescription_1.themeOperations, ...ThemeDescription_1.themeFields, ...UserDescription_1.userOperations, ...UserDescription_1.userFields, ...RoleDescription_1.roleOperations, ...RoleDescription_1.roleFields, ...StatsDescription_1.statsOperations, ...StatsDescription_1.statsFields, ], }; this.methods = { loadOptions: { // Get all the available tags to display them to user so that they can // select them easily async getTags() { const returnData = []; const tags = await (0, loadOptionsCache_1.getCachedMauticLoadOptions)(this, 'tags', () => GenericFunctions_1.mauticApiRequestAllItems.call(this, 'tags', 'GET', '/tags')); for (const tag of tags) { returnData.push({ name: tag.tag, value: tag.tag, }); } return returnData; }, // Get all the available stages to display them to user so that they can // select them easily async getStages() { const returnData = []; const stages = await (0, loadOptionsCache_1.getCachedMauticLoadOptions)(this, 'stages', () => GenericFunctions_1.mauticApiRequestAllItems.call(this, 'stages', 'GET', '/stages')); for (const stage of stages) { returnData.push({ name: stage.name, value: stage.id, }); } return returnData; }, // Get all the available company fields to display them to user so that they can // select them easily async getCompanyFields() { const returnData = []; const fields = await (0, loadOptionsCache_1.getCachedMauticLoadOptions)(this, 'fields:company', () => GenericFunctions_1.mauticApiRequestAllItems.call(this, 'fields', 'GET', '/fields/company')); for (const field of fields) { returnData.push({ name: field.label, value: field.alias, }); } return returnData; }, async getIndustries() { const returnData = []; const fields = await (0, loadOptionsCache_1.getCachedMauticLoadOptions)(this, 'fields:company', () => GenericFunctions_1.mauticApiRequestAllItems.call(this, 'fields', 'GET', '/fields/company')); for (const field of fields) { if (field.alias === 'companyindustry') { for (const { label, value } of field.properties.list) { returnData.push({ name: label, value, }); } } } return returnData; }, // Get all the available contact fields to display them to user so that they can // select them easily async getContactFields() { const returnData = []; const seen = new Set(); const addField = (field) => { const value = String(field.value); if (seen.has(value)) { return; } seen.add(value); returnData.push(field); }; // Add key system fields manually (except last_active, which is already present) const systemFields = [ { name: 'Date Added', value: 'date_added' }, { name: 'Date Modified', value: 'date_modified' }, { name: 'ID', value: 'id' }, { name: 'Owner ID', value: 'owner_id' }, ]; systemFields.forEach(addField); // Fetch custom and other fields from Mautic const fields = await (0, loadOptionsCache_1.getCachedMauticLoadOptions)(this, 'fields:contact', () => GenericFunctions_1.mauticApiRequestAllItems.call(this, 'fields', 'GET', '/fields/contact')); for (const field of fields) { addField({ name: field.label, value: field.alias, }); } return returnData; }, // Get all contact output fields, including raw top-level properties that are // not returned by Mautic's contact fields endpoint. async getContactFieldsToReturn() { const returnData = []; const seen = new Set(); const addField = (field) => { const value = String(field.value); if (seen.has(value)) { return; } seen.add(value); returnData.push(field); }; const rawContactFields = [ { name: 'Date Added', value: 'date_added' }, { name: 'Date Modified', value: 'date_modified' }, { name: 'ID', value: 'id' }, { name: 'Owner ID', value: 'owner_id' }, { name: 'Color', value: 'color' }, { name: 'Created By', value: 'createdBy' }, { name: 'Created By User', value: 'createdByUser' }, { name: 'Date Identified', value: 'date_identified' }, { name: 'Do Not Contact', value: 'doNotContact' }, { name: 'Frequency Rules', value: 'frequencyRules' }, { name: 'IP Addresses', value: 'ipAddresses' }, { name: 'Is Published', value: 'isPublished' }, { name: 'Last Active', value: 'last_active' }, { name: 'Modified By', value: 'modifiedBy' }, { name: 'Modified By User', value: 'modifiedByUser' }, { name: 'Owner', value: 'owner' }, { name: 'Points', value: 'points' }, { name: 'Preferred Profile Image', value: 'preferredProfileImage' }, { name: 'Stage', value: 'stage' }, { name: 'Tags', value: 'tags' }, { name: 'UTM Tags', value: 'utmtags' }, ]; rawContactFields.forEach(addField); const fields = await (0, loadOptionsCache_1.getCachedMauticLoadOptions)(this, 'fields:contact', () => GenericFunctions_1.mauticApiRequestAllItems.call(this, 'fields', 'GET', '/fields/contact')); for (const field of fields) { addField({ name: field.label, value: field.alias, }); } return returnData; }, // Get all the available segments to display them to user so that they can // select them easily async getSegments() { const returnData = []; const segments = await (0, loadOptionsCache_1.getCachedMauticLoadOptions)(this, 'segments', () => GenericFunctions_1.mauticApiRequestAllItems.call(this, 'lists', 'GET', '/segments')); for (const segment of segments) { returnData.push({ name: segment.name, value: segment.id, }); } return returnData; }, // Get all the available segments (by alias) for search filtering async getSegmentAliases() { const returnData = []; const segments = await (0, loadOptionsCache_1.getCachedMauticLoadOptions)(this, 'segments', () => GenericFunctions_1.mauticApiRequestAllItems.call(this, 'lists', 'GET', '/segments')); for (const segment of segments) { // Use alias if available, otherwise skip (alias is required for search syntax) const alias = segment.alias || segment.id?.toString(); if (alias) { returnData.push({ name: segment.name || alias, value: alias, }); } } return returnData; }, // Get all the available owners (users) for filtering async getOwners() { const returnData = []; const response = await GenericFunctions_1.mauticApiRequest.call(this, 'GET', '/users'); const users = response?.users ? Object.values(response.users) : []; for (const user of users) { const fullName = `${user.firstName || ''} ${user.lastName || ''}`.trim(); const display = fullName || user.username || `User ${user.id}`; const label = user.email ? `${display} (${user.email})` : display; returnData.push({ name: label, value: user.id }); } return returnData; }, // Get all the available campaings to display them to user so that they can // select them easily async getCampaigns() { const returnData = []; const campaings = await (0, loadOptionsCache_1.getCachedMauticLoadOptions)(this, 'campaigns', () => GenericFunctions_1.mauticApiRequestAllItems.call(this, 'campaigns', 'GET', '/campaigns')); for (const campaign of campaings) { returnData.push({ name: campaign.name, value: campaign.id, }); } return returnData; }, // Get all the available emails to display them to user so that they can // select them easily async getEmails() { const returnData = []; const emails = await (0, loadOptionsCache_1.getCachedMauticLoadOptions)(this, 'emails', () => GenericFunctions_1.mauticApiRequestAllItems.call(this, 'emails', 'GET', '/emails')); for (const email of emails) { returnData.push({ name: email.name, value: email.id, }); } return returnData; }, // Get all the available list / segment emails to display them to user so that they can // select them easily async getSegmentEmails() { const returnData = []; const emails = await (0, loadOptionsCache_1.getCachedMauticLoadOptions)(this, 'emails', () => GenericFunctions_1.mauticApiRequestAllItems.call(this, 'emails', 'GET', '/emails')); for (const email of emails) { if (email.emailType === 'list') { returnData.push({ name: email.name, value: email.id, }); } } return returnData; }, // Get all the available campaign / template emails to display them to user so that they can // select them easily async getCampaignEmails() { const returnData = []; const emails = await (0, loadOptionsCache_1.getCachedMauticLoadOptions)(this, 'emails', () => GenericFunctions_1.mauticApiRequestAllItems.call(this, 'emails', 'GET', '/emails')); for (const email of emails) { if (email.emailType === 'template') { returnData.push({ name: email.name, value: email.id, }); } } return returnData; }, // Get all the available email categories to display them to user so that they can // select them easily async getEmailCategories() { const returnData = []; const categories = await (0, loadOptionsCache_1.getCachedMauticLoadOptions)(this, 'categories', () => GenericFunctions_1.mauticApiRequestAllItems.call(this, 'categories', 'GET', '/categories')); for (const category of categories) { // Filter for email bundle categories if (category.bundle === 'email' || category.bundle === 'global') { returnData.push({ name: category.title, value: category.id, }); } } return returnData; }, // Get all the available forms to display them to user so that they can // select them easily async getForms() { const returnData = []; const forms = await (0, loadOptionsCache_1.getCachedMauticLoadOptions)(this, 'forms', () => GenericFunctions_1.mauticApiRequestAllItems.call(this, 'forms', 'GET', '/forms')); for (const form of forms) { returnData.push({ name: form.name, value: form.id, }); } return returnData; }, // Get all the available assets to display them to user so that they can // select them easily async getAssets() { const returnData = []; const assets = await (0, loadOptionsCache_1.getCachedMauticLoadOptions)(this, 'assets', () => GenericFunctions_1.mauticApiRequestAllItems.call(this, 'assets', 'GET', '/assets')); for (const asset of assets) { returnData.push({ name: asset.title, value: asset.id, }); } return returnData; }, // Get all the available themes to display them to user so that they can // select them easily async getThemes() { const returnData = []; const response = await GenericFunctions_1.mauticApiRequest.call(this, 'GET', '/themes'); const themes = response.themes || {}; for (const themeName of Object.keys(themes)) { returnData.push({ name: themeName, value: themeName, }); } return returnData; }, }, }; } async execute() { const items = this.getInputData(); const returnData = []; for (let i = 0; i < items.length; i++) { try { const resource = this.getNodeParameter('resource', i); const operation = this.getNodeParameter('operation', i); let result = []; switch (resource) { case 'contact': result = await (0, ContactOperations_1.executeContactOperation)(this, operation, i); break; case 'company': result = await (0, CompanyOperations_1.executeCompanyOperation)(this, operation, i); break; case 'campaign': result = await (0, CampaignOperations_1.executeCampaignOperation)(this, operation, i); break; case 'segment': result = await (0, SegmentOperations_1.executeSegmentOperation)(this, operation, i); break; case 'tag': result = await (0, MiscellaneousOperations_1.executeTagOperation)(this, operation, i); break; case 'category': result = await (0, MiscellaneousOperations_1.executeCategoryOperation)(this, operation, i); break; case 'email': result = await (0, EmailOperations_1.executeEmailOperation)(this, operation, i); break; case 'segmentEmail': result = await (0, MiscellaneousOperations_1.executeSegmentEmailOperation)(this, operation, i); break; case 'contactSegment': result = await (0, MiscellaneousOperations_1.executeContactSegmentOperation)(this, operation, i); break; case 'campaignContact': result = await (0, MiscellaneousOperations_1.executeCampaignContactOperation)(this, operation, i); break; case 'companyContact': result = await (0, MiscellaneousOperations_1.executeCompanyContactOperation)(this, operation, i); break; case 'field': result = await (0, FieldOperations_1.executeFieldOperation)(this, operation, i); break; case 'note': result = await (0, NoteOperations_1.executeNoteOperation)(this, operation, i); break; case 'notification': result = await (0, NotificationOperations_1.executeNotificationOperation)(this, operation, i); break; case 'theme': result = await (0, ThemeOperations_1.executeThemeOperation)(this, operation, i); break; case 'user': result = await (0, UserOperations_1.executeUserOperation)(this, operation, i); break; case 'role': result = await (0, RoleOperations_1.executeRoleOperation)(this, operation, i); break; case 'stats': result = await (0, StatsOperations_1.executeStatsOperation)(this, operation, i); break; default: throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Resource '${resource}' is not supported.`, { itemIndex: i }); } returnData.push(...result); } catch (error) { if (this.continueOnFail()) { returnData.push(...this.helpers.returnJsonArray({ error: error.message })); continue; } throw error; } } return [returnData]; } } exports.MauticAdvanced = MauticAdvanced;