Feature/extended active campaign (#928)

* feat: 🎸 node/activecampaign account, tag, account contact

* feat: 🎸 node/ActiveCampaign Update an accountContact assoc

* feat: 🎸 node/activecampaign Update an account

* feat: 🎸 node/activecampaign Get an account

* feat: 🎸 node/activecampaign GetAll & Delete an account

* feat: 🎸 node/activecampaign change ID's type to number

* refactor: 💡 node/activecampaign merge getAll properties

*  Improvements to #923

*  Improvements

*  Improvements

*  Add breaking change message

Co-authored-by: Ronald Diquélou <rdiquelou@opensafepro.com>
This commit is contained in:
Ricardo Espinoza
2020-09-18 03:42:01 -04:00
committed by GitHub
parent e18d7934ad
commit a552febab4
13 changed files with 1584 additions and 316 deletions

View File

@@ -7,6 +7,8 @@ import {
INodeTypeDescription,
INodeExecutionData,
INodeType,
ILoadOptionsFunctions,
INodePropertyOptions,
} from 'n8n-workflow';
import {
@@ -45,12 +47,31 @@ import {
connectionFields
} from './ConnectionDescription';
import {
accountFields,
accountOperations
} from "./AccountDescription";
import {
tagFields,
tagOperations
} from "./TagDescription";
import {
accountContactFields,
accountContactOperations
} from "./AccountContactDescription";
import {
contactTagFields,
contactTagOperations,
} from "./ContactTagDescription";
interface CustomProperty {
name: string;
value: string;
}
/**
* Add the additional fields to the body
*
@@ -63,6 +84,10 @@ function addAdditionalFields(body: IDataObject, additionalFields: IDataObject) {
for (const customProperty of (additionalFields.customProperties as IDataObject)!.property! as CustomProperty[]) {
body[customProperty.name] = customProperty.value;
}
} else if (key === 'fieldValues' && (additionalFields.fieldValues as IDataObject).property !== undefined) {
body.fieldValues = (additionalFields.fieldValues as IDataObject).property;
} else if (key === 'fields' && (additionalFields.fields as IDataObject).property !== undefined) {
body.fields = (additionalFields.fields as IDataObject).property;
} else {
body[key] = additionalFields[key];
}
@@ -88,7 +113,7 @@ export class ActiveCampaign implements INodeType {
{
name: 'activeCampaignApi',
required: true,
}
},
],
properties: [
// ----------------------------------
@@ -99,18 +124,30 @@ export class ActiveCampaign implements INodeType {
name: 'resource',
type: 'options',
options: [
{
name: 'Account',
value: 'account',
},
{
name: 'Account Contact',
value: 'accountContact',
},
{
name: 'Contact',
value: 'contact',
},
{
name: 'Deal',
value: 'deal',
name: 'Contact Tag',
value: 'contactTag',
},
{
name: 'Connection',
value: 'connection'
},
{
name: 'Deal',
value: 'deal',
},
{
name: 'E-commerce Order',
value: 'ecommerceOrder',
@@ -122,7 +159,11 @@ export class ActiveCampaign implements INodeType {
{
name: 'E-commerce Order Products',
value: 'ecommerceOrderProducts'
}
},
{
name: 'Tag',
value: 'tag',
},
],
default: 'contact',
description: 'The resource to operate on.',
@@ -131,7 +172,11 @@ export class ActiveCampaign implements INodeType {
// ----------------------------------
// operations
// ----------------------------------
...accountOperations,
...contactOperations,
...accountContactOperations,
...contactTagOperations,
...tagOperations,
...dealOperations,
...connectionOperations,
...ecomOrderOperations,
@@ -141,6 +186,26 @@ export class ActiveCampaign implements INodeType {
// ----------------------------------
// fields
// ----------------------------------
// ----------------------------------
// tag
// ----------------------------------
...tagFields,
// ----------------------------------
// tag
// ----------------------------------
...contactTagFields,
// ----------------------------------
// account
// ----------------------------------
...accountFields,
// ----------------------------------
// account
// ----------------------------------
...accountContactFields,
// ----------------------------------
// contact
// ----------------------------------
@@ -174,6 +239,40 @@ export class ActiveCampaign implements INodeType {
],
};
methods = {
loadOptions: {
// Get all the available custom fields to display them to user so that he can
// select them easily
async getContactCustomFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const { fields } = await activeCampaignApiRequest.call(this, 'GET', '/api/3/fields', {});
for (const field of fields) {
const fieldName = field.title;
const fieldId = field.id;
returnData.push({
name: fieldName,
value: fieldId,
});
}
return returnData;
},
// Get all the available custom fields to display them to user so that he can
// select them easily
async getAccountCustomFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const { accountCustomFieldMeta: fields } = await activeCampaignApiRequest.call(this, 'GET', '/api/3/accountCustomFieldMeta', {});
for (const field of fields) {
const fieldName = field.fieldLabel;
const fieldId = field.id;
returnData.push({
name: fieldName,
value: fieldId,
});
}
return returnData;
},
},
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
@@ -254,11 +353,24 @@ export class ActiveCampaign implements INodeType {
requestMethod = 'GET';
returnAll = this.getNodeParameter('returnAll', i) as boolean;
const simple = this.getNodeParameter('simple', i, true) as boolean;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
if (returnAll === false) {
qs.limit = this.getNodeParameter('limit', i) as number;
}
dataKey = 'contacts';
Object.assign(qs, additionalFields);
if (qs.orderBy) {
qs[qs.orderBy as string] = true;
delete qs.orderBy;
}
if (simple === true) {
dataKey = 'contacts';
}
endpoint = `/api/3/contacts`;
} else if (operation === 'update') {
@@ -278,6 +390,246 @@ export class ActiveCampaign implements INodeType {
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
addAdditionalFields(body.contact as IDataObject, updateFields);
} else {
throw new Error(`The operation "${operation}" is not known`);
}
} else if (resource === 'account') {
if (operation === 'create') {
// ----------------------------------
// account:create
// ----------------------------------
requestMethod = 'POST';
endpoint = '/api/3/accounts';
dataKey = 'account';
body.account = {
name: this.getNodeParameter('name', i) as string,
} as IDataObject;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
addAdditionalFields(body.account as IDataObject, additionalFields);
} else if (operation === 'delete') {
// ----------------------------------
// account:delete
// ----------------------------------
requestMethod = 'DELETE';
const accountId = this.getNodeParameter('accountId', i) as number;
endpoint = `/api/3/accounts/${accountId}`;
} else if (operation === 'get') {
// ----------------------------------
// account:get
// ----------------------------------
requestMethod = 'GET';
const accountId = this.getNodeParameter('accountId', i) as number;
endpoint = `/api/3/accounts/${accountId}`;
} else if (operation === 'getAll') {
// ----------------------------------
// account:getAll
// ----------------------------------
requestMethod = 'GET';
const simple = this.getNodeParameter('simple', i, true) as boolean;
returnAll = this.getNodeParameter('returnAll', i) as boolean;
if (returnAll === false) {
qs.limit = this.getNodeParameter('limit', i) as number;
}
if (simple === true) {
dataKey = 'accounts';
}
endpoint = `/api/3/accounts`;
const filters = this.getNodeParameter('filters', i) as IDataObject;
Object.assign(qs, filters);
} else if (operation === 'update') {
// ----------------------------------
// account:update
// ----------------------------------
requestMethod = 'PUT';
const accountId = this.getNodeParameter('accountId', i) as number;
endpoint = `/api/3/accounts/${accountId}`;
dataKey = 'account';
body.account = {} as IDataObject;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
addAdditionalFields(body.account as IDataObject, updateFields);
} else {
throw new Error(`The operation "${operation}" is not known`);
}
} else if (resource === 'accountContact') {
if (operation === 'create') {
// ----------------------------------
// account:create
// ----------------------------------
requestMethod = 'POST';
endpoint = '/api/3/accountContacts';
dataKey = 'accountContact';
body.accountContact = {
contact: this.getNodeParameter('contact', i) as string,
account: this.getNodeParameter('account', i) as string,
} as IDataObject;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
addAdditionalFields(body.account as IDataObject, additionalFields);
} else if (operation === 'update') {
// ----------------------------------
// accountContact:update
// ----------------------------------
requestMethod = 'PUT';
const accountContactId = this.getNodeParameter('accountContactId', i) as number;
endpoint = `/api/3/accountContacts/${accountContactId}`;
dataKey = 'accountContact';
body.accountContact = {} as IDataObject;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
addAdditionalFields(body.accountContact as IDataObject, updateFields);
} else if (operation === 'delete') {
// ----------------------------------
// accountContact:delete
// ----------------------------------
requestMethod = 'DELETE';
const accountContactId = this.getNodeParameter('accountContactId', i) as number;
endpoint = `/api/3/accountContacts/${accountContactId}`;
} else {
throw new Error(`The operation "${operation}" is not known`);
}
} else if (resource === 'contactTag') {
if (operation === 'add') {
// ----------------------------------
// contactTag:add
// ----------------------------------
requestMethod = 'POST';
endpoint = '/api/3/contactTags';
dataKey = 'contactTag';
body.contactTag = {
contact: this.getNodeParameter('contactId', i) as string,
tag: this.getNodeParameter('tagId', i) as string,
} as IDataObject;
} else if (operation === 'remove') {
// ----------------------------------
// contactTag:remove
// ----------------------------------
requestMethod = 'DELETE';
const contactTagId = this.getNodeParameter('contactTagId', i) as number;
endpoint = `/api/3/contactTags/${contactTagId}`;
} else {
throw new Error(`The operation "${operation}" is not known`);
}
} else if (resource === 'tag') {
if (operation === 'create') {
// ----------------------------------
// tag:create
// ----------------------------------
requestMethod = 'POST';
endpoint = '/api/3/tags';
dataKey = 'tag';
body.tag = {
tag: this.getNodeParameter('name', i) as string,
tagType: this.getNodeParameter('tagType', i) as string,
} as IDataObject;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
addAdditionalFields(body.tag as IDataObject, additionalFields);
} else if (operation === 'delete') {
// ----------------------------------
// tag:delete
// ----------------------------------
requestMethod = 'DELETE';
const tagId = this.getNodeParameter('tagId', i) as number;
endpoint = `/api/3/tags/${tagId}`;
} else if (operation === 'get') {
// ----------------------------------
// tag:get
// ----------------------------------
requestMethod = 'GET';
const tagId = this.getNodeParameter('tagId', i) as number;
endpoint = `/api/3/tags/${tagId}`;
} else if (operation === 'getAll') {
// ----------------------------------
// tags:getAll
// ----------------------------------
requestMethod = 'GET';
const simple = this.getNodeParameter('simple', i, true) as boolean;
returnAll = this.getNodeParameter('returnAll', i) as boolean;
if (returnAll === false) {
qs.limit = this.getNodeParameter('limit', i) as number;
}
if (simple === true) {
dataKey = 'tags';
}
endpoint = `/api/3/tags`;
} else if (operation === 'update') {
// ----------------------------------
// tags:update
// ----------------------------------
requestMethod = 'PUT';
const tagId = this.getNodeParameter('tagId', i) as number;
endpoint = `/api/3/tags/${tagId}`;
dataKey = 'tag';
body.tag = {} as IDataObject;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
addAdditionalFields(body.tag as IDataObject, updateFields);
} else {
throw new Error(`The operation "${operation}" is not known`);
}
@@ -358,11 +710,16 @@ export class ActiveCampaign implements INodeType {
requestMethod = 'GET';
const simple = this.getNodeParameter('simple', i, true) as boolean;
returnAll = this.getNodeParameter('returnAll', i) as boolean;
if (returnAll === false) {
qs.limit = this.getNodeParameter('limit', i) as number;
}
if (simple === true) {
dataKey = 'deals';
}
endpoint = `/api/3/deals`;
} else if (operation === 'createNote') {
@@ -455,11 +812,16 @@ export class ActiveCampaign implements INodeType {
requestMethod = 'GET';
const simple = this.getNodeParameter('simple', i, true) as boolean;
returnAll = this.getNodeParameter('returnAll', i) as boolean;
if (returnAll === false) {
qs.limit = this.getNodeParameter('limit', i) as number;
}
if (simple === true) {
dataKey = 'connections';
}
endpoint = `/api/3/connections`;
} else {
@@ -548,11 +910,16 @@ export class ActiveCampaign implements INodeType {
requestMethod = 'GET';
const simple = this.getNodeParameter('simple', i, true) as boolean;
returnAll = this.getNodeParameter('returnAll', i) as boolean;
if (returnAll === false) {
qs.limit = this.getNodeParameter('limit', i) as number;
}
if (simple === true) {
dataKey = 'ecomOrders';
}
endpoint = `/api/3/ecomOrders`;
} else {
@@ -633,11 +1000,16 @@ export class ActiveCampaign implements INodeType {
requestMethod = 'GET';
const simple = this.getNodeParameter('simple', i, true) as boolean;
returnAll = this.getNodeParameter('returnAll', i) as boolean;
if (returnAll === false) {
qs.limit = this.getNodeParameter('limit', i) as number;
}
if (simple === true) {
dataKey = 'ecomCustomers';
}
endpoint = `/api/3/ecomCustomers`;
} else {
@@ -662,6 +1034,8 @@ export class ActiveCampaign implements INodeType {
requestMethod = 'GET';
//dataKey = 'ecomOrderProducts';
const orderId = this.getNodeParameter('orderId', i) as number;
endpoint = `/api/3/ecomOrders/${orderId}/orderProducts`;
@@ -672,11 +1046,16 @@ export class ActiveCampaign implements INodeType {
requestMethod = 'GET';
const simple = this.getNodeParameter('simple', i, true) as boolean;
returnAll = this.getNodeParameter('returnAll', i) as boolean;
if (returnAll === false) {
qs.limit = this.getNodeParameter('limit', i) as number;
}
if (simple === true) {
dataKey = 'ecomOrderProducts';
}
endpoint = `/api/3/ecomOrderProducts`;
} else {
@@ -703,4 +1082,4 @@ export class ActiveCampaign implements INodeType {
return [this.helpers.returnJsonArray(returnData)];
}
}
}