Add support for multiple subscriptions in Hubspot Trigger (#1358)

*  Add support for multiple subscriptions in Hubspot Trigger

*  Load object properties for the user

*  Improvements

*  Some improvements to the Hubspot-Node

Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
This commit is contained in:
Ricardo Espinoza 2021-02-01 02:31:40 -05:00 committed by GitHub
parent 5549550928
commit dc98de1ab2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 2303 additions and 373 deletions

View file

@ -2,6 +2,18 @@
This list shows all the versions which include breaking changes and how to upgrade.
## 0.105.0
### What changed?
In the Hubspot Trigger, now multiple events can be provided and the field `App ID` was so moved to the credentials.
### When is action necessary?
If you are using the Hubspot Trigger node.
### How to upgrade:
Open the Hubspot Trigger and set the events again. Also open the credentials `Hubspot Developer API` and set your APP ID.
## 0.104.0
### What changed?

View file

@ -20,5 +20,13 @@ export class HubspotDeveloperApi implements ICredentialType {
type: 'string' as NodePropertyTypes,
default: '',
},
{
displayName: 'App ID',
name: 'appId',
type: 'string' as NodePropertyTypes,
required: true,
default: '',
description: 'The App ID',
},
];
}

View file

@ -1,6 +1,6 @@
import {
INodeProperties,
} from 'n8n-workflow';
} from 'n8n-workflow';
export const companyOperations = [
{
@ -63,9 +63,9 @@ export const companyOperations = [
export const companyFields = [
/* -------------------------------------------------------------------------- */
/* company:create */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* company:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'Name',
name: 'name',
@ -370,7 +370,7 @@ export const companyFields = [
description: 'The main website of the company or organization. This property is used to identify unique companies. Powered by HubSpot Insights.',
},
{
displayName: 'Year Founded',
displayName: 'Year Founded',
name: 'yearFounded',
type: 'string',
default: '',
@ -378,9 +378,10 @@ export const companyFields = [
},
],
},
/* -------------------------------------------------------------------------- */
/* company:update */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* company:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Company ID',
name: 'companyId',
@ -692,7 +693,7 @@ export const companyFields = [
description: 'The main website of the company or organization. This property is used to identify unique companies. Powered by HubSpot Insights.',
},
{
displayName: 'Year Founded',
displayName: 'Year Founded',
name: 'yearFounded',
type: 'string',
default: '',
@ -700,9 +701,10 @@ export const companyFields = [
},
],
},
/* -------------------------------------------------------------------------- */
/* company:get */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* company:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Company ID',
name: 'companyId',
@ -747,9 +749,10 @@ export const companyFields = [
},
],
},
/* -------------------------------------------------------------------------- */
/* company:getAll */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* company:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
@ -838,9 +841,10 @@ export const companyFields = [
},
],
},
/* -------------------------------------------------------------------------- */
/* company:delete */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* company:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'Company ID',
name: 'companyId',
@ -859,9 +863,10 @@ export const companyFields = [
default: '',
description: 'Unique identifier for a particular company',
},
/* -------------------------------------------------------------------------- */
/* company:getRecentlyCreated company:getRecentlyModifie */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* company:getRecentlyCreated company:getRecentlyModifie */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
@ -939,9 +944,10 @@ export const companyFields = [
},
],
},
/* -------------------------------------------------------------------------- */
/* company:searchByDomain */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* company:searchByDomain */
/* -------------------------------------------------------------------------- */
{
displayName: 'Domain',
name: 'domain',

View file

@ -1,6 +1,6 @@
import {
INodeProperties,
} from 'n8n-workflow';
} from 'n8n-workflow';
export const contactOperations = [
{
@ -53,9 +53,9 @@ export const contactOperations = [
export const contactFields = [
/* -------------------------------------------------------------------------- */
/* contact:upsert */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* contact:upsert */
/* -------------------------------------------------------------------------- */
{
displayName: 'Email',
name: 'email',
@ -121,7 +121,7 @@ export const contactFields = [
name: 'associatedCompanyId',
type: 'options',
typeOptions: {
loadOptionsMethod:'getCompanies' ,
loadOptionsMethod: 'getCompanies',
},
default: '',
description: 'Companies associated with the ticket',
@ -501,9 +501,10 @@ export const contactFields = [
},
],
},
/* -------------------------------------------------------------------------- */
/* contact:get */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* contact:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Contact ID',
name: 'contactId',
@ -603,9 +604,10 @@ export const contactFields = [
},
],
},
/* -------------------------------------------------------------------------- */
/* contact:getAll */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* contact:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
@ -728,9 +730,10 @@ export const contactFields = [
},
],
},
/* -------------------------------------------------------------------------- */
/* contact:delete */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* contact:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'Contact ID',
name: 'contactId',
@ -749,9 +752,10 @@ export const contactFields = [
default: '',
description: 'Unique identifier for a particular contact',
},
/* -------------------------------------------------------------------------- */
/* contact:getRecentlyCreatedUpdated */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* contact:getRecentlyCreatedUpdated */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
@ -875,9 +879,9 @@ export const contactFields = [
],
},
//*-------------------------------------------------------------------------- */
/* contact:search */
/* -------------------------------------------------------------------------- */
//*-------------------------------------------------------------------------- */
/* contact:search */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',

