UNPKG

n8n-nodes-easy-appointments

Version:
1,117 lines 50.9 kB
"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