Add user resource (#892)

This commit is contained in:
Ricardo Espinoza 2020-08-27 02:53:23 -04:00 committed by GitHub
parent 1727b4626b
commit 74e2bcd1e0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 824 additions and 5 deletions

View file

@ -23,7 +23,10 @@ export async function zendeskApiRequest(this: IHookFunctions | IExecuteFunctions
body,
//@ts-ignore
uri,
json: true
json: true,
qsStringifyOptions: {
arrayFormat: 'brackets',
},
};
options = Object.assign({}, options, option);
@ -43,8 +46,6 @@ export async function zendeskApiRequest(this: IHookFunctions | IExecuteFunctions
options.uri = `https://${credentials.subdomain}.zendesk.com/api/v2${resource}.json`;
options.headers!['Authorization'] = `Basic ${base64Key}`;
//console.log(options);
return await this.helpers.request!(options);
} else {
const credentials = this.getCredentials('zendeskOAuth2Api');
@ -58,6 +59,7 @@ export async function zendeskApiRequest(this: IHookFunctions | IExecuteFunctions
return await this.helpers.requestOAuth2!.call(this, 'zendeskOAuth2Api', options);
}
} catch(err) {
let errorMessage = err.message;
if (err.response && err.response.body && err.response.body.error) {
errorMessage = err.response.body.error;

View file

@ -0,0 +1,692 @@
import {
INodeProperties,
} from 'n8n-workflow';
export const userOperations = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'user',
],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a user',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a user',
},
{
name: 'Get',
value: 'get',
description: 'Get a user',
},
{
name: 'Get All',
value: 'getAll',
description: 'Get all users',
},
{
name: 'Update',
value: 'update',
description: 'Update a user',
},
],
default: 'create',
description: 'The operation to perform.',
},
] as INodeProperties[];
export const userFields = [
/* -------------------------------------------------------------------------- */
/* user:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
displayOptions: {
show: {
resource: [
'user',
],
operation: [
'create',
],
},
},
required: true,
description: `The user's name`,
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'user',
],
operation: [
'create',
],
},
},
options: [
{
displayName: 'Alias',
name: 'alis',
type: 'string',
default: '',
description: `An alias displayed to end users`,
},
{
displayName: 'Custom Role ID',
name: 'custom_role_id',
type: 'number',
default: 0,
description: `A custom role if the user is an agent on the Enterprise plan`,
},
{
displayName: 'Details',
name: 'details',
type: 'string',
default: '',
description: 'Any details you want to store about the user, such as an address',
},
{
displayName: 'Email',
name: 'email',
type: 'string',
default: '',
description: `The user's primary email address`,
},
{
displayName: 'External ID',
name: 'externalId',
type: 'string',
default: '',
description: 'A unique identifier from another system',
},
{
displayName: 'Locale ID',
name: 'locale',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLocales',
},
default: '',
description: `The user's locale.`,
},
{
displayName: 'Moderator',
name: 'moderator',
type: 'boolean',
default: false,
description: 'Designates whether the user has forum moderation capabilities',
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Any notes you want to store about the user',
},
{
displayName: 'Only Private Comments',
name: 'only_private_comments',
type: 'boolean',
default: false,
description: `true if the user can only create private comments`,
},
{
displayName: 'Organization ID',
name: 'organizationId',
type: 'number',
default: 0,
description: `The id of the user's organization. If the user has more than one organization memberships, the id of the user's default organization`,
},
{
displayName: 'Phone',
name: 'phone',
type: 'string',
default: '',
description: `The user's primary phone number.`,
},
{
displayName: 'Report CSV',
name: 'report_csv',
type: 'boolean',
default: false,
description: `Whether or not the user can access the CSV report on the Search tab of the Reporting page in the Support admin interface.`,
},
{
displayName: 'Restricted Agent',
name: 'restricted_agent',
type: 'boolean',
default: false,
description: `If the agent has any restrictions; false for admins and unrestricted agents, true for other agents`,
},
{
displayName: 'Role',
name: 'role',
type: 'options',
options: [
{
name: 'End User',
value: 'end-user',
},
{
name: 'Agent',
value: 'agent',
},
{
name: 'Admin',
value: 'admin',
},
],
default: '',
description: `The user's role`,
},
{
displayName: 'Signature',
name: 'signature',
type: 'string',
default: '',
description: `The user's signature. Only agents and admins can have signatures`,
},
{
displayName: 'Suspended',
name: 'suspended',
type: 'boolean',
default: false,
description: `If the agent is suspended. Tickets from suspended users are also suspended, and these users cannot sign in to the end user portal`,
},
{
displayName: 'Tags',
name: 'tags',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getTags',
},
default: [],
description: 'The array of tags applied to this user',
},
{
displayName: 'Ticket Restriction',
name: 'ticket_restriction',
type: 'options',
options: [
{
name: 'Organization',
value: 'organization',
},
{
name: 'Groups',
value: 'groups',
},
{
name: 'Assigned',
value: 'assigned',
},
{
name: 'Requested',
value: 'requested',
},
],
default: '',
description: `Specifies which tickets the user has access to`,
},
{
displayName: 'Timezone',
name: 'time_zone',
type: 'string',
default: '',
description: `The user's time zone.`,
},
{
displayName: 'User Fields',
name: 'userFieldsUi',
placeholder: 'Add User Field',
description: `Values of custom fields in the user's profile.`,
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
default: {},
options: [
{
name: 'userFieldValues',
displayName: 'Field',
values: [
{
displayName: 'Field',
name: 'field',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getUserFields',
},
default: '',
description: 'Name of the field to sort on.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'Value of the field.',
},
],
},
],
},
{
displayName: 'Verified',
name: 'verified',
type: 'boolean',
default: false,
description: `The user's primary identity is verified or not`,
},
],
},
/* -------------------------------------------------------------------------- */
/* user:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'User ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
resource: [
'user',
],
operation: [
'update',
],
},
},
description: 'User ID',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'user',
],
operation: [
'update',
],
},
},
options: [
{
displayName: 'Alias',
name: 'alis',
type: 'string',
default: '',
description: `An alias displayed to end users`,
},
{
displayName: 'Custom Role ID',
name: 'custom_role_id',
type: 'number',
default: 0,
description: `A custom role if the user is an agent on the Enterprise plan`,
},
{
displayName: 'Details',
name: 'details',
type: 'string',
default: '',
description: 'Any details you want to store about the user, such as an address',
},
{
displayName: 'Email',
name: 'email',
type: 'string',
default: '',
description: `The user's primary email address`,
},
{
displayName: 'External ID',
name: 'externalId',
type: 'string',
default: '',
description: 'A unique identifier from another system',
},
{
displayName: 'Locale ID',
name: 'locale',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLocales',
},
default: '',
description: `The user's locale.`,
},
{
displayName: 'Moderator',
name: 'moderator',
type: 'boolean',
default: false,
description: 'Designates whether the user has forum moderation capabilities',
},
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: `The user's name`,
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Any notes you want to store about the user',
},
{
displayName: 'Only Private Comments',
name: 'only_private_comments',
type: 'boolean',
default: false,
description: `true if the user can only create private comments`,
},
{
displayName: 'Organization ID',
name: 'organizationId',
type: 'number',
default: 0,
description: `The id of the user's organization. If the user has more than one organization memberships, the id of the user's default organization`,
},
{
displayName: 'Phone',
name: 'phone',
type: 'string',
default: '',
description: `The user's primary phone number.`,
},
{
displayName: 'Report CSV',
name: 'report_csv',
type: 'boolean',
default: false,
description: `Whether or not the user can access the CSV report on the Search tab of the Reporting page in the Support admin interface.`,
},
{
displayName: 'Restricted Agent',
name: 'restricted_agent',
type: 'boolean',
default: false,
description: `If the agent has any restrictions; false for admins and unrestricted agents, true for other agents`,
},
{
displayName: 'Role',
name: 'role',
type: 'options',
options: [
{
name: 'End User',
value: 'end-user',
},
{
name: 'Agent',
value: 'agent',
},
{
name: 'Admin',
value: 'admin',
},
],
default: '',
description: `The user's role`,
},
{
displayName: 'Signature',
name: 'signature',
type: 'string',
default: '',
description: `The user's signature. Only agents and admins can have signatures`,
},
{
displayName: 'Suspended',
name: 'suspended',
type: 'boolean',
default: false,
description: `If the agent is suspended. Tickets from suspended users are also suspended, and these users cannot sign in to the end user portal`,
},
{
displayName: 'Tags',
name: 'tags',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getTags',
},
default: [],
description: 'The array of tags applied to this user',
},
{
displayName: 'Ticket Restriction',
name: 'ticket_restriction',
type: 'options',
options: [
{
name: 'Organization',
value: 'organization',
},
{
name: 'Groups',
value: 'groups',
},
{
name: 'Assigned',
value: 'assigned',
},
{
name: 'Requested',
value: 'requested',
},
],
default: '',
description: `Specifies which tickets the user has access to`,
},
{
displayName: 'Timezone',
name: 'time_zone',
type: 'string',
default: '',
description: `The user's time zone.`,
},
{
displayName: 'User Fields',
name: 'userFieldsUi',
placeholder: 'Add User Field',
description: `Values of custom fields in the user's profile.`,
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
default: {},
options: [
{
name: 'userFieldValues',
displayName: 'Field',
values: [
{
displayName: 'Field',
name: 'field',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getUserFields',
},
default: '',
description: 'Name of the field to sort on.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'Value of the field.',
},
],
},
],
},
{
displayName: 'Verified',
name: 'verified',
type: 'boolean',
default: false,
description: `The user's primary identity is verified or not`,
},
],
},
/* -------------------------------------------------------------------------- */
/* user:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'User ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
resource: [
'user',
],
operation: [
'get',
],
},
},
description: 'User ID',
},
/* -------------------------------------------------------------------------- */
/* user:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: [
'user',
],
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: [
'user',
],
operation: [
'getAll',
],
returnAll: [
false,
],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 100,
description: 'How many results to return.',
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Filter',
default: {},
displayOptions: {
show: {
resource: [
'user',
],
operation: [
'getAll',
],
},
},
options: [
{
displayName: 'Roles',
name: 'role',
type: 'multiOptions',
options: [
{
name: 'End User',
value: 'end-user',
},
{
name: 'Agent',
value: 'agent',
},
{
name: 'Admin',
value: 'admin',
},
],
default: [],
},
],
},
/* -------------------------------------------------------------------------- */
/* user:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'User ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
resource: [
'user',
],
operation: [
'delete',
],
},
},
description: 'User ID',
},
] as INodeProperties[];

View file

@ -27,11 +27,15 @@ import {
ticketFieldOperations
} from './TicketFieldDescription';
import {
userFields,
userOperations
} from './UserDescription';
import {
ITicket,
IComment,
} from './TicketInterface';
import { response } from 'express';
export class Zendesk implements INodeType {
description: INodeTypeDescription = {
@ -105,6 +109,11 @@ export class Zendesk implements INodeType {
value: 'ticketField',
description: 'Manage system and custom ticket fields',
},
{
name: 'User',
value: 'user',
description: 'Manage users',
},
],
default: 'ticket',
description: 'Resource to consume.',
@ -112,9 +121,12 @@ export class Zendesk implements INodeType {
// TICKET
...ticketOperations,
...ticketFields,
// TICKET FIELDS
// TICKET FIELD
...ticketFieldOperations,
...ticketFieldFields,
// USER
...userOperations,
...userFields,
],
};
@ -177,6 +189,38 @@ export class Zendesk implements INodeType {
}
return returnData;
},
// Get all the locales to display them to user so that he can
// select them easily
async getLocales(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const locales = await zendeskApiRequestAllItems.call(this, 'locales', 'GET', '/locales');
for (const locale of locales) {
const localeName = `${locale.locale} - ${locale.name}`;
const localeId = locale.locale;
returnData.push({
name: localeName,
value: localeId,
});
}
return returnData;
},
// Get all the user fields to display them to user so that he can
// select them easily
async getUserFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const fields = await zendeskApiRequestAllItems.call(this, 'user_fields', 'GET', '/user_fields');
for (const field of fields) {
const fieldName = field.title;
const fieldId = field.key;
returnData.push({
name: fieldName,
value: fieldId,
});
}
return returnData;
},
}
};
@ -359,6 +403,87 @@ export class Zendesk implements INodeType {
}
}
}
//https://developer.zendesk.com/rest_api/docs/support/users
if (resource === 'user') {
//https://developer.zendesk.com/rest_api/docs/support/users#create-user
if (operation === 'create') {
const name = this.getNodeParameter('name', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
const body: IDataObject = {
name,
};
Object.assign(body, additionalFields);
if (body.userFieldsUi) {
const userFields = (body.userFieldsUi as IDataObject).userFieldValues as IDataObject[];
if (userFields) {
body.user_fields = {};
for (const userField of userFields) {
//@ts-ignore
body.user_fields[userField.field] = userField.value;
}
delete body.userFieldsUi;
}
}
responseData = await zendeskApiRequest.call(this, 'POST', '/users', { user: body });
responseData = responseData.user;
}
//https://developer.zendesk.com/rest_api/docs/support/tickets#update-ticket
if (operation === 'update') {
const userId = this.getNodeParameter('id', i) as string;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
const body: IDataObject = {};
Object.assign(body, updateFields);
if (body.userFieldsUi) {
const userFields = (body.userFieldsUi as IDataObject).userFieldValues as IDataObject[];
if (userFields) {
body.user_fields = {};
for (const userField of userFields) {
//@ts-ignore
body.user_fields[userField.field] = userField.value;
}
delete body.userFieldsUi;
}
}
responseData = await zendeskApiRequest.call(this, 'PUT', `/users/${userId}`, { user: body });
responseData = responseData.user;
}
//https://developer.zendesk.com/rest_api/docs/support/users#show-user
if (operation === 'get') {
const userId = this.getNodeParameter('id', i) as string;
responseData = await zendeskApiRequest.call(this, 'GET', `/users/${userId}`, {});
responseData = responseData.user;
}
//https://developer.zendesk.com/rest_api/docs/support/users#list-users
if (operation === 'getAll') {
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
const options = this.getNodeParameter('filters', i) as IDataObject;
Object.assign(qs, options);
if (returnAll) {
responseData = await zendeskApiRequestAllItems.call(this, 'users', 'GET', `/users`, {}, qs);
} else {
const limit = this.getNodeParameter('limit', i) as number;
qs.per_page = limit;
responseData = await zendeskApiRequest.call(this, 'GET', `/users`, {}, qs);
responseData = responseData.users;
}
}
//https://developer.zendesk.com/rest_api/docs/support/users#delete-user
if (operation === 'delete') {
const userId = this.getNodeParameter('id', i) as string;
responseData = await zendeskApiRequest.call(this, 'DELETE', `/users/${userId}`, {});
responseData = responseData.user;
}
}
if (Array.isArray(responseData)) {
returnData.push.apply(returnData, responseData as IDataObject[]);
} else {