View file

@ -120,6 +120,7 @@ export const contactListFields = [
},
default: '',
},
/* -------------------------------------------------------------------------- */
/* contactList:remove */
/* -------------------------------------------------------------------------- */

View file

@ -1,6 +1,6 @@
import {
IDataObject,
} from 'n8n-workflow';
} from 'n8n-workflow';
export interface IAssociation {
associatedCompanyIds?: number[];

View file

@ -1,6 +1,6 @@
import {
INodeProperties,
} from 'n8n-workflow';
} from 'n8n-workflow';
export const formOperations = [
{
@ -33,9 +33,9 @@ export const formOperations = [
export const formFields = [
/* -------------------------------------------------------------------------- */
/* form:submit */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* form:submit */
/* -------------------------------------------------------------------------- */
{
displayName: 'Form',
name: 'formId',
@ -301,9 +301,10 @@ export const formFields = [
},
],
},
/* -------------------------------------------------------------------------- */
/* form:getFields */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* form:getFields */
/* -------------------------------------------------------------------------- */
{
displayName: 'Form',
name: 'formId',

View file

@ -1,6 +1,6 @@
import {
IDataObject,
} from 'n8n-workflow';
} from 'n8n-workflow';
export interface IContext {
goToWebinarWebinarKey?: string;

File diff suppressed because it is too large Load diff

View file

@ -63,7 +63,7 @@ export class Hubspot implements INodeType {
description: INodeTypeDescription = {
displayName: 'HubSpot',
name: 'hubspot',
icon: 'file:hubspot.png',
icon: 'file:hubspot.svg',
group: ['output'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',

View file

@ -5,27 +5,36 @@ import {
import {
IDataObject,
ILoadOptionsFunctions,
INodePropertyOptions,
INodeType,
INodeTypeDescription,
IWebhookResponseData,
} from 'n8n-workflow';
import {
companyFields,
contactFields,
dealFields,
hubspotApiRequest,
propertyEvents,
} from './GenericFunctions';
import {
createHash,
} from 'crypto';
} from 'crypto';
import {
capitalCase,
} from 'change-case';
export class HubspotTrigger implements INodeType {
description: INodeTypeDescription = {
displayName: 'HubSpot Trigger',
name: 'hubspotTrigger',
icon: 'file:hubspot.png',
icon: 'file:hubspot.svg',
group: ['trigger'],
version: 1,
subtitle: '={{($parameter["appId"]) ? $parameter["event"] : ""}}',
description: 'Starts the workflow when HubSpot events occur.',
defaults: {
name: 'Hubspot Trigger',
@ -55,87 +64,132 @@ export class HubspotTrigger implements INodeType {
],
properties: [
{
displayName: 'App ID',
name: 'appId',
type: 'string',
default: '',
required: true,
description: 'App ID',
},
{
displayName: 'Event',
name: 'event',
type: 'options',
displayName: 'Events',
name: 'eventsUi',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
placeholder: 'Add Event',
default: {},
options: [
{
name: 'contact.creation',
value: 'contact.creation',
description: `To get notified if any contact is created in a customer's account.`,
},
{
name: 'contact.deletion',
value: 'contact.deletion',
description: `To get notified if any contact is deleted in a customer's account.`,
},
{
name: 'contact.privacyDeletion',
value: 'contact.privacyDeletion',
description: `To get notified if a contact is deleted for privacy compliance reasons. `,
},
{
name: 'contact.propertyChange',
value: 'contact.propertyChange',
description: `to get notified if a specified property is changed for any contact in a customer's account. `,
},
{
name: 'company.creation',
value: 'company.creation',
description: `To get notified if any company is created in a customer's account.`,
},
{
name: 'company.deletion',
value: 'company.deletion',
description: `To get notified if any company is deleted in a customer's account.`,
},
{
name: 'company.propertyChange',
value: 'company.propertyChange',
description: `To get notified if a specified property is changed for any company in a customer's account.`,
},
{
name: 'deal.creation',
value: 'deal.creation',
description: `To get notified if any deal is created in a customer's account.`,
},
{
name: 'deal.deletion',
value: 'deal.deletion',
description: `To get notified if any deal is deleted in a customer's account.`,
},
{
name: 'deal.propertyChange',
value: 'deal.propertyChange',
description: `To get notified if a specified property is changed for any deal in a customer's account.`,
},
],
default: 'contact.creation',
required: true,
},
{
displayName: 'Property',
name: 'property',
type: 'string',
displayOptions: {
show: {
event: [
'contact.propertyChange',
'company.propertyChange',
'deal.propertyChange',
displayName: 'Event',
name: 'eventValues',
values: [
{
displayName: 'Name',
name: 'name',
type: 'options',
options: [
{
name: 'Contact Created',
value: 'contact.creation',
description: `To get notified if any contact is created in a customer's account.`,
},
{
name: 'Contact Deleted',
value: 'contact.deletion',
description: `To get notified if any contact is deleted in a customer's account.`,
},
{
name: 'Contact Privacy Deleted',
value: 'contact.privacyDeletion',
description: `To get notified if a contact is deleted for privacy compliance reasons. `,
},
{
name: 'Contact Property Changed',
value: 'contact.propertyChange',
description: `to get notified if a specified property is changed for any contact in a customer's account. `,
},
{
name: 'Company Created',
value: 'company.creation',
description: `To get notified if any company is created in a customer's account.`,
},
{
name: 'Company Deleted',
value: 'company.deletion',
description: `To get notified if any company is deleted in a customer's account.`,
},
{
name: 'Company Property Changed',
value: 'company.propertyChange',
description: `To get notified if a specified property is changed for any company in a customer's account.`,
},
{
name: 'Deal Created',
value: 'deal.creation',
description: `To get notified if any deal is created in a customer's account.`,
},
{
name: 'Deal Deleted',
value: 'deal.deletion',
description: `To get notified if any deal is deleted in a customer's account.`,
},
{
name: 'Deal Property Changed',
value: 'deal.propertyChange',
description: `To get notified if a specified property is changed for any deal in a customer's account.`,
},
],
default: 'contact.creation',
required: true,
},
{
displayName: 'Property',
name: 'property',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getContactProperties',
},
displayOptions: {
show: {
name: [
'contact.propertyChange',
],
},
},
default: '',
required: true,
},
{
displayName: 'Property',
name: 'property',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCompanyProperties',
},
displayOptions: {
show: {
name: [
'company.propertyChange',
],
},
},
default: '',
required: true,
},
{
displayName: 'Property',
name: 'property',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getDealProperties',
},
displayOptions: {
show: {
name: [
'deal.propertyChange',
],
},
},
default: '',
required: true,
},
],
},
},
default: '',
required: true,
],
},
{
displayName: 'Additional Fields',
@ -156,7 +210,62 @@ export class HubspotTrigger implements INodeType {
],
},
],
};
methods = {
loadOptions: {
// Get all the available contacts to display them to user so that he can
// select them easily
async getContactProperties(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
for (const field of contactFields) {
returnData.push({
name: capitalCase(field.label),
value: field.id,
});
}
returnData.sort((a, b) => {
if (a.name < b.name) { return -1; }
if (a.name > b.name) { return 1; }
return 0;
});
return returnData;
},
// Get all the available companies to display them to user so that he can
// select them easily
async getCompanyProperties(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
for (const field of companyFields) {
returnData.push({
name: capitalCase(field.label),
value: field.id,
});
}
returnData.sort((a, b) => {
if (a.name < b.name) { return -1; }
if (a.name > b.name) { return 1; }
return 0;
});
return returnData;
},
// Get all the available deals to display them to user so that he can
// select them easily
async getDealProperties(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
for (const field of dealFields) {
returnData.push({
name: capitalCase(field.label),
value: field.id,
});
}
returnData.sort((a, b) => {
if (a.name < b.name) { return -1; }
if (a.name > b.name) { return 1; }
return 0;
});
return returnData;
},
},
};
// @ts-ignore (because of request)
@ -165,80 +274,78 @@ export class HubspotTrigger implements INodeType {
async checkExists(this: IHookFunctions): Promise<boolean> {
// Check all the webhooks which exist already if it is identical to the
// one that is supposed to get created.
const app = parseInt(this.getNodeParameter('appId') as string, 10);
const event = this.getNodeParameter('event') as string;
const webhookUrlUi = this.getNodeWebhookUrl('default') as string;
let endpoint = `/webhooks/v1/${app}/settings`;
const { webhookUrl , appId } = await hubspotApiRequest.call(this, 'GET', endpoint, {});
endpoint = `/webhooks/v1/${app}/subscriptions`;
const subscriptions = await hubspotApiRequest.call(this, 'GET', endpoint, {});
for (const subscription of subscriptions) {
if (webhookUrl === webhookUrlUi
&& appId === app
&& subscription.subscriptionDetails.subscriptionType === event
&& subscription.enabled === true) {
return true;
const currentWebhookUrl = this.getNodeWebhookUrl('default') as string;
const { appId } = this.getCredentials('hubspotDeveloperApi') as IDataObject;
try {
const { targetUrl } = await hubspotApiRequest.call(this, 'GET', `/webhooks/v3/${appId}/settings`, {});
if (targetUrl !== currentWebhookUrl) {
throw new Error(`The APP ID ${appId} already has a target url ${targetUrl}. Delete it or use another APP ID before executing the trigger. Due to Hubspot API limitations, you can have just one trigger per APP.`);
}
} catch (error) {
if (error.statusCode === 404) {
return false;
}
}
// if the app is using the current webhook url. Delete everything and create it again with the current events
const { results: subscriptions } = await hubspotApiRequest.call(this, 'GET', `/webhooks/v3/${appId}/subscriptions`, {});
// delete all subscriptions
for (const subscription of subscriptions) {
await hubspotApiRequest.call(this, 'DELETE', `/webhooks/v3/${appId}/subscriptions/${subscription.id}`, {});
}
await hubspotApiRequest.call(this, 'DELETE', `/webhooks/v3/${appId}/settings`, {});
return false;
},
async create(this: IHookFunctions): Promise<boolean> {
const webhookUrl = this.getNodeWebhookUrl('default');
const app = this.getNodeParameter('appId') as string;
const event = this.getNodeParameter('event') as string;
const { appId } = this.getCredentials('hubspotDeveloperApi') as IDataObject;
const events = (this.getNodeParameter('eventsUi') as IDataObject || {}).eventValues as IDataObject[] || [];
const additionalFields = this.getNodeParameter('additionalFields') as IDataObject;
const propertyEvents = [
'contact.propertyChange',
'company.propertyChange',
'deal.propertyChange',
];
let endpoint = `/webhooks/v1/${app}/settings`;
let endpoint = `/webhooks/v3/${appId}/settings`;
let body: IDataObject = {
webhookUrl,
targetUrl: webhookUrl,
maxConcurrentRequests: additionalFields.maxConcurrentRequests || 5,
};
await hubspotApiRequest.call(this, 'PUT', endpoint, body);
endpoint = `/webhooks/v1/${app}/subscriptions`;
body = {
subscriptionDetails: {
subscriptionType: event,
},
enabled: true,
};
if (propertyEvents.includes(event)) {
const property = this.getNodeParameter('property') as string;
//@ts-ignore
body.subscriptionDetails.propertyName = property;
endpoint = `/webhooks/v3/${appId}/subscriptions`;
if (Array.isArray(events) && events.length === 0) {
throw new Error(`You must define at least one event`);
}
const responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body);
if (responseData.id === undefined) {
// Required data is missing so was not successful
return false;
for (const event of events) {
body = {
eventType: event.name,
active: true,
};
if (propertyEvents.includes(event.name as string)) {
const property = event.property;
body.propertyName = property;
}
await hubspotApiRequest.call(this, 'POST', endpoint, body);
}
const webhookData = this.getWorkflowStaticData('node');
webhookData.webhookId = responseData.id as string;
return true;
},
async delete(this: IHookFunctions): Promise<boolean> {
const webhookData = this.getWorkflowStaticData('node');
const app = this.getNodeParameter('appId') as string;
if (webhookData.webhookId !== undefined) {
const endpoint = `/webhooks/v1/${app}/subscriptions/${webhookData.webhookId}`;
const { appId } = this.getCredentials('hubspotDeveloperApi') as IDataObject;
const body = {};
const { results: subscriptions } = await hubspotApiRequest.call(this, 'GET', `/webhooks/v3/${appId}/subscriptions`, {});
try {
await hubspotApiRequest.call(this, 'DELETE', endpoint, body);
} catch (e) {
return false;
}
// Remove from the static workflow data so that it is clear
// that no webhooks are registred anymore
delete webhookData.webhookId;
for (const subscription of subscriptions) {
await hubspotApiRequest.call(this, 'DELETE', `/webhooks/v3/${appId}/subscriptions/${subscription.id}`, {});
}
try {
await hubspotApiRequest.call(this, 'DELETE', `/webhooks/v3/${appId}/settings`, {});
} catch (e) {
return false;
}
return true;
},
@ -265,7 +372,7 @@ export class HubspotTrigger implements INodeType {
if (credentials.clientSecret !== '') {
const hash = `${credentials!.clientSecret}${JSON.stringify(bodyData)}`;
const signature = createHash('sha256').update(hash).digest('hex');
const signature = createHash('sha256').update(hash).digest('hex');
//@ts-ignore
if (signature !== headerData['x-hubspot-signature']) {
return {};

View file

@ -1,6 +1,6 @@
import {
INodeProperties,
} from 'n8n-workflow';
} from 'n8n-workflow';
export const ticketOperations = [
{
@ -48,9 +48,9 @@ export const ticketOperations = [
export const ticketFields = [
/* -------------------------------------------------------------------------- */
/* ticket:create */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* ticket:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'Pipeline ID',
name: 'pipelineId',
@ -70,7 +70,7 @@ export const ticketFields = [
},
},
default: '',
description: 'The ID of the pipeline the ticket is in. ',
description: 'The ID of the pipeline the ticket is in.',
},
{
displayName: 'Stage ID',
@ -94,7 +94,7 @@ export const ticketFields = [
},
},
default: '',
description: 'The ID of the pipeline the ticket is in. ',
description: 'The ID of the pipeline the ticket is in.',
},
{
displayName: 'Ticket Name',
@ -112,7 +112,7 @@ export const ticketFields = [
},
},
default: '',
description: 'The ID of the pipeline the ticket is in. ',
description: 'The ID of the pipeline the ticket is in.',
},
{
displayName: 'Additional Fields',
@ -136,7 +136,7 @@ export const ticketFields = [
name: 'associatedCompanyIds',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod:'getCompanies' ,
loadOptionsMethod: 'getCompanies',
},
default: [],
description: 'Companies associated with the ticket',
@ -146,7 +146,7 @@ export const ticketFields = [
name: 'associatedContactIds',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod:'getContacts' ,
loadOptionsMethod: 'getContacts',
},
default: [],
description: 'Contacts associated with the ticket',
@ -228,9 +228,9 @@ export const ticketFields = [
},
],
},
/* -------------------------------------------------------------------------- */
/* ticket:update */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* ticket:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Ticket ID',
name: 'ticketId',
@ -247,7 +247,7 @@ export const ticketFields = [
},
},
default: '',
description: 'Unique identifier for a particular ticket',
description: 'Unique identifier for a particular ticket.',
},
{
displayName: 'Update Fields',
@ -271,20 +271,20 @@ export const ticketFields = [
name: 'associatedCompanyIds',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod:'getCompanies' ,
loadOptionsMethod: 'getCompanies',
},
default: [],
description: 'Companies associated with the ticket',
description: 'Companies associated with the ticket.',
},
{
displayName: 'Contact Ids',
name: 'associatedContactIds',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod:'getContacts' ,
loadOptionsMethod: 'getContacts',
},
default: [],
description: 'Contact associated with the ticket',
description: 'Contact associated with the ticket.',
},
{
displayName: 'Category',
@ -294,21 +294,21 @@ export const ticketFields = [
loadOptionsMethod: 'getTicketCategories',
},
default: '',
description: 'Main reason customer reached out for help',
description: 'Main reason customer reached out for help.',
},
{
displayName: 'Close Date',
name: 'closeDate',
type: 'dateTime',
default: '',
description: 'The date the ticket was closed',
description: 'The date the ticket was closed.',
},
{
displayName: 'Create Date',
name: 'createDate',
type: 'dateTime',
default: '',
description: 'the date the ticket was created',
description: 'The date the ticket was created.',
},
{
displayName: 'Description',
@ -328,7 +328,7 @@ export const ticketFields = [
loadOptionsMethod: 'getTicketPipelines',
},
default: '',
description: 'The ID of the pipeline the ticket is in. ',
description: 'The ID of the pipeline the ticket is in.',
},
{
displayName: 'Priority',
@ -358,7 +358,7 @@ export const ticketFields = [
loadOptionsMethod: 'getTicketSources',
},
default: '',
description: 'Channel where ticket was originally submitted',
description: 'Channel where ticket was originally submitted.',
},
{
displayName: 'Ticket Name',
@ -380,176 +380,179 @@ export const ticketFields = [
},
],
},
/* -------------------------------------------------------------------------- */
/* ticket:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Ticket ID',
name: 'ticketId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: [
'ticket',
],
operation: [
'get',
],
},
},
default: '',
description: 'Unique identifier for a particular ticket',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'ticket',
],
operation: [
'get',
],
},
},
options: [
{
displayName: 'Include Deleted',
name: 'includeDeleted',
type: 'boolean',
default: false,
},
{
displayName: 'Properties',
name: 'properties',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getTicketProperties',
/* -------------------------------------------------------------------------- */
/* ticket:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Ticket ID',
name: 'ticketId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: [
'ticket',
],
operation: [
'get',
],
},
default: [],
description: `Used to include specific ticket properties in the results.<br/>
},
default: '',
description: 'Unique identifier for a particular ticket',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'ticket',
],
operation: [
'get',
],
},
},
options: [
{
displayName: 'Include Deleted',
name: 'includeDeleted',
type: 'boolean',
default: false,
},
{
displayName: 'Properties',
name: 'properties',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getTicketProperties',
},
default: [],
description: `Used to include specific ticket properties in the results.<br/>
By default, the results will only include ticket ID and will not include the values for any properties for your tickets.<br/>
Including this parameter will include the data for the specified property in the results.<br/>
You can include this parameter multiple times to request multiple properties separed by ,.`,
},
{
displayName: 'Properties With History',
name: 'propertiesWithHistory',
type: 'string',
default: '',
description: `Works similarly to properties=, but this parameter will include the history for the specified property,<br/>
instead of just including the current value. Use this parameter when you need the full history of changes to a property's value.`,
},
],
},
/* -------------------------------------------------------------------------- */
/* ticket:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: [
'ticket',
],
operation: [
'getAll',
],
},
},
default: false,
description: 'If all results should be returned or only up to a given limit.',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: [
'ticket',
],
operation: [
'getAll',
],
returnAll: [
false,
],
},
},
typeOptions: {
minValue: 1,
maxValue: 250,
},
default: 100,
description: 'How many results to return.',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'ticket',
],
operation: [
'getAll',
],
},
},
options: [
{
displayName: 'Properties',
name: 'properties',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getTicketProperties',
},
default: [],
description: `Used to include specific ticket properties in the results.<br/>
{
displayName: 'Properties With History',
name: 'propertiesWithHistory',
type: 'string',
default: '',
description: `Works similarly to properties=, but this parameter will include the history for the specified property,<br/>
instead of just including the current value. Use this parameter when you need the full history of changes to a property's value.`,
},
],
},
/* -------------------------------------------------------------------------- */
/* ticket:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: [
'ticket',
],
operation: [
'getAll',
],
},
},
default: false,
description: 'If all results should be returned or only up to a given limit.',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: [
'ticket',
],
operation: [
'getAll',
],
returnAll: [
false,
],
},
},
typeOptions: {
minValue: 1,
maxValue: 250,
},
default: 100,
description: 'How many results to return.',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'ticket',
],
operation: [
'getAll',
],
},
},
options: [
{
displayName: 'Properties',
name: 'properties',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getTicketProperties',
},
default: [],
description: `Used to include specific ticket properties in the results.<br/>
By default, the results will only include ticket ID and will not include the values for any properties for your tickets.<br/>
Including this parameter will include the data for the specified property in the results.<br/>
You can include this parameter multiple times to request multiple properties separed by ,.`,
},
{
displayName: 'Properties With History',
name: 'propertiesWithHistory',
type: 'string',
default: '',
description: `Works similarly to properties=, but this parameter will include the history for the specified property,<br/>
},
{
displayName: 'Properties With History',
name: 'propertiesWithHistory',
type: 'string',
default: '',
description: `Works similarly to properties=, but this parameter will include the history for the specified property,<br/>
instead of just including the current value. Use this parameter when you need the full history of changes to a property's value.`,
},
],
},
/* -------------------------------------------------------------------------- */
/* ticket:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'Ticket ID',
name: 'ticketId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: [
'ticket',
],
operation: [
'delete',
],
},
},
],
},
/* -------------------------------------------------------------------------- */
/* ticket:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'Ticket ID',
name: 'ticketId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: [
'ticket',
],
operation: [
'delete',
],
},
},
default: '',
description: 'Unique identifier for a particular ticket',
},
default: '',
description: 'Unique identifier for a particular ticket',
},
] as INodeProperties[];

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,022 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 62.883 69.883" fill="#fff" fill-rule="evenodd" stroke="#000" stroke-linecap="round" stroke-linejoin="round"><use xlink:href="#A" x="2.442" y="2.442"/><symbol id="A" overflow="visible"><path d="M55.504 30.401a16.26 16.26 0 0 0-5.904-5.864c-1.865-1.084-3.794-1.773-5.972-2.07v-7.798c2.161-.895 3.558-3.018 3.525-5.357a5.86 5.86 0 0 0-5.859-5.889 5.91 5.91 0 0 0-5.908 5.889c0 2.393 1.27 4.434 3.452 5.357v7.754c-1.808.262-3.562.812-5.195 1.631L12.769 8.247c.146-.552.273-1.123.273-1.724C13.042 2.92 10.122 0 6.519 0A6.52 6.52 0 0 0 0 6.524c0 3.604 2.92 6.524 6.524 6.524a6.47 6.47 0 0 0 3.35-.952l1.367 1.035 18.726 13.501c-.991.908-1.914 1.943-2.651 3.105-1.494 2.368-2.407 4.971-2.407 7.813v.586c.007 1.927.354 3.838 1.025 5.645.566 1.543 1.396 2.949 2.427 4.219l-6.221 6.235c-1.841-.684-3.906-.23-5.298 1.162-.947.942-1.48 2.227-1.475 3.565s.527 2.612 1.479 3.564 2.227 1.48 3.565 1.48a5.01 5.01 0 0 0 3.565-1.48c.942-.952 1.479-2.227 1.475-3.564a5.03 5.03 0 0 0-.234-1.514l6.426-6.426a16.09 16.09 0 0 0 2.856 1.563 16.7 16.7 0 0 0 6.685 1.406h.439a15.76 15.76 0 0 0 7.627-1.929 15.77 15.77 0 0 0 5.977-5.63c1.499-2.393 2.319-5.044 2.319-7.959v-.146c0-2.866-.664-5.508-2.051-7.93zm-7.847 13.487c-1.743 1.938-3.75 3.135-6.016 3.135h-.43c-1.294 0-2.564-.356-3.799-1.011a8.79 8.79 0 0 1-3.33-3.032c-.898-1.27-1.387-2.656-1.387-4.126v-.439c0-1.445.278-2.817.977-4.111.747-1.465 1.758-2.515 3.101-3.389a7.6 7.6 0 0 1 4.297-1.294h.147c1.416 0 2.769.278 4.038.928 1.286.677 2.378 1.67 3.174 2.886a9.18 9.18 0 0 1 1.421 4.053l.034.913c0 1.987-.762 3.828-2.28 5.498z" stroke="none" fill="#f8761f" fill-rule="nonzero"/></symbol></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB