First try to get custom properties to work with v1

This commit is contained in:
Jan Oberhauser 2019-09-11 17:15:42 +02:00
parent 6e81abef3c
commit 9bd5d4bec1
4 changed files with 147 additions and 102 deletions

View file

@ -2,6 +2,29 @@
This list shows all the versions which include breaking changes and how to upgrade
## 0.20.0
### What changed?
The node "ActiveCampaign" had to be changed to use v1 of their API. That API is sadly
quite bad but at least it is feature complete which their v3 sadly is not.
### When is action necessary?
If a "ActiveCampaign" node gets used in any workflow.
### How to upgrade:
After upgrading open all workflows which contain a "Read File From Url" node.
They will have a "?" as icon as they are not known anymore. Create a new
"HTTP Request" node to replace the old one and add the same URL as the previous
node had (in case you do not know it anymore you can select the old node, copy
it and paste it in a text-editor, it will display all the data the node
contained). Then set the "Response Format" to "File". Everything will then
function again like before.
## 0.19.0
### What changed?
@ -11,7 +34,7 @@ The node "Read File From Url" got removed as its functionality got added to
### When is action necessary?
If the "Read File From Url" gets used in any workflow.
If the "Read File From Url" node gets used in any workflow.
### How to upgrade:

View file

@ -23,8 +23,7 @@
"test:e2e": "vue-cli-service test:e2e",
"test:unit": "vue-cli-service test:unit"
},
"dependencies": {
},
"dependencies": {},
"devDependencies": {
"@beyonk/google-fonts-webpack-plugin": "^1.2.3",
"@fortawesome/fontawesome-svg-core": "^1.2.19",

View file

@ -183,14 +183,14 @@ export class ActiveCampaign implements INodeType {
options: [
{
displayName: 'First Name',
name: 'firstName',
name: 'first_name',
type: 'string',
default: '',
description: 'The first name of the contact to create',
},
{
displayName: 'Last Name',
name: 'lastName',
name: 'last_name',
type: 'string',
default: '',
description: 'The last name of the contact to create',
@ -282,50 +282,68 @@ export class ActiveCampaign implements INodeType {
description: 'ID of the contact to get.',
},
// ----------------------------------
// contact:getAll
// ----------------------------------
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
operation: [
'getAll',
],
resource: [
'contact',
],
},
},
default: false,
description: 'If all results should be returned or only up to a given limit.',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
operation: [
'getAll',
],
resource: [
'contact',
],
returnAll: [
false,
],
},
},
typeOptions: {
minValue: 1,
maxValue: 500,
},
default: 100,
description: 'How many results to return.',
},
// TODO: Does not work as expted so remove for now
// // ----------------------------------
// // contact:getAll
// // ----------------------------------
// {
// displayName: 'Full User Data',
// name: 'fullUserData',
// type: 'boolean',
// displayOptions: {
// show: {
// operation: [
// 'getAll',
// ],
// resource: [
// 'contact',
// ],
// },
// },
// default: false,
// description: 'If all data of the user should be returned or an abbreviated version.',
// },
// {
// displayName: 'Return All',
// name: 'returnAll',
// type: 'boolean',
// displayOptions: {
// show: {
// operation: [
// 'getAll',
// ],
// resource: [
// 'contact',
// ],
// },
// },
// default: false,
// description: 'If all results should be returned or only results of a given page.',
// },
// {
// displayName: 'Page',
// name: 'page',
// type: 'number',
// displayOptions: {
// show: {
// operation: [
// 'getAll',
// ],
// resource: [
// 'contact',
// ],
// returnAll: [
// false,
// ],
// },
// },
// typeOptions: {
// minValue: 1,
// maxValue: 500,
// },
// default: 1,
// description: 'Maximum 20 results per page get returned. Set which page to return.',
// },
// ----------------------------------
// contact:update
@ -375,14 +393,14 @@ export class ActiveCampaign implements INodeType {
},
{
displayName: 'First Name',
name: 'firstName',
name: 'first_name',
type: 'string',
default: '',
description: 'First name of the contact',
},
{
displayName: 'Last Name',
name: 'lastName',
name: 'last_name',
type: 'string',
default: '',
description: 'Last name of the contact',
@ -447,17 +465,16 @@ export class ActiveCampaign implements INodeType {
let qs: IDataObject;
let requestMethod: string;
let endpoint: string;
const endpoint = '/admin/api.php';
let returnAll = false;
let dataKey: string | undefined;
let dataKeys: string[] | undefined;
for (let i = 0; i < items.length; i++) {
dataKey = undefined;
resource = this.getNodeParameter('resource', 0) as string;
operation = this.getNodeParameter('operation', 0) as string;
dataKeys = undefined;
requestMethod = 'GET';
endpoint = '';
body = {} as IDataObject;
qs = {} as IDataObject;
@ -471,27 +488,27 @@ export class ActiveCampaign implements INodeType {
const updateIfExists = this.getNodeParameter('updateIfExists', i) as boolean;
if (updateIfExists === true) {
endpoint = '/api/3/contact/sync';
qs.api_action = 'contact_sync';
} else {
endpoint = '/api/3/contacts';
qs.api_action = 'contact_add';
}
dataKey = 'contact';
body.contact = {
email: this.getNodeParameter('email', i) as string,
} as IDataObject;
dataKeys = ['subscriber_id'];
body.email = this.getNodeParameter('email', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
addAdditionalFields(body.contact as IDataObject, additionalFields);
addAdditionalFields(body as IDataObject, additionalFields);
} else if (operation === 'delete') {
// ----------------------------------
// contact:delete
// ----------------------------------
requestMethod = 'DELETE';
requestMethod = 'GET';
qs.api_action = 'contact_delete';
const contactId = this.getNodeParameter('contactId', i) as number;
endpoint = `/api/3/contacts/${contactId}`;
qs.id = contactId;
} else if (operation === 'get') {
// ----------------------------------
@ -499,39 +516,45 @@ export class ActiveCampaign implements INodeType {
// ----------------------------------
requestMethod = 'GET';
qs.api_action = 'contact_view';
const contactId = this.getNodeParameter('contactId', i) as number;
endpoint = `/api/3/contacts/${contactId}`;
qs.id = contactId;
} else if (operation === 'getAll') {
// ----------------------------------
// persons:getAll
// ----------------------------------
// TODO: Does not work as expted so remove for now
// } else if (operation === 'getAll') {
// // ----------------------------------
// // contact:getAll
// // ----------------------------------
requestMethod = 'GET';
// requestMethod = 'GET';
// qs.api_action = 'contact_list';
// qs.ids = 'ALL';
returnAll = this.getNodeParameter('returnAll', i) as boolean;
if (returnAll === false) {
qs.limit = this.getNodeParameter('limit', i) as number;
}
// returnAll = this.getNodeParameter('returnAll', i) as boolean;
// if (returnAll === false) {
// qs.page = this.getNodeParameter('page', i) as number;
// }
dataKey = 'contacts';
endpoint = `/api/3/contacts`;
// const fullUserData = this.getNodeParameter('fullUserData', i) as boolean;
// qs.full = fullUserData === true ? 1 : 0;
} else if (operation === 'update') {
// ----------------------------------
// contact:update
// ----------------------------------
requestMethod = 'PUT';
requestMethod = 'POST';
const contactId = this.getNodeParameter('contactId', i) as number;
endpoint = `/api/3/contacts/${contactId}`;
qs.api_action = 'contact_edit';
qs.overwrite = 0;
dataKey = 'contact';
body.contact = {} as IDataObject;
dataKeys = ['subscriber_id'];
body.id = contactId;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
addAdditionalFields(body.contact as IDataObject, updateFields);
addAdditionalFields(body as IDataObject, updateFields);
}
} else {
@ -540,9 +563,9 @@ export class ActiveCampaign implements INodeType {
let responseData;
if (returnAll === true) {
responseData = await activeCampaignApiRequestAllItems.call(this, requestMethod, endpoint, body, qs, dataKey);
responseData = await activeCampaignApiRequestAllItems.call(this, requestMethod, endpoint, body, qs, dataKeys);
} else {
responseData = await activeCampaignApiRequest.call(this, requestMethod, endpoint, body, qs, dataKey);
responseData = await activeCampaignApiRequest.call(this, requestMethod, endpoint, body, qs, dataKeys);
}
if (Array.isArray(responseData)) {

View file

@ -19,7 +19,7 @@ import { OptionsWithUri } from 'request';
* @param {object} body
* @returns {Promise<any>}
*/
export async function activeCampaignApiRequest(this: IHookFunctions | IExecuteFunctions, method: string, endpoint: string, body: IDataObject, query?: IDataObject, dataKey?: string): Promise<any> { // tslint:disable-line:no-any
export async function activeCampaignApiRequest(this: IHookFunctions | IExecuteFunctions, method: string, endpoint: string, body: IDataObject, query?: IDataObject, dataKeys?: string[]): Promise<any> { // tslint:disable-line:no-any
const credentials = this.getCredentials('activeCampaignApi');
if (credentials === undefined) {
throw new Error('No credentials got returned!');
@ -29,10 +29,10 @@ export async function activeCampaignApiRequest(this: IHookFunctions | IExecuteFu
query = {};
}
query.api_key = credentials.apiKey;
query.api_output = 'json';
const options: OptionsWithUri = {
headers: {
'Api-Token': credentials.apiKey,
},
method,
qs: query,
uri: `${credentials.apiUrl}${endpoint}`,
@ -40,22 +40,27 @@ export async function activeCampaignApiRequest(this: IHookFunctions | IExecuteFu
};
if (Object.keys(body).length !== 0) {
options.body = body;
options.form = body;
}
const returnData: IDataObject = {};
try {
const responseData = await this.helpers.request(options);
if (responseData.success === false) {
throw new Error(`ActiveCampaign error response: ${responseData.error} (${responseData.error_info})`);
if (responseData.result_code === 0) {
throw new Error(`ActiveCampaign error response: ${responseData.result_message}`);
}
if (dataKey === undefined) {
if (dataKeys === undefined) {
return responseData;
} else {
return responseData[dataKey] as IDataObject;
}
for (const dataKey of dataKeys) {
returnData[dataKey] = responseData[dataKey];
}
return returnData;
} catch (error) {
if (error.statusCode === 403) {
// Return a clear error
@ -81,7 +86,7 @@ export async function activeCampaignApiRequest(this: IHookFunctions | IExecuteFu
* @param {IDataObject} [query]
* @returns {Promise<any>}
*/
export async function activeCampaignApiRequestAllItems(this: IHookFunctions | IExecuteFunctions, method: string, endpoint: string, body: IDataObject, query?: IDataObject, dataKey?: string): Promise<any> { // tslint:disable-line:no-any
export async function activeCampaignApiRequestAllItems(this: IHookFunctions | IExecuteFunctions, method: string, endpoint: string, body: IDataObject, query?: IDataObject, dataKeys?: string[]): Promise<any> { // tslint:disable-line:no-any
if (query === undefined) {
query = {};
@ -95,15 +100,10 @@ export async function activeCampaignApiRequestAllItems(this: IHookFunctions | IE
let itemsReceived = 0;
do {
responseData = await activeCampaignApiRequest.call(this, method, endpoint, body, query);
responseData = await activeCampaignApiRequest.call(this, method, endpoint, body, query, dataKeys);
if (dataKey === undefined) {
returnData.push.apply(returnData, responseData);
itemsReceived += returnData.length;
} else {
returnData.push.apply(returnData, responseData[dataKey]);
itemsReceived += responseData[dataKey].length;
}
query.offset = itemsReceived;
} while (