first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"node": "n8n-nodes-base.copper",
|
||||
"nodeVersion": "1.0",
|
||||
"codexVersion": "1.0",
|
||||
"categories": ["Marketing", "Sales"],
|
||||
"resources": {
|
||||
"credentialDocumentation": [
|
||||
{
|
||||
"url": "https://docs.n8n.io/integrations/builtin/credentials/copper/"
|
||||
}
|
||||
],
|
||||
"primaryDocumentation": [
|
||||
{
|
||||
"url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.copper/"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,639 @@
|
||||
import type {
|
||||
IExecuteFunctions,
|
||||
IDataObject,
|
||||
INodeExecutionData,
|
||||
INodeType,
|
||||
INodeTypeDescription,
|
||||
} from 'n8n-workflow';
|
||||
import { NodeConnectionTypes } from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
companyFields,
|
||||
companyOperations,
|
||||
customerSourceFields,
|
||||
customerSourceOperations,
|
||||
leadFields,
|
||||
leadOperations,
|
||||
opportunityFields,
|
||||
opportunityOperations,
|
||||
personFields,
|
||||
personOperations,
|
||||
projectFields,
|
||||
projectOperations,
|
||||
taskFields,
|
||||
taskOperations,
|
||||
userFields,
|
||||
userOperations,
|
||||
} from './descriptions';
|
||||
import {
|
||||
adjustCompanyFields,
|
||||
adjustLeadFields,
|
||||
adjustPersonFields,
|
||||
adjustTaskFields,
|
||||
copperApiRequest,
|
||||
handleListing,
|
||||
} from './GenericFunctions';
|
||||
|
||||
export class Copper implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'Copper',
|
||||
name: 'copper',
|
||||
icon: 'file:copper.svg',
|
||||
group: ['transform'],
|
||||
version: 1,
|
||||
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
||||
description: 'Consume the Copper API',
|
||||
defaults: {
|
||||
name: 'Copper',
|
||||
},
|
||||
usableAsTool: true,
|
||||
inputs: [NodeConnectionTypes.Main],
|
||||
outputs: [NodeConnectionTypes.Main],
|
||||
credentials: [
|
||||
{
|
||||
name: 'copperApi',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
properties: [
|
||||
{
|
||||
displayName: 'Resource',
|
||||
name: 'resource',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
options: [
|
||||
{
|
||||
name: 'Company',
|
||||
value: 'company',
|
||||
},
|
||||
{
|
||||
name: 'Customer Source',
|
||||
value: 'customerSource',
|
||||
},
|
||||
{
|
||||
name: 'Lead',
|
||||
value: 'lead',
|
||||
},
|
||||
{
|
||||
name: 'Opportunity',
|
||||
value: 'opportunity',
|
||||
},
|
||||
{
|
||||
name: 'Person',
|
||||
value: 'person',
|
||||
},
|
||||
{
|
||||
name: 'Project',
|
||||
value: 'project',
|
||||
},
|
||||
{
|
||||
name: 'Task',
|
||||
value: 'task',
|
||||
},
|
||||
{
|
||||
name: 'User',
|
||||
value: 'user',
|
||||
},
|
||||
],
|
||||
default: 'company',
|
||||
},
|
||||
...companyOperations,
|
||||
...companyFields,
|
||||
...customerSourceOperations,
|
||||
...customerSourceFields,
|
||||
...leadOperations,
|
||||
...leadFields,
|
||||
...opportunityOperations,
|
||||
...opportunityFields,
|
||||
...personOperations,
|
||||
...personFields,
|
||||
...projectOperations,
|
||||
...projectFields,
|
||||
...taskOperations,
|
||||
...taskFields,
|
||||
...userOperations,
|
||||
...userFields,
|
||||
],
|
||||
};
|
||||
|
||||
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||
const items = this.getInputData();
|
||||
const returnData: INodeExecutionData[] = [];
|
||||
|
||||
const resource = this.getNodeParameter('resource', 0);
|
||||
const operation = this.getNodeParameter('operation', 0);
|
||||
|
||||
let responseData;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
if (resource === 'company') {
|
||||
// **********************************************************************
|
||||
// company
|
||||
// **********************************************************************
|
||||
|
||||
if (operation === 'create') {
|
||||
// ----------------------------------------
|
||||
// company: create
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/companies/create-a-new-company.html
|
||||
|
||||
const body: IDataObject = {
|
||||
name: this.getNodeParameter('name', i),
|
||||
};
|
||||
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i);
|
||||
|
||||
if (Object.keys(additionalFields).length) {
|
||||
Object.assign(body, adjustCompanyFields(additionalFields));
|
||||
}
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'POST', '/companies', body);
|
||||
} else if (operation === 'delete') {
|
||||
// ----------------------------------------
|
||||
// company: delete
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/companies/delete-a-company.html
|
||||
|
||||
const companyId = this.getNodeParameter('companyId', i);
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'DELETE', `/companies/${companyId}`);
|
||||
} else if (operation === 'get') {
|
||||
// ----------------------------------------
|
||||
// company: get
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/companies/fetch-a-company-by-id.html
|
||||
|
||||
const companyId = this.getNodeParameter('companyId', i);
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'GET', `/companies/${companyId}`);
|
||||
} else if (operation === 'getAll') {
|
||||
// ----------------------------------------
|
||||
// company: getAll
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/companies/list-companies-search.html
|
||||
|
||||
const body: IDataObject = {};
|
||||
const filterFields = this.getNodeParameter('filterFields', i) as IDataObject;
|
||||
|
||||
if (Object.keys(filterFields).length) {
|
||||
Object.assign(body, filterFields);
|
||||
}
|
||||
|
||||
responseData = await handleListing.call(this, 'POST', '/companies/search', body);
|
||||
} else if (operation === 'update') {
|
||||
// ----------------------------------------
|
||||
// company: update
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/companies/update-a-company.html
|
||||
|
||||
const companyId = this.getNodeParameter('companyId', i);
|
||||
|
||||
const body: IDataObject = {};
|
||||
const updateFields = this.getNodeParameter('updateFields', i);
|
||||
|
||||
if (Object.keys(updateFields).length) {
|
||||
Object.assign(body, adjustCompanyFields(updateFields));
|
||||
}
|
||||
|
||||
responseData = await copperApiRequest.call(
|
||||
this,
|
||||
'PUT',
|
||||
`/companies/${companyId}`,
|
||||
body,
|
||||
);
|
||||
}
|
||||
} else if (resource === 'customerSource') {
|
||||
// **********************************************************************
|
||||
// customerSource
|
||||
// **********************************************************************
|
||||
|
||||
if (operation === 'getAll') {
|
||||
// ----------------------------------------
|
||||
// customerSource: getAll
|
||||
// ----------------------------------------
|
||||
|
||||
responseData = await handleListing.call(this, 'GET', '/customer_sources');
|
||||
}
|
||||
} else if (resource === 'lead') {
|
||||
// **********************************************************************
|
||||
// lead
|
||||
// **********************************************************************
|
||||
|
||||
if (operation === 'create') {
|
||||
// ----------------------------------------
|
||||
// lead: create
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/leads/create-a-new-lead.html
|
||||
|
||||
const body: IDataObject = {
|
||||
name: this.getNodeParameter('name', i),
|
||||
};
|
||||
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i);
|
||||
|
||||
if (Object.keys(additionalFields).length) {
|
||||
Object.assign(body, adjustLeadFields(additionalFields));
|
||||
}
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'POST', '/leads', body);
|
||||
} else if (operation === 'delete') {
|
||||
// ----------------------------------------
|
||||
// lead: delete
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/leads/delete-a-lead.html
|
||||
|
||||
const leadId = this.getNodeParameter('leadId', i);
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'DELETE', `/leads/${leadId}`);
|
||||
} else if (operation === 'get') {
|
||||
// ----------------------------------------
|
||||
// lead: get
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/leads/fetch-a-lead-by-id.html
|
||||
|
||||
const leadId = this.getNodeParameter('leadId', i);
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'GET', `/leads/${leadId}`);
|
||||
} else if (operation === 'getAll') {
|
||||
// ----------------------------------------
|
||||
// lead: getAll
|
||||
// ----------------------------------------
|
||||
|
||||
const body: IDataObject = {};
|
||||
const filterFields = this.getNodeParameter('filterFields', i) as IDataObject;
|
||||
|
||||
if (Object.keys(filterFields).length) {
|
||||
Object.assign(body, filterFields);
|
||||
}
|
||||
|
||||
responseData = await handleListing.call(this, 'POST', '/leads/search', body);
|
||||
} else if (operation === 'update') {
|
||||
// ----------------------------------------
|
||||
// lead: update
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/leads/update-a-lead.html
|
||||
|
||||
const leadId = this.getNodeParameter('leadId', i);
|
||||
|
||||
const body: IDataObject = {};
|
||||
const updateFields = this.getNodeParameter('updateFields', i);
|
||||
|
||||
if (Object.keys(updateFields).length) {
|
||||
Object.assign(body, adjustLeadFields(updateFields));
|
||||
}
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'PUT', `/leads/${leadId}`, body);
|
||||
}
|
||||
} else if (resource === 'opportunity') {
|
||||
// **********************************************************************
|
||||
// opportunity
|
||||
// **********************************************************************
|
||||
|
||||
if (operation === 'create') {
|
||||
// ----------------------------------------
|
||||
// opportunity: create
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/opportunities/create-a-new-opportunity.html
|
||||
|
||||
const body: IDataObject = {
|
||||
name: this.getNodeParameter('name', i),
|
||||
customer_source_id: this.getNodeParameter('customerSourceId', i),
|
||||
primary_contact_id: this.getNodeParameter('primaryContactId', i),
|
||||
};
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'POST', '/opportunities', body);
|
||||
} else if (operation === 'delete') {
|
||||
// ----------------------------------------
|
||||
// opportunity: delete
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/opportunities/delete-an-opportunity.html
|
||||
|
||||
const opportunityId = this.getNodeParameter('opportunityId', i);
|
||||
|
||||
responseData = await copperApiRequest.call(
|
||||
this,
|
||||
'DELETE',
|
||||
`/opportunities/${opportunityId}`,
|
||||
);
|
||||
} else if (operation === 'get') {
|
||||
// ----------------------------------------
|
||||
// opportunity: get
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/opportunities/fetch-an-opportunity-by-id.html
|
||||
|
||||
const opportunityId = this.getNodeParameter('opportunityId', i);
|
||||
|
||||
responseData = await copperApiRequest.call(
|
||||
this,
|
||||
'GET',
|
||||
`/opportunities/${opportunityId}`,
|
||||
);
|
||||
} else if (operation === 'getAll') {
|
||||
// ----------------------------------------
|
||||
// opportunity: getAll
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/opportunities/list-opportunities-search.html
|
||||
|
||||
const body: IDataObject = {};
|
||||
const filterFields = this.getNodeParameter('filterFields', i) as IDataObject;
|
||||
|
||||
if (Object.keys(filterFields).length) {
|
||||
Object.assign(body, filterFields);
|
||||
}
|
||||
|
||||
responseData = await handleListing.call(this, 'POST', '/opportunities/search', body);
|
||||
} else if (operation === 'update') {
|
||||
// ----------------------------------------
|
||||
// opportunity: update
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/opportunities/update-an-opportunity.html
|
||||
|
||||
const opportunityId = this.getNodeParameter('opportunityId', i);
|
||||
|
||||
const body: IDataObject = {};
|
||||
const updateFields = this.getNodeParameter('updateFields', i);
|
||||
|
||||
if (Object.keys(updateFields).length) {
|
||||
Object.assign(body, updateFields);
|
||||
}
|
||||
|
||||
responseData = await copperApiRequest.call(
|
||||
this,
|
||||
'PUT',
|
||||
`/opportunities/${opportunityId}`,
|
||||
body,
|
||||
);
|
||||
}
|
||||
} else if (resource === 'person') {
|
||||
// **********************************************************************
|
||||
// person
|
||||
// **********************************************************************
|
||||
|
||||
if (operation === 'create') {
|
||||
// ----------------------------------------
|
||||
// person: create
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/people/create-a-new-person.html
|
||||
|
||||
const body: IDataObject = {
|
||||
name: this.getNodeParameter('name', i),
|
||||
};
|
||||
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i);
|
||||
|
||||
if (Object.keys(additionalFields).length) {
|
||||
Object.assign(body, adjustPersonFields(additionalFields));
|
||||
}
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'POST', '/people', body);
|
||||
} else if (operation === 'delete') {
|
||||
// ----------------------------------------
|
||||
// person: delete
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/people/delete-a-person.html
|
||||
|
||||
const personId = this.getNodeParameter('personId', i);
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'DELETE', `/people/${personId}`);
|
||||
} else if (operation === 'get') {
|
||||
// ----------------------------------------
|
||||
// person: get
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/people/fetch-a-person-by-id.html
|
||||
|
||||
const personId = this.getNodeParameter('personId', i);
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'GET', `/people/${personId}`);
|
||||
} else if (operation === 'getAll') {
|
||||
// ----------------------------------------
|
||||
// person: getAll
|
||||
// ----------------------------------------
|
||||
|
||||
const body: IDataObject = {};
|
||||
const filterFields = this.getNodeParameter('filterFields', i) as IDataObject;
|
||||
|
||||
if (Object.keys(filterFields).length) {
|
||||
Object.assign(body, filterFields);
|
||||
}
|
||||
|
||||
responseData = await handleListing.call(this, 'POST', '/people/search', body);
|
||||
} else if (operation === 'update') {
|
||||
// ----------------------------------------
|
||||
// person: update
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/people/update-a-person.html
|
||||
|
||||
const personId = this.getNodeParameter('personId', i);
|
||||
|
||||
const body: IDataObject = {};
|
||||
const updateFields = this.getNodeParameter('updateFields', i);
|
||||
|
||||
if (Object.keys(updateFields).length) {
|
||||
Object.assign(body, adjustPersonFields(updateFields));
|
||||
}
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'PUT', `/people/${personId}`, body);
|
||||
}
|
||||
} else if (resource === 'project') {
|
||||
// **********************************************************************
|
||||
// project
|
||||
// **********************************************************************
|
||||
|
||||
if (operation === 'create') {
|
||||
// ----------------------------------------
|
||||
// project: create
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/projects/create-a-new-project.html
|
||||
|
||||
const body: IDataObject = {
|
||||
name: this.getNodeParameter('name', i),
|
||||
};
|
||||
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i);
|
||||
|
||||
if (Object.keys(additionalFields).length) {
|
||||
Object.assign(body, additionalFields);
|
||||
}
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'POST', '/projects', body);
|
||||
} else if (operation === 'delete') {
|
||||
// ----------------------------------------
|
||||
// project: delete
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/projects/delete-a-project.html
|
||||
|
||||
const projectId = this.getNodeParameter('projectId', i);
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'DELETE', `/projects/${projectId}`);
|
||||
} else if (operation === 'get') {
|
||||
// ----------------------------------------
|
||||
// project: get
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/projects/fetch-a-project-by-id.html
|
||||
|
||||
const projectId = this.getNodeParameter('projectId', i);
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'GET', `/projects/${projectId}`);
|
||||
} else if (operation === 'getAll') {
|
||||
// ----------------------------------------
|
||||
// project: getAll
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/projects/list-projects-search.html
|
||||
|
||||
const body: IDataObject = {};
|
||||
const filterFields = this.getNodeParameter('filterFields', i) as IDataObject;
|
||||
|
||||
if (Object.keys(filterFields).length) {
|
||||
Object.assign(body, filterFields);
|
||||
}
|
||||
|
||||
responseData = await handleListing.call(this, 'POST', '/projects/search', body);
|
||||
} else if (operation === 'update') {
|
||||
// ----------------------------------------
|
||||
// project: update
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/projects/update-a-project.html
|
||||
|
||||
const projectId = this.getNodeParameter('projectId', i);
|
||||
|
||||
const body: IDataObject = {};
|
||||
const updateFields = this.getNodeParameter('updateFields', i);
|
||||
|
||||
if (Object.keys(updateFields).length) {
|
||||
Object.assign(body, updateFields);
|
||||
}
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'PUT', `/projects/${projectId}`, body);
|
||||
}
|
||||
} else if (resource === 'task') {
|
||||
// **********************************************************************
|
||||
// task
|
||||
// **********************************************************************
|
||||
|
||||
if (operation === 'create') {
|
||||
// ----------------------------------------
|
||||
// task: create
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/tasks/create-a-new-task.html
|
||||
|
||||
const body: IDataObject = {
|
||||
name: this.getNodeParameter('name', i),
|
||||
};
|
||||
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i);
|
||||
|
||||
if (Object.keys(additionalFields).length) {
|
||||
Object.assign(body, additionalFields);
|
||||
}
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'POST', '/tasks', body);
|
||||
} else if (operation === 'delete') {
|
||||
// ----------------------------------------
|
||||
// task: delete
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/tasks/delete-a-task.html
|
||||
|
||||
const taskId = this.getNodeParameter('taskId', i);
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'DELETE', `/tasks/${taskId}`);
|
||||
} else if (operation === 'get') {
|
||||
// ----------------------------------------
|
||||
// task: get
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/tasks/fetch-a-task-by-id.html
|
||||
|
||||
const taskId = this.getNodeParameter('taskId', i);
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'GET', `/tasks/${taskId}`);
|
||||
} else if (operation === 'getAll') {
|
||||
// ----------------------------------------
|
||||
// task: getAll
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/tasks/list-tasks-search.html
|
||||
|
||||
const body: IDataObject = {};
|
||||
const filterFields = this.getNodeParameter('filterFields', i) as IDataObject;
|
||||
|
||||
if (Object.keys(filterFields).length) {
|
||||
Object.assign(body, adjustTaskFields(filterFields));
|
||||
}
|
||||
|
||||
responseData = await handleListing.call(this, 'POST', '/tasks/search', body);
|
||||
} else if (operation === 'update') {
|
||||
// ----------------------------------------
|
||||
// task: update
|
||||
// ----------------------------------------
|
||||
|
||||
// https://developer.copper.com/tasks/update-a-task.html
|
||||
|
||||
const taskId = this.getNodeParameter('taskId', i);
|
||||
|
||||
const body: IDataObject = {};
|
||||
const updateFields = this.getNodeParameter('updateFields', i);
|
||||
|
||||
if (Object.keys(updateFields).length) {
|
||||
Object.assign(body, updateFields);
|
||||
}
|
||||
|
||||
responseData = await copperApiRequest.call(this, 'PUT', `/tasks/${taskId}`, body);
|
||||
}
|
||||
} else if (resource === 'user') {
|
||||
// **********************************************************************
|
||||
// user
|
||||
// **********************************************************************
|
||||
|
||||
if (operation === 'getAll') {
|
||||
// ----------------------------------------
|
||||
// user: getAll
|
||||
// ----------------------------------------
|
||||
|
||||
responseData = await handleListing.call(this, 'POST', '/users/search');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.toString(), json: {} });
|
||||
continue;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
const executionData = this.helpers.constructExecutionMetaData(
|
||||
this.helpers.returnJsonArray(responseData as IDataObject[]),
|
||||
{ itemData: { item: i } },
|
||||
);
|
||||
returnData.push(...executionData);
|
||||
}
|
||||
|
||||
return [returnData];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"node": "n8n-nodes-base.copperTrigger",
|
||||
"nodeVersion": "1.0",
|
||||
"codexVersion": "1.0",
|
||||
"categories": ["Sales"],
|
||||
"resources": {
|
||||
"credentialDocumentation": [
|
||||
{
|
||||
"url": "https://docs.n8n.io/integrations/builtin/credentials/copper/"
|
||||
}
|
||||
],
|
||||
"primaryDocumentation": [
|
||||
{
|
||||
"url": "https://docs.n8n.io/integrations/builtin/trigger-nodes/n8n-nodes-base.coppertrigger/"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
import type {
|
||||
IHookFunctions,
|
||||
IWebhookFunctions,
|
||||
IDataObject,
|
||||
INodeType,
|
||||
INodeTypeDescription,
|
||||
IWebhookResponseData,
|
||||
} from 'n8n-workflow';
|
||||
import { NodeConnectionTypes } from 'n8n-workflow';
|
||||
|
||||
import { copperApiRequest, getAutomaticSecret } from './GenericFunctions';
|
||||
|
||||
export class CopperTrigger implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'Copper Trigger',
|
||||
name: 'copperTrigger',
|
||||
icon: 'file:copper.svg',
|
||||
group: ['trigger'],
|
||||
version: 1,
|
||||
description: 'Handle Copper events via webhooks',
|
||||
defaults: {
|
||||
name: 'Copper Trigger',
|
||||
},
|
||||
inputs: [],
|
||||
outputs: [NodeConnectionTypes.Main],
|
||||
credentials: [
|
||||
{
|
||||
name: 'copperApi',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
webhooks: [
|
||||
{
|
||||
name: 'default',
|
||||
httpMethod: 'POST',
|
||||
responseMode: 'onReceived',
|
||||
path: 'webhook',
|
||||
},
|
||||
],
|
||||
properties: [
|
||||
{
|
||||
displayName: 'Resource',
|
||||
name: 'resource',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
required: true,
|
||||
default: '',
|
||||
options: [
|
||||
{
|
||||
name: 'Company',
|
||||
value: 'company',
|
||||
},
|
||||
{
|
||||
name: 'Lead',
|
||||
value: 'lead',
|
||||
},
|
||||
{
|
||||
name: 'Opportunity',
|
||||
value: 'opportunity',
|
||||
},
|
||||
{
|
||||
name: 'Person',
|
||||
value: 'person',
|
||||
},
|
||||
{
|
||||
name: 'Project',
|
||||
value: 'project',
|
||||
},
|
||||
{
|
||||
name: 'Task',
|
||||
value: 'task',
|
||||
},
|
||||
],
|
||||
description: 'The resource which will fire the event',
|
||||
},
|
||||
{
|
||||
displayName: 'Event',
|
||||
name: 'event',
|
||||
type: 'options',
|
||||
required: true,
|
||||
default: '',
|
||||
options: [
|
||||
{
|
||||
name: 'Delete',
|
||||
value: 'delete',
|
||||
description: 'An existing record is removed',
|
||||
},
|
||||
{
|
||||
name: 'New',
|
||||
value: 'new',
|
||||
description: 'A new record is created',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
value: 'update',
|
||||
description: 'Any field in the existing entity record is changed',
|
||||
},
|
||||
],
|
||||
description: 'The event to listen to',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
webhookMethods = {
|
||||
default: {
|
||||
async checkExists(this: IHookFunctions): Promise<boolean> {
|
||||
const webhookData = this.getWorkflowStaticData('node');
|
||||
if (webhookData.webhookId === undefined) {
|
||||
return false;
|
||||
}
|
||||
const endpoint = `/webhooks/${webhookData.webhookId}`;
|
||||
try {
|
||||
await copperApiRequest.call(this, 'GET', endpoint);
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
async create(this: IHookFunctions): Promise<boolean> {
|
||||
const webhookUrl = this.getNodeWebhookUrl('default');
|
||||
const webhookData = this.getWorkflowStaticData('node');
|
||||
const resource = this.getNodeParameter('resource') as string;
|
||||
const event = this.getNodeParameter('event') as string;
|
||||
const endpoint = '/webhooks';
|
||||
const body: IDataObject = {
|
||||
target: webhookUrl,
|
||||
type: resource,
|
||||
event,
|
||||
};
|
||||
|
||||
const credentials = await this.getCredentials('copperApi');
|
||||
body.secret = {
|
||||
secret: getAutomaticSecret(credentials),
|
||||
};
|
||||
|
||||
const { id } = await copperApiRequest.call(this, 'POST', endpoint, body);
|
||||
webhookData.webhookId = id;
|
||||
return true;
|
||||
},
|
||||
async delete(this: IHookFunctions): Promise<boolean> {
|
||||
const webhookData = this.getWorkflowStaticData('node');
|
||||
const endpoint = `/webhooks/${webhookData.webhookId}`;
|
||||
try {
|
||||
await copperApiRequest.call(this, 'DELETE', endpoint);
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
delete webhookData.webhookId;
|
||||
return true;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> {
|
||||
const credentials = await this.getCredentials('copperApi');
|
||||
const req = this.getRequestObject();
|
||||
|
||||
// Check if the supplied secret matches. If not ignore request.
|
||||
if (req.body.secret !== getAutomaticSecret(credentials)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
workflowData: [this.helpers.returnJsonArray(req.body as IDataObject)],
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
import { createHash } from 'crypto';
|
||||
import flow from 'lodash/flow';
|
||||
import omit from 'lodash/omit';
|
||||
import type {
|
||||
ICredentialDataDecryptedObject,
|
||||
IDataObject,
|
||||
IExecuteFunctions,
|
||||
IHookFunctions,
|
||||
IHttpRequestMethods,
|
||||
ILoadOptionsFunctions,
|
||||
IHttpRequestOptions,
|
||||
IWebhookFunctions,
|
||||
JsonObject,
|
||||
} from 'n8n-workflow';
|
||||
import { NodeApiError } from 'n8n-workflow';
|
||||
|
||||
import type {
|
||||
AddressFixedCollection,
|
||||
EmailFixedCollection,
|
||||
EmailsFixedCollection,
|
||||
PhoneNumbersFixedCollection,
|
||||
} from './utils/types';
|
||||
|
||||
/**
|
||||
* Make an authenticated API request to Copper.
|
||||
*/
|
||||
export async function copperApiRequest(
|
||||
this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions | IWebhookFunctions,
|
||||
method: IHttpRequestMethods,
|
||||
resource: string,
|
||||
body: IDataObject = {},
|
||||
qs: IDataObject = {},
|
||||
uri = '',
|
||||
option: IDataObject = {},
|
||||
) {
|
||||
let options: IHttpRequestOptions = {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
method,
|
||||
qs,
|
||||
body,
|
||||
url: uri || `https://api.copper.com/developer_api/v1${resource}`,
|
||||
json: true,
|
||||
};
|
||||
|
||||
options = Object.assign({}, options, option);
|
||||
|
||||
if (!Object.keys(qs).length) {
|
||||
delete options.qs;
|
||||
}
|
||||
|
||||
if (Object.keys(options.body as IDataObject).length === 0) {
|
||||
delete options.body;
|
||||
}
|
||||
|
||||
try {
|
||||
return await this.helpers.requestWithAuthentication.call(this, 'copperApi', options);
|
||||
} catch (error) {
|
||||
throw new NodeApiError(this.getNode(), error as JsonObject);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a secret from the credentials
|
||||
*
|
||||
*/
|
||||
export function getAutomaticSecret(credentials: ICredentialDataDecryptedObject) {
|
||||
const data = `${credentials.email},${credentials.apiKey}`;
|
||||
return createHash('md5').update(data).digest('hex');
|
||||
}
|
||||
|
||||
export function adjustAddress(fixedCollection: AddressFixedCollection) {
|
||||
if (!fixedCollection.address) return fixedCollection;
|
||||
|
||||
const adjusted: { address?: object } = omit(fixedCollection, ['address']);
|
||||
|
||||
if (fixedCollection.address) {
|
||||
adjusted.address = fixedCollection.address.addressFields;
|
||||
}
|
||||
|
||||
return adjusted;
|
||||
}
|
||||
|
||||
export function adjustPhoneNumbers(fixedCollection: PhoneNumbersFixedCollection) {
|
||||
if (!fixedCollection.phone_numbers) return fixedCollection;
|
||||
|
||||
const adjusted: { phone_numbers?: object } = omit(fixedCollection, ['phone_numbers']);
|
||||
|
||||
if (fixedCollection.phone_numbers) {
|
||||
adjusted.phone_numbers = fixedCollection.phone_numbers.phoneFields;
|
||||
}
|
||||
|
||||
return adjusted;
|
||||
}
|
||||
|
||||
export function adjustEmails(fixedCollection: EmailsFixedCollection) {
|
||||
if (!fixedCollection.emails) return fixedCollection;
|
||||
|
||||
const adjusted: { emails?: object } = omit(fixedCollection, ['emails']);
|
||||
|
||||
if (fixedCollection.emails) {
|
||||
adjusted.emails = fixedCollection.emails.emailFields;
|
||||
}
|
||||
|
||||
return adjusted;
|
||||
}
|
||||
|
||||
export function adjustProjectIds(fields: { project_ids?: string }) {
|
||||
if (!fields.project_ids) return fields;
|
||||
|
||||
const adjusted: { project_ids?: string[] } = omit(fields, ['project_ids']);
|
||||
|
||||
adjusted.project_ids = fields.project_ids.includes(',')
|
||||
? fields.project_ids.split(',')
|
||||
: [fields.project_ids];
|
||||
|
||||
return adjusted;
|
||||
}
|
||||
|
||||
export function adjustEmail(fixedCollection: EmailFixedCollection) {
|
||||
if (!fixedCollection.email) return fixedCollection;
|
||||
|
||||
const adjusted: { email?: object } = omit(fixedCollection, ['email']);
|
||||
|
||||
if (fixedCollection.email) {
|
||||
adjusted.email = fixedCollection.email.emailFields;
|
||||
}
|
||||
|
||||
return adjusted;
|
||||
}
|
||||
|
||||
export const adjustCompanyFields = flow(adjustAddress, adjustPhoneNumbers);
|
||||
export const adjustLeadFields = flow(adjustCompanyFields, adjustEmail);
|
||||
export const adjustPersonFields = flow(adjustCompanyFields, adjustEmails);
|
||||
export const adjustTaskFields = flow(adjustLeadFields, adjustProjectIds);
|
||||
|
||||
/**
|
||||
* Make an authenticated API request to Copper and return all items.
|
||||
*/
|
||||
export async function copperApiRequestAllItems(
|
||||
this: IHookFunctions | ILoadOptionsFunctions | IExecuteFunctions,
|
||||
method: IHttpRequestMethods,
|
||||
resource: string,
|
||||
body: IDataObject = {},
|
||||
qs: IDataObject = {},
|
||||
uri = '',
|
||||
option: IDataObject = {},
|
||||
) {
|
||||
let responseData;
|
||||
qs.page_size = 200;
|
||||
let totalItems = 0;
|
||||
const returnData: IDataObject[] = [];
|
||||
|
||||
do {
|
||||
responseData = await copperApiRequest.call(this, method, resource, body, qs, uri, option);
|
||||
totalItems = responseData.headers['x-pw-total'];
|
||||
returnData.push(...(responseData.body as IDataObject[]));
|
||||
} while (totalItems > returnData.length);
|
||||
|
||||
return returnData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a Copper listing by returning all items or up to a limit.
|
||||
*/
|
||||
export async function handleListing(
|
||||
this: IExecuteFunctions,
|
||||
method: IHttpRequestMethods,
|
||||
endpoint: string,
|
||||
qs: IDataObject = {},
|
||||
body: IDataObject = {},
|
||||
uri = '',
|
||||
) {
|
||||
const returnAll = this.getNodeParameter('returnAll', 0);
|
||||
|
||||
const option = { resolveWithFullResponse: true };
|
||||
|
||||
if (returnAll) {
|
||||
return await copperApiRequestAllItems.call(this, method, endpoint, body, qs, uri, option);
|
||||
}
|
||||
|
||||
const limit = this.getNodeParameter('limit', 0);
|
||||
const responseData = await copperApiRequestAllItems.call(
|
||||
this,
|
||||
method,
|
||||
endpoint,
|
||||
body,
|
||||
qs,
|
||||
uri,
|
||||
option,
|
||||
);
|
||||
return responseData.slice(0, limit);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="20.0499" cy="20.0499" r="15.5118" fill="white"/>
|
||||
<path d="M17.79 0.136905C15.4247 0.422938 13.4114 1.01701 11.3542 2.01812C7.10772 4.08636 3.89535 7.32073 1.93713 11.4682C0.473957 14.5926 -0.230124 18.377 0.0669105 21.5014C0.23193 23.2506 0.473957 24.4497 1.05702 26.3859C1.48607 27.7941 2.89424 30.5114 3.96136 31.9306C4.65444 32.8657 6.66767 34.9119 7.72379 35.748C8.99994 36.7711 10.7711 37.7722 12.7844 38.6413C13.9835 39.1584 16.6128 39.7415 18.494 39.9175C19.6382 40.0275 20.2762 40.0275 21.4314 39.9175C28.0761 39.3234 33.6098 35.935 37.0752 30.3354C39.1764 26.925 40.2765 22.3815 39.9135 18.542C39.7705 16.9138 39.3964 15.0876 38.9124 13.6245C37.2512 8.58588 33.3347 4.17437 28.5712 1.98512C27.9991 1.72109 27.4491 1.45706 27.3611 1.41305C27.152 1.30304 25.1828 0.697969 24.5007 0.53295C22.2565 0.00488941 20.0012 -0.138127 17.79 0.136905ZM24.2257 8.7509C25.9859 9.23495 27.8561 10.3241 28.8462 11.4352C29.1213 11.7542 29.5723 12.4583 29.8363 13.0084C30.8815 15.1646 30.6834 17.1889 29.2973 18.575C28.5272 19.3451 28.1311 19.4881 26.811 19.4991C25.7989 19.4991 25.5899 19.4661 25.1278 19.2351C24.3687 18.8391 23.5986 17.981 23.3016 17.1889C22.9275 16.2098 22.9605 15.2746 23.4116 13.7125C24.1267 11.2482 23.8407 9.98304 22.4105 9.26796C21.9484 9.02593 20.7713 8.99293 20.1882 9.20195C19.2971 9.49898 18.252 10.6541 17.6139 12.0183C16.8878 13.5915 16.5028 15.7917 16.6128 17.8379C16.7338 20.2582 17.3059 21.9194 18.505 23.4156C20.1992 25.5058 23.0376 26.3419 26.1289 25.6488C27.4161 25.3628 28.6812 24.6807 29.9244 23.5916C30.5294 23.0635 30.7164 22.9535 30.9365 23.0085C31.0905 23.0525 31.2115 23.1406 31.2115 23.2176C31.2115 23.4266 30.2764 25.1978 29.7043 26.0999C28.4172 28.0801 26.3819 29.9173 24.5557 30.7204C22.7185 31.5345 20.1882 31.8096 17.878 31.4355C15.6887 31.0835 13.4445 29.9393 11.8493 28.3552C8.6149 25.1098 7.7568 19.8402 9.74803 15.4397C11.2552 12.1063 14.5116 9.52099 18.285 8.66289C19.5942 8.36585 22.9826 8.42086 24.2257 8.7509Z" fill="#FF2564"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,247 @@
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
import { isoCountryCodes } from '@utils/ISOCountryCodes';
|
||||
|
||||
import { addressFixedCollection, phoneNumbersFixedCollection } from '../utils/sharedFields';
|
||||
|
||||
export const companyOperations: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['company'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Create',
|
||||
value: 'create',
|
||||
action: 'Create a company',
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
value: 'delete',
|
||||
action: 'Delete a company',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
action: 'Get a company',
|
||||
},
|
||||
{
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
action: 'Get many companies',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
value: 'update',
|
||||
action: 'Update a company',
|
||||
},
|
||||
],
|
||||
default: 'create',
|
||||
},
|
||||
];
|
||||
|
||||
export const companyFields: INodeProperties[] = [
|
||||
// ----------------------------------------
|
||||
// company: create
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
description: 'Name of the company to create',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['company'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
name: 'additionalFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['company'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
addressFixedCollection,
|
||||
{
|
||||
displayName: 'Details',
|
||||
name: 'details',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Description of the company to create',
|
||||
},
|
||||
{
|
||||
displayName: 'Email Domain',
|
||||
name: 'email_domain',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
phoneNumbersFixedCollection,
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// company: delete
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Company ID',
|
||||
name: 'companyId',
|
||||
description: 'ID of the company to delete',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['company'],
|
||||
operation: ['delete'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// company: get
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Company ID',
|
||||
name: 'companyId',
|
||||
description: 'ID of the company to retrieve',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['company'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// company: getAll
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['company'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
default: 5,
|
||||
description: 'Max number of results to return',
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
maxValue: 1000,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['company'],
|
||||
operation: ['getAll'],
|
||||
returnAll: [false],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Filters',
|
||||
name: 'filterFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Filter',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['company'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Country',
|
||||
name: 'country',
|
||||
type: 'options',
|
||||
options: isoCountryCodes.map(({ name, alpha2 }) => ({ name, value: alpha2 })),
|
||||
default: '',
|
||||
description: 'Country of the company to filter by',
|
||||
},
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Name of the company to filter by',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// company: update
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Company ID',
|
||||
name: 'companyId',
|
||||
description: 'ID of the company to update',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['company'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Update Fields',
|
||||
name: 'updateFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['company'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
addressFixedCollection,
|
||||
{
|
||||
displayName: 'Details',
|
||||
name: 'details',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Description to set for the company',
|
||||
},
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Name to set for the company',
|
||||
},
|
||||
phoneNumbersFixedCollection,
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,60 @@
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
export const customerSourceOperations: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['customerSource'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
action: 'Get many customer sources',
|
||||
},
|
||||
],
|
||||
default: 'getAll',
|
||||
},
|
||||
];
|
||||
|
||||
export const customerSourceFields: INodeProperties[] = [
|
||||
// ----------------------------------------
|
||||
// customerSource: getAll
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['customerSource'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
default: 5,
|
||||
description: 'Max number of results to return',
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
maxValue: 1000,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['customerSource'],
|
||||
operation: ['getAll'],
|
||||
returnAll: [false],
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,233 @@
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
addressFixedCollection,
|
||||
emailFixedCollection,
|
||||
phoneNumbersFixedCollection,
|
||||
} from '../utils/sharedFields';
|
||||
|
||||
export const leadOperations: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['lead'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Create',
|
||||
value: 'create',
|
||||
action: 'Create a lead',
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
value: 'delete',
|
||||
action: 'Delete a lead',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
action: 'Get a lead',
|
||||
},
|
||||
{
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
action: 'Get many leads',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
value: 'update',
|
||||
action: 'Update a lead',
|
||||
},
|
||||
],
|
||||
default: 'create',
|
||||
},
|
||||
];
|
||||
|
||||
export const leadFields: INodeProperties[] = [
|
||||
// ----------------------------------------
|
||||
// lead: create
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
description: 'Name of the lead to create',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['lead'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
name: 'additionalFields',
|
||||
type: 'collection',
|
||||
default: {},
|
||||
placeholder: 'Add Field',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['lead'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
options: [addressFixedCollection, emailFixedCollection, phoneNumbersFixedCollection],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// lead: delete
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Lead ID',
|
||||
name: 'leadId',
|
||||
description: 'ID of the lead to delete',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['lead'],
|
||||
operation: ['delete'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// lead: get
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Lead ID',
|
||||
name: 'leadId',
|
||||
description: 'ID of the lead to retrieve',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['lead'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// lead: getAll
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['lead'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
default: 5,
|
||||
description: 'Max number of results to return',
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
maxValue: 1000,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['lead'],
|
||||
operation: ['getAll'],
|
||||
returnAll: [false],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Filters',
|
||||
name: 'filterFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Filter',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['lead'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Country',
|
||||
name: 'country',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Name of the country to filter by',
|
||||
},
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Name of the lead to filter by',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// lead: update
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Lead ID',
|
||||
name: 'leadId',
|
||||
description: 'ID of the lead to update',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['lead'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Update Fields',
|
||||
name: 'updateFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['lead'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
addressFixedCollection,
|
||||
{
|
||||
displayName: 'Details',
|
||||
name: 'details',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Description to set for the lead',
|
||||
},
|
||||
emailFixedCollection,
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Name to set for the lead',
|
||||
},
|
||||
phoneNumbersFixedCollection,
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,243 @@
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
export const opportunityOperations: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['opportunity'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Create',
|
||||
value: 'create',
|
||||
action: 'Create an opportunity',
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
value: 'delete',
|
||||
action: 'Delete an opportunity',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
action: 'Get an opportunity',
|
||||
},
|
||||
{
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
action: 'Get many opportunities',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
value: 'update',
|
||||
action: 'Update an opportunity',
|
||||
},
|
||||
],
|
||||
default: 'create',
|
||||
},
|
||||
];
|
||||
|
||||
export const opportunityFields: INodeProperties[] = [
|
||||
// ----------------------------------------
|
||||
// opportunity: create
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
description: 'Name of the opportunity to create',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['opportunity'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Customer Source ID',
|
||||
name: 'customerSourceId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'ID of the customer source that generated this opportunity',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['opportunity'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Primary Contact ID',
|
||||
name: 'primaryContactId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'ID of the primary company associated with this opportunity',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['opportunity'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// opportunity: delete
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Opportunity ID',
|
||||
name: 'opportunityId',
|
||||
description: 'ID of the opportunity to delete',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['opportunity'],
|
||||
operation: ['delete'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// opportunity: get
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Opportunity ID',
|
||||
name: 'opportunityId',
|
||||
description: 'ID of the opportunity to retrieve',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['opportunity'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// opportunity: getAll
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['opportunity'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
default: 5,
|
||||
description: 'Max number of results to return',
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
maxValue: 1000,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['opportunity'],
|
||||
operation: ['getAll'],
|
||||
returnAll: [false],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Filters',
|
||||
name: 'filterFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Filter',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['opportunity'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Company IDs',
|
||||
name: 'company_ids',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Comma-separated IDs of the primary companies to filter by',
|
||||
},
|
||||
{
|
||||
displayName: 'Customer Source IDs',
|
||||
name: 'customer_source_ids',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Comma-separated IDs of the customer sources to filter by',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// opportunity: update
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Opportunity ID',
|
||||
name: 'opportunityId',
|
||||
description: 'ID of the opportunity to update',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['opportunity'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Update Fields',
|
||||
name: 'updateFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['opportunity'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Customer Source ID',
|
||||
name: 'customer_source_id',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'ID of the primary company associated with this opportunity',
|
||||
},
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Name to set for the opportunity',
|
||||
},
|
||||
{
|
||||
displayName: 'Primary Contact ID',
|
||||
name: 'primary_contact_id',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'ID of the customer source that generated this opportunity',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,249 @@
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
addressFixedCollection,
|
||||
emailsFixedCollection,
|
||||
phoneNumbersFixedCollection,
|
||||
} from '../utils/sharedFields';
|
||||
|
||||
export const personOperations: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['person'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Create',
|
||||
value: 'create',
|
||||
action: 'Create a person',
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
value: 'delete',
|
||||
action: 'Delete a person',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
action: 'Get a person',
|
||||
},
|
||||
{
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
action: 'Get many people',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
value: 'update',
|
||||
action: 'Update a person',
|
||||
},
|
||||
],
|
||||
default: 'create',
|
||||
},
|
||||
];
|
||||
|
||||
export const personFields: INodeProperties[] = [
|
||||
// ----------------------------------------
|
||||
// person: create
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
description: 'Name of the person to create',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['person'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
name: 'additionalFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['person'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
addressFixedCollection,
|
||||
{
|
||||
displayName: 'Details',
|
||||
name: 'details',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Description to set for the person',
|
||||
},
|
||||
{
|
||||
displayName: 'Email Domain',
|
||||
name: 'email_domain',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
emailsFixedCollection,
|
||||
phoneNumbersFixedCollection,
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// person: delete
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Person ID',
|
||||
name: 'personId',
|
||||
description: 'ID of the person to delete',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['person'],
|
||||
operation: ['delete'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// person: get
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Person ID',
|
||||
name: 'personId',
|
||||
description: 'ID of the person to retrieve',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['person'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// person: getAll
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['person'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
default: 5,
|
||||
description: 'Max number of results to return',
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
maxValue: 1000,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['person'],
|
||||
operation: ['getAll'],
|
||||
returnAll: [false],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Filters',
|
||||
name: 'filterFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['person'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Name of the person to filter by',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// person: update
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Person ID',
|
||||
name: 'personId',
|
||||
description: 'ID of the person to update',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['person'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Update Fields',
|
||||
name: 'updateFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['person'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
addressFixedCollection,
|
||||
{
|
||||
displayName: 'Details',
|
||||
name: 'details',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Description to set for the person',
|
||||
},
|
||||
{
|
||||
displayName: 'Email Domain',
|
||||
name: 'email_domain',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
emailsFixedCollection,
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Name to set for the person',
|
||||
},
|
||||
phoneNumbersFixedCollection,
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,271 @@
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
export const projectOperations: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['project'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Create',
|
||||
value: 'create',
|
||||
action: 'Create a project',
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
value: 'delete',
|
||||
action: 'Delete a project',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
action: 'Get a project',
|
||||
},
|
||||
{
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
action: 'Get many projects',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
value: 'update',
|
||||
action: 'Update a project',
|
||||
},
|
||||
],
|
||||
default: 'create',
|
||||
},
|
||||
];
|
||||
|
||||
export const projectFields: INodeProperties[] = [
|
||||
// ----------------------------------------
|
||||
// project: create
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
description: 'Name of the project to create',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['project'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
name: 'additionalFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['project'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Assignee ID',
|
||||
name: 'assignee_id',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'ID of the user who will own the project to create',
|
||||
},
|
||||
{
|
||||
displayName: 'Details',
|
||||
name: 'details',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Description of the project to create',
|
||||
},
|
||||
{
|
||||
displayName: 'Status',
|
||||
name: 'status',
|
||||
type: 'options',
|
||||
default: 'Open',
|
||||
options: [
|
||||
{
|
||||
name: 'Completed',
|
||||
value: 'Completed',
|
||||
},
|
||||
{
|
||||
name: 'Open',
|
||||
value: 'Open',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// project: delete
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Project ID',
|
||||
name: 'projectId',
|
||||
description: 'ID of the project to delete',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['project'],
|
||||
operation: ['delete'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// project: get
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Project ID',
|
||||
name: 'projectId',
|
||||
description: 'ID of the project to retrieve',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['project'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// project: getAll
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['project'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
default: 5,
|
||||
description: 'Max number of results to return',
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
maxValue: 1000,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['project'],
|
||||
operation: ['getAll'],
|
||||
returnAll: [false],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Filters',
|
||||
name: 'filterFields',
|
||||
type: 'collection',
|
||||
default: {},
|
||||
placeholder: 'Add Filter',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['project'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Name of the project to filter by',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// project: update
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Project ID',
|
||||
name: 'projectId',
|
||||
description: 'ID of the project to update',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['project'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Update Fields',
|
||||
name: 'updateFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['project'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Assignee ID',
|
||||
name: 'assignee_id',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'ID of the user who will own the project',
|
||||
},
|
||||
{
|
||||
displayName: 'Details',
|
||||
name: 'details',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Description to set for the project',
|
||||
},
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Name to set for the project',
|
||||
},
|
||||
{
|
||||
displayName: 'Status',
|
||||
name: 'status',
|
||||
type: 'options',
|
||||
default: 'Open',
|
||||
options: [
|
||||
{
|
||||
name: 'Completed',
|
||||
value: 'Completed',
|
||||
},
|
||||
{
|
||||
name: 'Open',
|
||||
value: 'Open',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,309 @@
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
export const taskOperations: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['task'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Create',
|
||||
value: 'create',
|
||||
action: 'Create a task',
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
value: 'delete',
|
||||
action: 'Delete a task',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
action: 'Get a task',
|
||||
},
|
||||
{
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
action: 'Get many tasks',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
value: 'update',
|
||||
action: 'Update a task',
|
||||
},
|
||||
],
|
||||
default: 'create',
|
||||
},
|
||||
];
|
||||
|
||||
export const taskFields: INodeProperties[] = [
|
||||
// ----------------------------------------
|
||||
// task: create
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['task'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
name: 'additionalFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['task'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Assignee ID',
|
||||
name: 'assignee_id',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'ID of the user who will own the task to create',
|
||||
},
|
||||
{
|
||||
displayName: 'Details',
|
||||
name: 'details',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Description of the task to create',
|
||||
},
|
||||
{
|
||||
displayName: 'Priority',
|
||||
name: 'priority',
|
||||
type: 'options',
|
||||
default: 'High',
|
||||
options: [
|
||||
{
|
||||
name: 'High',
|
||||
value: 'High',
|
||||
},
|
||||
{
|
||||
name: 'None',
|
||||
value: 'None',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Status',
|
||||
name: 'status',
|
||||
type: 'options',
|
||||
default: 'Open',
|
||||
options: [
|
||||
{
|
||||
name: 'Completed',
|
||||
value: 'Completed',
|
||||
},
|
||||
{
|
||||
name: 'Open',
|
||||
value: 'Open',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// task: delete
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Task ID',
|
||||
name: 'taskId',
|
||||
description: 'ID of the task to delete',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['task'],
|
||||
operation: ['delete'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// task: get
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Task ID',
|
||||
name: 'taskId',
|
||||
description: 'ID of the task to retrieve',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['task'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// task: getAll
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['task'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
default: 5,
|
||||
description: 'Max number of results to return',
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
maxValue: 1000,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['task'],
|
||||
operation: ['getAll'],
|
||||
returnAll: [false],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Filters',
|
||||
name: 'filterFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Filter',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['task'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Assignee IDs',
|
||||
name: 'assignee_ids',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Comma-separated IDs of assignee IDs to filter by',
|
||||
},
|
||||
{
|
||||
displayName: 'Project IDs',
|
||||
name: 'project_ids',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Comma-separated IDs of project IDs to filter by',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// task: update
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Task ID',
|
||||
name: 'taskId',
|
||||
description: 'ID of the task to update',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['task'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Update Fields',
|
||||
name: 'updateFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['task'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Assignee ID',
|
||||
name: 'assignee_id',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'ID of the user who will own the task',
|
||||
},
|
||||
{
|
||||
displayName: 'Details',
|
||||
name: 'details',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Description to set for the task',
|
||||
},
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Name to set for the task',
|
||||
},
|
||||
{
|
||||
displayName: 'Priority',
|
||||
name: 'priority',
|
||||
type: 'options',
|
||||
default: 'High',
|
||||
options: [
|
||||
{
|
||||
name: 'High',
|
||||
value: 'High',
|
||||
},
|
||||
{
|
||||
name: 'None',
|
||||
value: 'None',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Status',
|
||||
name: 'status',
|
||||
type: 'options',
|
||||
default: 'Open',
|
||||
options: [
|
||||
{
|
||||
name: 'Completed',
|
||||
value: 'Completed',
|
||||
},
|
||||
{
|
||||
name: 'Open',
|
||||
value: 'Open',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,60 @@
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
export const userOperations: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['user'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
action: 'Get many users',
|
||||
},
|
||||
],
|
||||
default: 'getAll',
|
||||
},
|
||||
];
|
||||
|
||||
export const userFields: INodeProperties[] = [
|
||||
// ----------------------------------------
|
||||
// user: getAll
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['user'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
default: 5,
|
||||
description: 'Max number of results to return',
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
maxValue: 1000,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['user'],
|
||||
operation: ['getAll'],
|
||||
returnAll: [false],
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,8 @@
|
||||
export * from './CompanyDescription';
|
||||
export * from './CustomerSourceDescription';
|
||||
export * from './LeadDescription';
|
||||
export * from './OpportunityDescription';
|
||||
export * from './PersonDescription';
|
||||
export * from './ProjectDescription';
|
||||
export * from './TaskDescription';
|
||||
export * from './UserDescription';
|
||||
@@ -0,0 +1,144 @@
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
// for companies, leads, persons
|
||||
export const addressFixedCollection: INodeProperties = {
|
||||
displayName: 'Address',
|
||||
name: 'address',
|
||||
placeholder: 'Add Address Fields',
|
||||
type: 'fixedCollection',
|
||||
default: {},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Address Fields',
|
||||
name: 'addressFields',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Street',
|
||||
name: 'street',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'City',
|
||||
name: 'city',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'State',
|
||||
name: 'state',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Postal Code',
|
||||
name: 'postal_code',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Country',
|
||||
name: 'country',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'ISO 3166 alpha-2 country code',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// for companies, leads, persons
|
||||
export const phoneNumbersFixedCollection: INodeProperties = {
|
||||
displayName: 'Phone Numbers',
|
||||
name: 'phone_numbers',
|
||||
placeholder: 'Add Phone Number',
|
||||
type: 'fixedCollection',
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
default: {},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Phone Fields',
|
||||
name: 'phoneFields',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Number',
|
||||
name: 'number',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Category',
|
||||
name: 'category',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// for persons, multiple emails
|
||||
export const emailsFixedCollection: INodeProperties = {
|
||||
displayName: 'Emails',
|
||||
name: 'emails',
|
||||
placeholder: 'Add Email',
|
||||
type: 'fixedCollection',
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
default: {},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Email Fields',
|
||||
name: 'emailFields',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Email',
|
||||
name: 'email',
|
||||
type: 'string',
|
||||
placeholder: 'name@email.com',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Category',
|
||||
name: 'category',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// for leads, single email
|
||||
export const emailFixedCollection: INodeProperties = {
|
||||
displayName: 'Email',
|
||||
name: 'email',
|
||||
placeholder: 'Add Email',
|
||||
type: 'fixedCollection',
|
||||
default: {},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Email Fields',
|
||||
name: 'emailFields',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Email',
|
||||
name: 'email',
|
||||
type: 'string',
|
||||
placeholder: 'name@email.com',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Category',
|
||||
name: 'category',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
export type EmailFixedCollection = {
|
||||
email?: {
|
||||
emailFields: Array<{ email: string; category: string }>;
|
||||
};
|
||||
};
|
||||
|
||||
export type EmailsFixedCollection = {
|
||||
emails?: {
|
||||
emailFields: Array<{ email: string; category: string }>;
|
||||
};
|
||||
};
|
||||
|
||||
export type PhoneNumbersFixedCollection = {
|
||||
phone_numbers?: {
|
||||
phoneFields: object;
|
||||
};
|
||||
};
|
||||
|
||||
export type AddressFixedCollection = {
|
||||
address?: {
|
||||
addressFields: object;
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user