2019-11-08 08:26:09 -08:00
import {
IDataObject ,
ILoadOptionsFunctions ,
2020-10-01 05:01:39 -07:00
INodeExecutionData ,
2019-11-08 08:26:09 -08:00
INodePropertyOptions ,
2020-10-01 05:01:39 -07:00
INodeType ,
INodeTypeDescription ,
2021-04-16 09:33:36 -07:00
NodeOperationError ,
2019-11-08 08:26:09 -08:00
} from 'n8n-workflow' ;
2020-09-10 12:56:15 -07:00
2020-02-18 11:03:48 -08:00
import {
IExecuteFunctions ,
} from 'n8n-core' ;
2020-09-10 12:56:15 -07:00
2019-11-08 08:26:09 -08:00
import {
2020-10-01 05:01:39 -07:00
capitalize ,
2019-11-08 08:26:09 -08:00
freshdeskApiRequest ,
2020-02-18 11:03:48 -08:00
freshdeskApiRequestAllItems ,
2020-02-21 06:07:03 -08:00
// validateJSON,
2019-11-08 08:26:09 -08:00
} from './GenericFunctions' ;
2020-09-10 12:56:15 -07:00
import {
ICreateContactBody ,
} from './ContactInterface' ;
import {
contactFields ,
contactOperations ,
} from './ContactDescription' ;
2019-11-08 08:26:09 -08:00
enum Status {
2019-11-10 03:33:23 -08:00
Open = 2 ,
Pending = 3 ,
Resolved = 4 ,
Closed = 5 ,
2019-11-08 08:26:09 -08:00
}
enum Priority {
Low = 1 ,
Medium = 2 ,
High = 3 ,
2020-10-22 06:46:03 -07:00
Urgent = 4 ,
2019-11-08 08:26:09 -08:00
}
enum Source {
Email = 1 ,
Portal = 2 ,
Phone = 3 ,
2019-11-10 05:08:56 -08:00
Chat = 7 ,
Mobihelp = 8 ,
FeedbackWidget = 9 ,
2019-11-13 05:29:47 -08:00
OutboundEmail = 10 ,
2019-11-08 08:26:09 -08:00
}
2019-11-10 14:14:36 -08:00
interface ICreateTicketBody {
2019-11-08 08:26:09 -08:00
name? : string ;
requester_id? : number ;
email? : string ;
facebook_id? : string ;
phone? : string ;
twitter_id? : string ;
unique_external_id? : string ;
subject? : string | null ;
type ? : string ;
2020-02-18 11:03:48 -08:00
status? : Status ;
priority? : Priority ;
2019-11-08 08:26:09 -08:00
description? : string ;
responder_id? : number ;
cc_emails ? : [ string ] ;
custom_fields? : IDataObject ;
due_by? : string ;
email_config_id? : number ;
fr_due_by? : string ;
group_id? : number ;
product_id? : number ;
2020-02-18 11:03:48 -08:00
source? : Source ;
2019-11-08 08:26:09 -08:00
tags ? : [ string ] ;
company_id? : number ;
}
export class Freshdesk implements INodeType {
description : INodeTypeDescription = {
displayName : 'Freshdesk' ,
name : 'freshdesk' ,
icon : 'file:freshdesk.png' ,
group : [ 'output' ] ,
version : 1 ,
subtitle : '={{$parameter["operation"] + ": " + $parameter["resource"]}}' ,
description : 'Consume Freshdesk API' ,
defaults : {
name : 'Freshdesk' ,
2020-09-10 12:56:15 -07:00
color : '#25c10b' ,
2019-11-08 08:26:09 -08:00
} ,
inputs : [ 'main' ] ,
outputs : [ 'main' ] ,
credentials : [
{
name : 'freshdeskApi' ,
required : true ,
2020-02-18 11:03:48 -08:00
} ,
2019-11-10 14:14:36 -08:00
] ,
2019-11-08 08:26:09 -08:00
properties : [
{
displayName : 'Resource' ,
name : 'resource' ,
type : 'options' ,
required : true ,
options : [
2020-09-10 12:56:15 -07:00
{
name : 'Contact' ,
value : 'contact' ,
} ,
2019-11-08 08:26:09 -08:00
{
name : 'Ticket' ,
value : 'ticket' ,
} ,
] ,
default : 'ticket' ,
description : 'The resource to operate on.' ,
} ,
{
displayName : 'Operation' ,
name : 'operation' ,
type : 'options' ,
required : true ,
displayOptions : {
show : {
resource : [
'ticket' ,
2020-10-22 06:46:03 -07:00
] ,
2019-11-08 08:26:09 -08:00
} ,
} ,
options : [
{
name : 'Create' ,
value : 'create' ,
description : 'Create a new ticket' ,
2020-02-18 11:03:48 -08:00
} ,
{
2020-02-21 06:07:03 -08:00
name : 'Delete' ,
value : 'delete' ,
description : 'Delete a ticket' ,
2020-02-18 11:03:48 -08:00
} ,
{
name : 'Get' ,
value : 'get' ,
description : 'Get a ticket' ,
} ,
{
name : 'Get All' ,
value : 'getAll' ,
description : 'Get all tickets' ,
} ,
{
2020-02-21 06:07:03 -08:00
name : 'Update' ,
value : 'update' ,
description : 'Update a ticket' ,
2020-02-18 11:03:48 -08:00
} ,
2019-11-08 08:26:09 -08:00
] ,
default : 'create' ,
description : 'The operation to perform.' ,
} ,
{
displayName : 'Requester Identification' ,
name : 'requester' ,
type : 'options' ,
required : true ,
displayOptions : {
show : {
resource : [
'ticket' ,
] ,
operation : [
2020-02-21 06:07:03 -08:00
'create' ,
2020-10-22 06:46:03 -07:00
] ,
2019-11-08 08:26:09 -08:00
} ,
} ,
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. ` ,
} ,
2020-02-21 06:07:03 -08:00
{
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. ` ,
} ,
2019-11-08 08:26:09 -08:00
{
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' ,
description : 'Requester Identification' ,
} ,
{
displayName : 'Value' ,
name : 'requesterIdentificationValue' ,
type : 'string' ,
required : true ,
displayOptions : {
show : {
resource : [
'ticket' ,
] ,
operation : [
2020-02-21 06:07:03 -08:00
'create' ,
2020-10-22 06:46:03 -07:00
] ,
2019-11-08 08:26:09 -08:00
} ,
} ,
default : '' ,
description : ` Value of the identification selected ` ,
} ,
{
displayName : 'Status' ,
name : 'status' ,
type : 'options' ,
required : true ,
displayOptions : {
show : {
resource : [
'ticket' ,
] ,
operation : [
2020-02-21 06:07:03 -08:00
'create' ,
2020-10-22 06:46:03 -07:00
] ,
2019-11-08 08:26:09 -08:00
} ,
} ,
options : [
2020-02-21 06:07:03 -08:00
{
name : 'Closed' ,
value : 'closed' ,
} ,
2019-11-08 08:26:09 -08:00
{
name : 'Open' ,
value : 'open' ,
} ,
{
name : 'Pending' ,
value : 'pending' ,
} ,
{
name : 'Resolved' ,
value : 'resolved' ,
} ,
] ,
default : 'pending' ,
description : 'Status' ,
} ,
{
displayName : 'Priority' ,
name : 'priority' ,
type : 'options' ,
required : true ,
displayOptions : {
show : {
resource : [
'ticket' ,
] ,
operation : [
2020-10-22 06:46:03 -07:00
'create' ,
] ,
2019-11-08 08:26:09 -08:00
} ,
} ,
options : [
{
name : 'Low' ,
value : 'low' ,
} ,
{
name : 'Medium' ,
value : 'medium' ,
} ,
{
name : 'High' ,
value : 'high' ,
} ,
{
name : 'Urgent' ,
value : 'urgent' ,
2020-10-22 06:46:03 -07:00
} ,
2019-11-08 08:26:09 -08:00
] ,
default : 'low' ,
description : 'Priority' ,
} ,
{
displayName : 'Source' ,
name : 'source' ,
type : 'options' ,
required : true ,
displayOptions : {
show : {
resource : [
'ticket' ,
] ,
operation : [
2020-10-22 06:46:03 -07:00
'create' ,
] ,
2019-11-08 08:26:09 -08:00
} ,
} ,
options : [
2020-02-21 06:07:03 -08:00
{
name : 'Chat' ,
value : 'chat' ,
} ,
2019-11-08 08:26:09 -08:00
{
name : 'Email' ,
value : 'email' ,
} ,
{
2020-02-21 06:07:03 -08:00
name : 'Feedback Widget' ,
value : 'feedbackWidget' ,
2019-11-08 08:26:09 -08:00
} ,
{
name : 'Phone' ,
value : 'phone' ,
} ,
{
2020-02-21 06:07:03 -08:00
name : 'Portal' ,
value : 'portal' ,
2019-11-08 08:26:09 -08:00
} ,
{
name : 'Mobihelp' ,
value : 'mobileHelp' ,
} ,
2020-02-21 06:07:03 -08:00
2019-11-08 08:26:09 -08:00
{
name : 'Outbound Email' ,
value : 'OutboundEmail' ,
2020-02-21 06:07:03 -08:00
} ,
2019-11-08 08:26:09 -08:00
] ,
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 : [
2020-02-21 06:07:03 -08:00
'ticket' ,
2019-11-08 08:26:09 -08:00
] ,
operation : [
2020-02-21 06:07:03 -08:00
'create' ,
2019-11-08 08:26:09 -08:00
] ,
} ,
} ,
options : [
{
displayName : 'Agent' ,
name : 'agent' ,
type : 'options' ,
default : '' ,
typeOptions : {
2020-02-21 06:07:03 -08:00
loadOptionsMethod : 'getAgents' ,
2019-11-08 08:26:09 -08:00
} ,
description : 'ID of the agent to whom the ticket has been assigned' ,
} ,
{
displayName : 'CC Emails' ,
name : 'ccEmails' ,
type : 'string' ,
default : '' ,
2021-10-27 13:00:13 -07:00
description : ` Separated by a comma (,) email addresses added in the 'cc' field of the incoming ticket email ` ,
2019-11-08 08:26:09 -08:00
} ,
{
2020-02-18 11:03:48 -08:00
displayName : 'Company' ,
name : 'company' ,
type : 'options' ,
default : '' ,
typeOptions : {
2020-02-21 06:07:03 -08:00
loadOptionsMethod : 'getCompanies' ,
2020-02-18 11:03:48 -08:00
} ,
description : ` Company ID of the requester. This attribute can only be set if the Multiple Companies feature is enabled (Estate plan and above) ` ,
} ,
{
displayName : 'Description' ,
name : 'description' ,
2019-11-08 08:26:09 -08:00
type : 'string' ,
default : '' ,
2020-02-18 11:03:48 -08:00
typeOptions : {
rows : 5 ,
alwaysOpenEditWindow : true ,
} ,
description : 'HTML content of the ticket.' ,
2019-11-08 08:26:09 -08:00
} ,
{
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 : 'group' ,
type : 'options' ,
default : '' ,
typeOptions : {
2020-10-22 06:46:03 -07:00
loadOptionsMethod : 'getGroups' ,
2019-11-08 08:26:09 -08:00
} ,
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 ` ,
} ,
2020-02-18 11:03:48 -08:00
{
displayName : 'Name' ,
name : 'name' ,
type : 'string' ,
default : '' ,
placeholder : '' ,
description : 'Name of the requester' ,
} ,
2019-11-08 08:26:09 -08:00
{
displayName : 'Product' ,
name : 'product' ,
type : 'options' ,
default : '' ,
typeOptions : {
2020-10-22 06:46:03 -07:00
loadOptionsMethod : 'getProducts' ,
2019-11-08 08:26:09 -08:00
} ,
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 . ` ,
} ,
{
2020-02-18 11:03:48 -08:00
displayName : 'Subject' ,
name : 'subject' ,
type : 'string' ,
default : '' ,
placeholder : '' ,
description : 'Subject of the ticket.' ,
} ,
{
displayName : 'Tags' ,
name : 'tags' ,
type : 'string' ,
2019-11-08 08:26:09 -08:00
default : '' ,
2021-10-27 13:00:13 -07:00
description : ` separated by a comma (,) tags that have been associated with the ticket ` ,
2020-02-18 11:03:48 -08:00
} ,
{
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 : [
{
2020-02-21 06:07:03 -08:00
name : 'Feature Request' ,
value : 'Feature Request' ,
2020-02-18 11:03:48 -08:00
} ,
{
name : 'Incident' ,
2020-02-21 06:07:03 -08:00
value : 'Incident' ,
2020-02-18 11:03:48 -08:00
} ,
{
name : 'Problem' ,
2020-02-21 06:07:03 -08:00
value : 'Problem' ,
2020-02-18 11:03:48 -08:00
} ,
{
2020-02-21 06:07:03 -08:00
name : 'Question' ,
value : 'Question' ,
2020-02-18 11:03:48 -08:00
} ,
{
name : 'Refund' ,
2020-02-21 06:07:03 -08:00
value : 'Refund' ,
2020-02-18 11:03:48 -08:00
} ,
2020-10-22 06:46:03 -07:00
] ,
2019-11-08 08:26:09 -08:00
} ,
2020-10-22 06:46:03 -07:00
] ,
2019-11-08 08:26:09 -08:00
} ,
// {
// 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: [
2020-02-21 06:07:03 -08:00
// 'ticket',
2019-11-08 08:26:09 -08:00
// ],
// operation: [
2020-02-21 06:07:03 -08:00
// 'create',
2019-11-08 08:26:09 -08:00
// ],
// jsonParameters: [
// true,
// ],
// },
// },
// default: '',
// required: false,
// placeholder: `{
2020-02-21 06:07:03 -08:00
// 'gadget': 'Cold Welder',
2019-11-08 08:26:09 -08:00
// }`,
// description: 'Key value pairs containing the names and values of custom fields.',
// },
2020-02-18 11:03:48 -08:00
{
displayName : 'Ticket ID' ,
name : 'ticketId' ,
type : 'string' ,
required : true ,
displayOptions : {
show : {
resource : [
'ticket' ,
] ,
operation : [
2020-02-21 06:07:03 -08:00
'update' ,
2020-10-22 06:46:03 -07:00
] ,
2020-02-18 11:03:48 -08:00
} ,
} ,
default : '' ,
description : 'Ticket ID' ,
2019-11-08 08:26:09 -08:00
} ,
2020-02-18 11:03:48 -08:00
{
displayName : 'Update Fields' ,
name : 'updateFields' ,
type : 'collection' ,
placeholder : 'Add Field' ,
default : { } ,
displayOptions : {
show : {
resource : [
2020-02-21 06:07:03 -08:00
'ticket' ,
2020-02-18 11:03:48 -08:00
] ,
operation : [
2020-02-21 06:07:03 -08:00
'update' ,
2020-02-18 11:03:48 -08:00
] ,
} ,
} ,
options : [
{
displayName : 'Agent' ,
name : 'agent' ,
type : 'options' ,
default : '' ,
typeOptions : {
2020-02-21 06:07:03 -08:00
loadOptionsMethod : 'getAgents' ,
2020-02-18 11:03:48 -08:00
} ,
description : 'ID of the agent to whom the ticket has been assigned' ,
} ,
{
displayName : 'CC Emails' ,
name : 'ccEmails' ,
type : 'string' ,
default : '' ,
2021-10-27 13:00:13 -07:00
description : ` Separated by a comma (,) email addresses added in the 'cc' field of the incoming ticket email ` ,
2020-02-18 11:03:48 -08:00
} ,
{
displayName : 'Company' ,
name : 'company' ,
type : 'options' ,
default : '' ,
typeOptions : {
2020-02-21 06:07:03 -08:00
loadOptionsMethod : 'getCompanies' ,
2020-02-18 11:03:48 -08:00
} ,
description : ` Company ID of the requester. This attribute can only be set if the Multiple Companies feature is enabled (Estate plan and above) ` ,
} ,
{
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 : 'group' ,
type : 'options' ,
default : '' ,
typeOptions : {
2020-02-21 06:07:03 -08:00
loadOptionsMethod : 'getGroups' ,
2020-02-18 11:03:48 -08:00
} ,
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 ` ,
} ,
{
displayName : 'Name' ,
name : 'name' ,
type : 'string' ,
default : '' ,
placeholder : '' ,
description : 'Name of the requester' ,
} ,
{
displayName : 'Product' ,
name : 'product' ,
type : 'options' ,
default : '' ,
typeOptions : {
2020-02-21 06:07:03 -08:00
loadOptionsMethod : 'getProducts' ,
2020-02-18 11:03:48 -08:00
} ,
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 . ` ,
} ,
{
displayName : 'Priority' ,
name : 'priority' ,
type : 'options' ,
required : true ,
options : [
{
name : 'Low' ,
value : 'low' ,
} ,
{
name : 'Medium' ,
value : 'medium' ,
} ,
{
name : 'High' ,
value : 'high' ,
} ,
{
name : 'Urgent' ,
value : 'urgent' ,
2020-10-22 06:46:03 -07:00
} ,
2020-02-18 11:03:48 -08:00
] ,
default : 'low' ,
description : 'Priority' ,
} ,
{
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. ` ,
} ,
2020-02-21 06:07:03 -08:00
{
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. ` ,
} ,
2020-02-18 11:03:48 -08:00
{
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' ,
description : 'Requester Identification' ,
} ,
{
displayName : 'Requester Value' ,
name : 'requesterIdentificationValue' ,
type : 'string' ,
default : '' ,
description : ` Value of the identification selected ` ,
} ,
{
displayName : 'Status' ,
name : 'status' ,
type : 'options' ,
required : true ,
options : [
{
name : 'Open' ,
value : 'open' ,
} ,
{
name : 'Pending' ,
value : 'pending' ,
} ,
{
name : 'Resolved' ,
value : 'resolved' ,
} ,
{
name : 'Closed' ,
value : 'closed' ,
2020-10-22 06:46:03 -07:00
} ,
2020-02-18 11:03:48 -08:00
] ,
default : 'pending' ,
description : 'Status' ,
} ,
{
displayName : 'Source' ,
name : 'source' ,
type : 'options' ,
required : true ,
options : [
2020-02-21 06:07:03 -08:00
{
name : 'Chat' ,
value : 'chat' ,
} ,
2020-02-18 11:03:48 -08:00
{
name : 'Email' ,
value : 'email' ,
} ,
{
2020-02-21 06:07:03 -08:00
name : 'Feedback Widget' ,
value : 'feedbackWidget' ,
2020-02-18 11:03:48 -08:00
} ,
{
2020-02-21 06:07:03 -08:00
name : 'Mobihelp' ,
value : 'mobileHelp' ,
2020-02-18 11:03:48 -08:00
} ,
2020-02-21 06:07:03 -08:00
2020-02-18 11:03:48 -08:00
{
2020-02-21 06:07:03 -08:00
name : 'Outbound Email' ,
value : 'OutboundEmail' ,
2020-02-18 11:03:48 -08:00
} ,
{
2020-02-21 06:07:03 -08:00
name : 'Phone' ,
value : 'phone' ,
2020-02-18 11:03:48 -08:00
} ,
{
2020-02-21 06:07:03 -08:00
name : 'Portal' ,
value : 'portal' ,
2020-02-18 11:03:48 -08:00
} ,
] ,
default : 'portal' ,
description : 'The channel through which the ticket was created.' ,
} ,
{
displayName : 'Tags' ,
name : 'tags' ,
type : 'string' ,
default : '' ,
2021-10-27 13:00:13 -07:00
description : ` separated by a comma (,) tags that have been associated with the ticket ` ,
2020-02-18 11:03:48 -08:00
} ,
{
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 : [
{
2020-02-21 06:07:03 -08:00
name : 'Feature Request' ,
2020-10-22 06:46:03 -07:00
value : 'Feature Request' ,
2020-02-18 11:03:48 -08:00
} ,
{
name : 'Incident' ,
2020-10-22 06:46:03 -07:00
value : 'Incident' ,
2020-02-18 11:03:48 -08:00
} ,
{
name : 'Problem' ,
2020-10-22 06:46:03 -07:00
value : 'Problem' ,
2020-02-18 11:03:48 -08:00
} ,
{
2020-02-21 06:07:03 -08:00
name : 'Question' ,
2020-10-22 06:46:03 -07:00
value : 'Question' ,
2020-02-18 11:03:48 -08:00
} ,
{
name : 'Refund' ,
2020-10-22 06:46:03 -07:00
value : 'Refund' ,
2020-02-18 11:03:48 -08:00
} ,
2020-10-22 06:46:03 -07:00
] ,
2020-02-18 11:03:48 -08:00
} ,
2020-10-22 06:46:03 -07:00
] ,
2020-02-18 11:03:48 -08:00
} ,
{
displayName : 'Ticket ID' ,
name : 'ticketId' ,
type : 'string' ,
required : true ,
displayOptions : {
show : {
resource : [
'ticket' ,
] ,
operation : [
2020-10-22 06:46:03 -07:00
'get' ,
] ,
2020-02-18 11:03:48 -08:00
} ,
} ,
default : '' ,
description : 'Ticket ID' ,
} ,
{
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 : 10 ,
} ,
default : 5 ,
description : 'How many results to return.' ,
} ,
{
displayName : 'Options' ,
name : 'options' ,
type : 'collection' ,
placeholder : 'Add Option' ,
default : { } ,
displayOptions : {
show : {
resource : [
'ticket' ,
] ,
operation : [
'getAll' ,
] ,
} ,
} ,
options : [
{
2020-02-21 06:07:03 -08:00
displayName : 'Company ID' ,
name : 'companyId' ,
type : 'string' ,
default : '' ,
} ,
{
displayName : 'Include' ,
name : 'include' ,
type : 'multiOptions' ,
2020-02-18 11:03:48 -08:00
options : [
{
2020-02-21 06:07:03 -08:00
name : 'Company' ,
value : 'company' ,
2020-02-18 11:03:48 -08:00
} ,
{
2020-02-21 06:07:03 -08:00
name : 'Description' ,
value : 'description' ,
2020-02-18 11:03:48 -08:00
} ,
{
2020-02-21 06:07:03 -08:00
name : 'Requester' ,
value : 'requester' ,
} ,
{
name : 'Stats' ,
value : 'stats' ,
2020-02-18 11:03:48 -08:00
} ,
] ,
2020-02-21 06:07:03 -08:00
default : [ ] ,
2020-02-18 11:03:48 -08:00
} ,
{
displayName : 'Order' ,
name : 'order' ,
type : 'options' ,
options : [
{
name : 'ASC' ,
value : 'asc' ,
} ,
{
name : 'DESC' ,
value : 'desc' ,
} ,
] ,
default : 'desc' ,
description : 'Order sort attribute ascending or descending.' ,
} ,
{
2020-02-21 06:07:03 -08:00
displayName : 'Order By' ,
name : 'orderBy' ,
type : 'options' ,
options : [
{
name : 'Created At' ,
value : 'createdAt' ,
} ,
{
name : 'Due By' ,
value : 'dueBy' ,
} ,
{
name : 'Updated At' ,
value : 'updatedAt' ,
} ,
] ,
2020-02-18 11:03:48 -08:00
default : '' ,
2020-02-21 06:07:03 -08:00
description : 'Sort collection by object attribute.' ,
2020-02-18 11:03:48 -08:00
} ,
{
displayName : 'Requester Email' ,
name : 'requesterEmail' ,
type : 'string' ,
default : '' ,
} ,
{
2020-02-21 06:07:03 -08:00
displayName : 'Requester ID' ,
name : 'requesterId' ,
2020-02-18 11:03:48 -08:00
type : 'string' ,
default : '' ,
} ,
{
displayName : 'Updated Since' ,
name : 'updatedSince' ,
type : 'dateTime' ,
default : '' ,
} ,
2020-10-22 06:46:03 -07:00
] ,
2020-02-18 11:03:48 -08:00
} ,
{
displayName : 'Ticket ID' ,
name : 'ticketId' ,
type : 'string' ,
required : true ,
displayOptions : {
show : {
resource : [
'ticket' ,
] ,
operation : [
2020-10-22 06:46:03 -07:00
'delete' ,
] ,
2020-02-18 11:03:48 -08:00
} ,
} ,
default : '' ,
description : 'Ticket ID' ,
} ,
2020-09-10 12:56:15 -07:00
// CONTACTS
. . . contactOperations ,
. . . contactFields ,
2020-10-22 06:46:03 -07:00
] ,
2020-02-18 11:03:48 -08:00
} ;
2019-11-10 03:33:23 -08:00
2020-02-18 11:03:48 -08:00
methods = {
loadOptions : {
// Get all the agents to display them to user so that he can
// select them easily
async getAgents ( this : ILoadOptionsFunctions ) : Promise < INodePropertyOptions [ ] > {
const returnData : INodePropertyOptions [ ] = [ ] ;
2020-02-21 06:07:03 -08:00
const agents = await freshdeskApiRequest . call ( this , 'GET' , '/agents' ) ;
2020-02-18 11:03:48 -08:00
for ( const agent of agents ) {
const agentName = agent . contact . name ;
const agentId = agent . id ;
2019-11-08 08:26:09 -08:00
2020-02-18 11:03:48 -08:00
returnData . push ( {
name : agentName ,
value : agentId ,
} ) ;
2019-11-08 08:26:09 -08:00
}
2020-02-18 11:03:48 -08:00
return returnData ;
} ,
2019-11-08 08:26:09 -08:00
2020-02-18 11:03:48 -08:00
// Get all the groups to display them to user so that he can
// select them easily
async getGroups ( this : ILoadOptionsFunctions ) : Promise < INodePropertyOptions [ ] > {
const returnData : INodePropertyOptions [ ] = [ ] ;
2020-02-21 06:07:03 -08:00
const groups = await freshdeskApiRequest . call ( this , 'GET' , '/groups' ) ;
2020-02-18 11:03:48 -08:00
for ( const group of groups ) {
const groupName = group . name ;
const groupId = group . id ;
2019-11-08 08:26:09 -08:00
2020-02-18 11:03:48 -08:00
returnData . push ( {
name : groupName ,
value : groupId ,
} ) ;
2019-11-08 08:26:09 -08:00
}
2020-02-18 11:03:48 -08:00
return returnData ;
} ,
2019-11-08 08:26:09 -08:00
2020-02-18 11:03:48 -08:00
// Get all the products to display them to user so that he can
// select them easily
async getProducts ( this : ILoadOptionsFunctions ) : Promise < INodePropertyOptions [ ] > {
const returnData : INodePropertyOptions [ ] = [ ] ;
2020-02-21 06:07:03 -08:00
const products = await freshdeskApiRequest . call ( this , 'GET' , '/products' ) ;
2020-02-18 11:03:48 -08:00
for ( const product of products ) {
const productName = product . name ;
const productId = product . id ;
2019-11-08 08:26:09 -08:00
2020-02-18 11:03:48 -08:00
returnData . push ( {
name : productName ,
value : productId ,
} ) ;
2019-11-08 08:26:09 -08:00
}
2020-02-18 11:03:48 -08:00
return returnData ;
} ,
2019-11-08 08:26:09 -08:00
2020-02-18 11:03:48 -08:00
// Get all the companies to display them to user so that he can
// select them easily
async getCompanies ( this : ILoadOptionsFunctions ) : Promise < INodePropertyOptions [ ] > {
const returnData : INodePropertyOptions [ ] = [ ] ;
2020-02-21 06:07:03 -08:00
const companies = await freshdeskApiRequest . call ( this , 'GET' , '/companies' ) ;
2020-02-18 11:03:48 -08:00
for ( const company of companies ) {
const companyName = company . name ;
const companyId = company . id ;
2019-11-08 08:26:09 -08:00
2020-02-18 11:03:48 -08:00
returnData . push ( {
name : companyName ,
value : companyId ,
} ) ;
2019-11-08 08:26:09 -08:00
}
2020-02-18 11:03:48 -08:00
return returnData ;
} ,
} ,
} ;
2019-11-10 03:33:23 -08:00
2020-02-18 11:03:48 -08:00
async execute ( this : IExecuteFunctions ) : Promise < INodeExecutionData [ ] [ ] > {
const items = this . getInputData ( ) ;
const returnData : IDataObject [ ] = [ ] ;
let responseData ;
const qs : IDataObject = { } ;
const resource = this . getNodeParameter ( 'resource' , 0 ) as string ;
const operation = this . getNodeParameter ( 'operation' , 0 ) as string ;
2020-02-21 06:07:03 -08:00
for ( let i = 0 ; i < items . length ; i ++ ) {
2021-07-19 23:58:54 -07:00
try {
if ( resource === 'ticket' ) {
//https://developers.freshdesk.com/api/#create_ticket
if ( operation === 'create' ) {
const requester = this . getNodeParameter ( 'requester' , i ) as string ;
const value = this . getNodeParameter ( 'requesterIdentificationValue' , i ) as string ;
const status = this . getNodeParameter ( 'status' , i ) as string ;
const priority = this . getNodeParameter ( 'priority' , i ) as string ;
const source = this . getNodeParameter ( 'source' , i ) as string ;
const options = this . getNodeParameter ( 'options' , i ) as IDataObject ;
//const jsonActive = this.getNodeParameter('jsonParameters') as boolean;
const body : ICreateTicketBody = {
// @ts-ignore
status : Status [ capitalize ( status ) ] ,
// @ts-ignore
priority : Priority [ capitalize ( priority ) ] ,
// @ts-ignore
source : Source [ capitalize ( source ) ] ,
} ;
2019-11-08 08:26:09 -08:00
2021-07-19 23:58:54 -07:00
if ( requester === 'requesterId' ) {
// @ts-ignore
if ( isNaN ( value ) ) {
throw new NodeOperationError ( this . getNode ( ) , 'Requester Id must be a number' ) ;
}
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 ;
2020-02-18 11:03:48 -08:00
}
2019-11-08 08:26:09 -08:00
2021-07-19 23:58:54 -07:00
// 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);
// }
2019-11-08 08:26:09 -08:00
2021-07-19 23:58:54 -07:00
if ( options . name ) {
body . name = options . name as string ;
}
if ( options . subject ) {
body . subject = options . subject as string ;
} else {
body . subject = 'null' ;
}
if ( options . type ) {
body . type = options . type as string ;
}
if ( options . description ) {
body . description = options . description as string ;
} else {
body . description = 'null' ;
}
if ( options . agent ) {
body . responder_id = options . agent as number ;
}
if ( options . company ) {
body . company_id = options . company as number ;
}
if ( options . product ) {
body . product_id = options . product as number ;
}
if ( options . group ) {
body . group_id = options . group as number ;
}
if ( options . frDueBy ) {
body . fr_due_by = options . frDueBy as string ;
}
if ( options . emailConfigId ) {
body . email_config_id = options . emailConfigId as number ;
}
if ( options . dueBy ) {
body . due_by = options . dueBy as string ;
}
if ( options . tags ) {
body . tags = ( options . tags as string ) . split ( ',' ) as [ string ] ;
}
if ( options . ccEmails ) {
body . cc_emails = ( options . ccEmails as string ) . split ( ',' ) as [ string ] ;
}
responseData = await freshdeskApiRequest . call ( this , 'POST' , '/tickets' , body ) ;
2020-02-18 11:03:48 -08:00
}
2021-07-19 23:58:54 -07:00
//https://developers.freshdesk.com/api/#update_ticket
if ( operation === 'update' ) {
const ticketId = this . getNodeParameter ( 'ticketId' , i ) as string ;
const updateFields = this . getNodeParameter ( 'updateFields' , i ) as IDataObject ;
const body : ICreateTicketBody = { } ;
2019-11-10 03:33:23 -08:00
2021-07-19 23:58:54 -07:00
if ( updateFields . requester ) {
const value = updateFields . requesterIdentificationValue as string ;
if ( updateFields . requester === 'requesterId' ) {
// @ts-ignore
if ( isNaN ( parseInt ( value , 10 ) ) ) {
throw new NodeOperationError ( this . getNode ( ) , 'Requester Id must be a number' ) ;
}
body . requester_id = parseInt ( value as string , 10 ) ;
} else if ( updateFields . requester === 'email' ) {
body . email = value as string ;
} else if ( updateFields . requester === 'facebookId' ) {
body . facebook_id = value as string ;
} else if ( updateFields . requester === 'phone' ) {
body . phone = value as string ;
} else if ( updateFields . requester === 'twitterId' ) {
body . twitter_id = value as string ;
} else if ( updateFields . requester === 'uniqueExternalId' ) {
body . unique_external_id = value as string ;
2020-02-18 11:03:48 -08:00
}
}
2021-07-19 23:58:54 -07:00
if ( updateFields . status ) {
//@ts-ignore
body . status = Status [ capitalize ( updateFields . status ) ] ;
}
if ( updateFields . priority ) {
//@ts-ignore
body . priority = Priority [ capitalize ( updateFields . priority ) ] ;
}
if ( updateFields . source ) {
//@ts-ignore
body . source = Source [ capitalize ( updateFields . source ) ] ;
}
if ( updateFields . name ) {
body . name = updateFields . name as string ;
}
if ( updateFields . type ) {
body . type = updateFields . type as string ;
}
if ( updateFields . agent ) {
body . responder_id = updateFields . agent as number ;
}
if ( updateFields . company ) {
body . company_id = updateFields . company as number ;
}
if ( updateFields . product ) {
body . product_id = updateFields . product as number ;
}
if ( updateFields . group ) {
body . group_id = updateFields . group as number ;
}
if ( updateFields . frDueBy ) {
body . fr_due_by = updateFields . frDueBy as string ;
}
if ( updateFields . emailConfigId ) {
body . email_config_id = updateFields . emailConfigId as number ;
}
if ( updateFields . dueBy ) {
body . due_by = updateFields . dueBy as string ;
}
if ( updateFields . tags ) {
body . tags = ( updateFields . tags as string ) . split ( ',' ) as [ string ] ;
}
if ( updateFields . ccEmails ) {
body . cc_emails = ( updateFields . ccEmails as string ) . split ( ',' ) as [ string ] ;
}
responseData = await freshdeskApiRequest . call ( this , 'PUT' , ` /tickets/ ${ ticketId } ` , body ) ;
2020-02-18 11:03:48 -08:00
}
2021-07-19 23:58:54 -07:00
//https://developers.freshdesk.com/api/#view_a_ticket
if ( operation === 'get' ) {
const ticketId = this . getNodeParameter ( 'ticketId' , i ) as string ;
responseData = await freshdeskApiRequest . call ( this , 'GET' , ` /tickets/ ${ ticketId } ` ) ;
2020-02-18 11:03:48 -08:00
}
2021-07-19 23:58:54 -07:00
//https://developers.freshdesk.com/api/#list_all_tickets
if ( operation === 'getAll' ) {
const returnAll = this . getNodeParameter ( 'returnAll' , i ) as boolean ;
const options = this . getNodeParameter ( 'options' , i ) as IDataObject ;
if ( options . requesterId ) {
qs . requester_id = options . requesterId as string ;
}
if ( options . requesterEmail ) {
qs . email = options . requesterEmail as string ;
}
if ( options . companyId ) {
qs . company_id = options . companyId as string ;
}
if ( options . updatedSince ) {
qs . updated_since = options . updatedSince as string ;
}
if ( options . orderBy ) {
qs . order_by = options . orderBy as string ;
}
if ( options . order ) {
qs . order_type = options . order as string ;
}
if ( options . include ) {
if ( ( options . include as string [ ] ) . length !== 0 ) {
qs . include = ( options . include as string [ ] ) . join ( ',' ) ;
}
}
if ( returnAll === true ) {
responseData = await freshdeskApiRequestAllItems . call ( this , 'GET' , '/tickets' , { } , qs ) ;
} else {
qs . per_page = this . getNodeParameter ( 'limit' , i ) as number ;
responseData = await freshdeskApiRequest . call ( this , 'GET' , '/tickets' , { } , qs ) ;
2020-02-18 11:03:48 -08:00
}
}
2021-07-19 23:58:54 -07:00
//https://developers.freshdesk.com/api/#delete_a_ticket
if ( operation === 'delete' ) {
const ticketId = this . getNodeParameter ( 'ticketId' , i ) as string ;
responseData = await freshdeskApiRequest . call ( this , 'DELETE' , ` /tickets/ ${ ticketId } ` ) ;
2020-02-18 11:03:48 -08:00
}
2021-07-19 23:58:54 -07:00
} else if ( resource === 'contact' ) {
//https://developers.freshdesk.com/api/#create_contact
if ( operation === 'create' ) {
const name = this . getNodeParameter ( 'name' , i ) as string ;
const email = this . getNodeParameter ( 'email' , i ) as string ;
const additionalFields = this . getNodeParameter ( 'additionalFields' , i , { } ) as IDataObject ;
2020-09-10 12:56:15 -07:00
2021-07-19 23:58:54 -07:00
if ( additionalFields . customFields ) {
const metadata = ( additionalFields . customFields as IDataObject ) . customField as IDataObject [ ] ;
additionalFields . custom_fields = { } ;
for ( const data of metadata ) {
//@ts-ignore
additionalFields . custom_fields [ data . name as string ] = data . value ;
}
delete additionalFields . customFields ;
2020-09-10 12:56:15 -07:00
}
2021-07-19 23:58:54 -07:00
const body : ICreateContactBody = additionalFields ;
body . name = name ;
if ( email ) {
body . email = email ;
}
responseData = await freshdeskApiRequest . call ( this , 'POST' , '/contacts' , body ) ;
//https://developers.freshdesk.com/api/#delete_contact
} else if ( operation === 'delete' ) {
const contactId = this . getNodeParameter ( 'contactId' , i ) as string ;
responseData = await freshdeskApiRequest . call ( this , 'DELETE' , ` /contacts/ ${ contactId } ` , { } ) ;
} else if ( operation === 'get' ) {
const contactId = this . getNodeParameter ( 'contactId' , i ) as string ;
responseData = await freshdeskApiRequest . call ( this , 'GET' , ` /contacts/ ${ contactId } ` , { } ) ;
//https://developers.freshdesk.com/api/#list_all_contacts
} else if ( operation === 'getAll' ) {
const qs = this . getNodeParameter ( 'filters' , i , { } ) as IDataObject ;
responseData = await freshdeskApiRequest . call ( this , 'GET' , '/contacts' , { } , qs ) ;
//https://developers.freshdesk.com/api/#update_contact
} else if ( operation === 'update' ) {
const contactId = this . getNodeParameter ( 'contactId' , i ) as string ;
const additionalFields = this . getNodeParameter ( 'additionalFields' , i , { } ) as IDataObject ;
2020-09-10 12:56:15 -07:00
2021-07-19 23:58:54 -07:00
if ( additionalFields . customFields ) {
const metadata = ( additionalFields . customFields as IDataObject ) . customField as IDataObject [ ] ;
additionalFields . custom_fields = { } ;
for ( const data of metadata ) {
//@ts-ignore
additionalFields . custom_fields [ data . name as string ] = data . value ;
}
delete additionalFields . customFields ;
2020-09-10 12:56:15 -07:00
}
2021-07-19 23:58:54 -07:00
const body : ICreateContactBody = additionalFields ;
responseData = await freshdeskApiRequest . call ( this , 'PUT' , ` /contacts/ ${ contactId } ` , body ) ;
}
2020-09-10 12:56:15 -07:00
}
2021-07-19 23:58:54 -07:00
if ( Array . isArray ( responseData ) ) {
returnData . push . apply ( returnData , responseData as IDataObject [ ] ) ;
} else {
if ( responseData === undefined ) {
responseData = {
success : true ,
} ;
}
2020-02-21 06:07:03 -08:00
2021-07-19 23:58:54 -07:00
returnData . push ( responseData as IDataObject ) ;
}
} catch ( error ) {
if ( this . continueOnFail ( ) ) {
returnData . push ( { error : error.message } ) ;
continue ;
}
throw error ;
2019-11-08 08:26:09 -08:00
}
}
2020-02-18 11:03:48 -08:00
return [ this . helpers . returnJsonArray ( returnData ) ] ;
2019-11-10 14:14:36 -08:00
}
2019-11-08 08:26:09 -08:00
}