UNPKG

n8n-nodes-base

Version:

Base nodes of n8n

1,195 lines 57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Freshdesk = void 0; const n8n_workflow_1 = require("n8n-workflow"); const ContactDescription_1 = require("./ContactDescription"); const GenericFunctions_1 = require("./GenericFunctions"); const Status = { Open: 2, Pending: 3, Resolved: 4, Closed: 5, }; const Priority = { Low: 1, Medium: 2, High: 3, Urgent: 4, }; const Source = { Email: 1, Portal: 2, Phone: 3, Chat: 7, Mobihelp: 8, FeedbackWidget: 9, OutboundEmail: 10, }; class Freshdesk { description = { displayName: 'Freshdesk', name: 'freshdesk', icon: 'file:freshdesk.svg', group: ['output'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', description: 'Consume Freshdesk API', defaults: { name: 'Freshdesk', }, usableAsTool: true, inputs: [n8n_workflow_1.NodeConnectionTypes.Main], outputs: [n8n_workflow_1.NodeConnectionTypes.Main], credentials: [ { name: 'freshdeskApi', required: true, }, ], properties: [ { displayName: 'Resource', name: 'resource', type: 'options', noDataExpression: true, required: true, options: [ { name: 'Contact', value: 'contact', }, { name: 'Ticket', value: 'ticket', }, ], default: 'ticket', }, { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, required: true, displayOptions: { show: { resource: ['ticket'], }, }, options: [ { name: 'Create', value: 'create', description: 'Create a new ticket', action: 'Create a ticket', }, { name: 'Delete', value: 'delete', description: 'Delete a ticket', action: 'Delete a ticket', }, { name: 'Get', value: 'get', description: 'Get a ticket', action: 'Get a ticket', }, { name: 'Get Many', value: 'getAll', description: 'Get many tickets', action: 'Get many tickets', }, { name: 'Update', value: 'update', description: 'Update a ticket', action: 'Update a ticket', }, ], default: 'create', }, { displayName: 'Requester Identification', name: 'requester', type: 'options', required: true, displayOptions: { show: { resource: ['ticket'], operation: ['create'], }, }, options: [ { name: 'Email', value: 'email', description: 'Email address of the requester. If no contact exists with this email address in Freshdesk, it will be added as a new contact.', }, { name: 'Facebook ID', value: 'facebookId', description: 'Facebook ID of the requester. If no contact exists with this facebook_id, then a new contact will be created.', }, { name: 'Phone', value: 'phone', description: 'Phone number of the requester. If no contact exists with this phone number in Freshdesk, it will be added as a new contact. If the phone number is set and the email address is not, then the name attribute is mandatory.', }, { name: 'Requester ID', value: 'requesterId', description: "User ID of the requester. For existing contacts, the requester_id can be passed instead of the requester's email.", }, { name: 'Twitter ID', value: 'twitterId', description: 'Twitter handle of the requester. If no contact exists with this handle in Freshdesk, it will be added as a new contact.', }, { name: 'Unique External ID', value: 'uniqueExternalId', description: 'External ID of the requester. If no contact exists with this external ID in Freshdesk, they will be added as a new contact.', }, ], default: 'requesterId', }, { displayName: 'Value', name: 'requesterIdentificationValue', type: 'string', required: true, displayOptions: { show: { resource: ['ticket'], operation: ['create'], }, }, default: '', description: 'Value of the identification selected', }, { displayName: 'Status', name: 'status', type: 'options', required: true, displayOptions: { show: { resource: ['ticket'], operation: ['create'], }, }, options: [ { name: 'Closed', value: 'closed', }, { name: 'Open', value: 'open', }, { name: 'Pending', value: 'pending', }, { name: 'Resolved', value: 'resolved', }, ], default: 'pending', }, { displayName: 'Priority', name: 'priority', type: 'options', required: true, displayOptions: { show: { resource: ['ticket'], operation: ['create'], }, }, options: [ { name: 'Low', value: 'low', }, { name: 'Medium', value: 'medium', }, { name: 'High', value: 'high', }, { name: 'Urgent', value: 'urgent', }, ], default: 'low', }, { displayName: 'Source', name: 'source', type: 'options', required: true, displayOptions: { show: { resource: ['ticket'], operation: ['create'], }, }, options: [ { name: 'Chat', value: 'chat', }, { name: 'Email', value: 'email', }, { name: 'Feedback Widget', value: 'feedbackWidget', }, { name: 'Mobihelp', value: 'mobileHelp', }, { name: 'Outbound Email', value: 'OutboundEmail', }, { name: 'Phone', value: 'phone', }, { name: 'Portal', value: 'portal', }, ], default: 'portal', description: 'The channel through which the ticket was created', }, // { // displayName: 'JSON Parameters', // name: 'jsonParameters', // type: 'boolean', // default: false, // description: '', // displayOptions: { // show: { // resource: [ // 'ticket' // ], // operation: [ // 'create', // ] // }, // }, // }, { displayName: 'Options', name: 'options', type: 'collection', placeholder: 'Add option', default: {}, displayOptions: { show: { resource: ['ticket'], operation: ['create'], }, }, options: [ { displayName: 'Agent Name or ID', name: 'agent', type: 'options', default: '', typeOptions: { loadOptionsMethod: 'getAgents', }, description: 'ID of the agent to whom the ticket has been assigned. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.', }, { displayName: 'CC Emails', name: 'ccEmails', type: 'string', default: '', description: "Separated by a comma (,) email addresses added in the 'cc' field of the incoming ticket email", }, { displayName: 'Company Name or ID', name: 'company', type: 'options', default: '', typeOptions: { loadOptionsMethod: 'getCompanies', }, description: 'Company ID of the requester. This attribute can only be set if the Multiple Companies feature is enabled (Estate plan and above). Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.', }, { displayName: 'Description', name: 'description', type: 'string', default: '', typeOptions: { rows: 5, }, description: 'HTML content of the ticket', }, { displayName: 'Due By', name: 'dueBy', type: 'dateTime', default: '', description: 'Timestamp that denotes when the ticket is due to be resolved', }, { displayName: 'Email Config ID', name: 'emailConfigId', type: 'number', default: '', description: "ID of email config which is used for this ticket. (i.e., support@yourcompany.com/sales@yourcompany.com) If product_id is given and email_config_id is not given, product's primary email_config_id will be set.", }, { displayName: 'FR Due By', name: 'frDueBy', type: 'dateTime', default: '', description: 'Timestamp that denotes when the first response is due', }, { displayName: 'Group Name or ID', name: 'group', type: 'options', default: '', typeOptions: { loadOptionsMethod: 'getGroups', }, description: 'ID of the group to which the ticket has been assigned. The default value is the ID of the group that is associated with the given email_config_id. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.', }, { displayName: 'Name', name: 'name', type: 'string', default: '', placeholder: '', description: 'Name of the requester', }, { displayName: 'Product Name or ID', name: 'product', type: 'options', default: '', typeOptions: { loadOptionsMethod: 'getProducts', }, description: 'ID of the product to which the ticket is associated. It will be ignored if the email_config_id attribute is set in the request. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.', }, { displayName: 'Subject', name: 'subject', type: 'string', default: '', placeholder: '', description: 'Subject of the ticket', }, { displayName: 'Tags', name: 'tags', type: 'string', default: '', description: 'Separated by a comma (,) tags that have been associated with the ticket', }, { displayName: 'Type', name: 'type', type: 'options', default: 'Question', description: 'Helps categorize the ticket according to the different kinds of issues your support team deals with', options: [ { name: 'Feature Request', value: 'Feature Request', }, { name: 'Incident', value: 'Incident', }, { name: 'Problem', value: 'Problem', }, { name: 'Question', value: 'Question', }, { name: 'Refund', value: 'Refund', }, ], }, ], }, // { // displayName: 'Custom Fields', // name: 'customFieldsUi', // placeholder: 'Add Custom fields', // type: 'fixedCollection', // required: false, // default: '', // typeOptions: { // multipleValues: true, // }, // displayOptions: { // show: { // resource: [ // 'ticket' // ], // operation: [ // 'create' // ], // jsonParameters: [ // false, // ], // }, // }, // description: 'Key value pairs containing the names and values of custom fields.', // options: [ // { // name: 'customFieldsValues', // displayName: 'Custom fields', // values: [ // { // displayName: 'Key', // required: false, // name: 'key', // type: 'string', // default: '', // }, // { // displayName: 'Value', // name: 'value', // type: 'string', // required: false, // default: '', // }, // ], // }, // ], // }, // { // displayName: 'Custom Fields', // name: 'customFieldsJson', // type: 'json', // typeOptions: { // alwaysOpenEditWindow: true, // }, // displayOptions: { // show: { // resource: [ // 'ticket', // ], // operation: [ // 'create', // ], // jsonParameters: [ // true, // ], // }, // }, // default: '', // required: false, // placeholder: `{ // 'gadget': 'Cold Welder', // }`, // description: 'Key value pairs containing the names and values of custom fields.', // }, { displayName: 'Ticket ID', name: 'ticketId', type: 'string', required: true, displayOptions: { show: { resource: ['ticket'], operation: ['update'], }, }, default: '', }, { displayName: 'Update Fields', name: 'updateFields', type: 'collection', placeholder: 'Add Field', default: {}, displayOptions: { show: { resource: ['ticket'], operation: ['update'], }, }, options: [ { displayName: 'Agent Name or ID', name: 'agent', type: 'options', default: '', typeOptions: { loadOptionsMethod: 'getAgents', }, description: 'ID of the agent to whom the ticket has been assigned. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.', }, { displayName: 'CC Emails', name: 'ccEmails', type: 'string', default: '', description: "Separated by a comma (,) email addresses added in the 'cc' field of the incoming ticket email", }, { displayName: 'Company Name or ID', name: 'company', type: 'options', default: '', typeOptions: { loadOptionsMethod: 'getCompanies', }, description: 'Company ID of the requester. This attribute can only be set if the Multiple Companies feature is enabled (Estate plan and above). Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.', }, { displayName: 'Due By', name: 'dueBy', type: 'dateTime', default: '', description: 'Timestamp that denotes when the ticket is due to be resolved', }, { displayName: 'Email Config ID', name: 'emailConfigId', type: 'number', default: '', description: "ID of email config which is used for this ticket. (i.e., support@yourcompany.com/sales@yourcompany.com) If product_id is given and email_config_id is not given, product's primary email_config_id will be set.", }, { displayName: 'FR Due By', name: 'frDueBy', type: 'dateTime', default: '', description: 'Timestamp that denotes when the first response is due', }, { displayName: 'Group Name or ID', name: 'group', type: 'options', default: '', typeOptions: { loadOptionsMethod: 'getGroups', }, description: 'ID of the group to which the ticket has been assigned. The default value is the ID of the group that is associated with the given email_config_id. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.', }, { displayName: 'Name', name: 'name', type: 'string', default: '', placeholder: '', description: 'Name of the requester', }, { displayName: 'Product Name or ID', name: 'product', type: 'options', default: '', typeOptions: { loadOptionsMethod: 'getProducts', }, description: 'ID of the product to which the ticket is associated. It will be ignored if the email_config_id attribute is set in the request. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.', }, { displayName: 'Priority', name: 'priority', type: 'options', options: [ { name: 'Low', value: 'low', }, { name: 'Medium', value: 'medium', }, { name: 'High', value: 'high', }, { name: 'Urgent', value: 'urgent', }, ], default: 'low', }, { displayName: 'Requester Identification', name: 'requester', type: 'options', options: [ { name: 'Email', value: 'email', description: 'Email address of the requester. If no contact exists with this email address in Freshdesk, it will be added as a new contact.', }, { name: 'Facebook ID', value: 'facebookId', description: 'Facebook ID of the requester. If no contact exists with this facebook_id, then a new contact will be created.', }, { name: 'Phone', value: 'phone', description: 'Phone number of the requester. If no contact exists with this phone number in Freshdesk, it will be added as a new contact. If the phone number is set and the email address is not, then the name attribute is mandatory.', }, { name: 'Requester ID', value: 'requesterId', description: "User ID of the requester. For existing contacts, the requester_id can be passed instead of the requester's email.", }, { name: 'Twitter ID', value: 'twitterId', description: 'Twitter handle of the requester. If no contact exists with this handle in Freshdesk, it will be added as a new contact.', }, { name: 'Unique External ID', value: 'uniqueExternalId', description: 'External ID of the requester. If no contact exists with this external ID in Freshdesk, they will be added as a new contact.', }, ], default: 'requesterId', }, { displayName: 'Requester Value', name: 'requesterIdentificationValue', type: 'string', default: '', description: 'Value of the identification selected', }, { displayName: 'Status', name: 'status', type: 'options', options: [ { name: 'Open', value: 'open', }, { name: 'Pending', value: 'pending', }, { name: 'Resolved', value: 'resolved', }, { name: 'Closed', value: 'closed', }, ], default: 'pending', }, { displayName: 'Source', name: 'source', type: 'options', options: [ { name: 'Chat', value: 'chat', }, { name: 'Email', value: 'email', }, { name: 'Feedback Widget', value: 'feedbackWidget', }, { name: 'Mobihelp', value: 'mobileHelp', }, { name: 'Outbound Email', value: 'OutboundEmail', }, { name: 'Phone', value: 'phone', }, { name: 'Portal', value: 'portal', }, ], default: 'portal', description: 'The channel through which the ticket was created', }, { displayName: 'Tags', name: 'tags', type: 'string', default: '', description: 'Separated by a comma (,) tags that have been associated with the ticket', }, { displayName: 'Type', name: 'type', type: 'options', default: 'Question', description: 'Helps categorize the ticket according to the different kinds of issues your support team deals with', options: [ { name: 'Feature Request', value: 'Feature Request', }, { name: 'Incident', value: 'Incident', }, { name: 'Problem', value: 'Problem', }, { name: 'Question', value: 'Question', }, { name: 'Refund', value: 'Refund', }, ], }, ], }, { displayName: 'Ticket ID', name: 'ticketId', type: 'string', required: true, displayOptions: { show: { resource: ['ticket'], operation: ['get'], }, }, default: '', }, { displayName: 'Return All', name: 'returnAll', type: 'boolean', displayOptions: { show: { resource: ['ticket'], operation: ['getAll'], }, }, default: false, description: 'Whether to return all results 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: 10, }, default: 5, description: 'Max number of results to return', }, { displayName: 'Options', name: 'options', type: 'collection', placeholder: 'Add option', default: {}, displayOptions: { show: { resource: ['ticket'], operation: ['getAll'], }, }, options: [ { displayName: 'Company ID', name: 'companyId', type: 'string', default: '', }, { displayName: 'Include', name: 'include', type: 'multiOptions', options: [ { name: 'Company', value: 'company', }, { name: 'Description', value: 'description', }, { name: 'Requester', value: 'requester', }, { name: 'Stats', value: 'stats', }, ], default: [], }, { displayName: 'Order', name: 'order', type: 'options', options: [ { name: 'ASC', value: 'asc', }, { name: 'DESC', value: 'desc', }, ], default: 'desc', description: 'Order sort attribute ascending or descending', }, { displayName: 'Order By', name: 'orderBy', type: 'options', options: [ { name: 'Created At', value: 'createdAt', }, { name: 'Due By', value: 'dueBy', }, { name: 'Updated At', value: 'updatedAt', }, ], default: '', description: 'Sort collection by object attribute', }, { displayName: 'Requester Email', name: 'requesterEmail', type: 'string', default: '', }, { displayName: 'Requester ID', name: 'requesterId', type: 'string', default: '', }, { displayName: 'Updated Since', name: 'updatedSince', type: 'dateTime', default: '', }, ], }, { displayName: 'Ticket ID', name: 'ticketId', type: 'string', required: true, displayOptions: { show: { resource: ['ticket'], operation: ['delete'], }, }, default: '', }, // CONTACTS ...ContactDescription_1.contactOperations, ...ContactDescription_1.contactFields, ], }; methods = { loadOptions: { // Get all the agents to display them to user so that they can // select them easily async getAgents() { const returnData = []; const agents = await GenericFunctions_1.freshdeskApiRequest.call(this, 'GET', '/agents'); for (const agent of agents) { const agentName = agent.contact.name; const agentId = agent.id; returnData.push({ name: agentName, value: agentId, }); } return returnData; }, // Get all the groups to display them to user so that they can // select them easily async getGroups() { const returnData = []; const groups = await GenericFunctions_1.freshdeskApiRequest.call(this, 'GET', '/groups'); for (const group of groups) { const groupName = group.name; const groupId = group.id; returnData.push({ name: groupName, value: groupId, }); } return returnData; }, // Get all the products to display them to user so that they can // select them easily async getProducts() { const returnData = []; const products = await GenericFunctions_1.freshdeskApiRequest.call(this, 'GET', '/products'); for (const product of products) { const productName = product.name; const productId = product.id; returnData.push({ name: productName, value: productId, }); } return returnData; }, // Get all the companies to display them to user so that they can // select them easily async getCompanies() { const returnData = []; const companies = await GenericFunctions_1.freshdeskApiRequest.call(this, 'GET', '/companies'); for (const company of companies) { const companyName = company.name; const companyId = company.id; returnData.push({ name: companyName, value: companyId, }); } return returnData; }, }, }; async execute() { const items = this.getInputData(); const returnData = []; let responseData; const qs = {}; const resource = this.getNodeParameter('resource', 0); const operation = this.getNodeParameter('operation', 0); for (let i = 0; i < items.length; i++) { try { if (resource === 'ticket') { //https://developers.freshdesk.com/api/#create_ticket if (operation === 'create') { const requester = this.getNodeParameter('requester', i); const value = this.getNodeParameter('requesterIdentificationValue', i); const status = this.getNodeParameter('status', i); const priority = this.getNodeParameter('priority', i); const source = this.getNodeParameter('source', i); const options = this.getNodeParameter('options', i); //const jsonActive = this.getNodeParameter('jsonParameters') as boolean; const body = { status: Status[(0, GenericFunctions_1.capitalize)(status)], priority: Priority[(0, GenericFunctions_1.capitalize)(priority)], source: Source[(0, GenericFunctions_1.capitalize)(source)], }; if (requester === 'requesterId') { // @ts-ignore if (isNaN(value)) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Requester Id must be a number', { itemIndex: i, }); } body.requester_id = parseInt(value, 10); } else if (requester === 'email') { body.email = value; } else if (requester === 'facebookId') { body.facebook_id = value; } else if (requester === 'phone') { body.phone = value; } else if (requester === 'twitterId') { body.twitter_id = value; } else if (requester === 'uniqueExternalId') { body.unique_external_id = value; } // if (!jsonActive) { // const customFieldsUi = this.getNodeParameter('customFieldsUi') as IDataObject; // if (Object.keys(customFieldsUi).length > 0) { // const aux: IDataObject = {}; // // @ts-ignore // customFieldsUi.customFieldsValues.forEach( o => { // aux[`${o.key}`] = o.value; // return aux; // }); // body.custom_fields = aux; // } else { // body.custom_fields = validateJSON(this.getNodeParameter('customFielsJson') as string); // } if (options.name) { body.name = options.name; } if (options.subject) { body.subject = options.subject; } else { body.subject = 'null'; } if (options.type) { body.type = options.type; } if (options.description) { body.description = options.description; } else { body.description = 'null'; } if (options.agent) { body.responder_id = options.agent; } if (options.company) { body.company_id = options.company; } if (options.product) { body.product_id = options.product; } if (options.group) { body.group_id = options.group; } if (options.frDueBy) { body.fr_due_by = options.frDueBy; } if (options.emailConfigId) { body.email_config_id = options.emailConfigId; } if (options.dueBy) { body.due_by = options.dueBy; } if (options.tags) { body.tags = options.tags.split(','); } if (options.ccEmails) { body.cc_emails = options.ccEmails.split(','); } responseData = await GenericFunctions_1.freshdeskApiRequest.call(this, 'POST', '/tickets', body); } //https://developers.freshdesk.com/api/#update_ticket if (operation === 'update') { const ticketId = this.getNodeParameter('ticketId', i); const updateFields = this.getNodeParameter('updateFields', i); const body = {}; if (updateFields.requester) { const value = updateFields.requesterIdentificationValue; if (updateFields.requester === 'requesterId') { if (isNaN(parseInt(value, 10))) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Requester Id must be a number', { itemIndex: i, }); } body.requester_id = parseInt(value, 10); } else if (updateFields.requester === 'email') { body.email = value; } else if (updateFields.requester === 'facebookId') { body.facebook_id = value; } else if (updateFields.requester === 'phone') { body.phone = value; } else if (updateFields.requester === 'twitterId') { body.twitter_id = value; } else if (updateFields.requester === 'uniqueExternalId') { body.unique_external_id = value; } } if (updateFields.status) { //@ts-ignore body.status = Status[(0, GenericFunctions_1.capitalize)(updateFields.status)]; } if (updateFields.priority) { //@ts-ignore body.priority = Priority[(0, GenericFunctions_1.capitalize)(updateFields.priority)]; } if (updateFields.source) { //@ts-ignore body.source = Source[(0, GenericFunctions_1.capitalize)(updateFields.source)]; } if (updateFields.name) { body.name = updateFields.name; } if (updateFields.type) { body.type = updateFields.type; } if (updateFields.agent) { body.responder_id = updateFields.agent; } if (updateFields.company) { body.company_id = updateFields.company; } if (updateFields.product) { body.product_id = updateFields.product; } if (updateFields.group) { body.group_id = updateFields.group; } if (updateFields.frDueBy) { body.fr_due_by = updateFields.frDueBy; } if (updateFields.emailConfigId) { body.email_config_id = updateFields.emailConfigId; } if (updateFields.dueBy) { body.due_by = updateFields.dueBy; } if (updateFields.tags) { body.tags = updateFields.tags.split(','); } if (updateFields.ccEmails) { body.cc_emails = updateFields.ccEmails.split(','); } responseData = await GenericFunctions_1.freshdeskApiReque