This commit is contained in:
Ricardo Espinoza 2019-11-08 10:41:10 -05:00
parent 2292cc018c
commit c478fd9ddb
2 changed files with 254 additions and 102 deletions

View file

@ -10,7 +10,9 @@ import {
INodePropertyOptions, INodePropertyOptions,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { import {
freshdeskApiRequest freshdeskApiRequest,
validateJSON,
capitalize
} from './GenericFunctions'; } from './GenericFunctions';
enum Status { enum Status {
@ -34,7 +36,7 @@ enum Source {
Chat = 4, Chat = 4,
Mobihelp = 5, Mobihelp = 5,
FeedbackWidget = 6, FeedbackWidget = 6,
OutboundEmail =7 OutboundEmail = 7
} }
interface ICreateTicketBody { interface ICreateTicketBody {
@ -45,7 +47,7 @@ interface ICreateTicketBody {
phone?: string; phone?: string;
twitter_id?: string; twitter_id?: string;
unique_external_id?: string; unique_external_id?: string;
subject?: string; subject?: string | null;
type?: string; type?: string;
status: Status; status: Status;
priority: Priority; priority: Priority;
@ -59,8 +61,8 @@ interface ICreateTicketBody {
group_id?: number; group_id?: number;
product_id?: number; product_id?: number;
source: Source; source: Source;
tags: [string]; tags?: [string];
company_id: number; company_id?: number;
} }
export class Freshdesk implements INodeType { export class Freshdesk implements INodeType {
@ -310,23 +312,23 @@ export class Freshdesk implements INodeType {
default: 'portal', default: 'portal',
description: 'The channel through which the ticket was created.', description: 'The channel through which the ticket was created.',
}, },
{ // {
displayName: 'JSON Parameters', // displayName: 'JSON Parameters',
name: 'jsonParameters', // name: 'jsonParameters',
type: 'boolean', // type: 'boolean',
default: false, // default: false,
description: '', // description: '',
displayOptions: { // displayOptions: {
show: { // show: {
resource: [ // resource: [
'ticket' // 'ticket'
], // ],
operation: [ // operation: [
'create', // 'create',
] // ]
}, // },
}, // },
}, // },
{ {
displayName: 'Options', displayName: 'Options',
name: 'options', name: 'options',
@ -363,9 +365,31 @@ export class Freshdesk implements INodeType {
{ {
displayName: 'Type', displayName: 'Type',
name: 'type', name: 'type',
type: 'string', type: 'options',
default: '', default: 'Question',
description: 'Helps categorize the ticket according to the different kinds of issues your support team deals with.', description: 'Helps categorize the ticket according to the different kinds of issues your support team deals with.',
options: [
{
name: 'Question',
value: 'Question'
},
{
name: 'Incident',
value: 'Incident'
},
{
name: 'Problem',
value: 'Problem'
},
{
name: 'Feature Request',
value: 'Feature Request'
},
{
name: 'Refund',
value: 'Refund'
},
]
}, },
{ {
displayName: 'Description', displayName: 'Description',
@ -426,7 +450,7 @@ export class Freshdesk implements INodeType {
{ {
displayName: 'FR Due By', displayName: 'FR Due By',
name: 'frDueBy', name: 'frDueBy',
type: 'number', type: 'dateTime',
required: false, required: false,
default: '', default: '',
description: `Timestamp that denotes when the first response is due`, description: `Timestamp that denotes when the first response is due`,
@ -467,80 +491,80 @@ export class Freshdesk implements INodeType {
}, },
] ]
}, },
{ // {
displayName: 'Custom Fields', // displayName: 'Custom Fields',
name: 'customFieldsUi', // name: 'customFieldsUi',
placeholder: 'Add Custom fields', // placeholder: 'Add Custom fields',
type: 'fixedCollection', // type: 'fixedCollection',
required: false, // required: false,
default: '', // default: '',
typeOptions: { // typeOptions: {
multipleValues: true, // multipleValues: true,
}, // },
displayOptions: { // displayOptions: {
show: { // show: {
resource: [ // resource: [
'ticket' // 'ticket'
], // ],
operation: [ // operation: [
'create' // 'create'
], // ],
jsonParameters: [ // jsonParameters: [
false, // false,
], // ],
}, // },
}, // },
description: 'Key value pairs containing the names and values of custom fields.', // description: 'Key value pairs containing the names and values of custom fields.',
options: [ // options: [
{ // {
name: 'customFieldsValues', // name: 'customFieldsValues',
displayName: 'Custom fields', // displayName: 'Custom fields',
values: [ // values: [
{ // {
displayName: 'Key', // displayName: 'Key',
required: false, // required: false,
name: 'key', // name: 'key',
type: 'string', // type: 'string',
default: '', // default: '',
}, // },
{ // {
displayName: 'Value', // displayName: 'Value',
name: 'value', // name: 'value',
type: 'string', // type: 'string',
required: false, // required: false,
default: '', // default: '',
}, // },
], // ],
}, // },
], // ],
}, // },
{ // {
displayName: 'Custom Fields', // displayName: 'Custom Fields',
name: 'customFieldsJson', // name: 'customFieldsJson',
type: 'json', // type: 'json',
typeOptions: { // typeOptions: {
alwaysOpenEditWindow: true, // alwaysOpenEditWindow: true,
}, // },
displayOptions: { // displayOptions: {
show: { // show: {
resource: [ // resource: [
'ticket' // 'ticket'
], // ],
operation: [ // operation: [
'create' // 'create'
], // ],
jsonParameters: [ // jsonParameters: [
true, // true,
], // ],
}, // },
}, // },
default: '', // default: '',
required: false, // required: false,
placeholder: `{ // placeholder: `{
"gadget":"Cold Welder" // "gadget":"Cold Welder"
}`, // }`,
description: 'Key value pairs containing the names and values of custom fields.', // description: 'Key value pairs containing the names and values of custom fields.',
}, // },
] ]
}; };
@ -637,10 +661,124 @@ export class Freshdesk implements INodeType {
}; };
async executeSingle(this: IExecuteSingleFunctions): Promise<INodeExecutionData> { async executeSingle(this: IExecuteSingleFunctions): Promise<INodeExecutionData> {
const resource = this.getNodeParameter('resource') as string;
const opeation = this.getNodeParameter('operation') as string;
let response;
if (resource === 'ticket') {
if (opeation === 'create') {
const requester = this.getNodeParameter('requester') as string;
const value = this.getNodeParameter('requesterIdentificationValue') as string;
const status = this.getNodeParameter('status') as string;
const priority = this.getNodeParameter('priority') as string;
const source = this.getNodeParameter('source') as string;
const options = this.getNodeParameter('options') 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)]
};
if (requester === 'requesterId') {
// @ts-ignore
if (isNaN(value)) {
throw new Error('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;
}
// 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 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) {
options.responder_id = options.agent as number;
}
if (options.company) {
options.company_id = options.company as number;
}
if (options.product) {
options.product_id = options.product as number;
}
if (options.group) {
options.group_id = options.group as number;
}
if (options.frDueBy) {
options.fr_due_by = options.frDueBy as string;
}
if (options.emailConfigId) {
options.email_config_id = options.emailConfigId as number;
}
if (options.dueBy) {
options.due_by = options.dueBy as string;
}
if (options.ccEmails) {
// @ts-ignore
options.cc_emails = options.ccEmails.split(',') as [string];
}
try {
response = await freshdeskApiRequest.call(this, '/tickets', 'POST', body);
} catch (err) {
throw new Error(`Freskdesk Error: ${JSON.stringify(err)}`);
}
}
}
return { return {
json: {} json: response
}; };
} }
} }

View file

@ -9,7 +9,6 @@ import {
} from 'n8n-core'; } from 'n8n-core';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { IDataObject } from 'n8n-workflow';
export async function freshdeskApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, resource: string, method: string, body: any = {}, headers?: object): Promise<any> { // tslint:disable-line:no-any export async function freshdeskApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, resource: string, method: string, body: any = {}, headers?: object): Promise<any> { // tslint:disable-line:no-any
@ -50,3 +49,18 @@ export async function freshdeskApiRequest(this: IHookFunctions | IExecuteFunctio
throw error.response.body; throw error.response.body;
} }
} }
export function validateJSON(json: string | undefined): any { // tslint:disable-line:no-any
let result;
try {
result = JSON.parse(json!);
} catch (exception) {
result = [];
}
return result;
}
export function capitalize (s: string) : string {
if (typeof s !== 'string') return '';
return s.charAt(0).toUpperCase() + s.slice(1);
}