2023-01-27 03:22:44 -08:00
|
|
|
import type {
|
2021-06-27 04:07:25 -07:00
|
|
|
IDataObject,
|
2023-03-09 09:13:15 -08:00
|
|
|
IExecuteFunctions,
|
2021-06-27 04:07:25 -07:00
|
|
|
INodeExecutionData,
|
|
|
|
INodeType,
|
|
|
|
INodeTypeDescription,
|
|
|
|
} from 'n8n-workflow';
|
2024-08-29 06:55:53 -07:00
|
|
|
import { NodeConnectionType, NodeOperationError } from 'n8n-workflow';
|
2021-06-27 04:07:25 -07:00
|
|
|
|
|
|
|
import {
|
|
|
|
actionNetworkApiRequest,
|
|
|
|
adjustEventPayload,
|
|
|
|
adjustPersonPayload,
|
|
|
|
adjustPetitionPayload,
|
|
|
|
handleListing,
|
|
|
|
makeOsdiLink,
|
|
|
|
resourceLoaders,
|
|
|
|
simplifyResponse,
|
|
|
|
} from './GenericFunctions';
|
|
|
|
|
|
|
|
import {
|
|
|
|
attendanceFields,
|
|
|
|
attendanceOperations,
|
|
|
|
eventFields,
|
|
|
|
eventOperations,
|
|
|
|
personFields,
|
|
|
|
personOperations,
|
|
|
|
personTagFields,
|
|
|
|
personTagOperations,
|
|
|
|
petitionFields,
|
|
|
|
petitionOperations,
|
|
|
|
signatureFields,
|
|
|
|
signatureOperations,
|
|
|
|
tagFields,
|
|
|
|
tagOperations,
|
|
|
|
} from './descriptions';
|
|
|
|
|
2023-01-27 03:22:44 -08:00
|
|
|
import type {
|
2021-06-27 04:07:25 -07:00
|
|
|
AllFieldsUi,
|
|
|
|
EmailAddressUi,
|
|
|
|
Operation,
|
|
|
|
PersonResponse,
|
|
|
|
Resource,
|
|
|
|
Response,
|
|
|
|
} from './types';
|
|
|
|
|
|
|
|
export class ActionNetwork implements INodeType {
|
|
|
|
description: INodeTypeDescription = {
|
|
|
|
displayName: 'Action Network',
|
|
|
|
name: 'actionNetwork',
|
|
|
|
icon: 'file:actionNetwork.svg',
|
|
|
|
group: ['transform'],
|
|
|
|
version: 1,
|
|
|
|
subtitle: '={{$parameter["resource"] + ": " + $parameter["operation"]}}',
|
|
|
|
description: 'Consume the Action Network API',
|
|
|
|
defaults: {
|
|
|
|
name: 'Action Network',
|
|
|
|
},
|
2024-08-29 06:55:53 -07:00
|
|
|
inputs: [NodeConnectionType.Main],
|
|
|
|
outputs: [NodeConnectionType.Main],
|
2021-06-27 04:07:25 -07:00
|
|
|
credentials: [
|
|
|
|
{
|
|
|
|
name: 'actionNetworkApi',
|
|
|
|
required: true,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
properties: [
|
|
|
|
{
|
|
|
|
displayName: 'Resource',
|
|
|
|
name: 'resource',
|
|
|
|
type: 'options',
|
2022-05-20 14:47:24 -07:00
|
|
|
noDataExpression: true,
|
2021-06-27 04:07:25 -07:00
|
|
|
options: [
|
|
|
|
{
|
|
|
|
name: 'Attendance',
|
|
|
|
value: 'attendance',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'Event',
|
|
|
|
value: 'event',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'Person',
|
|
|
|
value: 'person',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'Person Tag',
|
|
|
|
value: 'personTag',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'Petition',
|
|
|
|
value: 'petition',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'Signature',
|
|
|
|
value: 'signature',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'Tag',
|
|
|
|
value: 'tag',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
default: 'attendance',
|
|
|
|
},
|
|
|
|
...attendanceOperations,
|
|
|
|
...attendanceFields,
|
|
|
|
...eventOperations,
|
|
|
|
...eventFields,
|
|
|
|
...personOperations,
|
|
|
|
...personFields,
|
|
|
|
...petitionOperations,
|
|
|
|
...petitionFields,
|
|
|
|
...signatureOperations,
|
|
|
|
...signatureFields,
|
|
|
|
...tagOperations,
|
|
|
|
...tagFields,
|
|
|
|
...personTagOperations,
|
|
|
|
...personTagFields,
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
|
|
|
methods = {
|
|
|
|
loadOptions: resourceLoaders,
|
|
|
|
};
|
|
|
|
|
|
|
|
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
|
|
|
const items = this.getInputData();
|
|
|
|
const returnData: IDataObject[] = [];
|
|
|
|
|
|
|
|
const resource = this.getNodeParameter('resource', 0) as Resource;
|
|
|
|
const operation = this.getNodeParameter('operation', 0) as Operation;
|
|
|
|
|
|
|
|
let response;
|
|
|
|
|
|
|
|
for (let i = 0; i < items.length; i++) {
|
|
|
|
try {
|
|
|
|
if (resource === 'attendance') {
|
|
|
|
// **********************************************************************
|
|
|
|
// attendance
|
|
|
|
// **********************************************************************
|
|
|
|
|
|
|
|
// https://actionnetwork.org/docs/v2/attendances
|
|
|
|
|
|
|
|
if (operation === 'create') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// attendance: create
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const personId = this.getNodeParameter('personId', i) as string;
|
|
|
|
const eventId = this.getNodeParameter('eventId', i);
|
|
|
|
|
|
|
|
const body = makeOsdiLink(personId) as IDataObject;
|
|
|
|
|
|
|
|
const endpoint = `/events/${eventId}/attendances`;
|
|
|
|
response = await actionNetworkApiRequest.call(this, 'POST', endpoint, body);
|
|
|
|
} else if (operation === 'get') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// attendance: get
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const eventId = this.getNodeParameter('eventId', i);
|
|
|
|
const attendanceId = this.getNodeParameter('attendanceId', i);
|
|
|
|
|
|
|
|
const endpoint = `/events/${eventId}/attendances/${attendanceId}`;
|
|
|
|
response = await actionNetworkApiRequest.call(this, 'GET', endpoint);
|
|
|
|
} else if (operation === 'getAll') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// attendance: getAll
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const eventId = this.getNodeParameter('eventId', i);
|
|
|
|
|
|
|
|
const endpoint = `/events/${eventId}/attendances`;
|
|
|
|
response = await handleListing.call(this, 'GET', endpoint);
|
|
|
|
}
|
|
|
|
} else if (resource === 'event') {
|
|
|
|
// **********************************************************************
|
|
|
|
// event
|
|
|
|
// **********************************************************************
|
|
|
|
|
|
|
|
// https://actionnetwork.org/docs/v2/events
|
|
|
|
|
|
|
|
if (operation === 'create') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// event: create
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const body = {
|
|
|
|
origin_system: this.getNodeParameter('originSystem', i),
|
|
|
|
title: this.getNodeParameter('title', i),
|
|
|
|
} as IDataObject;
|
|
|
|
|
|
|
|
const additionalFields = this.getNodeParameter('additionalFields', i) as AllFieldsUi;
|
|
|
|
|
|
|
|
if (Object.keys(additionalFields).length) {
|
|
|
|
Object.assign(body, adjustEventPayload(additionalFields));
|
|
|
|
}
|
|
|
|
|
|
|
|
response = await actionNetworkApiRequest.call(this, 'POST', '/events', body);
|
|
|
|
} else if (operation === 'get') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// event: get
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const eventId = this.getNodeParameter('eventId', i);
|
|
|
|
|
|
|
|
response = await actionNetworkApiRequest.call(this, 'GET', `/events/${eventId}`);
|
|
|
|
} else if (operation === 'getAll') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// event: getAll
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
response = await handleListing.call(this, 'GET', '/events');
|
|
|
|
}
|
|
|
|
} else if (resource === 'person') {
|
|
|
|
// **********************************************************************
|
|
|
|
// person
|
|
|
|
// **********************************************************************
|
|
|
|
|
|
|
|
// https://actionnetwork.org/docs/v2/people
|
|
|
|
|
|
|
|
if (operation === 'create') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// person: create
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const emailAddresses = this.getNodeParameter('email_addresses', i) as EmailAddressUi;
|
|
|
|
|
|
|
|
const body = {
|
|
|
|
person: {
|
|
|
|
email_addresses: [emailAddresses.email_addresses_fields], // only one accepted by API
|
|
|
|
},
|
|
|
|
} as IDataObject;
|
|
|
|
|
2022-11-18 07:29:44 -08:00
|
|
|
const additionalFields = this.getNodeParameter('additionalFields', i);
|
2021-06-27 04:07:25 -07:00
|
|
|
|
2022-10-05 04:36:09 -07:00
|
|
|
if (Object.keys(additionalFields).length && body.person) {
|
2021-06-27 04:07:25 -07:00
|
|
|
Object.assign(body.person, adjustPersonPayload(additionalFields));
|
|
|
|
}
|
|
|
|
|
|
|
|
response = await actionNetworkApiRequest.call(this, 'POST', '/people', body);
|
|
|
|
} else if (operation === 'get') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// person: get
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const personId = this.getNodeParameter('personId', i);
|
|
|
|
|
2022-08-01 13:47:55 -07:00
|
|
|
response = (await actionNetworkApiRequest.call(
|
|
|
|
this,
|
|
|
|
'GET',
|
|
|
|
`/people/${personId}`,
|
|
|
|
)) as PersonResponse;
|
2021-06-27 04:07:25 -07:00
|
|
|
} else if (operation === 'getAll') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// person: getAll
|
|
|
|
// ----------------------------------------
|
|
|
|
|
2022-08-01 13:47:55 -07:00
|
|
|
response = (await handleListing.call(this, 'GET', '/people')) as PersonResponse[];
|
2021-06-27 04:07:25 -07:00
|
|
|
} else if (operation === 'update') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// person: update
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const personId = this.getNodeParameter('personId', i);
|
|
|
|
const body = {} as IDataObject;
|
2022-11-18 07:29:44 -08:00
|
|
|
const updateFields = this.getNodeParameter('updateFields', i);
|
2021-06-27 04:07:25 -07:00
|
|
|
|
|
|
|
if (Object.keys(updateFields).length) {
|
|
|
|
Object.assign(body, adjustPersonPayload(updateFields));
|
|
|
|
} else {
|
|
|
|
throw new NodeOperationError(
|
|
|
|
this.getNode(),
|
|
|
|
`Please enter at least one field to update for the ${resource}.`,
|
2022-07-12 08:51:01 -07:00
|
|
|
{ itemIndex: i },
|
2021-06-27 04:07:25 -07:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
response = await actionNetworkApiRequest.call(this, 'PUT', `/people/${personId}`, body);
|
|
|
|
}
|
|
|
|
} else if (resource === 'petition') {
|
|
|
|
// **********************************************************************
|
|
|
|
// petition
|
|
|
|
// **********************************************************************
|
|
|
|
|
|
|
|
// https://actionnetwork.org/docs/v2/petitions
|
|
|
|
|
|
|
|
if (operation === 'create') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// petition: create
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const body = {
|
|
|
|
origin_system: this.getNodeParameter('originSystem', i),
|
|
|
|
title: this.getNodeParameter('title', i),
|
|
|
|
} as IDataObject;
|
|
|
|
|
|
|
|
const additionalFields = this.getNodeParameter('additionalFields', i) as AllFieldsUi;
|
|
|
|
|
|
|
|
if (Object.keys(additionalFields).length) {
|
|
|
|
Object.assign(body, adjustPetitionPayload(additionalFields));
|
|
|
|
}
|
|
|
|
|
|
|
|
response = await actionNetworkApiRequest.call(this, 'POST', '/petitions', body);
|
|
|
|
} else if (operation === 'get') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// petition: get
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const petitionId = this.getNodeParameter('petitionId', i);
|
|
|
|
|
|
|
|
const endpoint = `/petitions/${petitionId}`;
|
|
|
|
response = await actionNetworkApiRequest.call(this, 'GET', endpoint);
|
|
|
|
} else if (operation === 'getAll') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// petition: getAll
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
response = await handleListing.call(this, 'GET', '/petitions');
|
|
|
|
} else if (operation === 'update') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// petition: update
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const petitionId = this.getNodeParameter('petitionId', i);
|
|
|
|
const body = {} as IDataObject;
|
|
|
|
const updateFields = this.getNodeParameter('updateFields', i) as AllFieldsUi;
|
|
|
|
|
|
|
|
if (Object.keys(updateFields).length) {
|
|
|
|
Object.assign(body, adjustPetitionPayload(updateFields));
|
|
|
|
} else {
|
|
|
|
throw new NodeOperationError(
|
|
|
|
this.getNode(),
|
|
|
|
`Please enter at least one field to update for the ${resource}.`,
|
2022-07-12 08:51:01 -07:00
|
|
|
{ itemIndex: i },
|
2021-06-27 04:07:25 -07:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-01 13:47:55 -07:00
|
|
|
response = await actionNetworkApiRequest.call(
|
|
|
|
this,
|
|
|
|
'PUT',
|
|
|
|
`/petitions/${petitionId}`,
|
|
|
|
body,
|
|
|
|
);
|
2021-06-27 04:07:25 -07:00
|
|
|
}
|
|
|
|
} else if (resource === 'signature') {
|
|
|
|
// **********************************************************************
|
|
|
|
// signature
|
|
|
|
// **********************************************************************
|
|
|
|
|
|
|
|
// https://actionnetwork.org/docs/v2/signatures
|
|
|
|
|
|
|
|
if (operation === 'create') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// signature: create
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const personId = this.getNodeParameter('personId', i) as string;
|
|
|
|
const petitionId = this.getNodeParameter('petitionId', i);
|
|
|
|
|
|
|
|
const body = makeOsdiLink(personId) as IDataObject;
|
|
|
|
|
2022-11-18 07:29:44 -08:00
|
|
|
const additionalFields = this.getNodeParameter('additionalFields', i);
|
2021-06-27 04:07:25 -07:00
|
|
|
|
|
|
|
if (Object.keys(additionalFields).length) {
|
|
|
|
Object.assign(body, additionalFields);
|
|
|
|
}
|
|
|
|
|
|
|
|
const endpoint = `/petitions/${petitionId}/signatures`;
|
|
|
|
response = await actionNetworkApiRequest.call(this, 'POST', endpoint, body);
|
|
|
|
} else if (operation === 'get') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// signature: get
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const petitionId = this.getNodeParameter('petitionId', i);
|
|
|
|
const signatureId = this.getNodeParameter('signatureId', i);
|
|
|
|
|
|
|
|
const endpoint = `/petitions/${petitionId}/signatures/${signatureId}`;
|
|
|
|
response = await actionNetworkApiRequest.call(this, 'GET', endpoint);
|
|
|
|
} else if (operation === 'getAll') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// signature: getAll
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const petitionId = this.getNodeParameter('petitionId', i);
|
|
|
|
|
|
|
|
const endpoint = `/petitions/${petitionId}/signatures`;
|
|
|
|
response = await handleListing.call(this, 'GET', endpoint);
|
|
|
|
} else if (operation === 'update') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// signature: update
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const petitionId = this.getNodeParameter('petitionId', i);
|
|
|
|
const signatureId = this.getNodeParameter('signatureId', i);
|
|
|
|
const body = {};
|
|
|
|
const updateFields = this.getNodeParameter('updateFields', i) as AllFieldsUi;
|
|
|
|
|
|
|
|
if (Object.keys(updateFields).length) {
|
|
|
|
Object.assign(body, updateFields);
|
|
|
|
} else {
|
|
|
|
throw new NodeOperationError(
|
|
|
|
this.getNode(),
|
|
|
|
`Please enter at least one field to update for the ${resource}.`,
|
2022-07-12 08:51:01 -07:00
|
|
|
{ itemIndex: i },
|
2021-06-27 04:07:25 -07:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
const endpoint = `/petitions/${petitionId}/signatures/${signatureId}`;
|
|
|
|
response = await actionNetworkApiRequest.call(this, 'PUT', endpoint, body);
|
|
|
|
}
|
|
|
|
} else if (resource === 'tag') {
|
|
|
|
// **********************************************************************
|
|
|
|
// tag
|
|
|
|
// **********************************************************************
|
|
|
|
|
|
|
|
// https://actionnetwork.org/docs/v2/tags
|
|
|
|
|
|
|
|
if (operation === 'create') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// tag: create
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const body = {
|
|
|
|
name: this.getNodeParameter('name', i),
|
|
|
|
} as IDataObject;
|
|
|
|
|
|
|
|
response = await actionNetworkApiRequest.call(this, 'POST', '/tags', body);
|
|
|
|
} else if (operation === 'get') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// tag: get
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const tagId = this.getNodeParameter('tagId', i);
|
|
|
|
|
|
|
|
response = await actionNetworkApiRequest.call(this, 'GET', `/tags/${tagId}`);
|
|
|
|
} else if (operation === 'getAll') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// tag: getAll
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
response = await handleListing.call(this, 'GET', '/tags');
|
|
|
|
}
|
|
|
|
} else if (resource === 'personTag') {
|
|
|
|
// **********************************************************************
|
|
|
|
// personTag
|
|
|
|
// **********************************************************************
|
|
|
|
|
|
|
|
// https://actionnetwork.org/docs/v2/taggings
|
|
|
|
|
|
|
|
if (operation === 'add') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// personTag: add
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const personId = this.getNodeParameter('personId', i) as string;
|
|
|
|
const tagId = this.getNodeParameter('tagId', i);
|
|
|
|
|
|
|
|
const body = makeOsdiLink(personId) as IDataObject;
|
|
|
|
|
|
|
|
const endpoint = `/tags/${tagId}/taggings`;
|
|
|
|
response = await actionNetworkApiRequest.call(this, 'POST', endpoint, body);
|
|
|
|
} else if (operation === 'remove') {
|
|
|
|
// ----------------------------------------
|
|
|
|
// personTag: remove
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
const tagId = this.getNodeParameter('tagId', i);
|
|
|
|
const taggingId = this.getNodeParameter('taggingId', i);
|
|
|
|
|
|
|
|
const endpoint = `/tags/${tagId}/taggings/${taggingId}`;
|
|
|
|
response = await actionNetworkApiRequest.call(this, 'DELETE', endpoint);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const simplify = this.getNodeParameter('simple', i, false) as boolean;
|
|
|
|
|
|
|
|
if (simplify) {
|
2022-08-01 13:47:55 -07:00
|
|
|
response =
|
|
|
|
operation === 'getAll'
|
2022-12-02 12:54:28 -08:00
|
|
|
? response.map((entry: Response) => simplifyResponse(entry, resource))
|
2023-02-27 19:39:43 -08:00
|
|
|
: simplifyResponse(response as Response, resource);
|
2021-06-27 04:07:25 -07:00
|
|
|
}
|
|
|
|
|
2023-02-27 19:39:43 -08:00
|
|
|
Array.isArray(response)
|
|
|
|
? returnData.push(...(response as IDataObject[]))
|
|
|
|
: returnData.push(response as IDataObject);
|
2021-06-27 04:07:25 -07:00
|
|
|
} catch (error) {
|
2024-08-30 00:59:30 -07:00
|
|
|
if (this.continueOnFail()) {
|
2021-06-27 04:07:25 -07:00
|
|
|
returnData.push({ error: error.message });
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return [this.helpers.returnJsonArray(returnData)];
|
|
|
|
}
|
|
|
|
}
|