mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 04:34:06 -08:00
✨ Add Zammad node (#2621)
* add zammad * ⚡ First pass * 👕 Fix lint * ⚡ Refactor user resource * ⚡ Refactor group resource * ⚡ Refactor ticket resource * ⚡ Minor improvements * ⚡ Set workaround for broken endpoints * 👕 Fix lint * ⚡ Fix credentials test * 📦 Update package-lock.json * ⚡ Change defaults for active * ⚡ Refactor creds * 👕 Fix lint * 📦 Update package-lock.json * ⚡ Make first and last name required * ⚡ Replace email with login * ⚡ Switch defaults to true * ⚡ Add custom fields to groups * ⚡ Add inactive entities to loaders * ⚡ Move email to optional fields * ⚡ Validate for empty article * 🔥 Remove `ticket:update` per feedback * 📦 Update package-lock.json * 🚚 Rename import * 👕 Fix lint * ⚡ Small improvements * ⚡ Improvements Co-authored-by: quansenB <inaki.breinbauer@gmail.com> Co-authored-by: ricardo <ricardoespinoza105@gmail.com>
This commit is contained in:
parent
f43a38951c
commit
5528698c31
|
@ -0,0 +1,44 @@
|
||||||
|
import {
|
||||||
|
ICredentialType,
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
export class ZammadBasicAuthApi implements ICredentialType {
|
||||||
|
name = 'zammadBasicAuthApi';
|
||||||
|
displayName = 'Zammad Basic Auth API';
|
||||||
|
documentationUrl = 'zammad';
|
||||||
|
properties: INodeProperties[] = [
|
||||||
|
{
|
||||||
|
displayName: 'Base URL',
|
||||||
|
name: 'baseUrl',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'https://n8n-helpdesk.zammad.com',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Email',
|
||||||
|
name: 'username',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'helpdesk@n8n.io',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Password',
|
||||||
|
name: 'password',
|
||||||
|
type: 'string',
|
||||||
|
typeOptions: {
|
||||||
|
password: true,
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Ignore SSL Issues',
|
||||||
|
name: 'allowUnauthorizedCerts',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
import {
|
||||||
|
ICredentialType,
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
export class ZammadTokenAuthApi implements ICredentialType {
|
||||||
|
name = 'zammadTokenAuthApi';
|
||||||
|
displayName = 'Zammad Token Auth API';
|
||||||
|
documentationUrl = 'zammad';
|
||||||
|
properties: INodeProperties[] = [
|
||||||
|
{
|
||||||
|
displayName: 'Base URL',
|
||||||
|
name: 'baseUrl',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'https://n8n-helpdesk.zammad.com',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Access Token',
|
||||||
|
name: 'accessToken',
|
||||||
|
type: 'string',
|
||||||
|
typeOptions: {
|
||||||
|
password: true,
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Ignore SSL Issues',
|
||||||
|
name: 'allowUnauthorizedCerts',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
166
packages/nodes-base/nodes/Zammad/GenericFunctions.ts
Normal file
166
packages/nodes-base/nodes/Zammad/GenericFunctions.ts
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
import {
|
||||||
|
IExecuteFunctions,
|
||||||
|
} from 'n8n-core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
IDataObject,
|
||||||
|
ILoadOptionsFunctions,
|
||||||
|
NodeApiError,
|
||||||
|
NodeOperationError,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import {
|
||||||
|
OptionsWithUri,
|
||||||
|
} from 'request';
|
||||||
|
|
||||||
|
import {
|
||||||
|
flow,
|
||||||
|
} from 'lodash';
|
||||||
|
|
||||||
|
import type { Zammad } from './types';
|
||||||
|
|
||||||
|
export async function zammadApiRequest(
|
||||||
|
this: IExecuteFunctions | ILoadOptionsFunctions,
|
||||||
|
method: string,
|
||||||
|
endpoint: string,
|
||||||
|
body: IDataObject = {},
|
||||||
|
qs: IDataObject = {},
|
||||||
|
) {
|
||||||
|
const options: OptionsWithUri = {
|
||||||
|
method,
|
||||||
|
body,
|
||||||
|
qs,
|
||||||
|
uri: '',
|
||||||
|
json: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const authentication = this.getNodeParameter('authentication', 0) as 'basicAuth' | 'tokenAuth';
|
||||||
|
|
||||||
|
if (authentication === 'basicAuth') {
|
||||||
|
|
||||||
|
const credentials = await this.getCredentials('zammadBasicAuthApi') as Zammad.BasicAuthCredentials;
|
||||||
|
|
||||||
|
const baseUrl = tolerateTrailingSlash(credentials.baseUrl);
|
||||||
|
|
||||||
|
options.uri = `${baseUrl}/api/v1${endpoint}`;
|
||||||
|
|
||||||
|
options.auth = {
|
||||||
|
user: credentials.username,
|
||||||
|
pass: credentials.password,
|
||||||
|
};
|
||||||
|
|
||||||
|
options.rejectUnauthorized = !credentials.allowUnauthorizedCerts;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const credentials = await this.getCredentials('zammadTokenAuthApi') as Zammad.TokenAuthCredentials;
|
||||||
|
|
||||||
|
const baseUrl = tolerateTrailingSlash(credentials.baseUrl);
|
||||||
|
|
||||||
|
options.uri = `${baseUrl}/api/v1${endpoint}`;
|
||||||
|
|
||||||
|
options.headers = {
|
||||||
|
Authorization: `Token token=${credentials.accessToken}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
options.rejectUnauthorized = !credentials.allowUnauthorizedCerts;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Object.keys(body).length) {
|
||||||
|
delete options.body;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Object.keys(qs).length) {
|
||||||
|
delete options.qs;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await this.helpers.request!(options);
|
||||||
|
} catch (error) {
|
||||||
|
if (error.error.error === 'Object already exists!') {
|
||||||
|
error.error.error = 'An entity with this name already exists.';
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function zammadApiRequestAllItems(
|
||||||
|
this: IExecuteFunctions | ILoadOptionsFunctions,
|
||||||
|
method: string,
|
||||||
|
endpoint: string,
|
||||||
|
body: IDataObject = {},
|
||||||
|
qs: IDataObject = {},
|
||||||
|
limit = 0,
|
||||||
|
) {
|
||||||
|
// https://docs.zammad.org/en/latest/api/intro.html#pagination
|
||||||
|
|
||||||
|
const returnData: IDataObject[] = [];
|
||||||
|
|
||||||
|
let responseData;
|
||||||
|
qs.per_page = 20;
|
||||||
|
qs.page = 1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
responseData = await zammadApiRequest.call(this, method, endpoint, body, qs);
|
||||||
|
returnData.push(...responseData);
|
||||||
|
|
||||||
|
if (limit && returnData.length > limit) {
|
||||||
|
return returnData.slice(0, limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
qs.page++;
|
||||||
|
} while (responseData.length);
|
||||||
|
|
||||||
|
return returnData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function tolerateTrailingSlash(url: string) {
|
||||||
|
return url.endsWith('/')
|
||||||
|
? url.substr(0, url.length - 1)
|
||||||
|
: url;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function throwOnEmptyUpdate(this: IExecuteFunctions, resource: string) {
|
||||||
|
throw new NodeOperationError(
|
||||||
|
this.getNode(),
|
||||||
|
`Please enter at least one field to update for the ${resource}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// loadOptions utils
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
export const fieldToLoadOption = (i: Zammad.Field) => {
|
||||||
|
return { name: i.display ? prettifyDisplayName(i.display) : i.name, value: i.name };
|
||||||
|
};
|
||||||
|
|
||||||
|
export const prettifyDisplayName = (fieldName: string) => fieldName.replace('name', ' Name');
|
||||||
|
|
||||||
|
export const isCustomer = (user: Zammad.User) =>
|
||||||
|
user.role_ids.includes(3) && !user.email.endsWith('@zammad.org');
|
||||||
|
|
||||||
|
export async function getAllFields(this: ILoadOptionsFunctions) {
|
||||||
|
return await zammadApiRequest.call(this, 'GET', '/object_manager_attributes') as Zammad.Field[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const isTypeField = (resource: 'Group' | 'Organization' | 'Ticket' | 'User') =>
|
||||||
|
(arr: Zammad.Field[]) => arr.filter(i => i.object === resource);
|
||||||
|
|
||||||
|
export const getGroupFields = isTypeField('Group');
|
||||||
|
export const getOrganizationFields = isTypeField('Organization');
|
||||||
|
export const getUserFields = isTypeField('User');
|
||||||
|
export const getTicketFields = isTypeField('Ticket');
|
||||||
|
|
||||||
|
const getCustomFields = (arr: Zammad.Field[]) => arr.filter(i => i.created_by_id !== 1);
|
||||||
|
|
||||||
|
export const getGroupCustomFields = flow(getGroupFields, getCustomFields);
|
||||||
|
export const getOrganizationCustomFields = flow(getOrganizationFields, getCustomFields);
|
||||||
|
export const getUserCustomFields = flow(getUserFields, getCustomFields);
|
||||||
|
export const getTicketCustomFields = flow(getTicketFields, getCustomFields);
|
||||||
|
|
||||||
|
export const isNotZammadFoundation = (i: Zammad.Organization) => i.name !== 'Zammad Foundation';
|
||||||
|
|
||||||
|
export const doesNotBelongToZammad = (i: Zammad.User) => !i.email.endsWith('@zammad.org') && i.login !== '-';
|
20
packages/nodes-base/nodes/Zammad/Zammad.node.json
Normal file
20
packages/nodes-base/nodes/Zammad/Zammad.node.json
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"node": "n8n-nodes-base.zammad",
|
||||||
|
"nodeVersion": "1.0",
|
||||||
|
"codexVersion": "1.0",
|
||||||
|
"categories": [
|
||||||
|
"Communication"
|
||||||
|
],
|
||||||
|
"resources": {
|
||||||
|
"credentialDocumentation": [
|
||||||
|
{
|
||||||
|
"url": "https://docs.n8n.io/credentials/zammad/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryDocumentation": [
|
||||||
|
{
|
||||||
|
"url": "https://docs.n8n.io/nodes/n8n-nodes-base.zammad/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
782
packages/nodes-base/nodes/Zammad/Zammad.node.ts
Normal file
782
packages/nodes-base/nodes/Zammad/Zammad.node.ts
Normal file
|
@ -0,0 +1,782 @@
|
||||||
|
import {
|
||||||
|
IExecuteFunctions,
|
||||||
|
} from 'n8n-core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ICredentialsDecrypted,
|
||||||
|
ICredentialTestFunctions,
|
||||||
|
IDataObject,
|
||||||
|
ILoadOptionsFunctions,
|
||||||
|
INodeCredentialTestResult,
|
||||||
|
INodeExecutionData,
|
||||||
|
INodeType,
|
||||||
|
INodeTypeDescription,
|
||||||
|
NodeOperationError,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import {
|
||||||
|
OptionsWithUri,
|
||||||
|
} from 'request';
|
||||||
|
|
||||||
|
import {
|
||||||
|
groupDescription,
|
||||||
|
organizationDescription,
|
||||||
|
ticketDescription,
|
||||||
|
userDescription,
|
||||||
|
} from './descriptions';
|
||||||
|
|
||||||
|
import {
|
||||||
|
doesNotBelongToZammad,
|
||||||
|
fieldToLoadOption,
|
||||||
|
getAllFields,
|
||||||
|
getGroupCustomFields,
|
||||||
|
getGroupFields,
|
||||||
|
getOrganizationCustomFields,
|
||||||
|
getOrganizationFields,
|
||||||
|
getTicketCustomFields,
|
||||||
|
getTicketFields,
|
||||||
|
getUserCustomFields,
|
||||||
|
getUserFields,
|
||||||
|
isCustomer,
|
||||||
|
isNotZammadFoundation,
|
||||||
|
throwOnEmptyUpdate,
|
||||||
|
tolerateTrailingSlash,
|
||||||
|
zammadApiRequest,
|
||||||
|
zammadApiRequestAllItems,
|
||||||
|
} from './GenericFunctions';
|
||||||
|
|
||||||
|
import type { Zammad as ZammadTypes } from './types';
|
||||||
|
|
||||||
|
export class Zammad implements INodeType {
|
||||||
|
description: INodeTypeDescription = {
|
||||||
|
displayName: 'Zammad',
|
||||||
|
name: 'zammad',
|
||||||
|
icon: 'file:zammad.svg',
|
||||||
|
group: ['input'],
|
||||||
|
version: 1,
|
||||||
|
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
||||||
|
description: 'Consume the Zammad API',
|
||||||
|
defaults: {
|
||||||
|
name: 'Zammad',
|
||||||
|
},
|
||||||
|
inputs: [
|
||||||
|
'main',
|
||||||
|
],
|
||||||
|
outputs: [
|
||||||
|
'main',
|
||||||
|
],
|
||||||
|
credentials: [
|
||||||
|
{
|
||||||
|
name: 'zammadBasicAuthApi',
|
||||||
|
required: true,
|
||||||
|
testedBy: 'zammadBasicAuthApiTest',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
authentication: [
|
||||||
|
'basicAuth',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'zammadTokenAuthApi',
|
||||||
|
required: true,
|
||||||
|
testedBy: 'zammadTokenAuthApiTest',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
authentication: [
|
||||||
|
'tokenAuth',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
properties: [
|
||||||
|
{
|
||||||
|
displayName: 'Authentication',
|
||||||
|
name: 'authentication',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Basic Auth',
|
||||||
|
value: 'basicAuth',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Token Auth',
|
||||||
|
value: 'tokenAuth',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'tokenAuth',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Resource',
|
||||||
|
name: 'resource',
|
||||||
|
noDataExpression: true,
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Group',
|
||||||
|
value: 'group',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Organization',
|
||||||
|
value: 'organization',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Ticket',
|
||||||
|
value: 'ticket',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'User',
|
||||||
|
value: 'user',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'user',
|
||||||
|
},
|
||||||
|
|
||||||
|
...groupDescription,
|
||||||
|
...organizationDescription,
|
||||||
|
...ticketDescription,
|
||||||
|
...userDescription,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
methods = {
|
||||||
|
loadOptions: {
|
||||||
|
// ----------------------------------
|
||||||
|
// custom fields
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
async loadGroupCustomFields(this: ILoadOptionsFunctions) {
|
||||||
|
const allFields = await getAllFields.call(this);
|
||||||
|
|
||||||
|
return getGroupCustomFields(allFields).map(fieldToLoadOption);
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadOrganizationCustomFields(this: ILoadOptionsFunctions) {
|
||||||
|
const allFields = await getAllFields.call(this);
|
||||||
|
|
||||||
|
return getOrganizationCustomFields(allFields).map(fieldToLoadOption);
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadUserCustomFields(this: ILoadOptionsFunctions) {
|
||||||
|
const allFields = await getAllFields.call(this);
|
||||||
|
|
||||||
|
return getUserCustomFields(allFields).map(fieldToLoadOption);
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadTicketCustomFields(this: ILoadOptionsFunctions) {
|
||||||
|
const allFields = await getAllFields.call(this);
|
||||||
|
|
||||||
|
return getTicketCustomFields(allFields).map((i) => ({ name: i.name, value: i.id }));
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// built-in fields
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
async loadGroupFields(this: ILoadOptionsFunctions) {
|
||||||
|
const allFields = await getAllFields.call(this);
|
||||||
|
|
||||||
|
return getGroupFields(allFields).map(fieldToLoadOption);
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadOrganizationFields(this: ILoadOptionsFunctions) {
|
||||||
|
const allFields = await getAllFields.call(this);
|
||||||
|
|
||||||
|
return getOrganizationFields(allFields).map(fieldToLoadOption);
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadTicketFields(this: ILoadOptionsFunctions) {
|
||||||
|
const allFields = await getAllFields.call(this);
|
||||||
|
|
||||||
|
return getTicketFields(allFields).map(fieldToLoadOption);
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadUserFields(this: ILoadOptionsFunctions) {
|
||||||
|
const allFields = await getAllFields.call(this);
|
||||||
|
|
||||||
|
return getUserFields(allFields).map(fieldToLoadOption);
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// resources
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// by non-ID attribute
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST /tickets requires group name instead of group ID.
|
||||||
|
*/
|
||||||
|
async loadGroupNames(this: ILoadOptionsFunctions) {
|
||||||
|
const groups = await zammadApiRequest.call(this, 'GET', '/groups') as ZammadTypes.Group[];
|
||||||
|
|
||||||
|
return groups.map(i => ({ name: i.name, value: i.name }));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PUT /users requires organization name instead of organization ID.
|
||||||
|
*/
|
||||||
|
async loadOrganizationNames(this: ILoadOptionsFunctions) {
|
||||||
|
const orgs = await zammadApiRequest.call(this, 'GET', '/organizations') as ZammadTypes.Group[];
|
||||||
|
|
||||||
|
return orgs.filter(isNotZammadFoundation).map(i => ({ name: i.name, value: i.name }));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST & PUT /tickets requires customer email instead of customer ID.
|
||||||
|
*/
|
||||||
|
async loadCustomerEmails(this: ILoadOptionsFunctions) {
|
||||||
|
const users = await zammadApiRequest.call(this, 'GET', '/users') as ZammadTypes.User[];
|
||||||
|
|
||||||
|
return users.filter(isCustomer).map(i => ({ name: i.email, value: i.email }));
|
||||||
|
},
|
||||||
|
|
||||||
|
// by ID
|
||||||
|
|
||||||
|
async loadGroups(this: ILoadOptionsFunctions) {
|
||||||
|
const groups = await zammadApiRequest.call(this, 'GET', '/groups') as ZammadTypes.Group[];
|
||||||
|
|
||||||
|
return groups.map(i => ({ name: i.name, value: i.id }));
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadOrganizations(this: ILoadOptionsFunctions) {
|
||||||
|
const orgs = await zammadApiRequest.call(this, 'GET', '/organizations') as ZammadTypes.Organization[];
|
||||||
|
|
||||||
|
return orgs.filter(isNotZammadFoundation).map(i => ({ name: i.name, value: i.id }));
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadUsers(this: ILoadOptionsFunctions) {
|
||||||
|
const users = await zammadApiRequest.call(this, 'GET', '/users') as ZammadTypes.User[];
|
||||||
|
|
||||||
|
return users.filter(doesNotBelongToZammad).map(i => ({ name: i.login, value: i.id }));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
credentialTest: {
|
||||||
|
async zammadBasicAuthApiTest(
|
||||||
|
this: ICredentialTestFunctions,
|
||||||
|
credential: ICredentialsDecrypted,
|
||||||
|
): Promise<INodeCredentialTestResult> {
|
||||||
|
const credentials = credential.data as ZammadTypes.BasicAuthCredentials;
|
||||||
|
|
||||||
|
const baseUrl = tolerateTrailingSlash(credentials.baseUrl);
|
||||||
|
|
||||||
|
const options: OptionsWithUri = {
|
||||||
|
method: 'GET',
|
||||||
|
uri: `${baseUrl}/api/v1/users/me`,
|
||||||
|
json: true,
|
||||||
|
rejectUnauthorized: !credentials.allowUnauthorizedCerts,
|
||||||
|
auth: {
|
||||||
|
user: credentials.username,
|
||||||
|
pass: credentials.password,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.helpers.request(options);
|
||||||
|
return {
|
||||||
|
status: 'OK',
|
||||||
|
message: 'Authentication successful',
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
status: 'Error',
|
||||||
|
message: error.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async zammadTokenAuthApiTest(
|
||||||
|
this: ICredentialTestFunctions,
|
||||||
|
credential: ICredentialsDecrypted,
|
||||||
|
): Promise<INodeCredentialTestResult> {
|
||||||
|
const credentials = credential.data as ZammadTypes.TokenAuthCredentials;
|
||||||
|
|
||||||
|
const baseUrl = tolerateTrailingSlash(credentials.baseUrl);
|
||||||
|
|
||||||
|
const options: OptionsWithUri = {
|
||||||
|
method: 'GET',
|
||||||
|
uri: `${baseUrl}/api/v1/users/me`,
|
||||||
|
json: true,
|
||||||
|
rejectUnauthorized: !credentials.allowUnauthorizedCerts,
|
||||||
|
headers: {
|
||||||
|
Authorization: `Token token=${credentials.accessToken}`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.helpers.request(options);
|
||||||
|
return {
|
||||||
|
status: 'OK',
|
||||||
|
message: 'Authentication successful',
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
status: 'Error',
|
||||||
|
message: error.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||||
|
const items = this.getInputData();
|
||||||
|
|
||||||
|
const resource = this.getNodeParameter('resource', 0) as ZammadTypes.Resource;
|
||||||
|
const operation = this.getNodeParameter('operation', 0) as string;
|
||||||
|
|
||||||
|
let responseData;
|
||||||
|
const returnData: IDataObject[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (resource === 'user') {
|
||||||
|
|
||||||
|
// **********************************************************************
|
||||||
|
// user
|
||||||
|
// **********************************************************************
|
||||||
|
|
||||||
|
if (operation === 'create') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// user:create
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/user.html#create
|
||||||
|
|
||||||
|
const body: IDataObject = {
|
||||||
|
firstname: this.getNodeParameter('firstname', i),
|
||||||
|
lastname: this.getNodeParameter('lastname', i),
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
addressUi,
|
||||||
|
customFieldsUi,
|
||||||
|
...rest
|
||||||
|
} = this.getNodeParameter('additionalFields', i) as ZammadTypes.UserAdditionalFields;
|
||||||
|
|
||||||
|
Object.assign(body, addressUi?.addressDetails);
|
||||||
|
|
||||||
|
customFieldsUi?.customFieldPairs.forEach((pair) => {
|
||||||
|
body[pair['name']] = pair['value'];
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.assign(body, rest);
|
||||||
|
|
||||||
|
responseData = await zammadApiRequest.call(this, 'POST', '/users', body);
|
||||||
|
|
||||||
|
} else if (operation === 'update') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// user:update
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/user.html#update
|
||||||
|
|
||||||
|
const id = this.getNodeParameter('id', i);
|
||||||
|
|
||||||
|
const body: IDataObject = {};
|
||||||
|
|
||||||
|
const updateFields = this.getNodeParameter('updateFields', i) as ZammadTypes.UserUpdateFields;
|
||||||
|
|
||||||
|
if (!Object.keys(updateFields).length) {
|
||||||
|
throwOnEmptyUpdate.call(this, resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { addressUi, customFieldsUi, ...rest } = updateFields;
|
||||||
|
|
||||||
|
Object.assign(body, addressUi?.addressDetails);
|
||||||
|
|
||||||
|
customFieldsUi?.customFieldPairs.forEach((pair) => {
|
||||||
|
body[pair['name']] = pair['value'];
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.assign(body, rest);
|
||||||
|
|
||||||
|
responseData = await zammadApiRequest.call(this, 'PUT', `/users/${id}`, body);
|
||||||
|
|
||||||
|
} else if (operation === 'delete') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// user:delete
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/user.html#delete
|
||||||
|
|
||||||
|
const id = this.getNodeParameter('id', i) as string;
|
||||||
|
|
||||||
|
await zammadApiRequest.call(this, 'DELETE', `/users/${id}`);
|
||||||
|
|
||||||
|
responseData = { success: true };
|
||||||
|
|
||||||
|
} else if (operation === 'get') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// user:get
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/user.html#show
|
||||||
|
|
||||||
|
const id = this.getNodeParameter('id', i) as string;
|
||||||
|
|
||||||
|
responseData = await zammadApiRequest.call(this, 'GET', `/users/${id}`);
|
||||||
|
|
||||||
|
} else if (operation === 'getAll') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// user:getAll
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/user.html#list
|
||||||
|
// https://docs.zammad.org/en/latest/api/user.html#search
|
||||||
|
|
||||||
|
const qs: IDataObject = {};
|
||||||
|
|
||||||
|
const { sortUi, ...rest } = this.getNodeParameter('filters', i) as ZammadTypes.UserFilterFields;
|
||||||
|
|
||||||
|
Object.assign(qs, sortUi?.sortDetails);
|
||||||
|
|
||||||
|
Object.assign(qs, rest);
|
||||||
|
|
||||||
|
qs.query ||= ''; // otherwise triggers 500
|
||||||
|
|
||||||
|
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||||
|
|
||||||
|
const limit = returnAll ? 0 : this.getNodeParameter('limit', i) as number;
|
||||||
|
|
||||||
|
responseData = await zammadApiRequestAllItems.call(
|
||||||
|
this, 'GET', '/users/search', {}, qs, limit,
|
||||||
|
).then(responseData => {
|
||||||
|
return responseData.map(user => {
|
||||||
|
const { preferences, ...rest } = user;
|
||||||
|
return rest;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
} else if (operation === 'getSelf') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// user:me
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/user.html#me-current-user
|
||||||
|
|
||||||
|
responseData = await zammadApiRequest.call(this, 'GET', '/users/me');
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (resource === 'organization') {
|
||||||
|
|
||||||
|
// **********************************************************************
|
||||||
|
// organization
|
||||||
|
// **********************************************************************
|
||||||
|
|
||||||
|
if (operation === 'create') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// organization:create
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/organization.html#create
|
||||||
|
|
||||||
|
const body: IDataObject = {
|
||||||
|
name: this.getNodeParameter('name', i),
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
customFieldsUi,
|
||||||
|
...rest
|
||||||
|
} = this.getNodeParameter('additionalFields', i) as ZammadTypes.UserAdditionalFields;
|
||||||
|
|
||||||
|
customFieldsUi?.customFieldPairs.forEach((pair) => {
|
||||||
|
body[pair['name']] = pair['value'];
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.assign(body, rest);
|
||||||
|
|
||||||
|
responseData = await zammadApiRequest.call(this, 'POST', '/organizations', body);
|
||||||
|
|
||||||
|
} else if (operation === 'update') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// organization:update
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/organization.html#update
|
||||||
|
|
||||||
|
const id = this.getNodeParameter('id', i);
|
||||||
|
|
||||||
|
const body: IDataObject = {};
|
||||||
|
|
||||||
|
const updateFields = this.getNodeParameter('updateFields', i) as ZammadTypes.UserUpdateFields;
|
||||||
|
|
||||||
|
if (!Object.keys(updateFields).length) {
|
||||||
|
throwOnEmptyUpdate.call(this, resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { customFieldsUi, ...rest } = updateFields;
|
||||||
|
|
||||||
|
customFieldsUi?.customFieldPairs.forEach((pair) => {
|
||||||
|
body[pair['name']] = pair['value'];
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.assign(body, rest);
|
||||||
|
|
||||||
|
responseData = await zammadApiRequest.call(this, 'PUT', `/organizations/${id}`, body);
|
||||||
|
|
||||||
|
} else if (operation === 'delete') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// organization:delete
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/organization.html#delete
|
||||||
|
|
||||||
|
const id = this.getNodeParameter('id', i) as string;
|
||||||
|
|
||||||
|
await zammadApiRequest.call(this, 'DELETE', `/organizations/${id}`);
|
||||||
|
|
||||||
|
responseData = { success: true };
|
||||||
|
|
||||||
|
} else if (operation === 'get') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// organization:get
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/organization.html#show
|
||||||
|
|
||||||
|
const id = this.getNodeParameter('id', i) as string;
|
||||||
|
|
||||||
|
responseData = await zammadApiRequest.call(this, 'GET', `/organizations/${id}`);
|
||||||
|
|
||||||
|
} else if (operation === 'getAll') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// organization:getAll
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/organization.html#list
|
||||||
|
// https://docs.zammad.org/en/latest/api/organization.html#search - returning empty always
|
||||||
|
|
||||||
|
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||||
|
|
||||||
|
const limit = returnAll ? 0 : this.getNodeParameter('limit', i) as number;
|
||||||
|
|
||||||
|
responseData = await zammadApiRequestAllItems.call(
|
||||||
|
this, 'GET', '/organizations', {}, {}, limit,
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (resource === 'group') {
|
||||||
|
|
||||||
|
// **********************************************************************
|
||||||
|
// group
|
||||||
|
// **********************************************************************
|
||||||
|
|
||||||
|
if (operation === 'create') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// group:create
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/group.html#create
|
||||||
|
|
||||||
|
const body: IDataObject = {
|
||||||
|
name: this.getNodeParameter('name', i) as string,
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
customFieldsUi,
|
||||||
|
...rest
|
||||||
|
} = this.getNodeParameter('additionalFields', i) as ZammadTypes.UserAdditionalFields;
|
||||||
|
|
||||||
|
customFieldsUi?.customFieldPairs.forEach((pair) => {
|
||||||
|
body[pair['name']] = pair['value'];
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.assign(body, rest);
|
||||||
|
|
||||||
|
responseData = await zammadApiRequest.call(this, 'POST', '/groups', body);
|
||||||
|
|
||||||
|
} else if (operation === 'update') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// group:update
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/group.html#update
|
||||||
|
|
||||||
|
const id = this.getNodeParameter('id', i) as string;
|
||||||
|
|
||||||
|
const body: IDataObject = {};
|
||||||
|
|
||||||
|
const updateFields = this.getNodeParameter('updateFields', i) as ZammadTypes.GroupUpdateFields;
|
||||||
|
|
||||||
|
if (!Object.keys(updateFields).length) {
|
||||||
|
throwOnEmptyUpdate.call(this, resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { customFieldsUi, ...rest } = updateFields;
|
||||||
|
|
||||||
|
customFieldsUi?.customFieldPairs.forEach((pair) => {
|
||||||
|
body[pair['name']] = pair['value'];
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.assign(body, rest);
|
||||||
|
|
||||||
|
responseData = await zammadApiRequest.call(this, 'PUT', `/groups/${id}`, body);
|
||||||
|
|
||||||
|
} else if (operation === 'delete') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// group:delete
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/group.html#delete
|
||||||
|
|
||||||
|
const id = this.getNodeParameter('id', i) as string;
|
||||||
|
|
||||||
|
await zammadApiRequest.call(this, 'DELETE', `/groups/${id}`);
|
||||||
|
|
||||||
|
responseData = { success: true };
|
||||||
|
|
||||||
|
} else if (operation === 'get') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// group:get
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/group.html#show
|
||||||
|
|
||||||
|
const id = this.getNodeParameter('id', i) as string;
|
||||||
|
|
||||||
|
responseData = await zammadApiRequest.call(this, 'GET', `/groups/${id}`);
|
||||||
|
|
||||||
|
} else if (operation === 'getAll') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// group:getAll
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/group.html#list
|
||||||
|
|
||||||
|
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||||
|
|
||||||
|
const limit = returnAll ? 0 : this.getNodeParameter('limit', i) as number;
|
||||||
|
|
||||||
|
responseData = await zammadApiRequestAllItems.call(
|
||||||
|
this, 'GET', '/groups', {}, {}, limit,
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (resource === 'ticket') {
|
||||||
|
|
||||||
|
// **********************************************************************
|
||||||
|
// ticket
|
||||||
|
// **********************************************************************
|
||||||
|
|
||||||
|
if (operation === 'create') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// ticket:create
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/ticket/index.html#create
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
article: {},
|
||||||
|
title: this.getNodeParameter('title', i) as string,
|
||||||
|
group: this.getNodeParameter('group', i) as string,
|
||||||
|
customer: this.getNodeParameter('customer', i) as string,
|
||||||
|
};
|
||||||
|
|
||||||
|
const article = this.getNodeParameter('article', i) as ZammadTypes.Article;
|
||||||
|
|
||||||
|
if (!Object.keys(article).length) {
|
||||||
|
throw new NodeOperationError(this.getNode(), 'Article is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
articleDetails: { visibility, ...rest },
|
||||||
|
} = article;
|
||||||
|
|
||||||
|
body.article = {
|
||||||
|
...rest,
|
||||||
|
internal: visibility === 'internal',
|
||||||
|
};
|
||||||
|
|
||||||
|
responseData = await zammadApiRequest.call(this, 'POST', '/tickets', body);
|
||||||
|
|
||||||
|
const { id } = responseData;
|
||||||
|
|
||||||
|
responseData.articles = await zammadApiRequest.call(this, 'GET', `/ticket_articles/by_ticket/${id}`);
|
||||||
|
|
||||||
|
} else if (operation === 'delete') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// ticket:delete
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/ticket/index.html#delete
|
||||||
|
|
||||||
|
const id = this.getNodeParameter('id', i) as string;
|
||||||
|
|
||||||
|
await zammadApiRequest.call(this, 'DELETE', `/tickets/${id}`);
|
||||||
|
|
||||||
|
responseData = { success: true };
|
||||||
|
|
||||||
|
} else if (operation === 'get') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// ticket:get
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/ticket/index.html#show
|
||||||
|
|
||||||
|
const id = this.getNodeParameter('id', i) as string;
|
||||||
|
|
||||||
|
responseData = await zammadApiRequest.call(this, 'GET', `/tickets/${id}`);
|
||||||
|
responseData.articles = await zammadApiRequest.call(this, 'GET', `/ticket_articles/by_ticket/${id}`);
|
||||||
|
|
||||||
|
} else if (operation === 'getAll') {
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// ticket:getAll
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// https://docs.zammad.org/en/latest/api/ticket/index.html#list
|
||||||
|
// https://docs.zammad.org/en/latest/api/ticket/index.html#search - returning empty always
|
||||||
|
|
||||||
|
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||||
|
|
||||||
|
const limit = returnAll ? 0 : this.getNodeParameter('limit', i) as number;
|
||||||
|
|
||||||
|
responseData = await zammadApiRequestAllItems.call(
|
||||||
|
this, 'GET', '/tickets', {}, {}, limit,
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.isArray(responseData)
|
||||||
|
? returnData.push(...responseData)
|
||||||
|
: returnData.push(responseData);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (this.continueOnFail()) {
|
||||||
|
returnData.push({ error: error.message });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [this.helpers.returnJsonArray(returnData)];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,310 @@
|
||||||
|
import {
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
export const groupDescription: INodeProperties[] = [
|
||||||
|
// ----------------------------------
|
||||||
|
// operations
|
||||||
|
// ----------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
noDataExpression: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'group',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Create',
|
||||||
|
value: 'create',
|
||||||
|
description: 'Create a group',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Delete',
|
||||||
|
value: 'delete',
|
||||||
|
description: 'Delete a group',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Get',
|
||||||
|
value: 'get',
|
||||||
|
description: 'Retrieve a group',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Get All',
|
||||||
|
value: 'getAll',
|
||||||
|
description: 'Get all groups',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Update',
|
||||||
|
value: 'update',
|
||||||
|
description: 'Update a group',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'create',
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// fields
|
||||||
|
// ----------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Group Name',
|
||||||
|
name: 'name',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'group',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Group ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Group to update. Specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'group',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Group ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Group to delete. Specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'group',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'delete',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Group ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Group to retrieve. Specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'group',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'get',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
displayName: 'Additional Fields',
|
||||||
|
name: 'additionalFields',
|
||||||
|
type: 'collection',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'group',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
placeholder: 'Add Field',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Active',
|
||||||
|
name: 'active',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Custom Fields',
|
||||||
|
name: 'customFieldsUi',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Add Custom Field',
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'customFieldPairs',
|
||||||
|
displayName: 'Custom Field',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Field Name',
|
||||||
|
name: 'name',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadGroupCustomFields',
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'Name of the custom field to set',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Field Value',
|
||||||
|
name: 'value',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Value to set on the custom field',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Notes',
|
||||||
|
name: 'note',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
alwaysOpenEditWindow: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Update Fields',
|
||||||
|
name: 'updateFields',
|
||||||
|
type: 'collection',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'group',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
placeholder: 'Add Field',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Active',
|
||||||
|
name: 'active',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Custom Fields',
|
||||||
|
name: 'customFieldsUi',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Add Custom Field',
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'customFieldPairs',
|
||||||
|
displayName: 'Custom Field',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Field Name',
|
||||||
|
name: 'name',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadGroupCustomFields',
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'Name of the custom field to set',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Field Value',
|
||||||
|
name: 'value',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Value to set on the custom field',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Group Name',
|
||||||
|
name: 'name',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Notes',
|
||||||
|
name: 'note',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
alwaysOpenEditWindow: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Return All',
|
||||||
|
name: 'returnAll',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Whether to return all results or only up to a given limit',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'group',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Limit',
|
||||||
|
name: 'limit',
|
||||||
|
type: 'number',
|
||||||
|
default: 50,
|
||||||
|
description: 'Max number of results to return',
|
||||||
|
typeOptions: {
|
||||||
|
minValue: 1,
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'group',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
returnAll: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
|
@ -0,0 +1,309 @@
|
||||||
|
import {
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
export const organizationDescription: INodeProperties[] = [
|
||||||
|
// ----------------------------------
|
||||||
|
// operations
|
||||||
|
// ----------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
noDataExpression: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'organization',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Create',
|
||||||
|
value: 'create',
|
||||||
|
description: 'Create an organization',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Delete',
|
||||||
|
value: 'delete',
|
||||||
|
description: 'Delete an organization',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Get',
|
||||||
|
value: 'get',
|
||||||
|
description: 'Retrieve an organization',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Get All',
|
||||||
|
value: 'getAll',
|
||||||
|
description: 'Retrieve all organizations',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Update',
|
||||||
|
value: 'update',
|
||||||
|
description: 'Update an organization',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'create',
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// fields
|
||||||
|
// ----------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Organization Name',
|
||||||
|
name: 'name',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'organization',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Organization ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Organization to update. Specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'organization',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Organization ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Organization to delete. Specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'organization',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'delete',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Organization ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Organization to retrieve. Specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'organization',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'get',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Additional Fields',
|
||||||
|
name: 'additionalFields',
|
||||||
|
type: 'collection',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'organization',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
placeholder: 'Add Field',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Active',
|
||||||
|
name: 'active',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Custom Fields',
|
||||||
|
name: 'customFieldsUi',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Add Custom Field',
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'customFieldPairs',
|
||||||
|
displayName: 'Custom Field',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Field',
|
||||||
|
name: 'name',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadOrganizationCustomFields',
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'Name of the custom field to set',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Value',
|
||||||
|
name: 'value',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Value to set on the custom field',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Notes',
|
||||||
|
name: 'note',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
alwaysOpenEditWindow: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Update Fields',
|
||||||
|
name: 'updateFields',
|
||||||
|
type: 'collection',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'organization',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
placeholder: 'Add Field',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Active',
|
||||||
|
name: 'active',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Custom Fields',
|
||||||
|
name: 'customFieldsUi',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Add Custom Field',
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'customFieldPairs',
|
||||||
|
displayName: 'Custom Field',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Field',
|
||||||
|
name: 'name',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadOrganizationCustomFields',
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'Name of the custom field to set',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Value',
|
||||||
|
name: 'value',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Value to set on the custom field',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Organization Name',
|
||||||
|
name: 'name',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Notes',
|
||||||
|
name: 'note',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
alwaysOpenEditWindow: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Return All',
|
||||||
|
name: 'returnAll',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Whether to return all results or only up to a given limit',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'organization',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Limit',
|
||||||
|
name: 'limit',
|
||||||
|
type: 'number',
|
||||||
|
default: 50,
|
||||||
|
description: 'Max number of results to return',
|
||||||
|
typeOptions: {
|
||||||
|
minValue: 1,
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'organization',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
returnAll: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
|
@ -0,0 +1,333 @@
|
||||||
|
import {
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
export const ticketDescription: INodeProperties[] = [
|
||||||
|
// ----------------------------------
|
||||||
|
// operations
|
||||||
|
// ----------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
noDataExpression: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'ticket',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Create',
|
||||||
|
value: 'create',
|
||||||
|
description: 'Create a ticket',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Delete',
|
||||||
|
value: 'delete',
|
||||||
|
description: 'Delete a ticket',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Get',
|
||||||
|
value: 'get',
|
||||||
|
description: 'Retrieve a ticket',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Get All',
|
||||||
|
value: 'getAll',
|
||||||
|
description: 'Retrieve all tickets',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'create',
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// fields
|
||||||
|
// ----------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Title',
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Title of the ticket to create',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'ticket',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Group Name/ID',
|
||||||
|
name: 'group',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadGroupNames',
|
||||||
|
},
|
||||||
|
placeholder: 'First-Level Helpdesk',
|
||||||
|
description: 'Group that will own the ticket to create. Choose from the list or specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'ticket',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Customer Email',
|
||||||
|
name: 'customer',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadCustomerEmails',
|
||||||
|
},
|
||||||
|
description: 'Email address of the customer concerned in the ticket to create. Choose from the list or specify an email using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'hello@n8n.io',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'ticket',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Ticket ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Ticket to retrieve. Specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'ticket',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'get',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Ticket ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Ticket to delete. Specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'ticket',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'delete',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Article',
|
||||||
|
name: 'article',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
placeholder: 'Add Article',
|
||||||
|
required: true,
|
||||||
|
default: {},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'ticket',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Article Details',
|
||||||
|
name: 'articleDetails',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Subject',
|
||||||
|
name: 'subject',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Body',
|
||||||
|
name: 'body',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
alwaysOpenEditWindow: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Visibility',
|
||||||
|
name: 'visibility',
|
||||||
|
type: 'options',
|
||||||
|
default: 'internal',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'External',
|
||||||
|
value: 'external',
|
||||||
|
description: 'Visible to customers',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Internal',
|
||||||
|
value: 'internal',
|
||||||
|
description: 'Visible to help desk',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Article Type',
|
||||||
|
name: 'type',
|
||||||
|
type: 'options',
|
||||||
|
// https://docs.zammad.org/en/latest/api/ticket/articles.html
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Chat',
|
||||||
|
value: 'chat',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Email',
|
||||||
|
value: 'email',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Fax',
|
||||||
|
value: 'fax',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Note',
|
||||||
|
value: 'note',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Phone',
|
||||||
|
value: 'phone',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'SMS',
|
||||||
|
value: 'sms',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'note',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Additional Fields',
|
||||||
|
name: 'additionalFields',
|
||||||
|
type: 'collection',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'ticket',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
placeholder: 'Add Field',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Custom Fields',
|
||||||
|
name: 'customFieldsUi',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Add Custom Field',
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'customFieldPairs',
|
||||||
|
displayName: 'Custom Field',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Field',
|
||||||
|
name: 'name',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadTicketCustomFields',
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'Name of the custom field to set',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Value',
|
||||||
|
name: 'value',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Value to set on the custom field',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Return All',
|
||||||
|
name: 'returnAll',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Whether to return all results or only up to a given limit',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'ticket',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Limit',
|
||||||
|
name: 'limit',
|
||||||
|
type: 'number',
|
||||||
|
default: 50,
|
||||||
|
description: 'Max number of results to return',
|
||||||
|
typeOptions: {
|
||||||
|
minValue: 1,
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'ticket',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
returnAll: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
662
packages/nodes-base/nodes/Zammad/descriptions/UserDescription.ts
Normal file
662
packages/nodes-base/nodes/Zammad/descriptions/UserDescription.ts
Normal file
|
@ -0,0 +1,662 @@
|
||||||
|
import {
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
export const userDescription: INodeProperties[] = [
|
||||||
|
// ----------------------------------
|
||||||
|
// operations
|
||||||
|
// ----------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
noDataExpression: true,
|
||||||
|
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: 'Retrieve a user',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Get All',
|
||||||
|
value: 'getAll',
|
||||||
|
description: 'Retrieve all users',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Get Self',
|
||||||
|
value: 'getSelf',
|
||||||
|
description: 'Retrieve currently logged-in user',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Update',
|
||||||
|
value: 'update',
|
||||||
|
description: 'Update a user',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'create',
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// fields
|
||||||
|
// ----------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'First Name',
|
||||||
|
name: 'firstname',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'John',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'user',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Last Name',
|
||||||
|
name: 'lastname',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Smith',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'user',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'User ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
description: 'User to update. Specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'user',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'User ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
description: 'User to delete. Specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'user',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'delete',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'User ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
description: 'User to retrieve. Specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'user',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'get',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Additional Fields',
|
||||||
|
name: 'additionalFields',
|
||||||
|
type: 'collection',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'user',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
placeholder: 'Add Field',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Active',
|
||||||
|
name: 'active',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Address',
|
||||||
|
name: 'addressUi',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
placeholder: 'Add Address',
|
||||||
|
default: {},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Address Details',
|
||||||
|
name: 'addressDetails',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'City',
|
||||||
|
name: 'city',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Berlin',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Country',
|
||||||
|
name: 'country',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Germany',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Street & Number',
|
||||||
|
name: 'address',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Borsigstr. 27',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Zip Code',
|
||||||
|
name: 'zip',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: '10115',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Custom Fields',
|
||||||
|
name: 'customFieldsUi',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Add Custom Field',
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'customFieldPairs',
|
||||||
|
displayName: 'Custom Field',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Field Name',
|
||||||
|
name: 'name',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadUserCustomFields',
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'Name of the custom field to set',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Field Value',
|
||||||
|
name: 'value',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Value to set on the custom field',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Department',
|
||||||
|
name: 'department',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Finance',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Email Address',
|
||||||
|
name: 'email',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Fax',
|
||||||
|
name: 'fax',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: '+49 30 901820',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Notes',
|
||||||
|
name: 'note',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
alwaysOpenEditWindow: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Organization Name/ID',
|
||||||
|
name: 'organization',
|
||||||
|
type: 'options',
|
||||||
|
description: 'Name of the organization to assign to the user. Choose from the list or specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.',
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadOrganizations',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Phone (Landline)',
|
||||||
|
name: 'phone',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: '+49 30 901820',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Phone (Mobile)',
|
||||||
|
name: 'mobile',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: '+49 1522 3433333',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Verified',
|
||||||
|
name: 'verified',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Whether the user has been verified',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'VIP',
|
||||||
|
name: 'vip',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Whether the user is a Very Important Person',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Website',
|
||||||
|
name: 'web',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'https://n8n.io',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Update Fields',
|
||||||
|
name: 'updateFields',
|
||||||
|
type: 'collection',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'user',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
placeholder: 'Add Field',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Active',
|
||||||
|
name: 'active',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Address',
|
||||||
|
name: 'addressUi',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
placeholder: 'Add Address',
|
||||||
|
default: {},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Address Details',
|
||||||
|
name: 'addressDetails',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'City',
|
||||||
|
name: 'city',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Berlin',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Country',
|
||||||
|
name: 'country',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Germany',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Street & Number',
|
||||||
|
name: 'address',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Borsigstr. 27',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Zip Code',
|
||||||
|
name: 'zip',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: '10115',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Custom Fields',
|
||||||
|
name: 'customFieldsUi',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Add Custom Field',
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'customFieldPairs',
|
||||||
|
displayName: 'Custom Field',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Field Name',
|
||||||
|
name: 'name',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadUserCustomFields',
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'Name of the custom field to set',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Field Value',
|
||||||
|
name: 'value',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Value to set on the custom field',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Department',
|
||||||
|
name: 'department',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Finance',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Email Address',
|
||||||
|
name: 'email',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'hello@n8n.io',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Fax',
|
||||||
|
name: 'fax',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: '+49 30 901820',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'First Name',
|
||||||
|
name: 'firstname',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'John',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Last Name',
|
||||||
|
name: 'lastname',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Smith',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Notes',
|
||||||
|
name: 'note',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
alwaysOpenEditWindow: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Organization Name/ID',
|
||||||
|
name: 'organization',
|
||||||
|
type: 'options',
|
||||||
|
description: 'Name of the organization to assign to the user. Choose from the list or specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>.',
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadOrganizationNames',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Phone (Landline)',
|
||||||
|
name: 'phone',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: '+49 30 901820',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Phone (Mobile)',
|
||||||
|
name: 'mobile',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: '+49 1522 3433333',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Verified',
|
||||||
|
name: 'verified',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Whether the user has been verified',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'VIP',
|
||||||
|
name: 'vip',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Whether the user is a Very Important Person',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Website',
|
||||||
|
name: 'web',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'https://n8n.io',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Query',
|
||||||
|
name: 'query',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'search',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'user',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Limit',
|
||||||
|
name: 'limit',
|
||||||
|
type: 'number',
|
||||||
|
default: 50,
|
||||||
|
typeOptions: {
|
||||||
|
minValue: 1,
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'search',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'user',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Max number of results to return',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Return All',
|
||||||
|
name: 'returnAll',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Whether to return all results or only up to a given limit',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'user',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Limit',
|
||||||
|
name: 'limit',
|
||||||
|
type: 'number',
|
||||||
|
default: 50,
|
||||||
|
description: 'Max number of results to return',
|
||||||
|
typeOptions: {
|
||||||
|
minValue: 1,
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'user',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
returnAll: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Filters',
|
||||||
|
name: 'filters',
|
||||||
|
type: 'collection',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'user',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
placeholder: 'Add Filter',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Query',
|
||||||
|
name: 'query',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Query to filter results by',
|
||||||
|
placeholder: 'user.firstname:john',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Sort',
|
||||||
|
name: 'sortUi',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
placeholder: 'Add Sort Options',
|
||||||
|
default: {},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Sort Options',
|
||||||
|
name: 'sortDetails',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Sort Key',
|
||||||
|
name: 'sort_by',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadUserFields',
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Sort Order',
|
||||||
|
name: 'order_by',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Ascending',
|
||||||
|
value: 'asc',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Descending',
|
||||||
|
value: 'desc',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'asc',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
4
packages/nodes-base/nodes/Zammad/descriptions/index.ts
Normal file
4
packages/nodes-base/nodes/Zammad/descriptions/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
export * from './GroupDescription';
|
||||||
|
export * from './OrganizationDescription';
|
||||||
|
export * from './TicketDescription';
|
||||||
|
export * from './UserDescription';
|
97
packages/nodes-base/nodes/Zammad/types.d.ts
vendored
Normal file
97
packages/nodes-base/nodes/Zammad/types.d.ts
vendored
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
import {
|
||||||
|
IDataObject,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
export declare namespace Zammad {
|
||||||
|
export type Resource = 'group' | 'organization' | 'ticket' | 'user';
|
||||||
|
|
||||||
|
export type AuthMethod = 'basicAuth' | 'tokenAuth';
|
||||||
|
|
||||||
|
export type Credentials = BasicAuthCredentials | TokenAuthCredentials;
|
||||||
|
|
||||||
|
type CredentialsBase = {
|
||||||
|
baseUrl: string;
|
||||||
|
allowUnauthorizedCerts: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BasicAuthCredentials = CredentialsBase & {
|
||||||
|
authType: 'basicAuth';
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TokenAuthCredentials = CredentialsBase & {
|
||||||
|
authType: 'tokenAuth';
|
||||||
|
accessToken: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UserAdditionalFields = IDataObject & Zammad.CustomFieldsUi & Zammad.AddressUi;
|
||||||
|
export type UserUpdateFields = UserAdditionalFields;
|
||||||
|
export type UserFilterFields = IDataObject & Zammad.SortUi;
|
||||||
|
|
||||||
|
export type Organization = {
|
||||||
|
active: boolean;
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Group = Organization;
|
||||||
|
|
||||||
|
export type GroupUpdateFields = UserUpdateFields;
|
||||||
|
|
||||||
|
export type User = {
|
||||||
|
id: number;
|
||||||
|
login: string;
|
||||||
|
lastname: string;
|
||||||
|
email: string;
|
||||||
|
role_ids: number[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Field = {
|
||||||
|
id: number,
|
||||||
|
display: string;
|
||||||
|
name: string;
|
||||||
|
object: string;
|
||||||
|
created_by_id: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UserField = {
|
||||||
|
display: string;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CustomFieldsUi = {
|
||||||
|
customFieldsUi?: {
|
||||||
|
customFieldPairs: Array<{ name: string, value: string }>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SortUi = {
|
||||||
|
sortUi?: {
|
||||||
|
sortDetails: {
|
||||||
|
sort_by: string;
|
||||||
|
order_by: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AddressUi = {
|
||||||
|
addressUi?: {
|
||||||
|
addressDetails: {
|
||||||
|
city: string;
|
||||||
|
country: string;
|
||||||
|
street: string;
|
||||||
|
zip: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Article = {
|
||||||
|
articleDetails: {
|
||||||
|
visibility: 'external' | 'internal',
|
||||||
|
subject: string,
|
||||||
|
body: string,
|
||||||
|
type: 'chat' | 'email' | 'fax' | 'note' | 'phone' | 'sms',
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
27
packages/nodes-base/nodes/Zammad/zammad.svg
Normal file
27
packages/nodes-base/nodes/Zammad/zammad.svg
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<svg
|
||||||
|
version="1.1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
viewBox="140 210 140 140"
|
||||||
|
xml:space="preserve"
|
||||||
|
>
|
||||||
|
<g>
|
||||||
|
<polygon fill="#CA2317" points="230.5,250 272.2,237.2 247.5,252.9"/>
|
||||||
|
<polygon fill="#E84F83" points="255.9,281.2 247.5,252.9 272.2,237.2 264.8,262.6"/>
|
||||||
|
<polygon fill="#CA2317" points="284.4,229.5 279.8,237.2 264.8,262.6 272.2,237.2"/>
|
||||||
|
<polygon fill="#E54011" points="285.9,234.5 274.3,246.4 279.8,237.2"/>
|
||||||
|
<polygon fill="#E54011" points="233,242.1 267.1,238.7 243.4,246"/>
|
||||||
|
<polygon fill="#CA2317" points="234.3,261.4 247.5,252.9 255.9,281.2 251.5,290.2"/>
|
||||||
|
<polygon fill="#B7DFF2" points="214.6,295 208.3,218 251.5,290.2"/>
|
||||||
|
<polygon fill="#E54011" points="196.7,314.7 214.6,295 251.5,290.2"/>
|
||||||
|
<polygon fill="#FFCE33" points="109.7,353.4 196.7,314.7 214.6,295 186.2,292.1"/>
|
||||||
|
<polygon fill="#D6B12D" points="113,321.8 157.7,315 171.6,303.8 164.8,300.8"/>
|
||||||
|
<polygon fill="#FFDE85" points="129.1,285.3 171.6,303.8 186.2,292.1"/>
|
||||||
|
<polygon fill="#009EC6" points="205.1,245.9 199.7,246.8 186.2,292.1 200.8,282.9"/>
|
||||||
|
<polygon fill="#5EAFCE" points="213,275.1 200.8,282.9 208.3,218"/>
|
||||||
|
<polygon fill="#045972" points="166.9,252 205.1,245.9 206.8,230.8"/>
|
||||||
|
<polygon fill="#5A8591" points="162.8,216.6 196,236.6 206.8,230.8 207.1,228.7"/>
|
||||||
|
<polygon fill="#009EC6" points="169.3,194.8 199.5,226.6 207.1,228.7 208.3,218"/>
|
||||||
|
<polygon fill="#F39804" points="186.2,292.1 213,275.1 214.6,295"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -314,6 +314,8 @@
|
||||||
"dist/credentials/XeroOAuth2Api.credentials.js",
|
"dist/credentials/XeroOAuth2Api.credentials.js",
|
||||||
"dist/credentials/YourlsApi.credentials.js",
|
"dist/credentials/YourlsApi.credentials.js",
|
||||||
"dist/credentials/YouTubeOAuth2Api.credentials.js",
|
"dist/credentials/YouTubeOAuth2Api.credentials.js",
|
||||||
|
"dist/credentials/ZammadBasicAuthApi.credentials.js",
|
||||||
|
"dist/credentials/ZammadTokenAuthApi.credentials.js",
|
||||||
"dist/credentials/ZendeskApi.credentials.js",
|
"dist/credentials/ZendeskApi.credentials.js",
|
||||||
"dist/credentials/ZendeskOAuth2Api.credentials.js",
|
"dist/credentials/ZendeskOAuth2Api.credentials.js",
|
||||||
"dist/credentials/ZohoOAuth2Api.credentials.js",
|
"dist/credentials/ZohoOAuth2Api.credentials.js",
|
||||||
|
@ -661,6 +663,7 @@
|
||||||
"dist/nodes/Xero/Xero.node.js",
|
"dist/nodes/Xero/Xero.node.js",
|
||||||
"dist/nodes/Xml/Xml.node.js",
|
"dist/nodes/Xml/Xml.node.js",
|
||||||
"dist/nodes/Yourls/Yourls.node.js",
|
"dist/nodes/Yourls/Yourls.node.js",
|
||||||
|
"dist/nodes/Zammad/Zammad.node.js",
|
||||||
"dist/nodes/Zendesk/Zendesk.node.js",
|
"dist/nodes/Zendesk/Zendesk.node.js",
|
||||||
"dist/nodes/Zendesk/ZendeskTrigger.node.js",
|
"dist/nodes/Zendesk/ZendeskTrigger.node.js",
|
||||||
"dist/nodes/Zoho/ZohoCrm.node.js",
|
"dist/nodes/Zoho/ZohoCrm.node.js",
|
||||||
|
|
Loading…
Reference in a new issue