n8n-nodes-easy-appointments
Version:
n8n nodes for Easy!Appointments API integration
1,117 lines • 50.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EasyAppointments = void 0;
const n8n_workflow_1 = require("n8n-workflow");
const GenericFunctions_1 = require("./GenericFunctions");
class EasyAppointments {
constructor() {
this.description = {
displayName: 'Easy!Appointments',
name: 'easyAppointments',
icon: 'file:icon.svg',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'Interact with Easy!Appointments API',
defaults: {
name: 'Easy!Appointments',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'easyAppointmentsApi',
required: true,
},
],
requestDefaults: {
baseURL: '={{$credentials.baseUrl}}',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
},
properties: [
{
displayName: 'Resource',
name: 'resource',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Appointment',
value: 'appointment',
},
{
name: 'Availability',
value: 'availability',
},
{
name: 'Customer',
value: 'customer',
},
{
name: 'Provider',
value: 'provider',
},
{
name: 'Service',
value: 'service',
},
],
default: 'appointment',
required: true,
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['appointment', 'customer', 'provider', 'service'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a record',
action: 'Create a record',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a record',
action: 'Delete a record',
},
{
name: 'Get',
value: 'get',
description: 'Get a record',
action: 'Get a record',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many records',
action: 'Get many records',
},
{
name: 'Update',
value: 'update',
description: 'Update a record',
action: 'Update a record',
},
],
default: 'getAll',
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['availability'],
},
},
options: [
{
name: 'Get',
value: 'get',
description: 'Get availabilities',
action: 'Get availabilities',
},
],
default: 'get',
},
...GenericFunctions_1.commonFields,
{
displayName: 'Appointment ID',
name: 'appointmentId',
type: 'string',
required: true,
default: '',
displayOptions: {
show: {
resource: ['appointment'],
operation: ['get', 'update', 'delete'],
},
},
description: 'The ID of the appointment',
},
{
displayName: 'Start Date Time',
name: 'start',
type: 'dateTime',
required: true,
default: '',
displayOptions: {
show: {
resource: ['appointment'],
operation: ['create', 'update'],
},
},
description: 'The start date and time of the appointment',
},
{
displayName: 'End Date Time',
name: 'end',
type: 'dateTime',
required: true,
default: '',
displayOptions: {
show: {
resource: ['appointment'],
operation: ['create', 'update'],
},
},
description: 'The end date and time of the appointment',
},
{
displayName: 'Customer ID',
name: 'customerId',
type: 'number',
required: true,
default: 0,
displayOptions: {
show: {
resource: ['appointment'],
operation: ['create', 'update'],
},
},
description: 'The ID of the customer for this appointment',
},
{
displayName: 'Provider ID',
name: 'providerId',
type: 'number',
required: true,
default: 0,
displayOptions: {
show: {
resource: ['appointment'],
operation: ['create', 'update'],
},
},
description: 'The ID of the provider for this appointment',
},
{
displayName: 'Service ID',
name: 'serviceId',
type: 'number',
required: true,
default: 0,
displayOptions: {
show: {
resource: ['appointment'],
operation: ['create', 'update'],
},
},
description: 'The ID of the service for this appointment',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['appointment'],
operation: ['create', 'update'],
},
},
options: [
{
displayName: 'Location',
name: 'location',
type: 'string',
default: '',
description: 'The location of the appointment',
},
{
displayName: 'Color',
name: 'color',
type: 'color',
default: '#000000',
description: 'The color of the appointment in the calendar',
},
{
displayName: 'Status',
name: 'status',
type: 'options',
options: [
{
name: 'Booked',
value: 'Booked',
},
{
name: 'Cancelled',
value: 'Cancelled',
},
{
name: 'Confirmed',
value: 'Confirmed',
},
],
default: 'Booked',
description: 'The status of the appointment',
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
typeOptions: {
rows: 4,
},
default: '',
description: 'Notes about the appointment',
},
],
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Filter',
default: {},
displayOptions: {
show: {
resource: ['appointment'],
operation: ['getAll'],
},
},
options: [
{
displayName: 'Date',
name: 'date',
type: 'dateTime',
default: '',
description: 'Filter appointments by specific date',
},
{
displayName: 'From Date',
name: 'from',
type: 'dateTime',
default: '',
description: 'Filter appointments from this date',
},
{
displayName: 'Till Date',
name: 'till',
type: 'dateTime',
default: '',
description: 'Filter appointments until this date',
},
{
displayName: 'Service ID',
name: 'serviceId',
type: 'number',
default: 0,
description: 'Filter appointments by service ID',
},
{
displayName: 'Provider ID',
name: 'providerId',
type: 'number',
default: 0,
description: 'Filter appointments by provider ID',
},
{
displayName: 'Customer ID',
name: 'customerId',
type: 'number',
default: 0,
description: 'Filter appointments by customer ID',
},
],
},
{
displayName: 'Customer ID',
name: 'customerId',
type: 'string',
required: true,
default: '',
displayOptions: {
show: {
resource: ['customer'],
operation: ['get', 'update', 'delete'],
},
},
description: 'The ID of the customer',
},
{
displayName: 'First Name',
name: 'firstName',
type: 'string',
default: '',
displayOptions: {
show: {
resource: ['customer'],
operation: ['create', 'update'],
},
},
description: 'The first name of the customer',
},
{
displayName: 'Last Name',
name: 'lastName',
type: 'string',
default: '',
displayOptions: {
show: {
resource: ['customer'],
operation: ['create', 'update'],
},
},
description: 'The last name of the customer',
},
{
displayName: 'Email',
name: 'email',
type: 'string',
placeholder: 'name@email.com',
default: '',
displayOptions: {
show: {
resource: ['customer'],
operation: ['create', 'update'],
},
},
description: 'The email address of the customer',
},
{
displayName: 'Phone',
name: 'phone',
type: 'string',
default: '',
displayOptions: {
show: {
resource: ['customer'],
operation: ['create', 'update'],
},
},
description: 'The phone number of the customer (may be required depending on your Easy!Appointments settings)',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['customer'],
operation: ['create', 'update'],
},
},
options: [
{
displayName: 'Address',
name: 'address',
type: 'string',
default: '',
description: 'The address of the customer',
},
{
displayName: 'City',
name: 'city',
type: 'string',
default: '',
description: 'The city of the customer',
},
{
displayName: 'ZIP',
name: 'zip',
type: 'string',
default: '',
description: 'The ZIP code of the customer',
},
{
displayName: 'Timezone',
name: 'timezone',
type: 'string',
default: 'UTC',
description: 'The timezone of the customer',
},
{
displayName: 'Language',
name: 'language',
type: 'string',
default: 'english',
description: 'The language of the customer',
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
typeOptions: {
rows: 4,
},
default: '',
description: 'Notes about the customer',
},
{
displayName: 'Custom Field 1',
name: 'customField1',
type: 'string',
default: '',
description: 'Custom field 1 value',
},
{
displayName: 'Custom Field 2',
name: 'customField2',
type: 'string',
default: '',
description: 'Custom field 2 value',
},
{
displayName: 'Custom Field 3',
name: 'customField3',
type: 'string',
default: '',
description: 'Custom field 3 value',
},
{
displayName: 'Custom Field 4',
name: 'customField4',
type: 'string',
default: '',
description: 'Custom field 4 value',
},
{
displayName: 'Custom Field 5',
name: 'customField5',
type: 'string',
default: '',
description: 'Custom field 5 value',
},
],
},
{
displayName: 'Service ID',
name: 'serviceId',
type: 'string',
required: true,
default: '',
displayOptions: {
show: {
resource: ['service'],
operation: ['get', 'update', 'delete'],
},
},
description: 'The ID of the service',
},
{
displayName: 'Name',
name: 'name',
type: 'string',
required: true,
default: '',
displayOptions: {
show: {
resource: ['service'],
operation: ['create', 'update'],
},
},
description: 'The name of the service',
},
{
displayName: 'Duration (Minutes)',
name: 'duration',
type: 'number',
required: true,
default: 60,
displayOptions: {
show: {
resource: ['service'],
operation: ['create', 'update'],
},
},
description: 'The duration of the service in minutes',
},
{
displayName: 'Price',
name: 'price',
type: 'number',
required: true,
default: 0,
displayOptions: {
show: {
resource: ['service'],
operation: ['create', 'update'],
},
},
description: 'The price of the service',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['service'],
operation: ['create', 'update'],
},
},
options: [
{
displayName: 'Currency',
name: 'currency',
type: 'string',
default: 'USD',
description: 'The currency of the service price',
},
{
displayName: 'Location',
name: 'location',
type: 'string',
default: '',
description: 'The location where the service is provided',
},
{
displayName: 'Description',
name: 'description',
type: 'string',
typeOptions: {
rows: 4,
},
default: '',
description: 'Description of the service',
},
{
displayName: 'Availabilities Type',
name: 'availabilitiesType',
type: 'options',
options: [
{
name: 'Flexible',
value: 'flexible',
},
{
name: 'Fixed',
value: 'fixed',
},
],
default: 'flexible',
description: 'The type of availability for the service',
},
{
displayName: 'Attendants Number',
name: 'attendantsNumber',
type: 'number',
default: 1,
description: 'The number of attendants for the service',
},
{
displayName: 'Is Private',
name: 'isPrivate',
type: 'boolean',
default: false,
description: 'Whether the service is private',
},
{
displayName: 'Service Category ID',
name: 'serviceCategoryId',
type: 'number',
default: 0,
description: 'The ID of the category this service belongs to',
},
],
},
{
displayName: 'Provider ID',
name: 'providerId',
type: 'string',
required: true,
default: '',
displayOptions: {
show: {
resource: ['provider'],
operation: ['get', 'update', 'delete'],
},
},
description: 'The ID of the provider',
},
{
displayName: 'First Name',
name: 'firstName',
type: 'string',
default: '',
displayOptions: {
show: {
resource: ['provider'],
operation: ['create', 'update'],
},
},
description: 'The first name of the provider',
},
{
displayName: 'Last Name',
name: 'lastName',
type: 'string',
default: '',
displayOptions: {
show: {
resource: ['provider'],
operation: ['create', 'update'],
},
},
description: 'The last name of the provider',
},
{
displayName: 'Email',
name: 'email',
type: 'string',
placeholder: 'name@email.com',
default: '',
displayOptions: {
show: {
resource: ['provider'],
operation: ['create', 'update'],
},
},
description: 'The email address of the provider',
},
{
displayName: 'Phone',
name: 'phone',
type: 'string',
default: '',
displayOptions: {
show: {
resource: ['provider'],
operation: ['create', 'update'],
},
},
description: 'The phone number of the provider',
},
{
displayName: 'Services',
name: 'services',
type: 'string',
default: '',
displayOptions: {
show: {
resource: ['provider'],
operation: ['create', 'update'],
},
},
description: 'Comma-separated list of service IDs that the provider can provide',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['provider'],
operation: ['create', 'update'],
},
},
options: [
{
displayName: 'Address',
name: 'address',
type: 'string',
default: '',
description: 'The address of the provider',
},
{
displayName: 'City',
name: 'city',
type: 'string',
default: '',
description: 'The city of the provider',
},
{
displayName: 'ZIP',
name: 'zip',
type: 'string',
default: '',
description: 'The ZIP code of the provider',
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
typeOptions: {
rows: 4,
},
default: '',
description: 'Notes about the provider',
},
{
displayName: 'Timezone',
name: 'timezone',
type: 'string',
default: 'UTC',
description: 'The timezone of the provider',
},
{
displayName: 'Language',
name: 'language',
type: 'string',
default: 'english',
description: 'The language of the provider',
},
{
displayName: 'Is Private',
name: 'isPrivate',
type: 'boolean',
default: false,
description: 'Whether the provider is private',
},
{
displayName: 'Settings',
name: 'settings',
type: 'json',
default: '{}',
description: 'Provider settings as JSON object (username, password, notifications, etc.)',
},
],
},
{
displayName: 'Provider ID',
name: 'providerId',
type: 'number',
default: 0,
displayOptions: {
show: {
resource: ['availability'],
operation: ['get'],
},
},
description: 'The ID of the provider to get availabilities for',
},
{
displayName: 'Service ID',
name: 'serviceId',
type: 'number',
default: 0,
displayOptions: {
show: {
resource: ['availability'],
operation: ['get'],
},
},
description: 'The ID of the service to get availabilities for',
},
{
displayName: 'Date',
name: 'date',
type: 'dateTime',
default: '',
displayOptions: {
show: {
resource: ['availability'],
operation: ['get'],
},
},
description: 'The date to get availabilities for',
},
],
};
}
async execute() {
const items = this.getInputData();
const returnData = [];
const resource = this.getNodeParameter('resource', 0);
const operation = this.getNodeParameter('operation', 0);
let responseData;
for (let i = 0; i < items.length; i++) {
try {
if (resource === 'appointment') {
if (operation === 'create') {
const fields = [
'start',
'end',
'customerId',
'providerId',
'serviceId',
];
const additionalFields = this.getNodeParameter('additionalFields', i, {});
if (additionalFields.location)
fields.push('location');
if (additionalFields.color)
fields.push('color');
if (additionalFields.status)
fields.push('status');
if (additionalFields.notes)
fields.push('notes');
responseData = await GenericFunctions_1.createResource.call(this, i, '/appointments', fields);
}
else if (operation === 'delete') {
const appointmentId = this.getNodeParameter('appointmentId', i);
responseData = await GenericFunctions_1.deleteResource.call(this, i, `/appointments/${appointmentId}`);
}
else if (operation === 'get') {
const appointmentId = this.getNodeParameter('appointmentId', i);
responseData = await GenericFunctions_1.getResource.call(this, i, `/appointments/${appointmentId}`);
}
else if (operation === 'getAll') {
responseData = await GenericFunctions_1.getAllResources.call(this, i, '/appointments');
}
else if (operation === 'update') {
const appointmentId = this.getNodeParameter('appointmentId', i);
const fields = [
'start',
'end',
'customerId',
'providerId',
'serviceId',
];
const additionalFields = this.getNodeParameter('additionalFields', i, {});
if (additionalFields.location)
fields.push('location');
if (additionalFields.color)
fields.push('color');
if (additionalFields.status)
fields.push('status');
if (additionalFields.notes)
fields.push('notes');
responseData = await GenericFunctions_1.updateResource.call(this, i, `/appointments/${appointmentId}`, fields);
}
}
else if (resource === 'customer') {
if (operation === 'create') {
const fields = [
'firstName',
'lastName',
'email',
'phone',
];
const additionalFields = this.getNodeParameter('additionalFields', i, {});
if (additionalFields.address)
fields.push('address');
if (additionalFields.city)
fields.push('city');
if (additionalFields.zip)
fields.push('zip');
if (additionalFields.timezone)
fields.push('timezone');
if (additionalFields.language)
fields.push('language');
if (additionalFields.notes)
fields.push('notes');
if (additionalFields.customField1)
fields.push('customField1');
if (additionalFields.customField2)
fields.push('customField2');
if (additionalFields.customField3)
fields.push('customField3');
if (additionalFields.customField4)
fields.push('customField4');
if (additionalFields.customField5)
fields.push('customField5');
responseData = await GenericFunctions_1.createResource.call(this, i, '/customers', fields);
}
else if (operation === 'delete') {
const customerId = this.getNodeParameter('customerId', i);
responseData = await GenericFunctions_1.deleteResource.call(this, i, `/customers/${customerId}`);
}
else if (operation === 'get') {
const customerId = this.getNodeParameter('customerId', i);
responseData = await GenericFunctions_1.getResource.call(this, i, `/customers/${customerId}`);
}
else if (operation === 'getAll') {
responseData = await GenericFunctions_1.getAllResources.call(this, i, '/customers');
}
else if (operation === 'update') {
const customerId = this.getNodeParameter('customerId', i);
const fields = [
'firstName',
'lastName',
'email',
'phone',
];
const additionalFields = this.getNodeParameter('additionalFields', i, {});
if (additionalFields.address)
fields.push('address');
if (additionalFields.city)
fields.push('city');
if (additionalFields.zip)
fields.push('zip');
if (additionalFields.timezone)
fields.push('timezone');
if (additionalFields.language)
fields.push('language');
if (additionalFields.notes)
fields.push('notes');
if (additionalFields.customField1)
fields.push('customField1');
if (additionalFields.customField2)
fields.push('customField2');
if (additionalFields.customField3)
fields.push('customField3');
if (additionalFields.customField4)
fields.push('customField4');
if (additionalFields.customField5)
fields.push('customField5');
responseData = await GenericFunctions_1.updateResource.call(this, i, `/customers/${customerId}`, fields);
}
}
else if (resource === 'service') {
if (operation === 'create') {
const fields = [
'name',
'duration',
'price',
];
const additionalFields = this.getNodeParameter('additionalFields', i, {});
if (additionalFields.currency)
fields.push('currency');
if (additionalFields.location)
fields.push('location');
if (additionalFields.description)
fields.push('description');
if (additionalFields.availabilitiesType)
fields.push('availabilitiesType');
if (additionalFields.attendantsNumber)
fields.push('attendantsNumber');
if (additionalFields.isPrivate !== undefined)
fields.push('isPrivate');
if (additionalFields.serviceCategoryId)
fields.push('serviceCategoryId');
responseData = await GenericFunctions_1.createResource.call(this, i, '/services', fields);
}
else if (operation === 'delete') {
const serviceId = this.getNodeParameter('serviceId', i);
responseData = await GenericFunctions_1.deleteResource.call(this, i, `/services/${serviceId}`);
}
else if (operation === 'get') {
const serviceId = this.getNodeParameter('serviceId', i);
responseData = await GenericFunctions_1.getResource.call(this, i, `/services/${serviceId}`);
}
else if (operation === 'getAll') {
responseData = await GenericFunctions_1.getAllResources.call(this, i, '/services');
}
else if (operation === 'update') {
const serviceId = this.getNodeParameter('serviceId', i);
const fields = [
'name',
'duration',
'price',
];
const additionalFields = this.getNodeParameter('additionalFields', i, {});
if (additionalFields.currency)
fields.push('currency');
if (additionalFields.location)
fields.push('location');
if (additionalFields.description)
fields.push('description');
if (additionalFields.availabilitiesType)
fields.push('availabilitiesType');
if (additionalFields.attendantsNumber)
fields.push('attendantsNumber');
if (additionalFields.isPrivate !== undefined)
fields.push('isPrivate');
if (additionalFields.serviceCategoryId)
fields.push('serviceCategoryId');
responseData = await GenericFunctions_1.updateResource.call(this, i, `/services/${serviceId}`, fields);
}
}
else if (resource === 'provider') {
if (operation === 'create') {
const body = {};
body.firstName = this.getNodeParameter('firstName', i, '');
body.lastName = this.getNodeParameter('lastName', i, '');
body.email = this.getNodeParameter('email', i, '');
body.phone = this.getNodeParameter('phone', i, '');
const services = this.getNodeParameter('services', i, '');
if (services) {
body.services = services.split(',').map(id => parseInt(id.trim(), 10));
}
const additionalFields = this.getNodeParameter('additionalFields', i, {});
if (additionalFields.address)
body.address = additionalFields.address;
if (additionalFields.city)
body.city = additionalFields.city;
if (additionalFields.zip)
body.zip = additionalFields.zip;
if (additionalFields.notes)
body.notes = additionalFields.notes;
if (additionalFields.timezone)
body.timezone = additionalFields.timezone;
if (additionalFields.language)
body.language = additionalFields.language;
if (additionalFields.isPrivate !== undefined)
body.isPrivate = additionalFields.isPrivate;
if (additionalFields.settings) {
try {
body.settings = JSON.parse(additionalFields.settings);
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid settings JSON: ${error.message}`);
}
}
responseData = await GenericFunctions_1.easyAppointmentsApiRequest.call(this, 'POST', '/providers', body);
}
else if (operation === 'delete') {
const providerId = this.getNodeParameter('providerId', i);
responseData = await GenericFunctions_1.deleteResource.call(this, i, `/providers/${providerId}`);
}
else if (operation === 'get') {
const providerId = this.getNodeParameter('providerId', i);
responseData = await GenericFunctions_1.getResource.call(this, i, `/providers/${providerId}`);
}
else if (operation === 'getAll') {
responseData = await GenericFunctions_1.getAllResources.call(this, i, '/providers');
}
else if (operation === 'update') {
const providerId = this.getNodeParameter('providerId', i);
const body = {};
body.firstName = this.getNodeParameter('firstName', i, '');
body.lastName = this.getNodeParameter('lastName', i, '');
body.email = this.getNodeParameter('email', i, '');
body.phone = this.getNodeParameter('phone', i, '');
const services = this.getNodeParameter('services', i, '');
if (services) {
body.services = services.split(',').map(id => parseInt(id.trim(), 10));
}
const additionalFields = this.getNodeParameter('additionalFields', i, {});
if (additionalFields.address)
body.address = additionalFields.address;
if (additionalFields.city)
body.city = additionalFields.city;
if (additionalFields.zip)
body.zip = additionalFields.zip;
if (additionalFields.notes)
body.notes = additionalFields.notes;
if (additionalFields.timezone)
body.timezone = additionalFields.timezone;
if (additionalFields.language)
body.language = additionalFields.language;
if (additionalFields.isPrivate !== undefined)
body.isPrivate = additionalFields.isPrivate;
if (additionalFields.settings) {
try {
body.settings = JSON.parse(additionalFields.settings);
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid settings JSON: ${error.message}`);
}
}
responseData = await GenericFunctions_1.easyAppointmentsApiRequest.call(this, 'PUT', `/providers/${providerId}`, body);
}
}
else if (resource === 'availability') {
if (operation === 'get') {
const qs = {};
const providerId = this.getNodeParameter('providerId', i, 0);
if (providerId) {
qs.providerId = providerId;
}
const serviceId = this.getNodeParameter('serviceId', i, 0);
if (serviceId) {
qs.serviceId = serviceId;
}
const date = this.getNodeParameter('date', i, '');
if (date) {
qs.date = dat