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
JavaScript
"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;