mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 10:02:05 +00:00
UI changes
This commit is contained in:
@@ -9,10 +9,23 @@ export class FreshdeskApi implements ICredentialType {
|
|||||||
displayName = 'Freshdesk API';
|
displayName = 'Freshdesk API';
|
||||||
properties = [
|
properties = [
|
||||||
{
|
{
|
||||||
displayName: 'API Key',
|
displayName: 'Username',
|
||||||
name: 'apiKey',
|
name: 'username',
|
||||||
type: 'string' as NodePropertyTypes,
|
type: 'string' as NodePropertyTypes,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Password',
|
||||||
|
name: 'password',
|
||||||
|
type: 'password' as NodePropertyTypes,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Domain',
|
||||||
|
name: 'domain',
|
||||||
|
type: 'string' as NodePropertyTypes,
|
||||||
|
default: '',
|
||||||
|
placeholder: 'https://domain.freshdesk.com'
|
||||||
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
454
packages/nodes-base/nodes/Freshdesk/Freshdesk.node.ts
Normal file
454
packages/nodes-base/nodes/Freshdesk/Freshdesk.node.ts
Normal file
@@ -0,0 +1,454 @@
|
|||||||
|
import {
|
||||||
|
IExecuteSingleFunctions,
|
||||||
|
} from 'n8n-core';
|
||||||
|
import {
|
||||||
|
IDataObject,
|
||||||
|
INodeTypeDescription,
|
||||||
|
INodeExecutionData,
|
||||||
|
INodeType,
|
||||||
|
ILoadOptionsFunctions,
|
||||||
|
INodePropertyOptions,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
import {
|
||||||
|
freshdeskApiRequest
|
||||||
|
} from './GenericFunctions';
|
||||||
|
|
||||||
|
import moment = require('moment');
|
||||||
|
import _ = require('lodash')
|
||||||
|
|
||||||
|
enum Status {
|
||||||
|
Open = 1,
|
||||||
|
Pending = 2,
|
||||||
|
Resolved = 3,
|
||||||
|
Closed = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Priority {
|
||||||
|
Low = 1,
|
||||||
|
Medium = 2,
|
||||||
|
High = 3,
|
||||||
|
Urgent = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICreateTicketBody {
|
||||||
|
name?: string;
|
||||||
|
requester_id?: number;
|
||||||
|
email?: string;
|
||||||
|
facebook_id?: string;
|
||||||
|
phone?: string;
|
||||||
|
twitter_id?: string;
|
||||||
|
unique_external_id?: string,
|
||||||
|
subject?: string,
|
||||||
|
type?: string,
|
||||||
|
status: Status,
|
||||||
|
priority: Priority,
|
||||||
|
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;
|
||||||
|
source: number;
|
||||||
|
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',
|
||||||
|
color: '#c02428',
|
||||||
|
},
|
||||||
|
inputs: ['main'],
|
||||||
|
outputs: ['main'],
|
||||||
|
credentials: [
|
||||||
|
{
|
||||||
|
name: 'freshdeskApi',
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
properties: [
|
||||||
|
{
|
||||||
|
displayName: 'Resource',
|
||||||
|
name: 'resource',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Ticket',
|
||||||
|
value: 'ticket',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'ticket',
|
||||||
|
description: 'The resource to operate on.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'ticket',
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Create',
|
||||||
|
value: 'create',
|
||||||
|
description: 'Create a new ticket',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
default: 'create',
|
||||||
|
description: 'The operation to perform.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Requester Identification',
|
||||||
|
name: 'requester',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'ticket',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
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: '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: '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: [
|
||||||
|
'create'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: `Value of the identification selected `,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Status',
|
||||||
|
name: 'status',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'ticket',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Open',
|
||||||
|
value: 'open',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Pending',
|
||||||
|
value: 'pending',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Resolved',
|
||||||
|
value: 'resolved',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Closed',
|
||||||
|
value: 'closed',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
default: 'pending',
|
||||||
|
description: 'Status',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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',
|
||||||
|
description: 'Priority',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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: 'Name',
|
||||||
|
name: 'name',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: '',
|
||||||
|
description: 'Name of the requester',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Subject',
|
||||||
|
name: 'subject',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: '',
|
||||||
|
description: 'Subject of the ticket.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Type',
|
||||||
|
name: 'type',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Helps categorize the ticket according to the different kinds of issues your support team deals with.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Description',
|
||||||
|
name: 'description',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
rows: 5,
|
||||||
|
alwaysOpenEditWindow: true,
|
||||||
|
},
|
||||||
|
description: 'HTML content of the ticket.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Agent',
|
||||||
|
name: 'agent',
|
||||||
|
type: 'options',
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getAgents'
|
||||||
|
},
|
||||||
|
description: 'ID of the agent to whom the ticket has been assigned',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'CC Emails',
|
||||||
|
name: 'ccEmails',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: `separated by , email addresses added in the 'cc' field of the incoming ticket email`,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Custom Fields',
|
||||||
|
name: 'customFieldsUi',
|
||||||
|
placeholder: 'Add Custom fields',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
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',
|
||||||
|
name: 'key',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Value',
|
||||||
|
name: 'value',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Custom Fields',
|
||||||
|
name: 'customFieldsJson',
|
||||||
|
type: 'json',
|
||||||
|
typeOptions: {
|
||||||
|
alwaysOpenEditWindow: true,
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'ticket'
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create'
|
||||||
|
],
|
||||||
|
jsonParameters: [
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
placeholder: `{
|
||||||
|
"gadget":"Cold Welder"
|
||||||
|
}`,
|
||||||
|
description: 'Key value pairs containing the names and values of custom fields.',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
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[] = [];
|
||||||
|
let agents;
|
||||||
|
try {
|
||||||
|
agents = await freshdeskApiRequest.call(this, '/agents', 'GET');
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`Mandrill Error: ${err}`);
|
||||||
|
}
|
||||||
|
for (const agent of agents) {
|
||||||
|
const agentName = agent.contact.name;
|
||||||
|
const agentId = agent.id;
|
||||||
|
|
||||||
|
returnData.push({
|
||||||
|
name: agentName,
|
||||||
|
value: agentId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnData;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async executeSingle(this: IExecuteSingleFunctions): Promise<INodeExecutionData> {
|
||||||
|
|
||||||
|
return {
|
||||||
|
json: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
import {
|
|
||||||
IExecuteSingleFunctions,
|
|
||||||
} from 'n8n-core';
|
|
||||||
import {
|
|
||||||
IDataObject,
|
|
||||||
INodeTypeDescription,
|
|
||||||
INodeExecutionData,
|
|
||||||
INodeType,
|
|
||||||
ILoadOptionsFunctions,
|
|
||||||
INodePropertyOptions,
|
|
||||||
} from 'n8n-workflow';
|
|
||||||
import {
|
|
||||||
freshdeskApiRequest
|
|
||||||
} from './GenericFunctions';
|
|
||||||
|
|
||||||
import moment = require('moment');
|
|
||||||
import _ = require('lodash')
|
|
||||||
|
|
||||||
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',
|
|
||||||
color: '#c02428',
|
|
||||||
},
|
|
||||||
inputs: ['main'],
|
|
||||||
outputs: ['main'],
|
|
||||||
credentials: [
|
|
||||||
{
|
|
||||||
name: 'freshdeskApi',
|
|
||||||
required: true,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
properties: [
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
methods = {
|
|
||||||
loadOptions: {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// async executeSingle(this: IExecuteSingleFunctions): Promise<INodeExecutionData> {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
@@ -4,31 +4,38 @@ import {
|
|||||||
IExecuteFunctions,
|
IExecuteFunctions,
|
||||||
IHookFunctions,
|
IHookFunctions,
|
||||||
ILoadOptionsFunctions,
|
ILoadOptionsFunctions,
|
||||||
IExecuteSingleFunctions
|
IExecuteSingleFunctions,
|
||||||
|
BINARY_ENCODING
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { IDataObject } from 'n8n-workflow';
|
import { IDataObject } from 'n8n-workflow';
|
||||||
|
|
||||||
export async function freshdeskApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, resource: string, method: string, action: 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
|
||||||
const credentials = this.getCredentials('mandrillApi');
|
|
||||||
|
const credentials = this.getCredentials('freshdeskApi');
|
||||||
|
|
||||||
if (credentials === undefined) {
|
if (credentials === undefined) {
|
||||||
throw new Error('No credentials got returned!');
|
throw new Error('No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = Object.assign({}, body, { key: credentials.apiKey });
|
const userpass = `${credentials.username}:${credentials.password}`
|
||||||
|
|
||||||
const endpoint = 'mandrillapp.com/api/1.0';
|
const headerWithAuthentication = Object.assign({}, headers, { Authorization: `Basic ${Buffer.from(userpass).toString(BINARY_ENCODING)}` });
|
||||||
|
|
||||||
|
const endpoint = 'freshdesk.com/api/v2/';
|
||||||
|
|
||||||
const options: OptionsWithUri = {
|
const options: OptionsWithUri = {
|
||||||
headers,
|
headers: headerWithAuthentication,
|
||||||
method,
|
method,
|
||||||
uri: `https://${endpoint}${resource}${action}.json`,
|
body,
|
||||||
body: data,
|
uri: `https://${credentials.domain}.${endpoint}${resource}`,
|
||||||
json: true
|
json: true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (_.isEmpty(options.body)) {
|
||||||
|
delete options.body
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await this.helpers.request!(options);
|
return await this.helpers.request!(options);
|
||||||
@@ -36,13 +43,6 @@ export async function freshdeskApiRequest(this: IHookFunctions | IExecuteFunctio
|
|||||||
console.error(error);
|
console.error(error);
|
||||||
|
|
||||||
const errorMessage = error.response.body.message || error.response.body.Message;
|
const errorMessage = error.response.body.message || error.response.body.Message;
|
||||||
if (error.name === 'Invalid_Key') {
|
|
||||||
throw new Error('The provided API key is not a valid Mandrill API key');
|
|
||||||
} else if (error.name === 'ValidationError') {
|
|
||||||
throw new Error('The parameters passed to the API call are invalid or not provided when required');
|
|
||||||
} else if (error.name === 'GeneralError') {
|
|
||||||
throw new Error('An unexpected error occurred processing the request. Mandrill developers will be notified.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorMessage !== undefined) {
|
if (errorMessage !== undefined) {
|
||||||
throw errorMessage;
|
throw errorMessage;
|
||||||
|
|||||||
Reference in New Issue
Block a user