├── index.js ├── .npmignore ├── .gitignore ├── nodes └── HighLevelV2 │ ├── __schema__ │ └── v2.0.0 │ │ ├── appointmentNotes │ │ ├── delete.json │ │ ├── create.json │ │ ├── update.json │ │ └── getAll.json │ │ ├── calendarResource │ │ ├── delete.json │ │ ├── get.json │ │ ├── create.json │ │ ├── update.json │ │ └── getAll.json │ │ ├── customField │ │ ├── delete.json │ │ ├── getFolder.json │ │ ├── deleteFolder.json │ │ ├── get.json │ │ ├── updateFolder.json │ │ ├── createFolder.json │ │ ├── update.json │ │ └── create.json │ │ ├── business │ │ ├── delete.json │ │ ├── get.json │ │ ├── create.json │ │ ├── update.json │ │ └── getAll.json │ │ ├── calendarGroup │ │ ├── delete.json │ │ ├── validateSlug.json │ │ ├── create.json │ │ ├── disable.json │ │ ├── update.json │ │ └── getAll.json │ │ ├── calendarEvent │ │ ├── deleteEvent.json │ │ ├── createBlockSlot.json │ │ ├── updateBlockSlot.json │ │ ├── createAppointment.json │ │ ├── getAppointment.json │ │ ├── updateAppointment.json │ │ └── getBlockedSlots.json │ │ ├── calendar │ │ ├── delete.json │ │ ├── getFreeSlots.json │ │ ├── update.json │ │ ├── create.json │ │ ├── get.json │ │ └── getAll.json │ │ ├── coupon │ │ └── delete.json │ │ ├── customObjects │ │ ├── deleteRecord.json │ │ ├── updateRecord.json │ │ ├── createRecord.json │ │ ├── getRecord.json │ │ ├── updateObjectSchema.json │ │ ├── createObject.json │ │ ├── getObjectSchema.json │ │ ├── searchRecords.json │ │ └── getAllObjects.json │ │ ├── product │ │ └── delete.json │ │ ├── objectAssociations │ │ ├── deleteAssociation.json │ │ ├── deleteRelation.json │ │ ├── getAssociationKeyByKeyName.json │ │ ├── createRelation.json │ │ ├── updateAssociation.json │ │ ├── createAssociation.json │ │ ├── getAssociationById.json │ │ ├── getAssociationByObjectKeys.json │ │ └── getAllRelationsByRecordId.json │ │ ├── blog │ │ ├── delete.json │ │ └── create.json │ │ ├── customValues │ │ ├── delete.json │ │ ├── get.json │ │ ├── create.json │ │ ├── update.json │ │ └── getAll.json │ │ ├── conversation │ │ ├── deleteConversation.json │ │ ├── cancelScheduledMessage.json │ │ ├── updateConversation.json │ │ ├── createConversation.json │ │ ├── sendMessage.json │ │ └── addInboundMessage.json │ │ ├── notes │ │ ├── delete.json │ │ ├── get.json │ │ ├── create.json │ │ ├── update.json │ │ └── getAll.json │ │ ├── redirect │ │ ├── delete.json │ │ ├── create.json │ │ ├── update.json │ │ └── getAll.json │ │ ├── media │ │ ├── deleteFile.json │ │ ├── uploadFile.json │ │ └── getFiles.json │ │ ├── task │ │ ├── create.json │ │ ├── getAll.json │ │ └── search.json │ │ ├── contact │ │ ├── getAll.json │ │ ├── create.json │ │ ├── update.json │ │ └── get.json │ │ ├── tags │ │ ├── addTags.json │ │ └── removeTags.json │ │ ├── funnel │ │ ├── getPageCount.json │ │ └── getFunnels.json │ │ ├── saas │ │ ├── pauseLocation.json │ │ ├── disableSaas.json │ │ ├── getLocationsByStripeId.json │ │ ├── enableSaas.json │ │ └── updateSubscription.json │ │ └── socialPlanner │ │ ├── schedulePost.json │ │ └── createPost.json │ ├── v2 │ ├── description │ │ └── n8n-highlevel.code-workspace │ └── test │ │ ├── IsPhoneValid.test.ts │ │ ├── DateToIsoSuperssMillis.test.ts │ │ ├── GetPipelines.test.ts │ │ ├── GetUsers.test.ts │ │ ├── GetContacts.test.ts │ │ ├── BusinessOperations.test.ts │ │ ├── AppointmentNotesOperations.test.ts │ │ ├── IsEmailValid.test.ts │ │ ├── ValidEmailAndPhonePreSendAction.test.ts │ │ ├── CalendarEventOperations.test.ts │ │ ├── DueDatePreSendAction.test.ts │ │ ├── TaskPostReceiceAction.test.ts │ │ ├── SplitTagsPreSendAction.test.ts │ │ ├── GetPipelineStages.test.ts │ │ ├── DateTimeToEpochPreSendAction.test.ts │ │ ├── AddCustomFieldsPreSendAction.test.ts │ │ ├── CalendarGroupOperations.test.ts │ │ ├── CalendarResourceOperations.test.ts │ │ └── HighLevelApiPagination.test.ts │ ├── HighLevel.node.json │ ├── highLevel.svg │ └── HighLevel.node.ts ├── .vscode └── extensions.json ├── gulpfile.js ├── .editorconfig ├── .eslintrc.prepublish.js ├── jest.d.ts ├── tsconfig.json ├── LICENSE.md ├── .prettierrc.js └── package.json /index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.tsbuildinfo 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | .tmp 4 | tmp 5 | dist 6 | npm-debug.log* 7 | yarn.lock 8 | .vscode/launch.json 9 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/appointmentNotes/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "message": "Appointment note deleted successfully" 4 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarResource/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "message": "Calendar resource deleted successfully" 4 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/description/n8n-highlevel.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "../../../.." 5 | } 6 | ], 7 | "settings": {} 8 | } -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "EditorConfig.EditorConfig", 5 | "esbenp.prettier-vscode", 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customField/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "delete": { 3 | "request": { 4 | "basePath": "/locations/{locationId}/customFields/{id}", 5 | "method": "DELETE" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customField/getFolder.json: -------------------------------------------------------------------------------- 1 | { 2 | "getFolder": { 3 | "request": { 4 | "basePath": "/locations/{locationId}/customFields/folders/{id}", 5 | "method": "GET" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customField/deleteFolder.json: -------------------------------------------------------------------------------- 1 | { 2 | "deleteFolder": { 3 | "request": { 4 | "basePath": "/locations/{locationId}/customFields/folders/{id}", 5 | "method": "DELETE" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customField/get.json: -------------------------------------------------------------------------------- 1 | { 2 | "get": { 3 | "request": { 4 | "basePath": "/locations/{locationId}/customFields", 5 | "method": "GET", 6 | "qs": { 7 | "model": "string" 8 | } 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/business/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean" 6 | }, 7 | "message": { 8 | "type": "string" 9 | } 10 | }, 11 | "version": 1 12 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarGroup/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean" 6 | }, 7 | "message": { 8 | "type": "string" 9 | } 10 | }, 11 | "version": 1 12 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customField/updateFolder.json: -------------------------------------------------------------------------------- 1 | { 2 | "updateFolder": { 3 | "request": { 4 | "basePath": "/locations/{locationId}/customFields/folders/{id}", 5 | "method": "PUT", 6 | "body": { 7 | "name": "string" 8 | } 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarEvent/deleteEvent.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean" 6 | }, 7 | "message": { 8 | "type": "string" 9 | } 10 | }, 11 | "version": 1 12 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customField/createFolder.json: -------------------------------------------------------------------------------- 1 | { 2 | "createFolder": { 3 | "request": { 4 | "basePath": "/locations/{locationId}/customFields/folders", 5 | "method": "POST", 6 | "body": { 7 | "name": "string", 8 | "position": "number", 9 | "model": "string" 10 | } 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { task, src, dest } = require('gulp'); 3 | 4 | task('build:icons', copyIcons); 5 | 6 | function copyIcons() { 7 | const nodeSource = path.resolve('nodes', '**', '*.{png,svg}'); 8 | const nodeDestination = path.resolve('dist', 'nodes'); 9 | 10 | return src(nodeSource).pipe(dest(nodeDestination)); 11 | } 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = tab 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [package.json] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.md] 16 | trim_trailing_whitespace = false 17 | 18 | [*.yml] 19 | indent_style = space 20 | indent_size = 2 21 | -------------------------------------------------------------------------------- /.eslintrc.prepublish.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {import('@types/eslint').ESLint.ConfigData} 3 | */ 4 | module.exports = { 5 | extends: "./.eslintrc.js", 6 | 7 | overrides: [ 8 | { 9 | files: ['package.json'], 10 | plugins: ['eslint-plugin-n8n-nodes-base'], 11 | rules: { 12 | 'n8n-nodes-base/community-package-json-name-still-default': 'error', 13 | }, 14 | }, 15 | ], 16 | }; 17 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/HighLevel.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "node": "highlevelv2", 3 | "nodeVersion": "1.0", 4 | "codexVersion": "1.0", 5 | "categories": ["Marketing", "Sales"], 6 | "resources": { 7 | "credentialDocumentation": [ 8 | { 9 | "url": "https://olliebot.ai" 10 | } 11 | ], 12 | "primaryDocumentation": [ 13 | { 14 | "url": "https://olliebot.ai" 15 | } 16 | ] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendar/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "success": { 6 | "type": "boolean", 7 | "description": "Whether the deletion was successful" 8 | }, 9 | "message": { 10 | "type": "string", 11 | "description": "Success message" 12 | } 13 | }, 14 | "additionalProperties": false 15 | } 16 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/coupon/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean", 6 | "description": "Indicates if the coupon was successfully deleted" 7 | }, 8 | "message": { 9 | "type": "string", 10 | "description": "Success message" 11 | } 12 | }, 13 | "version": 1 14 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customObjects/deleteRecord.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean", 6 | "description": "Whether the deletion was successful" 7 | }, 8 | "message": { 9 | "type": "string", 10 | "description": "Success message" 11 | } 12 | }, 13 | "version": 1 14 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/product/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean", 6 | "description": "Indicates if the product was successfully deleted" 7 | }, 8 | "message": { 9 | "type": "string", 10 | "description": "Success message" 11 | } 12 | }, 13 | "version": 1 14 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/appointmentNotes/create.json: -------------------------------------------------------------------------------- 1 | { 2 | "note": { 3 | "id": "6669e4c3a0b142cc43a00e97", 4 | "body": "This is a follow-up note for the appointment scheduled tomorrow.", 5 | "contactId": "vcGaRBUhfEqKMJ2jFzqLi", 6 | "userId": "user123", 7 | "appointmentId": "appointment456", 8 | "createdAt": "2024-06-12T12:14:43.159Z", 9 | "updatedAt": "2024-06-12T12:14:43.159Z" 10 | } 11 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/objectAssociations/deleteAssociation.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean", 6 | "description": "Whether the deletion was successful" 7 | }, 8 | "message": { 9 | "type": "string", 10 | "description": "Success message" 11 | } 12 | }, 13 | "version": 1 14 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/objectAssociations/deleteRelation.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean", 6 | "description": "Whether the deletion was successful" 7 | }, 8 | "message": { 9 | "type": "string", 10 | "description": "Success message" 11 | } 12 | }, 13 | "version": 1 14 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/appointmentNotes/update.json: -------------------------------------------------------------------------------- 1 | { 2 | "note": { 3 | "id": "6669e4c3a0b142cc43a00e97", 4 | "body": "This is an updated follow-up note for the appointment scheduled tomorrow.", 5 | "contactId": "vcGaRBUhfEqKMJ2jFzqLi", 6 | "userId": "user123", 7 | "appointmentId": "appointment456", 8 | "createdAt": "2024-06-12T12:14:43.159Z", 9 | "updatedAt": "2024-06-12T12:20:15.242Z" 10 | } 11 | } -------------------------------------------------------------------------------- /jest.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | function describe(description: string, fn: () => void): void; 3 | function it(description: string, fn: () => void | Promise): void; 4 | function beforeEach(fn: () => void | Promise): void; 5 | function expect(actual: any): any; 6 | 7 | namespace jest { 8 | interface Mock { 9 | mockResolvedValue(value: any): Mock; 10 | mockRejectedValue(value: any): Mock; 11 | } 12 | function fn(): Mock; 13 | } 14 | } 15 | 16 | export {}; -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarResource/get.json: -------------------------------------------------------------------------------- 1 | { 2 | "resource": { 3 | "id": "resource_6669e4c3a0b142cc43a00e97", 4 | "name": "Conference Room A", 5 | "description": "Large conference room with projector and video conferencing capabilities", 6 | "type": "room", 7 | "quantity": 1, 8 | "isActive": true, 9 | "locationId": "location_123456789", 10 | "createdAt": "2024-06-12T12:14:43.159Z", 11 | "updatedAt": "2024-06-12T12:14:43.159Z" 12 | } 13 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarResource/create.json: -------------------------------------------------------------------------------- 1 | { 2 | "resource": { 3 | "id": "resource_6669e4c3a0b142cc43a00e97", 4 | "name": "Conference Room A", 5 | "description": "Large conference room with projector and video conferencing capabilities", 6 | "type": "room", 7 | "quantity": 1, 8 | "isActive": true, 9 | "locationId": "location_123456789", 10 | "createdAt": "2024-06-12T12:14:43.159Z", 11 | "updatedAt": "2024-06-12T12:14:43.159Z" 12 | } 13 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarResource/update.json: -------------------------------------------------------------------------------- 1 | { 2 | "resource": { 3 | "id": "resource_6669e4c3a0b142cc43a00e97", 4 | "name": "Conference Room A - Updated", 5 | "description": "Large conference room with projector and video conferencing capabilities - Updated description", 6 | "type": "room", 7 | "quantity": 2, 8 | "isActive": true, 9 | "locationId": "location_123456789", 10 | "createdAt": "2024-06-12T12:14:43.159Z", 11 | "updatedAt": "2024-06-12T12:20:15.242Z" 12 | } 13 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarGroup/validateSlug.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "isValid": { 5 | "type": "boolean" 6 | }, 7 | "slug": { 8 | "type": "string" 9 | }, 10 | "message": { 11 | "type": "string" 12 | }, 13 | "suggestions": { 14 | "type": "array", 15 | "items": { 16 | "type": "string" 17 | } 18 | } 19 | }, 20 | "version": 1 21 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/blog/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean", 6 | "description": "Indicates whether the blog post was successfully deleted" 7 | }, 8 | "message": { 9 | "type": "string", 10 | "description": "Success or error message" 11 | }, 12 | "deletedId": { 13 | "type": "string", 14 | "description": "ID of the deleted blog post" 15 | } 16 | }, 17 | "version": 1 18 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customField/update.json: -------------------------------------------------------------------------------- 1 | { 2 | "update": { 3 | "request": { 4 | "basePath": "/locations/{locationId}/customFields/{id}", 5 | "method": "PUT", 6 | "body": { 7 | "name": "string", 8 | "dataType": "string", 9 | "position": "number", 10 | "isRequired": "boolean", 11 | "isMultipleValues": "boolean", 12 | "isImportant": "boolean", 13 | "picklistOptions": "object", 14 | "picklistImageOptions": "object", 15 | "fileType": "string", 16 | "acceptedFormat": "string", 17 | "placeholder": "string" 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customField/create.json: -------------------------------------------------------------------------------- 1 | { 2 | "create": { 3 | "request": { 4 | "basePath": "/locations/{locationId}/customFields", 5 | "method": "POST", 6 | "body": { 7 | "name": "string", 8 | "dataType": "string", 9 | "position": "number", 10 | "isRequired": "boolean", 11 | "isMultipleValues": "boolean", 12 | "model": "string", 13 | "parentId": "string", 14 | "isImportant": "boolean", 15 | "picklistOptions": "object", 16 | "picklistImageOptions": "object", 17 | "fileType": "string", 18 | "acceptedFormat": "string", 19 | "placeholder": "string" 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customValues/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean" 6 | }, 7 | "message": { 8 | "type": "string" 9 | }, 10 | "deletedCustomValue": { 11 | "type": "object", 12 | "properties": { 13 | "id": { 14 | "type": "string" 15 | }, 16 | "locationId": { 17 | "type": "string" 18 | }, 19 | "deletedAt": { 20 | "type": "string" 21 | } 22 | } 23 | } 24 | }, 25 | "version": 1 26 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/conversation/deleteConversation.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean", 6 | "description": "Whether the conversation was deleted successfully" 7 | }, 8 | "message": { 9 | "type": "string", 10 | "description": "Success or error message" 11 | }, 12 | "deletedConversationId": { 13 | "type": "string", 14 | "description": "ID of the deleted conversation" 15 | }, 16 | "deletedAt": { 17 | "type": "string", 18 | "format": "date-time", 19 | "description": "Timestamp when the conversation was deleted" 20 | } 21 | }, 22 | "version": 1 23 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/notes/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean" 6 | }, 7 | "message": { 8 | "type": "string" 9 | }, 10 | "deletedNote": { 11 | "type": "object", 12 | "properties": { 13 | "id": { 14 | "type": "string" 15 | }, 16 | "contactId": { 17 | "type": "string" 18 | }, 19 | "locationId": { 20 | "type": "string" 21 | }, 22 | "deletedAt": { 23 | "type": "string" 24 | } 25 | } 26 | } 27 | }, 28 | "version": 1 29 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "target": "es2019", 7 | "lib": ["es2019", "es2020", "es2022.error"], 8 | "removeComments": true, 9 | "useUnknownInCatchVariables": false, 10 | "forceConsistentCasingInFileNames": true, 11 | "noImplicitAny": true, 12 | "noImplicitReturns": true, 13 | "noUnusedLocals": true, 14 | "strictNullChecks": true, 15 | "preserveConstEnums": true, 16 | "esModuleInterop": true, 17 | "resolveJsonModule": true, 18 | "incremental": true, 19 | "declaration": true, 20 | "sourceMap": true, 21 | "skipLibCheck": true, 22 | "outDir": "./dist/", 23 | }, 24 | "include": [ 25 | "credentials/**/*", 26 | "nodes/**/*", 27 | "nodes/**/*.json", 28 | "package.json", 29 | ], 30 | } 31 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/highLevel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/redirect/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean" 6 | }, 7 | "message": { 8 | "type": "string" 9 | }, 10 | "deletedRedirect": { 11 | "type": "object", 12 | "properties": { 13 | "id": { 14 | "type": "string" 15 | }, 16 | "sourceUrl": { 17 | "type": "string" 18 | }, 19 | "targetUrl": { 20 | "type": "string" 21 | }, 22 | "locationId": { 23 | "type": "string" 24 | }, 25 | "deletedAt": { 26 | "type": "string" 27 | } 28 | } 29 | } 30 | }, 31 | "version": 1 32 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/HighLevel.node.ts: -------------------------------------------------------------------------------- 1 | import type { INodeTypeBaseDescription, IVersionedNodeType } from 'n8n-workflow'; 2 | import { VersionedNodeType } from 'n8n-workflow'; 3 | 4 | import { HighLevelV2 } from './v2/HighLevelV2.node'; 5 | 6 | export class HighLevel extends VersionedNodeType { 7 | constructor() { 8 | const baseDescription: INodeTypeBaseDescription = { 9 | displayName: 'HighLevel v2', 10 | name: 'highLevelv2', 11 | icon: 'file:highLevel.svg', 12 | group: ['transform'], 13 | defaultVersion: 2, 14 | description: 'For utilizing the HighLevel API v2 by Mario Aldayuz. This is a fork of the original HighLevel node. This is a work in progress and is not yet ready for production. Submit isues here: https://github.com/marioaldayuz/n8n-highlevel/issues', 15 | }; 16 | 17 | const nodeVersions: IVersionedNodeType['nodeVersions'] = { 18 | 2: new HighLevelV2(baseDescription), 19 | }; 20 | 21 | super(nodeVersions, baseDescription); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/appointmentNotes/getAll.json: -------------------------------------------------------------------------------- 1 | { 2 | "notes": [ 3 | { 4 | "id": "6669e4c3a0b142cc43a00e97", 5 | "body": "This is a follow-up note for the appointment scheduled tomorrow.", 6 | "contactId": "vcGaRBUhfEqKMJ2jFzqLi", 7 | "userId": "user123", 8 | "appointmentId": "appointment456", 9 | "createdAt": "2024-06-12T12:14:43.159Z", 10 | "updatedAt": "2024-06-12T12:14:43.159Z" 11 | }, 12 | { 13 | "id": "6669e4c3a0b142cc43a00e98", 14 | "body": "Appointment confirmed with client. Reminder sent via SMS.", 15 | "contactId": "vcGaRBUhfEqKMJ2jFzqLi", 16 | "userId": "user456", 17 | "appointmentId": "appointment789", 18 | "createdAt": "2024-06-12T10:30:12.455Z", 19 | "updatedAt": "2024-06-12T10:30:12.455Z" 20 | } 21 | ], 22 | "meta": { 23 | "total": 2, 24 | "currentPage": 1, 25 | "nextPage": null, 26 | "prevPage": null, 27 | "limit": 20 28 | } 29 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/media/deleteFile.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean" 6 | }, 7 | "message": { 8 | "type": "string" 9 | }, 10 | "deletedFile": { 11 | "type": "object", 12 | "properties": { 13 | "id": { 14 | "type": "string" 15 | }, 16 | "name": { 17 | "type": "string" 18 | }, 19 | "type": { 20 | "type": "string" 21 | }, 22 | "isFolder": { 23 | "type": "boolean" 24 | }, 25 | "locationId": { 26 | "type": "string" 27 | }, 28 | "deletedAt": { 29 | "type": "string" 30 | } 31 | } 32 | } 33 | }, 34 | "version": 1 35 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/task/create.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "contactId": { 5 | "type": "string" 6 | }, 7 | "task": { 8 | "type": "object", 9 | "properties": { 10 | "businessId": { 11 | "type": "string" 12 | }, 13 | "completed": { 14 | "type": "boolean" 15 | }, 16 | "contactId": { 17 | "type": "string" 18 | }, 19 | "dueDate": { 20 | "type": "string" 21 | }, 22 | "id": { 23 | "type": "string" 24 | }, 25 | "title": { 26 | "type": "string" 27 | } 28 | } 29 | }, 30 | "traceId": { 31 | "type": "string" 32 | } 33 | }, 34 | "version": 1 35 | } 36 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendar/getFreeSlots.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "slots": { 6 | "type": "array", 7 | "items": { 8 | "type": "object", 9 | "properties": { 10 | "startTime": { 11 | "type": "number", 12 | "description": "Start time of the free slot (Unix timestamp)" 13 | }, 14 | "endTime": { 15 | "type": "number", 16 | "description": "End time of the free slot (Unix timestamp)" 17 | }, 18 | "date": { 19 | "type": "string", 20 | "format": "date", 21 | "description": "Date of the slot" 22 | }, 23 | "available": { 24 | "type": "boolean", 25 | "description": "Whether the slot is available" 26 | } 27 | } 28 | } 29 | }, 30 | "timezone": { 31 | "type": "string", 32 | "description": "Timezone used for the slots" 33 | }, 34 | "calendarId": { 35 | "type": "string", 36 | "description": "Calendar ID for which slots were retrieved" 37 | } 38 | }, 39 | "additionalProperties": false 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2024 Mario Aldayuz 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/IsPhoneValid.test.ts: -------------------------------------------------------------------------------- 1 | import { isPhoneValid } from '../GenericFunctions'; 2 | 3 | describe('isPhoneValid', () => { 4 | it('should return true for a valid phone number', () => { 5 | const phone = '+1234567890'; 6 | const result = isPhoneValid(phone); 7 | expect(result).toBe(true); 8 | }); 9 | 10 | it('should return false for an invalid phone number', () => { 11 | const phone = 'invalid-phone'; 12 | const result = isPhoneValid(phone); 13 | expect(result).toBe(false); 14 | }); 15 | 16 | it('should return false for a phone number with invalid characters', () => { 17 | const phone = '+123-abc-456'; 18 | const result = isPhoneValid(phone); 19 | expect(result).toBe(false); 20 | }); 21 | 22 | it('should return false for an empty phone number', () => { 23 | const phone = ''; 24 | const result = isPhoneValid(phone); 25 | expect(result).toBe(false); 26 | }); 27 | 28 | it('should return false for a phone number with only special characters', () => { 29 | const phone = '!!!@@@###'; 30 | const result = isPhoneValid(phone); 31 | expect(result).toBe(false); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | /** 3 | * https://prettier.io/docs/en/options.html#semicolons 4 | */ 5 | semi: true, 6 | 7 | /** 8 | * https://prettier.io/docs/en/options.html#trailing-commas 9 | */ 10 | trailingComma: 'all', 11 | 12 | /** 13 | * https://prettier.io/docs/en/options.html#bracket-spacing 14 | */ 15 | bracketSpacing: true, 16 | 17 | /** 18 | * https://prettier.io/docs/en/options.html#tabs 19 | */ 20 | useTabs: true, 21 | 22 | /** 23 | * https://prettier.io/docs/en/options.html#tab-width 24 | */ 25 | tabWidth: 2, 26 | 27 | /** 28 | * https://prettier.io/docs/en/options.html#arrow-function-parentheses 29 | */ 30 | arrowParens: 'always', 31 | 32 | /** 33 | * https://prettier.io/docs/en/options.html#quotes 34 | */ 35 | singleQuote: true, 36 | 37 | /** 38 | * https://prettier.io/docs/en/options.html#quote-props 39 | */ 40 | quoteProps: 'as-needed', 41 | 42 | /** 43 | * https://prettier.io/docs/en/options.html#end-of-line 44 | */ 45 | endOfLine: 'lf', 46 | 47 | /** 48 | * https://prettier.io/docs/en/options.html#print-width 49 | */ 50 | printWidth: 100, 51 | }; 52 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/notes/get.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "note": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "body": { 11 | "type": "string" 12 | }, 13 | "contactId": { 14 | "type": "string" 15 | }, 16 | "userId": { 17 | "type": "string" 18 | }, 19 | "locationId": { 20 | "type": "string" 21 | }, 22 | "dateAdded": { 23 | "type": "string" 24 | }, 25 | "dateUpdated": { 26 | "type": "string" 27 | }, 28 | "createdBy": { 29 | "type": "string" 30 | }, 31 | "updatedBy": { 32 | "type": "string" 33 | } 34 | } 35 | }, 36 | "success": { 37 | "type": "boolean" 38 | } 39 | }, 40 | "version": 1 41 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/notes/create.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "note": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "body": { 11 | "type": "string" 12 | }, 13 | "contactId": { 14 | "type": "string" 15 | }, 16 | "userId": { 17 | "type": "string" 18 | }, 19 | "locationId": { 20 | "type": "string" 21 | }, 22 | "dateAdded": { 23 | "type": "string" 24 | }, 25 | "dateUpdated": { 26 | "type": "string" 27 | }, 28 | "createdBy": { 29 | "type": "string" 30 | }, 31 | "updatedBy": { 32 | "type": "string" 33 | } 34 | } 35 | }, 36 | "success": { 37 | "type": "boolean" 38 | }, 39 | "message": { 40 | "type": "string" 41 | } 42 | }, 43 | "version": 1 44 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/notes/update.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "note": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "body": { 11 | "type": "string" 12 | }, 13 | "contactId": { 14 | "type": "string" 15 | }, 16 | "userId": { 17 | "type": "string" 18 | }, 19 | "locationId": { 20 | "type": "string" 21 | }, 22 | "dateAdded": { 23 | "type": "string" 24 | }, 25 | "dateUpdated": { 26 | "type": "string" 27 | }, 28 | "createdBy": { 29 | "type": "string" 30 | }, 31 | "updatedBy": { 32 | "type": "string" 33 | } 34 | } 35 | }, 36 | "success": { 37 | "type": "boolean" 38 | }, 39 | "message": { 40 | "type": "string" 41 | } 42 | }, 43 | "version": 1 44 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/DateToIsoSuperssMillis.test.ts: -------------------------------------------------------------------------------- 1 | import { dateToIsoSupressMillis } from '../GenericFunctions'; 2 | 3 | describe('dateToIsoSupressMillis', () => { 4 | it('should return an ISO string without milliseconds (UTC)', () => { 5 | const dateTime = '2024-12-25T10:15:30.123Z'; 6 | const result = dateToIsoSupressMillis(dateTime); 7 | expect(result).toBe('2024-12-25T10:15:30.123+00:00'); 8 | }); 9 | 10 | it('should handle dates without milliseconds correctly', () => { 11 | const dateTime = '2024-12-25T10:15:30Z'; 12 | const result = dateToIsoSupressMillis(dateTime); 13 | expect(result).toBe('2024-12-25T10:15:30+00:00'); 14 | }); 15 | 16 | it('should handle time zone offsets correctly', () => { 17 | const dateTime = '2024-12-25T10:15:30.123+02:00'; 18 | const result = dateToIsoSupressMillis(dateTime); 19 | expect(result).toBe('2024-12-25T08:15:30.123+00:00'); 20 | }); 21 | 22 | it('should handle edge case for empty input', () => { 23 | const dateTime = ''; 24 | const result = dateToIsoSupressMillis(dateTime); 25 | expect(result).toBeNull(); 26 | }); 27 | 28 | it('should handle edge case for null input', () => { 29 | const dateTime = null as unknown as string; 30 | const result = dateToIsoSupressMillis(dateTime); 31 | expect(result).toBeNull(); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarEvent/createBlockSlot.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "blockedSlot": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "calendarId": { 11 | "type": "string" 12 | }, 13 | "userId": { 14 | "type": "string" 15 | }, 16 | "locationId": { 17 | "type": "string" 18 | }, 19 | "title": { 20 | "type": "string" 21 | }, 22 | "startTime": { 23 | "type": "string", 24 | "format": "date-time" 25 | }, 26 | "endTime": { 27 | "type": "string", 28 | "format": "date-time" 29 | }, 30 | "dateCreated": { 31 | "type": "string", 32 | "format": "date-time" 33 | }, 34 | "dateUpdated": { 35 | "type": "string", 36 | "format": "date-time" 37 | } 38 | } 39 | } 40 | }, 41 | "version": 1 42 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarEvent/updateBlockSlot.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "blockedSlot": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "calendarId": { 11 | "type": "string" 12 | }, 13 | "userId": { 14 | "type": "string" 15 | }, 16 | "locationId": { 17 | "type": "string" 18 | }, 19 | "title": { 20 | "type": "string" 21 | }, 22 | "startTime": { 23 | "type": "string", 24 | "format": "date-time" 25 | }, 26 | "endTime": { 27 | "type": "string", 28 | "format": "date-time" 29 | }, 30 | "dateCreated": { 31 | "type": "string", 32 | "format": "date-time" 33 | }, 34 | "dateUpdated": { 35 | "type": "string", 36 | "format": "date-time" 37 | } 38 | } 39 | } 40 | }, 41 | "version": 1 42 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customObjects/updateRecord.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "id": { 5 | "type": "string", 6 | "description": "Unique identifier for the record" 7 | }, 8 | "objectId": { 9 | "type": "string", 10 | "description": "ID of the custom object this record belongs to" 11 | }, 12 | "locationId": { 13 | "type": "string", 14 | "description": "The location ID where the record belongs" 15 | }, 16 | "data": { 17 | "type": "object", 18 | "description": "The record data according to the custom object schema" 19 | }, 20 | "updatedAt": { 21 | "type": "string", 22 | "format": "date-time", 23 | "description": "Timestamp when the record was last updated" 24 | }, 25 | "updatedBy": { 26 | "type": "object", 27 | "properties": { 28 | "id": { 29 | "type": "string" 30 | }, 31 | "name": { 32 | "type": "string" 33 | }, 34 | "email": { 35 | "type": "string" 36 | } 37 | }, 38 | "description": "User who updated the record" 39 | } 40 | }, 41 | "version": 1 42 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarGroup/create.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "group": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "name": { 11 | "type": "string" 12 | }, 13 | "slug": { 14 | "type": "string" 15 | }, 16 | "description": { 17 | "type": "string" 18 | }, 19 | "locationId": { 20 | "type": "string" 21 | }, 22 | "calendarIds": { 23 | "type": "array", 24 | "items": { 25 | "type": "string" 26 | } 27 | }, 28 | "isActive": { 29 | "type": "boolean" 30 | }, 31 | "teamId": { 32 | "type": "string" 33 | }, 34 | "createdAt": { 35 | "type": "string", 36 | "format": "date-time" 37 | }, 38 | "updatedAt": { 39 | "type": "string", 40 | "format": "date-time" 41 | } 42 | } 43 | } 44 | }, 45 | "version": 1 46 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarGroup/disable.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "group": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "name": { 11 | "type": "string" 12 | }, 13 | "slug": { 14 | "type": "string" 15 | }, 16 | "description": { 17 | "type": "string" 18 | }, 19 | "locationId": { 20 | "type": "string" 21 | }, 22 | "calendarIds": { 23 | "type": "array", 24 | "items": { 25 | "type": "string" 26 | } 27 | }, 28 | "isActive": { 29 | "type": "boolean" 30 | }, 31 | "teamId": { 32 | "type": "string" 33 | }, 34 | "createdAt": { 35 | "type": "string", 36 | "format": "date-time" 37 | }, 38 | "updatedAt": { 39 | "type": "string", 40 | "format": "date-time" 41 | } 42 | } 43 | } 44 | }, 45 | "version": 1 46 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarGroup/update.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "group": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "name": { 11 | "type": "string" 12 | }, 13 | "slug": { 14 | "type": "string" 15 | }, 16 | "description": { 17 | "type": "string" 18 | }, 19 | "locationId": { 20 | "type": "string" 21 | }, 22 | "calendarIds": { 23 | "type": "array", 24 | "items": { 25 | "type": "string" 26 | } 27 | }, 28 | "isActive": { 29 | "type": "boolean" 30 | }, 31 | "teamId": { 32 | "type": "string" 33 | }, 34 | "createdAt": { 35 | "type": "string", 36 | "format": "date-time" 37 | }, 38 | "updatedAt": { 39 | "type": "string", 40 | "format": "date-time" 41 | } 42 | } 43 | } 44 | }, 45 | "version": 1 46 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarResource/getAll.json: -------------------------------------------------------------------------------- 1 | { 2 | "resources": [ 3 | { 4 | "id": "resource_6669e4c3a0b142cc43a00e97", 5 | "name": "Conference Room A", 6 | "description": "Large conference room with projector and video conferencing capabilities", 7 | "type": "room", 8 | "quantity": 1, 9 | "isActive": true, 10 | "locationId": "location_123456789", 11 | "createdAt": "2024-06-12T12:14:43.159Z", 12 | "updatedAt": "2024-06-12T12:14:43.159Z" 13 | }, 14 | { 15 | "id": "resource_6669e4c3a0b142cc43a00e98", 16 | "name": "Laptop - Dell XPS 15", 17 | "description": "High-performance laptop for presentations and meetings", 18 | "type": "equipment", 19 | "quantity": 3, 20 | "isActive": true, 21 | "locationId": "location_123456789", 22 | "createdAt": "2024-06-12T10:30:12.455Z", 23 | "updatedAt": "2024-06-12T10:30:12.455Z" 24 | }, 25 | { 26 | "id": "resource_6669e4c3a0b142cc43a00e99", 27 | "name": "Meeting Room B", 28 | "description": "Small meeting room perfect for team discussions", 29 | "type": "room", 30 | "quantity": 1, 31 | "isActive": false, 32 | "locationId": "location_123456789", 33 | "createdAt": "2024-06-12T09:15:30.123Z", 34 | "updatedAt": "2024-06-12T14:45:22.789Z" 35 | } 36 | ], 37 | "meta": { 38 | "total": 3, 39 | "currentPage": 1, 40 | "nextPage": null, 41 | "prevPage": null, 42 | "limit": 20 43 | } 44 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/GetPipelines.test.ts: -------------------------------------------------------------------------------- 1 | import type { ILoadOptionsFunctions } from 'n8n-workflow'; 2 | 3 | import { getPipelines } from '../GenericFunctions'; 4 | 5 | describe('getPipelines', () => { 6 | const mockHighLevelApiRequest = jest.fn(); 7 | const mockGetCredentials = jest.fn(); 8 | const mockContext = { 9 | getCredentials: mockGetCredentials, 10 | helpers: { 11 | httpRequestWithAuthentication: mockHighLevelApiRequest, 12 | }, 13 | } as unknown as ILoadOptionsFunctions; 14 | 15 | beforeEach(() => { 16 | mockHighLevelApiRequest.mockClear(); 17 | mockGetCredentials.mockClear(); 18 | }); 19 | 20 | it('should return a list of pipelines', async () => { 21 | const mockPipelines = [ 22 | { id: '1', name: 'Pipeline A' }, 23 | { id: '2', name: 'Pipeline B' }, 24 | ]; 25 | 26 | mockHighLevelApiRequest.mockResolvedValue({ pipelines: mockPipelines }); 27 | mockGetCredentials.mockResolvedValue({ oauthTokenData: { locationId: '123' } }); 28 | 29 | const response = await getPipelines.call(mockContext); 30 | 31 | expect(response).toEqual([ 32 | { name: 'Pipeline A', value: '1' }, 33 | { name: 'Pipeline B', value: '2' }, 34 | ]); 35 | }); 36 | 37 | it('should handle empty pipelines list', async () => { 38 | mockHighLevelApiRequest.mockResolvedValue({ pipelines: [] }); 39 | mockGetCredentials.mockResolvedValue({ oauthTokenData: { locationId: '123' } }); 40 | 41 | const response = await getPipelines.call(mockContext); 42 | 43 | expect(response).toEqual([]); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/GetUsers.test.ts: -------------------------------------------------------------------------------- 1 | import type { ILoadOptionsFunctions } from 'n8n-workflow'; 2 | 3 | import { getUsers } from '../GenericFunctions'; 4 | 5 | describe('getUsers', () => { 6 | const mockHighLevelApiRequest = jest.fn(); 7 | const mockGetCredentials = jest.fn(); 8 | const mockContext = { 9 | getCredentials: mockGetCredentials, 10 | helpers: { 11 | httpRequestWithAuthentication: mockHighLevelApiRequest, 12 | }, 13 | } as unknown as ILoadOptionsFunctions; 14 | 15 | beforeEach(() => { 16 | mockHighLevelApiRequest.mockClear(); 17 | mockGetCredentials.mockClear(); 18 | }); 19 | 20 | it('should return a list of users', async () => { 21 | const mockUsers = [ 22 | { id: '1', name: 'John Doe', email: 'john.doe@example.com' }, 23 | { id: '2', name: 'Jane Smith', email: 'jane.smith@example.com' }, 24 | ]; 25 | 26 | mockHighLevelApiRequest.mockResolvedValue({ users: mockUsers }); 27 | mockGetCredentials.mockResolvedValue({ oauthTokenData: { locationId: '123' } }); 28 | 29 | const response = await getUsers.call(mockContext); 30 | 31 | expect(response).toEqual([ 32 | { name: 'John Doe', value: '1' }, 33 | { name: 'Jane Smith', value: '2' }, 34 | ]); 35 | }); 36 | 37 | it('should handle empty users list', async () => { 38 | mockHighLevelApiRequest.mockResolvedValue({ users: [] }); 39 | mockGetCredentials.mockResolvedValue({ oauthTokenData: { locationId: '123' } }); 40 | 41 | const response = await getUsers.call(mockContext); 42 | 43 | expect(response).toEqual([]); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendar/update.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "locationId": { 6 | "type": "string", 7 | "description": "The HighLevel location ID" 8 | }, 9 | "name": { 10 | "type": "string", 11 | "description": "Name of the calendar" 12 | }, 13 | "description": { 14 | "type": "string", 15 | "description": "Description of the calendar" 16 | }, 17 | "appointmentDuration": { 18 | "type": "number", 19 | "description": "Default appointment duration in minutes" 20 | }, 21 | "availability": { 22 | "type": "object", 23 | "description": "Availability settings for the calendar" 24 | }, 25 | "bufferTime": { 26 | "type": "number", 27 | "description": "Buffer time in minutes between appointments" 28 | }, 29 | "calendarType": { 30 | "type": "string", 31 | "enum": ["round_robin_event", "round_robin_availability", "service_menu", "class_booking"], 32 | "description": "Type of calendar" 33 | }, 34 | "enableRecurring": { 35 | "type": "boolean", 36 | "description": "Whether to enable recurring appointments" 37 | }, 38 | "eventColor": { 39 | "type": "string", 40 | "description": "Color for calendar events" 41 | }, 42 | "eventTitle": { 43 | "type": "string", 44 | "description": "Default title for calendar events" 45 | }, 46 | "slug": { 47 | "type": "string", 48 | "description": "URL slug for the calendar" 49 | } 50 | }, 51 | "additionalProperties": false 52 | } 53 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/GetContacts.test.ts: -------------------------------------------------------------------------------- 1 | import type { ILoadOptionsFunctions } from 'n8n-workflow'; 2 | 3 | import { getContacts } from '../GenericFunctions'; 4 | 5 | describe('getContacts', () => { 6 | const mockHighLevelApiRequest = jest.fn(); 7 | const mockGetCredentials = jest.fn(); 8 | const mockContext = { 9 | getCredentials: mockGetCredentials, 10 | helpers: { 11 | httpRequestWithAuthentication: mockHighLevelApiRequest, 12 | }, 13 | } as unknown as ILoadOptionsFunctions; 14 | 15 | beforeEach(() => { 16 | mockHighLevelApiRequest.mockClear(); 17 | mockGetCredentials.mockClear(); 18 | }); 19 | 20 | it('should return a list of contacts', async () => { 21 | const mockContacts = [ 22 | { id: '1', name: 'Alice', email: 'alice@example.com' }, 23 | { id: '2', name: 'Bob', email: 'bob@example.com' }, 24 | ]; 25 | 26 | mockHighLevelApiRequest.mockResolvedValue({ contacts: mockContacts }); 27 | mockGetCredentials.mockResolvedValue({ oauthTokenData: { locationId: '123' } }); 28 | 29 | const response = await getContacts.call(mockContext); 30 | 31 | expect(response).toEqual([ 32 | { name: 'alice@example.com', value: '1' }, 33 | { name: 'bob@example.com', value: '2' }, 34 | ]); 35 | }); 36 | 37 | it('should handle empty contacts list', async () => { 38 | mockHighLevelApiRequest.mockResolvedValue({ contacts: [] }); 39 | mockGetCredentials.mockResolvedValue({ oauthTokenData: { locationId: '123' } }); 40 | 41 | const response = await getContacts.call(mockContext); 42 | 43 | expect(response).toEqual([]); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendar/create.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "locationId": { 6 | "type": "string", 7 | "description": "The HighLevel location ID" 8 | }, 9 | "name": { 10 | "type": "string", 11 | "description": "Name of the calendar" 12 | }, 13 | "description": { 14 | "type": "string", 15 | "description": "Description of the calendar" 16 | }, 17 | "appointmentDuration": { 18 | "type": "number", 19 | "description": "Default appointment duration in minutes" 20 | }, 21 | "availability": { 22 | "type": "object", 23 | "description": "Availability settings for the calendar" 24 | }, 25 | "bufferTime": { 26 | "type": "number", 27 | "description": "Buffer time in minutes between appointments" 28 | }, 29 | "calendarType": { 30 | "type": "string", 31 | "enum": ["round_robin_event", "round_robin_availability", "service_menu", "class_booking"], 32 | "description": "Type of calendar" 33 | }, 34 | "enableRecurring": { 35 | "type": "boolean", 36 | "description": "Whether to enable recurring appointments" 37 | }, 38 | "eventColor": { 39 | "type": "string", 40 | "description": "Color for calendar events" 41 | }, 42 | "eventTitle": { 43 | "type": "string", 44 | "description": "Default title for calendar events" 45 | }, 46 | "slug": { 47 | "type": "string", 48 | "description": "URL slug for the calendar" 49 | } 50 | }, 51 | "required": ["locationId", "name"], 52 | "additionalProperties": false 53 | } 54 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customObjects/createRecord.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "id": { 5 | "type": "string", 6 | "description": "Unique identifier for the record" 7 | }, 8 | "objectId": { 9 | "type": "string", 10 | "description": "ID of the custom object this record belongs to" 11 | }, 12 | "locationId": { 13 | "type": "string", 14 | "description": "The location ID where the record belongs" 15 | }, 16 | "data": { 17 | "type": "object", 18 | "description": "The record data according to the custom object schema" 19 | }, 20 | "createdAt": { 21 | "type": "string", 22 | "format": "date-time", 23 | "description": "Timestamp when the record was created" 24 | }, 25 | "updatedAt": { 26 | "type": "string", 27 | "format": "date-time", 28 | "description": "Timestamp when the record was last updated" 29 | }, 30 | "createdBy": { 31 | "type": "object", 32 | "properties": { 33 | "id": { 34 | "type": "string" 35 | }, 36 | "name": { 37 | "type": "string" 38 | }, 39 | "email": { 40 | "type": "string" 41 | } 42 | }, 43 | "description": "User who created the record" 44 | } 45 | }, 46 | "version": 1 47 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customObjects/getRecord.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "id": { 5 | "type": "string", 6 | "description": "Unique identifier for the record" 7 | }, 8 | "objectId": { 9 | "type": "string", 10 | "description": "ID of the custom object this record belongs to" 11 | }, 12 | "locationId": { 13 | "type": "string", 14 | "description": "The location ID where the record belongs" 15 | }, 16 | "data": { 17 | "type": "object", 18 | "description": "The record data according to the custom object schema" 19 | }, 20 | "createdAt": { 21 | "type": "string", 22 | "format": "date-time", 23 | "description": "Timestamp when the record was created" 24 | }, 25 | "updatedAt": { 26 | "type": "string", 27 | "format": "date-time", 28 | "description": "Timestamp when the record was last updated" 29 | }, 30 | "createdBy": { 31 | "type": "object", 32 | "properties": { 33 | "id": { 34 | "type": "string" 35 | }, 36 | "name": { 37 | "type": "string" 38 | }, 39 | "email": { 40 | "type": "string" 41 | } 42 | }, 43 | "description": "User who created the record" 44 | } 45 | }, 46 | "version": 1 47 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/contact/getAll.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "attributions": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "isFirst": { 10 | "type": "boolean" 11 | }, 12 | "medium": { 13 | "type": "string" 14 | }, 15 | "utmSessionSource": { 16 | "type": "string" 17 | } 18 | } 19 | } 20 | }, 21 | "contactName": { 22 | "type": "string" 23 | }, 24 | "customFields": { 25 | "type": "array", 26 | "items": { 27 | "type": "object", 28 | "properties": { 29 | "id": { 30 | "type": "string" 31 | } 32 | } 33 | } 34 | }, 35 | "dateAdded": { 36 | "type": "string" 37 | }, 38 | "dateUpdated": { 39 | "type": "string" 40 | }, 41 | "dnd": { 42 | "type": "boolean" 43 | }, 44 | "id": { 45 | "type": "string" 46 | }, 47 | "locationId": { 48 | "type": "string" 49 | }, 50 | "tags": { 51 | "type": "array", 52 | "items": { 53 | "type": "string" 54 | } 55 | } 56 | }, 57 | "version": 1 58 | } 59 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/objectAssociations/getAssociationKeyByKeyName.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "id": { 5 | "type": "string", 6 | "description": "Unique identifier for the association key" 7 | }, 8 | "name": { 9 | "type": "string", 10 | "description": "Name of the association key" 11 | }, 12 | "description": { 13 | "type": "string", 14 | "description": "Description of the association key" 15 | }, 16 | "fromObjectType": { 17 | "type": "string", 18 | "description": "Type of the source object" 19 | }, 20 | "toObjectType": { 21 | "type": "string", 22 | "description": "Type of the target object" 23 | }, 24 | "cardinality": { 25 | "type": "string", 26 | "enum": ["ONE_TO_ONE", "ONE_TO_MANY", "MANY_TO_ONE", "MANY_TO_MANY"], 27 | "description": "Cardinality of the association" 28 | }, 29 | "isSystemDefined": { 30 | "type": "boolean", 31 | "description": "Whether this is a system-defined association key" 32 | }, 33 | "createdAt": { 34 | "type": "string", 35 | "format": "date-time", 36 | "description": "Timestamp when the association key was created" 37 | }, 38 | "updatedAt": { 39 | "type": "string", 40 | "format": "date-time", 41 | "description": "Timestamp when the association key was last updated" 42 | } 43 | }, 44 | "version": 1 45 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/tags/addTags.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "contact": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "contactName": { 11 | "type": "string" 12 | }, 13 | "firstName": { 14 | "type": "string" 15 | }, 16 | "lastName": { 17 | "type": "string" 18 | }, 19 | "email": { 20 | "type": "string" 21 | }, 22 | "phone": { 23 | "type": "string" 24 | }, 25 | "tags": { 26 | "type": "array", 27 | "items": { 28 | "type": "string" 29 | } 30 | }, 31 | "locationId": { 32 | "type": "string" 33 | }, 34 | "dateAdded": { 35 | "type": "string" 36 | }, 37 | "dateUpdated": { 38 | "type": "string" 39 | } 40 | } 41 | }, 42 | "success": { 43 | "type": "boolean" 44 | }, 45 | "message": { 46 | "type": "string" 47 | }, 48 | "addedTags": { 49 | "type": "array", 50 | "items": { 51 | "type": "string" 52 | } 53 | } 54 | }, 55 | "version": 1 56 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/redirect/create.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "redirect": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "sourceUrl": { 11 | "type": "string" 12 | }, 13 | "targetUrl": { 14 | "type": "string" 15 | }, 16 | "redirectType": { 17 | "type": "string", 18 | "enum": ["301", "302"] 19 | }, 20 | "description": { 21 | "type": "string" 22 | }, 23 | "isActive": { 24 | "type": "boolean" 25 | }, 26 | "locationId": { 27 | "type": "string" 28 | }, 29 | "createdAt": { 30 | "type": "string" 31 | }, 32 | "updatedAt": { 33 | "type": "string" 34 | }, 35 | "createdBy": { 36 | "type": "string" 37 | }, 38 | "clickCount": { 39 | "type": "number" 40 | }, 41 | "lastAccessed": { 42 | "type": "string" 43 | } 44 | } 45 | }, 46 | "success": { 47 | "type": "boolean" 48 | }, 49 | "message": { 50 | "type": "string" 51 | } 52 | }, 53 | "version": 1 54 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/redirect/update.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "redirect": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "sourceUrl": { 11 | "type": "string" 12 | }, 13 | "targetUrl": { 14 | "type": "string" 15 | }, 16 | "redirectType": { 17 | "type": "string", 18 | "enum": ["301", "302"] 19 | }, 20 | "description": { 21 | "type": "string" 22 | }, 23 | "isActive": { 24 | "type": "boolean" 25 | }, 26 | "locationId": { 27 | "type": "string" 28 | }, 29 | "createdAt": { 30 | "type": "string" 31 | }, 32 | "updatedAt": { 33 | "type": "string" 34 | }, 35 | "createdBy": { 36 | "type": "string" 37 | }, 38 | "clickCount": { 39 | "type": "number" 40 | }, 41 | "lastAccessed": { 42 | "type": "string" 43 | } 44 | } 45 | }, 46 | "success": { 47 | "type": "boolean" 48 | }, 49 | "message": { 50 | "type": "string" 51 | } 52 | }, 53 | "version": 1 54 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/tags/removeTags.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "contact": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "contactName": { 11 | "type": "string" 12 | }, 13 | "firstName": { 14 | "type": "string" 15 | }, 16 | "lastName": { 17 | "type": "string" 18 | }, 19 | "email": { 20 | "type": "string" 21 | }, 22 | "phone": { 23 | "type": "string" 24 | }, 25 | "tags": { 26 | "type": "array", 27 | "items": { 28 | "type": "string" 29 | } 30 | }, 31 | "locationId": { 32 | "type": "string" 33 | }, 34 | "dateAdded": { 35 | "type": "string" 36 | }, 37 | "dateUpdated": { 38 | "type": "string" 39 | } 40 | } 41 | }, 42 | "success": { 43 | "type": "boolean" 44 | }, 45 | "message": { 46 | "type": "string" 47 | }, 48 | "removedTags": { 49 | "type": "array", 50 | "items": { 51 | "type": "string" 52 | } 53 | } 54 | }, 55 | "version": 1 56 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/business/get.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "business": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "name": { 11 | "type": "string" 12 | }, 13 | "address": { 14 | "type": "string" 15 | }, 16 | "city": { 17 | "type": "string" 18 | }, 19 | "state": { 20 | "type": "string" 21 | }, 22 | "postalCode": { 23 | "type": "string" 24 | }, 25 | "country": { 26 | "type": "string" 27 | }, 28 | "phone": { 29 | "type": "string" 30 | }, 31 | "email": { 32 | "type": "string" 33 | }, 34 | "website": { 35 | "type": "string" 36 | }, 37 | "description": { 38 | "type": "string" 39 | }, 40 | "locationId": { 41 | "type": "string" 42 | }, 43 | "createdAt": { 44 | "type": "string" 45 | }, 46 | "updatedAt": { 47 | "type": "string" 48 | } 49 | } 50 | }, 51 | "success": { 52 | "type": "boolean" 53 | } 54 | }, 55 | "version": 1 56 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/business/create.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "business": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "name": { 11 | "type": "string" 12 | }, 13 | "address": { 14 | "type": "string" 15 | }, 16 | "city": { 17 | "type": "string" 18 | }, 19 | "state": { 20 | "type": "string" 21 | }, 22 | "postalCode": { 23 | "type": "string" 24 | }, 25 | "country": { 26 | "type": "string" 27 | }, 28 | "phone": { 29 | "type": "string" 30 | }, 31 | "email": { 32 | "type": "string" 33 | }, 34 | "website": { 35 | "type": "string" 36 | }, 37 | "description": { 38 | "type": "string" 39 | }, 40 | "locationId": { 41 | "type": "string" 42 | }, 43 | "createdAt": { 44 | "type": "string" 45 | }, 46 | "updatedAt": { 47 | "type": "string" 48 | } 49 | } 50 | }, 51 | "success": { 52 | "type": "boolean" 53 | } 54 | }, 55 | "version": 1 56 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/business/update.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "business": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "name": { 11 | "type": "string" 12 | }, 13 | "address": { 14 | "type": "string" 15 | }, 16 | "city": { 17 | "type": "string" 18 | }, 19 | "state": { 20 | "type": "string" 21 | }, 22 | "postalCode": { 23 | "type": "string" 24 | }, 25 | "country": { 26 | "type": "string" 27 | }, 28 | "phone": { 29 | "type": "string" 30 | }, 31 | "email": { 32 | "type": "string" 33 | }, 34 | "website": { 35 | "type": "string" 36 | }, 37 | "description": { 38 | "type": "string" 39 | }, 40 | "locationId": { 41 | "type": "string" 42 | }, 43 | "createdAt": { 44 | "type": "string" 45 | }, 46 | "updatedAt": { 47 | "type": "string" 48 | } 49 | } 50 | }, 51 | "success": { 52 | "type": "boolean" 53 | } 54 | }, 55 | "version": 1 56 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customValues/get.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "customValue": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "name": { 11 | "type": "string" 12 | }, 13 | "value": { 14 | "type": "string" 15 | }, 16 | "description": { 17 | "type": "string" 18 | }, 19 | "type": { 20 | "type": "string", 21 | "enum": ["text", "number", "boolean", "date", "url", "email"] 22 | }, 23 | "category": { 24 | "type": "string" 25 | }, 26 | "isActive": { 27 | "type": "boolean" 28 | }, 29 | "sortOrder": { 30 | "type": "number" 31 | }, 32 | "locationId": { 33 | "type": "string" 34 | }, 35 | "createdAt": { 36 | "type": "string" 37 | }, 38 | "updatedAt": { 39 | "type": "string" 40 | }, 41 | "createdBy": { 42 | "type": "string" 43 | }, 44 | "updatedBy": { 45 | "type": "string" 46 | } 47 | } 48 | }, 49 | "success": { 50 | "type": "boolean" 51 | } 52 | }, 53 | "version": 1 54 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/objectAssociations/createRelation.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "id": { 5 | "type": "string", 6 | "description": "Unique identifier for the relation" 7 | }, 8 | "associationId": { 9 | "type": "string", 10 | "description": "ID of the association this relation belongs to" 11 | }, 12 | "fromObjectId": { 13 | "type": "string", 14 | "description": "ID of the source object" 15 | }, 16 | "toObjectId": { 17 | "type": "string", 18 | "description": "ID of the target object" 19 | }, 20 | "metadata": { 21 | "type": "object", 22 | "description": "Additional metadata for the relation" 23 | }, 24 | "createdAt": { 25 | "type": "string", 26 | "format": "date-time", 27 | "description": "Timestamp when the relation was created" 28 | }, 29 | "updatedAt": { 30 | "type": "string", 31 | "format": "date-time", 32 | "description": "Timestamp when the relation was last updated" 33 | }, 34 | "createdBy": { 35 | "type": "object", 36 | "properties": { 37 | "id": { 38 | "type": "string" 39 | }, 40 | "name": { 41 | "type": "string" 42 | }, 43 | "email": { 44 | "type": "string" 45 | } 46 | }, 47 | "description": "User who created the relation" 48 | } 49 | }, 50 | "version": 1 51 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarEvent/createAppointment.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "appointment": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "calendarId": { 11 | "type": "string" 12 | }, 13 | "contactId": { 14 | "type": "string" 15 | }, 16 | "locationId": { 17 | "type": "string" 18 | }, 19 | "title": { 20 | "type": "string" 21 | }, 22 | "appointmentStatus": { 23 | "type": "string" 24 | }, 25 | "assignedUserId": { 26 | "type": "string" 27 | }, 28 | "address": { 29 | "type": "string" 30 | }, 31 | "notes": { 32 | "type": "string" 33 | }, 34 | "startTime": { 35 | "type": "string", 36 | "format": "date-time" 37 | }, 38 | "endTime": { 39 | "type": "string", 40 | "format": "date-time" 41 | }, 42 | "dateCreated": { 43 | "type": "string", 44 | "format": "date-time" 45 | }, 46 | "dateUpdated": { 47 | "type": "string", 48 | "format": "date-time" 49 | } 50 | } 51 | } 52 | }, 53 | "version": 1 54 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarEvent/getAppointment.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "appointment": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "calendarId": { 11 | "type": "string" 12 | }, 13 | "contactId": { 14 | "type": "string" 15 | }, 16 | "locationId": { 17 | "type": "string" 18 | }, 19 | "title": { 20 | "type": "string" 21 | }, 22 | "appointmentStatus": { 23 | "type": "string" 24 | }, 25 | "assignedUserId": { 26 | "type": "string" 27 | }, 28 | "address": { 29 | "type": "string" 30 | }, 31 | "notes": { 32 | "type": "string" 33 | }, 34 | "startTime": { 35 | "type": "string", 36 | "format": "date-time" 37 | }, 38 | "endTime": { 39 | "type": "string", 40 | "format": "date-time" 41 | }, 42 | "dateCreated": { 43 | "type": "string", 44 | "format": "date-time" 45 | }, 46 | "dateUpdated": { 47 | "type": "string", 48 | "format": "date-time" 49 | } 50 | } 51 | } 52 | }, 53 | "version": 1 54 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarEvent/updateAppointment.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "appointment": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "calendarId": { 11 | "type": "string" 12 | }, 13 | "contactId": { 14 | "type": "string" 15 | }, 16 | "locationId": { 17 | "type": "string" 18 | }, 19 | "title": { 20 | "type": "string" 21 | }, 22 | "appointmentStatus": { 23 | "type": "string" 24 | }, 25 | "assignedUserId": { 26 | "type": "string" 27 | }, 28 | "address": { 29 | "type": "string" 30 | }, 31 | "notes": { 32 | "type": "string" 33 | }, 34 | "startTime": { 35 | "type": "string", 36 | "format": "date-time" 37 | }, 38 | "endTime": { 39 | "type": "string", 40 | "format": "date-time" 41 | }, 42 | "dateCreated": { 43 | "type": "string", 44 | "format": "date-time" 45 | }, 46 | "dateUpdated": { 47 | "type": "string", 48 | "format": "date-time" 49 | } 50 | } 51 | } 52 | }, 53 | "version": 1 54 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customValues/create.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "customValue": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "name": { 11 | "type": "string" 12 | }, 13 | "value": { 14 | "type": "string" 15 | }, 16 | "description": { 17 | "type": "string" 18 | }, 19 | "type": { 20 | "type": "string", 21 | "enum": ["text", "number", "boolean", "date", "url", "email"] 22 | }, 23 | "category": { 24 | "type": "string" 25 | }, 26 | "isActive": { 27 | "type": "boolean" 28 | }, 29 | "sortOrder": { 30 | "type": "number" 31 | }, 32 | "locationId": { 33 | "type": "string" 34 | }, 35 | "createdAt": { 36 | "type": "string" 37 | }, 38 | "updatedAt": { 39 | "type": "string" 40 | }, 41 | "createdBy": { 42 | "type": "string" 43 | }, 44 | "updatedBy": { 45 | "type": "string" 46 | } 47 | } 48 | }, 49 | "success": { 50 | "type": "boolean" 51 | }, 52 | "message": { 53 | "type": "string" 54 | } 55 | }, 56 | "version": 1 57 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customValues/update.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "customValue": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "name": { 11 | "type": "string" 12 | }, 13 | "value": { 14 | "type": "string" 15 | }, 16 | "description": { 17 | "type": "string" 18 | }, 19 | "type": { 20 | "type": "string", 21 | "enum": ["text", "number", "boolean", "date", "url", "email"] 22 | }, 23 | "category": { 24 | "type": "string" 25 | }, 26 | "isActive": { 27 | "type": "boolean" 28 | }, 29 | "sortOrder": { 30 | "type": "number" 31 | }, 32 | "locationId": { 33 | "type": "string" 34 | }, 35 | "createdAt": { 36 | "type": "string" 37 | }, 38 | "updatedAt": { 39 | "type": "string" 40 | }, 41 | "createdBy": { 42 | "type": "string" 43 | }, 44 | "updatedBy": { 45 | "type": "string" 46 | } 47 | } 48 | }, 49 | "success": { 50 | "type": "boolean" 51 | }, 52 | "message": { 53 | "type": "string" 54 | } 55 | }, 56 | "version": 1 57 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendar/get.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "id": { 6 | "type": "string", 7 | "description": "Calendar ID" 8 | }, 9 | "locationId": { 10 | "type": "string", 11 | "description": "The HighLevel location ID" 12 | }, 13 | "name": { 14 | "type": "string", 15 | "description": "Name of the calendar" 16 | }, 17 | "description": { 18 | "type": "string", 19 | "description": "Description of the calendar" 20 | }, 21 | "appointmentDuration": { 22 | "type": "number", 23 | "description": "Default appointment duration in minutes" 24 | }, 25 | "availability": { 26 | "type": "object", 27 | "description": "Availability settings for the calendar" 28 | }, 29 | "bufferTime": { 30 | "type": "number", 31 | "description": "Buffer time in minutes between appointments" 32 | }, 33 | "calendarType": { 34 | "type": "string", 35 | "description": "Type of calendar" 36 | }, 37 | "enableRecurring": { 38 | "type": "boolean", 39 | "description": "Whether recurring appointments are enabled" 40 | }, 41 | "eventColor": { 42 | "type": "string", 43 | "description": "Color for calendar events" 44 | }, 45 | "eventTitle": { 46 | "type": "string", 47 | "description": "Default title for calendar events" 48 | }, 49 | "slug": { 50 | "type": "string", 51 | "description": "URL slug for the calendar" 52 | }, 53 | "createdAt": { 54 | "type": "string", 55 | "format": "date-time", 56 | "description": "Creation timestamp" 57 | }, 58 | "updatedAt": { 59 | "type": "string", 60 | "format": "date-time", 61 | "description": "Last update timestamp" 62 | } 63 | }, 64 | "additionalProperties": false 65 | } 66 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/funnel/getPageCount.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "count": { 5 | "type": "object", 6 | "properties": { 7 | "total": { 8 | "type": "number" 9 | }, 10 | "active": { 11 | "type": "number" 12 | }, 13 | "inactive": { 14 | "type": "number" 15 | }, 16 | "draft": { 17 | "type": "number" 18 | }, 19 | "byType": { 20 | "type": "object", 21 | "properties": { 22 | "landing": { 23 | "type": "number" 24 | }, 25 | "thankyou": { 26 | "type": "number" 27 | }, 28 | "sales": { 29 | "type": "number" 30 | }, 31 | "checkout": { 32 | "type": "number" 33 | }, 34 | "upsell": { 35 | "type": "number" 36 | }, 37 | "downsell": { 38 | "type": "number" 39 | } 40 | } 41 | }, 42 | "funnelId": { 43 | "type": "string" 44 | }, 45 | "locationId": { 46 | "type": "string" 47 | } 48 | } 49 | }, 50 | "success": { 51 | "type": "boolean" 52 | } 53 | }, 54 | "version": 1 55 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarGroup/getAll.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "groups": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "id": { 10 | "type": "string" 11 | }, 12 | "name": { 13 | "type": "string" 14 | }, 15 | "slug": { 16 | "type": "string" 17 | }, 18 | "description": { 19 | "type": "string" 20 | }, 21 | "locationId": { 22 | "type": "string" 23 | }, 24 | "calendarIds": { 25 | "type": "array", 26 | "items": { 27 | "type": "string" 28 | } 29 | }, 30 | "isActive": { 31 | "type": "boolean" 32 | }, 33 | "teamId": { 34 | "type": "string" 35 | }, 36 | "createdAt": { 37 | "type": "string", 38 | "format": "date-time" 39 | }, 40 | "updatedAt": { 41 | "type": "string", 42 | "format": "date-time" 43 | } 44 | } 45 | } 46 | }, 47 | "total": { 48 | "type": "number" 49 | }, 50 | "count": { 51 | "type": "number" 52 | } 53 | }, 54 | "version": 1 55 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customObjects/updateObjectSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "id": { 5 | "type": "string", 6 | "description": "Unique identifier for the custom object" 7 | }, 8 | "locationId": { 9 | "type": "string", 10 | "description": "The location ID where the custom object belongs" 11 | }, 12 | "name": { 13 | "type": "string", 14 | "description": "Name of the custom object" 15 | }, 16 | "description": { 17 | "type": "string", 18 | "description": "Description of the custom object" 19 | }, 20 | "schema": { 21 | "type": "object", 22 | "description": "JSON schema definition for the custom object" 23 | }, 24 | "displayField": { 25 | "type": "string", 26 | "description": "Field to use as display name for records" 27 | }, 28 | "enableApiAccess": { 29 | "type": "boolean", 30 | "description": "Whether API access is enabled for this object" 31 | }, 32 | "updatedAt": { 33 | "type": "string", 34 | "format": "date-time", 35 | "description": "Timestamp when the custom object was last updated" 36 | }, 37 | "updatedBy": { 38 | "type": "object", 39 | "properties": { 40 | "id": { 41 | "type": "string" 42 | }, 43 | "name": { 44 | "type": "string" 45 | }, 46 | "email": { 47 | "type": "string" 48 | } 49 | }, 50 | "description": "User who updated the custom object" 51 | } 52 | }, 53 | "version": 1 54 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/objectAssociations/updateAssociation.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "id": { 5 | "type": "string", 6 | "description": "Unique identifier for the association" 7 | }, 8 | "locationId": { 9 | "type": "string", 10 | "description": "The location ID where the association belongs" 11 | }, 12 | "name": { 13 | "type": "string", 14 | "description": "Name of the association" 15 | }, 16 | "description": { 17 | "type": "string", 18 | "description": "Description of the association" 19 | }, 20 | "fromObjectType": { 21 | "type": "string", 22 | "description": "Type of the source object" 23 | }, 24 | "toObjectType": { 25 | "type": "string", 26 | "description": "Type of the target object" 27 | }, 28 | "cardinality": { 29 | "type": "string", 30 | "enum": ["ONE_TO_ONE", "ONE_TO_MANY", "MANY_TO_ONE", "MANY_TO_MANY"], 31 | "description": "Cardinality of the association" 32 | }, 33 | "updatedAt": { 34 | "type": "string", 35 | "format": "date-time", 36 | "description": "Timestamp when the association was last updated" 37 | }, 38 | "updatedBy": { 39 | "type": "object", 40 | "properties": { 41 | "id": { 42 | "type": "string" 43 | }, 44 | "name": { 45 | "type": "string" 46 | }, 47 | "email": { 48 | "type": "string" 49 | } 50 | }, 51 | "description": "User who updated the association" 52 | } 53 | }, 54 | "version": 1 55 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/saas/pauseLocation.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean", 6 | "description": "Whether the location was successfully paused" 7 | }, 8 | "message": { 9 | "type": "string", 10 | "description": "Success or error message" 11 | }, 12 | "location": { 13 | "type": "object", 14 | "properties": { 15 | "locationId": { 16 | "type": "string", 17 | "description": "ID of the paused location" 18 | }, 19 | "name": { 20 | "type": "string", 21 | "description": "Name of the location" 22 | }, 23 | "status": { 24 | "type": "string", 25 | "enum": ["paused", "active", "inactive"], 26 | "description": "Current status of the location" 27 | }, 28 | "pausedAt": { 29 | "type": "string", 30 | "format": "date-time", 31 | "description": "Timestamp when the location was paused" 32 | }, 33 | "pausedBy": { 34 | "type": "string", 35 | "description": "User who paused the location" 36 | }, 37 | "pauseReason": { 38 | "type": "string", 39 | "description": "Reason for pausing the location" 40 | }, 41 | "subscriptionStatus": { 42 | "type": "string", 43 | "description": "Current subscription status after pausing" 44 | } 45 | }, 46 | "description": "Details of the paused location" 47 | } 48 | }, 49 | "version": 1 50 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/notes/getAll.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "notes": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "id": { 10 | "type": "string" 11 | }, 12 | "body": { 13 | "type": "string" 14 | }, 15 | "contactId": { 16 | "type": "string" 17 | }, 18 | "userId": { 19 | "type": "string" 20 | }, 21 | "locationId": { 22 | "type": "string" 23 | }, 24 | "dateAdded": { 25 | "type": "string" 26 | }, 27 | "dateUpdated": { 28 | "type": "string" 29 | }, 30 | "createdBy": { 31 | "type": "string" 32 | }, 33 | "updatedBy": { 34 | "type": "string" 35 | } 36 | } 37 | } 38 | }, 39 | "meta": { 40 | "type": "object", 41 | "properties": { 42 | "total": { 43 | "type": "number" 44 | }, 45 | "count": { 46 | "type": "number" 47 | }, 48 | "limit": { 49 | "type": "number" 50 | }, 51 | "offset": { 52 | "type": "number" 53 | }, 54 | "contactId": { 55 | "type": "string" 56 | } 57 | } 58 | } 59 | }, 60 | "version": 1 61 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/blog/create.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "title": { 6 | "type": "string", 7 | "description": "Title of the blog post" 8 | }, 9 | "locationId": { 10 | "type": "string", 11 | "description": "The HighLevel location ID" 12 | }, 13 | "blogId": { 14 | "type": "string", 15 | "description": "The blog ID where the post will be created" 16 | }, 17 | "rawHTML": { 18 | "type": "string", 19 | "description": "HTML content of the blog post" 20 | }, 21 | "status": { 22 | "type": "string", 23 | "enum": ["DRAFT", "PUBLISHED", "SCHEDULED"], 24 | "description": "Status of the blog post" 25 | }, 26 | "description": { 27 | "type": "string", 28 | "description": "A short description of the blog post" 29 | }, 30 | "imageUrl": { 31 | "type": "string", 32 | "description": "URL of the blog image" 33 | }, 34 | "imageAltText": { 35 | "type": "string", 36 | "description": "Alt text for the blog image" 37 | }, 38 | "categories": { 39 | "type": "array", 40 | "items": { 41 | "type": "string" 42 | }, 43 | "description": "Category IDs for the blog post" 44 | }, 45 | "tags": { 46 | "type": "array", 47 | "items": { 48 | "type": "string" 49 | }, 50 | "description": "Tags for the blog post" 51 | }, 52 | "author": { 53 | "type": "string", 54 | "description": "Author ID for the blog post" 55 | }, 56 | "urlSlug": { 57 | "type": "string", 58 | "description": "URL slug for the blog post" 59 | }, 60 | "canonicalLink": { 61 | "type": "string", 62 | "description": "Canonical URL for the blog post" 63 | }, 64 | "publishedAt": { 65 | "type": "string", 66 | "format": "date-time", 67 | "description": "Date and time when the blog post was/will be published" 68 | } 69 | }, 70 | "required": ["title", "locationId", "blogId", "rawHTML", "status"], 71 | "additionalProperties": false 72 | } 73 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/BusinessOperations.test.ts: -------------------------------------------------------------------------------- 1 | // Mock data for Business operations testing 2 | 3 | // Mock functions for business operations testing 4 | export const mockBusinessResponse = { 5 | business: { 6 | id: 'business_123', 7 | name: 'Test Business', 8 | address: '123 Main St', 9 | city: 'Test City', 10 | state: 'Test State', 11 | postalCode: '12345', 12 | country: 'US', 13 | phone: '+1234567890', 14 | email: 'test@business.com', 15 | website: 'https://testbusiness.com', 16 | description: 'A test business', 17 | locationId: 'location_456', 18 | createdAt: '2023-01-01T00:00:00.000Z', 19 | updatedAt: '2023-01-01T00:00:00.000Z', 20 | }, 21 | success: true, 22 | }; 23 | 24 | export const mockBusinessListResponse = { 25 | businesses: [ 26 | { 27 | id: 'business_123', 28 | name: 'Test Business 1', 29 | address: '123 Main St', 30 | city: 'Test City', 31 | state: 'Test State', 32 | postalCode: '12345', 33 | country: 'US', 34 | phone: '+1234567890', 35 | email: 'test1@business.com', 36 | website: 'https://testbusiness1.com', 37 | description: 'Test business 1', 38 | locationId: 'location_456', 39 | createdAt: '2023-01-01T00:00:00.000Z', 40 | updatedAt: '2023-01-01T00:00:00.000Z', 41 | }, 42 | { 43 | id: 'business_124', 44 | name: 'Test Business 2', 45 | address: '456 Oak Ave', 46 | city: 'Another City', 47 | state: 'Another State', 48 | postalCode: '67890', 49 | country: 'US', 50 | phone: '+0987654321', 51 | email: 'test2@business.com', 52 | website: 'https://testbusiness2.com', 53 | description: 'Test business 2', 54 | locationId: 'location_456', 55 | createdAt: '2023-01-02T00:00:00.000Z', 56 | updatedAt: '2023-01-02T00:00:00.000Z', 57 | }, 58 | ], 59 | meta: { 60 | total: 2, 61 | count: 2, 62 | limit: 50, 63 | offset: 0, 64 | }, 65 | success: true, 66 | }; 67 | 68 | export const mockBusinessDeleteResponse = { 69 | success: true, 70 | message: 'Business deleted successfully', 71 | }; -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/AppointmentNotesOperations.test.ts: -------------------------------------------------------------------------------- 1 | // Mock response data for appointment notes operations 2 | export const appointmentNotesOperationsMockData = { 3 | create: { 4 | note: { 5 | id: "6669e4c3a0b142cc43a00e97", 6 | body: "This is a follow-up note for the appointment scheduled tomorrow.", 7 | contactId: "vcGaRBUhfEqKMJ2jFzqLi", 8 | userId: "user123", 9 | appointmentId: "appointment456", 10 | createdAt: "2024-06-12T12:14:43.159Z", 11 | updatedAt: "2024-06-12T12:14:43.159Z" 12 | } 13 | }, 14 | update: { 15 | note: { 16 | id: "6669e4c3a0b142cc43a00e97", 17 | body: "This is an updated follow-up note for the appointment scheduled tomorrow.", 18 | contactId: "vcGaRBUhfEqKMJ2jFzqLi", 19 | userId: "user123", 20 | appointmentId: "appointment456", 21 | createdAt: "2024-06-12T12:14:43.159Z", 22 | updatedAt: "2024-06-12T12:20:15.242Z" 23 | } 24 | }, 25 | getAll: { 26 | notes: [ 27 | { 28 | id: "6669e4c3a0b142cc43a00e97", 29 | body: "This is a follow-up note for the appointment scheduled tomorrow.", 30 | contactId: "vcGaRBUhfEqKMJ2jFzqLi", 31 | userId: "user123", 32 | appointmentId: "appointment456", 33 | createdAt: "2024-06-12T12:14:43.159Z", 34 | updatedAt: "2024-06-12T12:14:43.159Z" 35 | }, 36 | { 37 | id: "6669e4c3a0b142cc43a00e98", 38 | body: "Appointment confirmed with client. Reminder sent via SMS.", 39 | contactId: "vcGaRBUhfEqKMJ2jFzqLi", 40 | userId: "user456", 41 | appointmentId: "appointment789", 42 | createdAt: "2024-06-12T10:30:12.455Z", 43 | updatedAt: "2024-06-12T10:30:12.455Z" 44 | } 45 | ], 46 | meta: { 47 | total: 2, 48 | currentPage: 1, 49 | nextPage: null, 50 | prevPage: null, 51 | limit: 20 52 | } 53 | }, 54 | delete: { 55 | success: true, 56 | message: "Appointment note deleted successfully" 57 | } 58 | }; -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customObjects/createObject.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "id": { 5 | "type": "string", 6 | "description": "Unique identifier for the custom object" 7 | }, 8 | "locationId": { 9 | "type": "string", 10 | "description": "The location ID where the custom object belongs" 11 | }, 12 | "name": { 13 | "type": "string", 14 | "description": "Name of the custom object" 15 | }, 16 | "description": { 17 | "type": "string", 18 | "description": "Description of the custom object" 19 | }, 20 | "schema": { 21 | "type": "object", 22 | "description": "JSON schema definition for the custom object" 23 | }, 24 | "displayField": { 25 | "type": "string", 26 | "description": "Field to use as display name for records" 27 | }, 28 | "enableApiAccess": { 29 | "type": "boolean", 30 | "description": "Whether API access is enabled for this object" 31 | }, 32 | "createdAt": { 33 | "type": "string", 34 | "format": "date-time", 35 | "description": "Timestamp when the custom object was created" 36 | }, 37 | "updatedAt": { 38 | "type": "string", 39 | "format": "date-time", 40 | "description": "Timestamp when the custom object was last updated" 41 | }, 42 | "createdBy": { 43 | "type": "object", 44 | "properties": { 45 | "id": { 46 | "type": "string" 47 | }, 48 | "name": { 49 | "type": "string" 50 | }, 51 | "email": { 52 | "type": "string" 53 | } 54 | }, 55 | "description": "User who created the custom object" 56 | } 57 | }, 58 | "version": 1 59 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/media/uploadFile.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "file": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | }, 10 | "name": { 11 | "type": "string" 12 | }, 13 | "type": { 14 | "type": "string" 15 | }, 16 | "size": { 17 | "type": "number" 18 | }, 19 | "url": { 20 | "type": "string" 21 | }, 22 | "thumbnailUrl": { 23 | "type": "string" 24 | }, 25 | "folderId": { 26 | "type": "string" 27 | }, 28 | "isFolder": { 29 | "type": "boolean" 30 | }, 31 | "mimeType": { 32 | "type": "string" 33 | }, 34 | "createdAt": { 35 | "type": "string" 36 | }, 37 | "updatedAt": { 38 | "type": "string" 39 | }, 40 | "createdBy": { 41 | "type": "string" 42 | }, 43 | "locationId": { 44 | "type": "string" 45 | }, 46 | "description": { 47 | "type": "string" 48 | }, 49 | "tags": { 50 | "type": "array", 51 | "items": { 52 | "type": "string" 53 | } 54 | }, 55 | "isPublic": { 56 | "type": "boolean" 57 | } 58 | } 59 | }, 60 | "success": { 61 | "type": "boolean" 62 | }, 63 | "message": { 64 | "type": "string" 65 | } 66 | }, 67 | "version": 1 68 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/conversation/cancelScheduledMessage.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean", 6 | "description": "Whether the scheduled message was cancelled successfully" 7 | }, 8 | "message": { 9 | "type": "string", 10 | "description": "Success or error message" 11 | }, 12 | "cancelledMessageId": { 13 | "type": "string", 14 | "description": "ID of the cancelled message" 15 | }, 16 | "originalScheduledDate": { 17 | "type": "string", 18 | "format": "date-time", 19 | "description": "Original scheduled send date" 20 | }, 21 | "cancelledAt": { 22 | "type": "string", 23 | "format": "date-time", 24 | "description": "Timestamp when the message was cancelled" 25 | }, 26 | "messageDetails": { 27 | "type": "object", 28 | "properties": { 29 | "id": { 30 | "type": "string", 31 | "description": "Message ID" 32 | }, 33 | "type": { 34 | "type": "string", 35 | "enum": ["SMS", "Email", "WhatsApp"], 36 | "description": "Type of cancelled message" 37 | }, 38 | "status": { 39 | "type": "string", 40 | "enum": ["cancelled"], 41 | "description": "Updated status after cancellation" 42 | }, 43 | "subject": { 44 | "type": "string", 45 | "description": "Message subject (for emails)" 46 | }, 47 | "body": { 48 | "type": "string", 49 | "description": "Message content" 50 | } 51 | }, 52 | "description": "Details of the cancelled message" 53 | } 54 | }, 55 | "version": 1 56 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/objectAssociations/createAssociation.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "id": { 5 | "type": "string", 6 | "description": "Unique identifier for the association" 7 | }, 8 | "locationId": { 9 | "type": "string", 10 | "description": "The location ID where the association belongs" 11 | }, 12 | "name": { 13 | "type": "string", 14 | "description": "Name of the association" 15 | }, 16 | "description": { 17 | "type": "string", 18 | "description": "Description of the association" 19 | }, 20 | "fromObjectType": { 21 | "type": "string", 22 | "description": "Type of the source object" 23 | }, 24 | "toObjectType": { 25 | "type": "string", 26 | "description": "Type of the target object" 27 | }, 28 | "cardinality": { 29 | "type": "string", 30 | "enum": ["ONE_TO_ONE", "ONE_TO_MANY", "MANY_TO_ONE", "MANY_TO_MANY"], 31 | "description": "Cardinality of the association" 32 | }, 33 | "createdAt": { 34 | "type": "string", 35 | "format": "date-time", 36 | "description": "Timestamp when the association was created" 37 | }, 38 | "updatedAt": { 39 | "type": "string", 40 | "format": "date-time", 41 | "description": "Timestamp when the association was last updated" 42 | }, 43 | "createdBy": { 44 | "type": "object", 45 | "properties": { 46 | "id": { 47 | "type": "string" 48 | }, 49 | "name": { 50 | "type": "string" 51 | }, 52 | "email": { 53 | "type": "string" 54 | } 55 | }, 56 | "description": "User who created the association" 57 | } 58 | }, 59 | "version": 1 60 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/saas/disableSaas.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean", 6 | "description": "Whether SaaS was successfully disabled" 7 | }, 8 | "message": { 9 | "type": "string", 10 | "description": "Success or error message" 11 | }, 12 | "affectedLocations": { 13 | "type": "array", 14 | "items": { 15 | "type": "object", 16 | "properties": { 17 | "locationId": { 18 | "type": "string", 19 | "description": "ID of the location" 20 | }, 21 | "name": { 22 | "type": "string", 23 | "description": "Name of the location" 24 | }, 25 | "saasEnabled": { 26 | "type": "boolean", 27 | "description": "Current SaaS status (should be false after disabling)" 28 | }, 29 | "disabledAt": { 30 | "type": "string", 31 | "format": "date-time", 32 | "description": "Timestamp when SaaS was disabled" 33 | } 34 | } 35 | }, 36 | "description": "List of locations that had SaaS disabled" 37 | }, 38 | "errors": { 39 | "type": "array", 40 | "items": { 41 | "type": "object", 42 | "properties": { 43 | "locationId": { 44 | "type": "string", 45 | "description": "ID of the location that failed" 46 | }, 47 | "error": { 48 | "type": "string", 49 | "description": "Error message" 50 | } 51 | } 52 | }, 53 | "description": "List of errors encountered during the operation" 54 | } 55 | }, 56 | "version": 1 57 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/IsEmailValid.test.ts: -------------------------------------------------------------------------------- 1 | import { isEmailValid } from '../GenericFunctions'; 2 | 3 | describe('isEmailValid', () => { 4 | it('should return true for a valid email address', () => { 5 | const email = 'test@example.com'; 6 | const result = isEmailValid(email); 7 | expect(result).toBe(true); 8 | }); 9 | 10 | it('should return false for an invalid email address', () => { 11 | const email = 'invalid-email'; 12 | const result = isEmailValid(email); 13 | expect(result).toBe(false); 14 | }); 15 | 16 | it('should return true for an email address with subdomain', () => { 17 | const email = 'user@sub.example.com'; 18 | const result = isEmailValid(email); 19 | expect(result).toBe(true); 20 | }); 21 | 22 | it('should return false for an email address without a domain', () => { 23 | const email = 'user@'; 24 | const result = isEmailValid(email); 25 | expect(result).toBe(false); 26 | }); 27 | 28 | it('should return false for an email address without a username', () => { 29 | const email = '@example.com'; 30 | const result = isEmailValid(email); 31 | expect(result).toBe(false); 32 | }); 33 | 34 | it('should return true for an email address with a plus sign', () => { 35 | const email = 'user+alias@example.com'; 36 | const result = isEmailValid(email); 37 | expect(result).toBe(true); 38 | }); 39 | 40 | it('should return false for an email address with invalid characters', () => { 41 | const email = 'user@exa$mple.com'; 42 | const result = isEmailValid(email); 43 | expect(result).toBe(false); 44 | }); 45 | 46 | it('should return false for an email address without a top-level domain', () => { 47 | const email = 'user@example'; 48 | const result = isEmailValid(email); 49 | expect(result).toBe(false); 50 | }); 51 | 52 | it('should return true for an email address with a valid top-level domain', () => { 53 | const email = 'user@example.co.uk'; 54 | const result = isEmailValid(email); 55 | expect(result).toBe(true); 56 | }); 57 | 58 | it('should return false for an empty email string', () => { 59 | const email = ''; 60 | const result = isEmailValid(email); 61 | expect(result).toBe(false); 62 | }); 63 | }); 64 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendarEvent/getBlockedSlots.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "blockedSlots": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "id": { 10 | "type": "string" 11 | }, 12 | "calendarId": { 13 | "type": "string" 14 | }, 15 | "userId": { 16 | "type": "string" 17 | }, 18 | "locationId": { 19 | "type": "string" 20 | }, 21 | "title": { 22 | "type": "string" 23 | }, 24 | "startTime": { 25 | "type": "string", 26 | "format": "date-time" 27 | }, 28 | "endTime": { 29 | "type": "string", 30 | "format": "date-time" 31 | }, 32 | "dateCreated": { 33 | "type": "string", 34 | "format": "date-time" 35 | }, 36 | "dateUpdated": { 37 | "type": "string", 38 | "format": "date-time" 39 | } 40 | } 41 | } 42 | }, 43 | "meta": { 44 | "type": "object", 45 | "properties": { 46 | "total": { 47 | "type": "integer" 48 | }, 49 | "count": { 50 | "type": "integer" 51 | }, 52 | "currentPage": { 53 | "type": "integer" 54 | }, 55 | "nextPageUrl": { 56 | "type": "string" 57 | }, 58 | "prevPageUrl": { 59 | "type": "string" 60 | } 61 | } 62 | } 63 | }, 64 | "version": 1 65 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/calendar/getAll.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "calendars": { 6 | "type": "array", 7 | "items": { 8 | "type": "object", 9 | "properties": { 10 | "id": { 11 | "type": "string", 12 | "description": "Calendar ID" 13 | }, 14 | "locationId": { 15 | "type": "string", 16 | "description": "The HighLevel location ID" 17 | }, 18 | "name": { 19 | "type": "string", 20 | "description": "Name of the calendar" 21 | }, 22 | "description": { 23 | "type": "string", 24 | "description": "Description of the calendar" 25 | }, 26 | "appointmentDuration": { 27 | "type": "number", 28 | "description": "Default appointment duration in minutes" 29 | }, 30 | "availability": { 31 | "type": "object", 32 | "description": "Availability settings for the calendar" 33 | }, 34 | "bufferTime": { 35 | "type": "number", 36 | "description": "Buffer time in minutes between appointments" 37 | }, 38 | "calendarType": { 39 | "type": "string", 40 | "description": "Type of calendar" 41 | }, 42 | "enableRecurring": { 43 | "type": "boolean", 44 | "description": "Whether recurring appointments are enabled" 45 | }, 46 | "eventColor": { 47 | "type": "string", 48 | "description": "Color for calendar events" 49 | }, 50 | "eventTitle": { 51 | "type": "string", 52 | "description": "Default title for calendar events" 53 | }, 54 | "slug": { 55 | "type": "string", 56 | "description": "URL slug for the calendar" 57 | }, 58 | "createdAt": { 59 | "type": "string", 60 | "format": "date-time", 61 | "description": "Creation timestamp" 62 | }, 63 | "updatedAt": { 64 | "type": "string", 65 | "format": "date-time", 66 | "description": "Last update timestamp" 67 | } 68 | } 69 | } 70 | }, 71 | "total": { 72 | "type": "number", 73 | "description": "Total number of calendars" 74 | } 75 | }, 76 | "additionalProperties": false 77 | } 78 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customObjects/getObjectSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "id": { 5 | "type": "string", 6 | "description": "Unique identifier for the custom object" 7 | }, 8 | "locationId": { 9 | "type": "string", 10 | "description": "The location ID where the custom object belongs" 11 | }, 12 | "name": { 13 | "type": "string", 14 | "description": "Name of the custom object" 15 | }, 16 | "description": { 17 | "type": "string", 18 | "description": "Description of the custom object" 19 | }, 20 | "schema": { 21 | "type": "object", 22 | "description": "JSON schema definition for the custom object" 23 | }, 24 | "displayField": { 25 | "type": "string", 26 | "description": "Field to use as display name for records" 27 | }, 28 | "enableApiAccess": { 29 | "type": "boolean", 30 | "description": "Whether API access is enabled for this object" 31 | }, 32 | "recordCount": { 33 | "type": "integer", 34 | "description": "Total number of records in this custom object" 35 | }, 36 | "createdAt": { 37 | "type": "string", 38 | "format": "date-time", 39 | "description": "Timestamp when the custom object was created" 40 | }, 41 | "updatedAt": { 42 | "type": "string", 43 | "format": "date-time", 44 | "description": "Timestamp when the custom object was last updated" 45 | }, 46 | "createdBy": { 47 | "type": "object", 48 | "properties": { 49 | "id": { 50 | "type": "string" 51 | }, 52 | "name": { 53 | "type": "string" 54 | }, 55 | "email": { 56 | "type": "string" 57 | } 58 | }, 59 | "description": "User who created the custom object" 60 | } 61 | }, 62 | "version": 1 63 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/redirect/getAll.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "redirects": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "id": { 10 | "type": "string" 11 | }, 12 | "sourceUrl": { 13 | "type": "string" 14 | }, 15 | "targetUrl": { 16 | "type": "string" 17 | }, 18 | "redirectType": { 19 | "type": "string", 20 | "enum": ["301", "302"] 21 | }, 22 | "description": { 23 | "type": "string" 24 | }, 25 | "isActive": { 26 | "type": "boolean" 27 | }, 28 | "locationId": { 29 | "type": "string" 30 | }, 31 | "createdAt": { 32 | "type": "string" 33 | }, 34 | "updatedAt": { 35 | "type": "string" 36 | }, 37 | "createdBy": { 38 | "type": "string" 39 | }, 40 | "clickCount": { 41 | "type": "number" 42 | }, 43 | "lastAccessed": { 44 | "type": "string" 45 | } 46 | } 47 | } 48 | }, 49 | "meta": { 50 | "type": "object", 51 | "properties": { 52 | "total": { 53 | "type": "number" 54 | }, 55 | "count": { 56 | "type": "number" 57 | }, 58 | "limit": { 59 | "type": "number" 60 | }, 61 | "offset": { 62 | "type": "number" 63 | } 64 | } 65 | } 66 | }, 67 | "version": 1 68 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/objectAssociations/getAssociationById.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "id": { 5 | "type": "string", 6 | "description": "Unique identifier for the association" 7 | }, 8 | "locationId": { 9 | "type": "string", 10 | "description": "The location ID where the association belongs" 11 | }, 12 | "name": { 13 | "type": "string", 14 | "description": "Name of the association" 15 | }, 16 | "description": { 17 | "type": "string", 18 | "description": "Description of the association" 19 | }, 20 | "fromObjectType": { 21 | "type": "string", 22 | "description": "Type of the source object" 23 | }, 24 | "toObjectType": { 25 | "type": "string", 26 | "description": "Type of the target object" 27 | }, 28 | "cardinality": { 29 | "type": "string", 30 | "enum": ["ONE_TO_ONE", "ONE_TO_MANY", "MANY_TO_ONE", "MANY_TO_MANY"], 31 | "description": "Cardinality of the association" 32 | }, 33 | "relationCount": { 34 | "type": "integer", 35 | "description": "Number of relations using this association" 36 | }, 37 | "createdAt": { 38 | "type": "string", 39 | "format": "date-time", 40 | "description": "Timestamp when the association was created" 41 | }, 42 | "updatedAt": { 43 | "type": "string", 44 | "format": "date-time", 45 | "description": "Timestamp when the association was last updated" 46 | }, 47 | "createdBy": { 48 | "type": "object", 49 | "properties": { 50 | "id": { 51 | "type": "string" 52 | }, 53 | "name": { 54 | "type": "string" 55 | }, 56 | "email": { 57 | "type": "string" 58 | } 59 | }, 60 | "description": "User who created the association" 61 | } 62 | }, 63 | "version": 1 64 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/ValidEmailAndPhonePreSendAction.test.ts: -------------------------------------------------------------------------------- 1 | import type { IExecuteSingleFunctions, IHttpRequestOptions, INode } from 'n8n-workflow'; 2 | 3 | import { validEmailAndPhonePreSendAction, isEmailValid, isPhoneValid } from '../GenericFunctions'; 4 | 5 | jest.mock('../GenericFunctions', () => ({ 6 | ...jest.requireActual('../GenericFunctions'), 7 | isEmailValid: jest.fn(), 8 | isPhoneValid: jest.fn(), 9 | })); 10 | 11 | describe('validEmailAndPhonePreSendAction', () => { 12 | let mockThis: IExecuteSingleFunctions; 13 | 14 | beforeEach(() => { 15 | mockThis = { 16 | getNode: jest.fn( 17 | () => 18 | ({ 19 | id: 'mock-node-id', 20 | name: 'mock-node', 21 | typeVersion: 1, 22 | type: 'n8n-nodes-base.mockNode', 23 | position: [0, 0], 24 | parameters: {}, 25 | }) as INode, 26 | ), 27 | } as unknown as IExecuteSingleFunctions; 28 | 29 | jest.clearAllMocks(); 30 | }); 31 | 32 | it('should return requestOptions unchanged if email and phone are valid', async () => { 33 | (isEmailValid as jest.Mock).mockReturnValue(true); 34 | (isPhoneValid as jest.Mock).mockReturnValue(true); 35 | 36 | const requestOptions: IHttpRequestOptions = { 37 | url: 'https://example.com/api', 38 | body: { 39 | email: 'valid@example.com', 40 | phone: '+1234567890', 41 | }, 42 | }; 43 | 44 | const result = await validEmailAndPhonePreSendAction.call(mockThis, requestOptions); 45 | 46 | expect(result).toEqual(requestOptions); 47 | }); 48 | 49 | it('should not modify requestOptions if no email or phone is provided', async () => { 50 | const requestOptions: IHttpRequestOptions = { 51 | url: 'https://example.com/api', 52 | body: {}, 53 | }; 54 | 55 | const result = await validEmailAndPhonePreSendAction.call(mockThis, requestOptions); 56 | 57 | expect(result).toEqual(requestOptions); 58 | }); 59 | 60 | it('should not modify requestOptions if body is undefined', async () => { 61 | const requestOptions: IHttpRequestOptions = { 62 | url: 'https://example.com/api', 63 | body: undefined, 64 | }; 65 | 66 | const result = await validEmailAndPhonePreSendAction.call(mockThis, requestOptions); 67 | 68 | expect(result).toEqual(requestOptions); 69 | }); 70 | }); 71 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/CalendarEventOperations.test.ts: -------------------------------------------------------------------------------- 1 | // Mock data for Calendar Event operations testing 2 | 3 | // Mock functions for calendar event operations testing 4 | export const mockAppointmentResponse = { 5 | appointment: { 6 | id: 'appointment_123', 7 | calendarId: 'calendar_456', 8 | contactId: 'contact_789', 9 | locationId: 'location_abc', 10 | title: 'Test Appointment', 11 | appointmentStatus: 'confirmed', 12 | assignedUserId: 'user_def', 13 | address: '123 Test Street, Test City, TS 12345', 14 | notes: 'This is a test appointment for development', 15 | startTime: '2023-12-01T10:00:00.000Z', 16 | endTime: '2023-12-01T11:00:00.000Z', 17 | dateCreated: '2023-01-01T00:00:00.000Z', 18 | dateUpdated: '2023-01-01T00:00:00.000Z', 19 | }, 20 | }; 21 | 22 | export const mockBlockedSlotResponse = { 23 | blockedSlot: { 24 | id: 'blocked_123', 25 | calendarId: 'calendar_456', 26 | userId: 'user_def', 27 | locationId: 'location_abc', 28 | title: 'Blocked Time Slot', 29 | startTime: '2023-12-01T12:00:00.000Z', 30 | endTime: '2023-12-01T13:00:00.000Z', 31 | dateCreated: '2023-01-01T00:00:00.000Z', 32 | dateUpdated: '2023-01-01T00:00:00.000Z', 33 | }, 34 | }; 35 | 36 | export const mockBlockedSlotsListResponse = { 37 | blockedSlots: [ 38 | { 39 | id: 'blocked_123', 40 | calendarId: 'calendar_456', 41 | userId: 'user_def', 42 | locationId: 'location_abc', 43 | title: 'Blocked Time Slot 1', 44 | startTime: '2023-12-01T12:00:00.000Z', 45 | endTime: '2023-12-01T13:00:00.000Z', 46 | dateCreated: '2023-01-01T00:00:00.000Z', 47 | dateUpdated: '2023-01-01T00:00:00.000Z', 48 | }, 49 | { 50 | id: 'blocked_456', 51 | calendarId: 'calendar_789', 52 | userId: 'user_abc', 53 | locationId: 'location_abc', 54 | title: 'Blocked Time Slot 2', 55 | startTime: '2023-12-01T14:00:00.000Z', 56 | endTime: '2023-12-01T15:00:00.000Z', 57 | dateCreated: '2023-01-01T00:00:00.000Z', 58 | dateUpdated: '2023-01-01T00:00:00.000Z', 59 | }, 60 | ], 61 | meta: { 62 | total: 2, 63 | count: 2, 64 | currentPage: 1, 65 | nextPageUrl: null, 66 | prevPageUrl: null, 67 | }, 68 | }; 69 | 70 | export const mockDeleteEventResponse = { 71 | success: true, 72 | message: 'Event deleted successfully', 73 | }; -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/contact/create.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "country": { 5 | "type": "string" 6 | }, 7 | "createdBy": { 8 | "type": "object", 9 | "properties": { 10 | "channel": { 11 | "type": "string" 12 | }, 13 | "source": { 14 | "type": "string" 15 | }, 16 | "sourceId": { 17 | "type": "string" 18 | }, 19 | "timestamp": { 20 | "type": "string" 21 | } 22 | } 23 | }, 24 | "customFields": { 25 | "type": "array", 26 | "items": { 27 | "type": "object", 28 | "properties": { 29 | "id": { 30 | "type": "string" 31 | } 32 | } 33 | } 34 | }, 35 | "dateAdded": { 36 | "type": "string" 37 | }, 38 | "dateUpdated": { 39 | "type": "string" 40 | }, 41 | "email": { 42 | "type": "string" 43 | }, 44 | "emailLowerCase": { 45 | "type": "string" 46 | }, 47 | "firstName": { 48 | "type": "string" 49 | }, 50 | "firstNameLowerCase": { 51 | "type": "string" 52 | }, 53 | "followers": { 54 | "type": "array", 55 | "items": { 56 | "type": "string" 57 | } 58 | }, 59 | "fullNameLowerCase": { 60 | "type": "string" 61 | }, 62 | "id": { 63 | "type": "string" 64 | }, 65 | "lastName": { 66 | "type": "string" 67 | }, 68 | "lastNameLowerCase": { 69 | "type": "string" 70 | }, 71 | "locationId": { 72 | "type": "string" 73 | }, 74 | "tags": { 75 | "type": "array", 76 | "items": { 77 | "type": "string" 78 | } 79 | }, 80 | "type": { 81 | "type": "string" 82 | } 83 | }, 84 | "version": 1 85 | } 86 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/DueDatePreSendAction.test.ts: -------------------------------------------------------------------------------- 1 | import type { IExecuteSingleFunctions, IHttpRequestOptions, INode } from 'n8n-workflow'; 2 | 3 | import { dueDatePreSendAction } from '../GenericFunctions'; 4 | 5 | describe('dueDatePreSendAction', () => { 6 | let mockThis: IExecuteSingleFunctions; 7 | 8 | beforeEach(() => { 9 | mockThis = { 10 | getNode: jest.fn( 11 | () => 12 | ({ 13 | id: 'mock-node-id', 14 | name: 'mock-node', 15 | typeVersion: 1, 16 | type: 'n8n-nodes-base.mockNode', 17 | position: [0, 0], 18 | parameters: {}, 19 | }) as INode, 20 | ), 21 | getNodeParameter: jest.fn(), 22 | getInputData: jest.fn(), 23 | helpers: {} as any, 24 | } as unknown as IExecuteSingleFunctions; 25 | 26 | jest.clearAllMocks(); 27 | }); 28 | 29 | it('should add formatted dueDate to requestOptions.body if dueDate is provided directly', async () => { 30 | (mockThis.getNodeParameter as jest.Mock).mockReturnValueOnce('2024-12-25'); 31 | 32 | const requestOptions: IHttpRequestOptions = { url: 'https://example.com/api' }; 33 | 34 | const result = await dueDatePreSendAction.call(mockThis, requestOptions); 35 | 36 | expect(result.body).toEqual({ dueDate: '2024-12-25T00:00:00+00:00' }); 37 | }); 38 | 39 | it('should add formatted dueDate to requestOptions.body if dueDate is provided in updateFields', async () => { 40 | (mockThis.getNodeParameter as jest.Mock).mockImplementation((paramName: string) => { 41 | if (paramName === 'dueDate') return null; 42 | if (paramName === 'updateFields') return { dueDate: '2024-12-25' }; 43 | return undefined; 44 | }); 45 | 46 | const requestOptions: IHttpRequestOptions = { url: 'https://example.com/api' }; 47 | 48 | const result = await dueDatePreSendAction.call(mockThis, requestOptions); 49 | 50 | expect(result.body).toEqual({ dueDate: '2024-12-25T00:00:00+00:00' }); 51 | }); 52 | 53 | it('should initialize body as an empty object if it is undefined', async () => { 54 | (mockThis.getNodeParameter as jest.Mock).mockReturnValueOnce('2024-12-25'); 55 | 56 | const requestOptions: IHttpRequestOptions = { url: 'https://example.com/api', body: undefined }; 57 | 58 | const result = await dueDatePreSendAction.call(mockThis, requestOptions); 59 | 60 | expect(result.body).toEqual({ dueDate: '2024-12-25T00:00:00+00:00' }); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/task/getAll.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "tasks": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "id": { 10 | "type": "string" 11 | }, 12 | "title": { 13 | "type": "string" 14 | }, 15 | "body": { 16 | "type": "string" 17 | }, 18 | "contactId": { 19 | "type": "string" 20 | }, 21 | "businessId": { 22 | "type": "string" 23 | }, 24 | "assignedTo": { 25 | "type": "string" 26 | }, 27 | "completed": { 28 | "type": "boolean" 29 | }, 30 | "dueDate": { 31 | "type": "string" 32 | }, 33 | "completedDate": { 34 | "type": "string" 35 | }, 36 | "createdAt": { 37 | "type": "string" 38 | }, 39 | "updatedAt": { 40 | "type": "string" 41 | }, 42 | "createdBy": { 43 | "type": "string" 44 | }, 45 | "updatedBy": { 46 | "type": "string" 47 | } 48 | } 49 | } 50 | }, 51 | "meta": { 52 | "type": "object", 53 | "properties": { 54 | "total": { 55 | "type": "number" 56 | }, 57 | "count": { 58 | "type": "number" 59 | }, 60 | "limit": { 61 | "type": "number" 62 | }, 63 | "offset": { 64 | "type": "number" 65 | }, 66 | "locationId": { 67 | "type": "string" 68 | } 69 | } 70 | } 71 | }, 72 | "version": 1 73 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/task/search.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "tasks": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "id": { 10 | "type": "string" 11 | }, 12 | "title": { 13 | "type": "string" 14 | }, 15 | "body": { 16 | "type": "string" 17 | }, 18 | "contactId": { 19 | "type": "string" 20 | }, 21 | "businessId": { 22 | "type": "string" 23 | }, 24 | "assignedTo": { 25 | "type": "string" 26 | }, 27 | "completed": { 28 | "type": "boolean" 29 | }, 30 | "dueDate": { 31 | "type": "string" 32 | }, 33 | "completedDate": { 34 | "type": "string" 35 | }, 36 | "createdAt": { 37 | "type": "string" 38 | }, 39 | "updatedAt": { 40 | "type": "string" 41 | }, 42 | "createdBy": { 43 | "type": "string" 44 | }, 45 | "updatedBy": { 46 | "type": "string" 47 | } 48 | } 49 | } 50 | }, 51 | "meta": { 52 | "type": "object", 53 | "properties": { 54 | "total": { 55 | "type": "number" 56 | }, 57 | "count": { 58 | "type": "number" 59 | }, 60 | "limit": { 61 | "type": "number" 62 | }, 63 | "offset": { 64 | "type": "number" 65 | }, 66 | "locationId": { 67 | "type": "string" 68 | } 69 | } 70 | } 71 | }, 72 | "version": 1 73 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/conversation/updateConversation.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "conversation": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string", 9 | "description": "Unique identifier for the conversation" 10 | }, 11 | "locationId": { 12 | "type": "string", 13 | "description": "Location ID where the conversation belongs" 14 | }, 15 | "contactId": { 16 | "type": "string", 17 | "description": "Contact ID associated with the conversation" 18 | }, 19 | "type": { 20 | "type": "string", 21 | "enum": ["SMS", "Email", "WhatsApp", "Phone", "Voicemail", "Chat", "Review", "Facebook", "Instagram"], 22 | "description": "Type of conversation" 23 | }, 24 | "status": { 25 | "type": "string", 26 | "enum": ["open", "closed", "archived"], 27 | "description": "Updated status of the conversation" 28 | }, 29 | "assignedTo": { 30 | "type": "string", 31 | "description": "User ID assigned to handle the conversation" 32 | }, 33 | "tags": { 34 | "type": "array", 35 | "items": { 36 | "type": "string" 37 | }, 38 | "description": "Updated tags associated with the conversation" 39 | }, 40 | "customFields": { 41 | "type": "object", 42 | "description": "Updated custom fields associated with the conversation" 43 | }, 44 | "updatedAt": { 45 | "type": "string", 46 | "format": "date-time", 47 | "description": "Last update timestamp" 48 | } 49 | }, 50 | "description": "Updated conversation details" 51 | }, 52 | "success": { 53 | "type": "boolean", 54 | "description": "Whether the conversation was updated successfully" 55 | } 56 | }, 57 | "version": 1 58 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/business/getAll.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "businesses": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "id": { 10 | "type": "string" 11 | }, 12 | "name": { 13 | "type": "string" 14 | }, 15 | "address": { 16 | "type": "string" 17 | }, 18 | "city": { 19 | "type": "string" 20 | }, 21 | "state": { 22 | "type": "string" 23 | }, 24 | "postalCode": { 25 | "type": "string" 26 | }, 27 | "country": { 28 | "type": "string" 29 | }, 30 | "phone": { 31 | "type": "string" 32 | }, 33 | "email": { 34 | "type": "string" 35 | }, 36 | "website": { 37 | "type": "string" 38 | }, 39 | "description": { 40 | "type": "string" 41 | }, 42 | "locationId": { 43 | "type": "string" 44 | }, 45 | "createdAt": { 46 | "type": "string" 47 | }, 48 | "updatedAt": { 49 | "type": "string" 50 | } 51 | } 52 | } 53 | }, 54 | "meta": { 55 | "type": "object", 56 | "properties": { 57 | "total": { 58 | "type": "number" 59 | }, 60 | "count": { 61 | "type": "number" 62 | }, 63 | "limit": { 64 | "type": "number" 65 | }, 66 | "offset": { 67 | "type": "number" 68 | } 69 | } 70 | }, 71 | "success": { 72 | "type": "boolean" 73 | } 74 | }, 75 | "version": 1 76 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customValues/getAll.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "customValues": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "id": { 10 | "type": "string" 11 | }, 12 | "name": { 13 | "type": "string" 14 | }, 15 | "value": { 16 | "type": "string" 17 | }, 18 | "description": { 19 | "type": "string" 20 | }, 21 | "type": { 22 | "type": "string", 23 | "enum": ["text", "number", "boolean", "date", "url", "email"] 24 | }, 25 | "category": { 26 | "type": "string" 27 | }, 28 | "isActive": { 29 | "type": "boolean" 30 | }, 31 | "sortOrder": { 32 | "type": "number" 33 | }, 34 | "locationId": { 35 | "type": "string" 36 | }, 37 | "createdAt": { 38 | "type": "string" 39 | }, 40 | "updatedAt": { 41 | "type": "string" 42 | }, 43 | "createdBy": { 44 | "type": "string" 45 | }, 46 | "updatedBy": { 47 | "type": "string" 48 | } 49 | } 50 | } 51 | }, 52 | "meta": { 53 | "type": "object", 54 | "properties": { 55 | "total": { 56 | "type": "number" 57 | }, 58 | "count": { 59 | "type": "number" 60 | }, 61 | "limit": { 62 | "type": "number" 63 | }, 64 | "offset": { 65 | "type": "number" 66 | }, 67 | "locationId": { 68 | "type": "string" 69 | } 70 | } 71 | } 72 | }, 73 | "version": 1 74 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/TaskPostReceiceAction.test.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | IExecuteSingleFunctions, 3 | INodeExecutionData, 4 | IN8nHttpFullResponse, 5 | } from 'n8n-workflow'; 6 | 7 | import { taskPostReceiceAction } from '../GenericFunctions'; 8 | 9 | describe('taskPostReceiceAction', () => { 10 | let mockThis: Partial; 11 | 12 | beforeEach(() => { 13 | mockThis = { 14 | getNodeParameter: jest.fn((parameterName: string) => { 15 | if (parameterName === 'contactId') return '12345'; 16 | return undefined; 17 | }), 18 | }; 19 | }); 20 | 21 | it('should add contactId to each item in items', async () => { 22 | const items: INodeExecutionData[] = [ 23 | { json: { field1: 'value1' } }, 24 | { json: { field2: 'value2' } }, 25 | ]; 26 | 27 | const response: IN8nHttpFullResponse = { 28 | body: {}, 29 | headers: {}, 30 | statusCode: 200, 31 | }; 32 | 33 | const result = await taskPostReceiceAction.call( 34 | mockThis as IExecuteSingleFunctions, 35 | items, 36 | response, 37 | ); 38 | 39 | expect(result).toEqual([ 40 | { json: { field1: 'value1', contactId: '12345' } }, 41 | { json: { field2: 'value2', contactId: '12345' } }, 42 | ]); 43 | expect(mockThis.getNodeParameter).toHaveBeenCalledWith('contactId'); 44 | }); 45 | 46 | it('should not modify other fields in items', async () => { 47 | const items: INodeExecutionData[] = [{ json: { name: 'John Doe' } }, { json: { age: 30 } }]; 48 | 49 | const response: IN8nHttpFullResponse = { 50 | body: {}, 51 | headers: {}, 52 | statusCode: 200, 53 | }; 54 | 55 | const result = await taskPostReceiceAction.call( 56 | mockThis as IExecuteSingleFunctions, 57 | items, 58 | response, 59 | ); 60 | 61 | expect(result).toEqual([ 62 | { json: { name: 'John Doe', contactId: '12345' } }, 63 | { json: { age: 30, contactId: '12345' } }, 64 | ]); 65 | expect(mockThis.getNodeParameter).toHaveBeenCalledWith('contactId'); 66 | }); 67 | 68 | it('should return an empty array if items is empty', async () => { 69 | const items: INodeExecutionData[] = []; 70 | 71 | const response: IN8nHttpFullResponse = { 72 | body: {}, 73 | headers: {}, 74 | statusCode: 200, 75 | }; 76 | 77 | const result = await taskPostReceiceAction.call( 78 | mockThis as IExecuteSingleFunctions, 79 | items, 80 | response, 81 | ); 82 | 83 | expect(result).toEqual([]); 84 | expect(mockThis.getNodeParameter).toHaveBeenCalledWith('contactId'); 85 | }); 86 | }); 87 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/saas/getLocationsByStripeId.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "locations": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "id": { 10 | "type": "string", 11 | "description": "Location ID" 12 | }, 13 | "name": { 14 | "type": "string", 15 | "description": "Location name" 16 | }, 17 | "stripeCustomerId": { 18 | "type": "string", 19 | "description": "Stripe customer ID associated with the location" 20 | }, 21 | "companyId": { 22 | "type": "string", 23 | "description": "Company ID associated with the location" 24 | }, 25 | "subscriptionId": { 26 | "type": "string", 27 | "description": "Subscription ID for the location" 28 | }, 29 | "planId": { 30 | "type": "string", 31 | "description": "SaaS plan ID" 32 | }, 33 | "status": { 34 | "type": "string", 35 | "enum": ["active", "inactive", "paused", "cancelled"], 36 | "description": "Current status of the location" 37 | }, 38 | "saasEnabled": { 39 | "type": "boolean", 40 | "description": "Whether SaaS is enabled for this location" 41 | }, 42 | "createdAt": { 43 | "type": "string", 44 | "format": "date-time", 45 | "description": "Location creation timestamp" 46 | }, 47 | "updatedAt": { 48 | "type": "string", 49 | "format": "date-time", 50 | "description": "Location last updated timestamp" 51 | } 52 | } 53 | }, 54 | "description": "Array of locations matching the search criteria" 55 | }, 56 | "count": { 57 | "type": "integer", 58 | "description": "Total number of locations found" 59 | } 60 | }, 61 | "version": 1 62 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/socialPlanner/schedulePost.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "id": { 5 | "type": "string", 6 | "description": "Unique identifier for the scheduled post" 7 | }, 8 | "locationId": { 9 | "type": "string", 10 | "description": "The location ID where the post was scheduled" 11 | }, 12 | "content": { 13 | "type": "string", 14 | "description": "The content of the social media post" 15 | }, 16 | "socialAccounts": { 17 | "type": "array", 18 | "items": { 19 | "type": "string" 20 | }, 21 | "description": "List of social media platforms the post is scheduled for" 22 | }, 23 | "scheduledDate": { 24 | "type": "string", 25 | "format": "date-time", 26 | "description": "The date and time when the post is scheduled to be published" 27 | }, 28 | "timezone": { 29 | "type": "string", 30 | "description": "Timezone for the scheduled post" 31 | }, 32 | "mediaUrls": { 33 | "type": "array", 34 | "items": { 35 | "type": "string" 36 | }, 37 | "description": "List of media URLs attached to the post" 38 | }, 39 | "hashtags": { 40 | "type": "array", 41 | "items": { 42 | "type": "string" 43 | }, 44 | "description": "List of hashtags used in the post" 45 | }, 46 | "postType": { 47 | "type": "string", 48 | "enum": ["post", "story", "reel"], 49 | "description": "Type of social media post" 50 | }, 51 | "locationTag": { 52 | "type": "string", 53 | "description": "Location tag for the post" 54 | }, 55 | "status": { 56 | "type": "string", 57 | "enum": ["scheduled", "failed"], 58 | "description": "Current status of the scheduled post" 59 | }, 60 | "createdAt": { 61 | "type": "string", 62 | "format": "date-time", 63 | "description": "Timestamp when the post was created" 64 | }, 65 | "updatedAt": { 66 | "type": "string", 67 | "format": "date-time", 68 | "description": "Timestamp when the post was last updated" 69 | } 70 | }, 71 | "required": ["id", "locationId", "content", "socialAccounts", "scheduledDate", "status"], 72 | "version": 1 73 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/SplitTagsPreSendAction.test.ts: -------------------------------------------------------------------------------- 1 | import type { IExecuteSingleFunctions, IHttpRequestOptions } from 'n8n-workflow'; 2 | 3 | import { splitTagsPreSendAction } from '../GenericFunctions'; 4 | 5 | describe('splitTagsPreSendAction', () => { 6 | let mockThis: Partial; 7 | 8 | beforeEach(() => { 9 | mockThis = {}; 10 | }); 11 | 12 | it('should return requestOptions unchanged if tags are already an array', async () => { 13 | const requestOptions: IHttpRequestOptions = { 14 | url: 'https://example.com/api', 15 | body: { 16 | tags: ['tag1', 'tag2', 'tag3'], 17 | }, 18 | }; 19 | 20 | const result = await splitTagsPreSendAction.call( 21 | mockThis as IExecuteSingleFunctions, 22 | requestOptions, 23 | ); 24 | 25 | expect(result).toEqual(requestOptions); 26 | }); 27 | 28 | it('should split a comma-separated string of tags into an array', async () => { 29 | const requestOptions: IHttpRequestOptions = { 30 | url: 'https://example.com/api', 31 | body: { 32 | tags: 'tag1, tag2, tag3', 33 | }, 34 | }; 35 | 36 | const result = await splitTagsPreSendAction.call( 37 | mockThis as IExecuteSingleFunctions, 38 | requestOptions, 39 | ); 40 | 41 | expect(result.body).toEqual({ 42 | tags: ['tag1', 'tag2', 'tag3'], 43 | }); 44 | }); 45 | 46 | it('should trim whitespace around tags when splitting a string', async () => { 47 | const requestOptions: IHttpRequestOptions = { 48 | url: 'https://example.com/api', 49 | body: { 50 | tags: 'tag1 , tag2 , tag3 ', 51 | }, 52 | }; 53 | 54 | const result = await splitTagsPreSendAction.call( 55 | mockThis as IExecuteSingleFunctions, 56 | requestOptions, 57 | ); 58 | 59 | expect(result.body).toEqual({ 60 | tags: ['tag1', 'tag2', 'tag3'], 61 | }); 62 | }); 63 | 64 | it('should return requestOptions unchanged if tags are not provided', async () => { 65 | const requestOptions: IHttpRequestOptions = { 66 | url: 'https://example.com/api', 67 | body: {}, 68 | }; 69 | 70 | const result = await splitTagsPreSendAction.call( 71 | mockThis as IExecuteSingleFunctions, 72 | requestOptions, 73 | ); 74 | 75 | expect(result).toEqual(requestOptions); 76 | }); 77 | 78 | it('should return requestOptions unchanged if body is undefined', async () => { 79 | const requestOptions: IHttpRequestOptions = { 80 | url: 'https://example.com/api', 81 | body: undefined, 82 | }; 83 | 84 | const result = await splitTagsPreSendAction.call( 85 | mockThis as IExecuteSingleFunctions, 86 | requestOptions, 87 | ); 88 | 89 | expect(result).toEqual(requestOptions); 90 | }); 91 | }); 92 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/conversation/createConversation.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "conversation": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string", 9 | "description": "Unique identifier for the created conversation" 10 | }, 11 | "locationId": { 12 | "type": "string", 13 | "description": "Location ID where the conversation was created" 14 | }, 15 | "contactId": { 16 | "type": "string", 17 | "description": "Contact ID associated with the conversation" 18 | }, 19 | "type": { 20 | "type": "string", 21 | "enum": ["SMS", "Email", "WhatsApp", "Phone", "Voicemail", "Chat", "Review", "Facebook", "Instagram"], 22 | "description": "Type of conversation" 23 | }, 24 | "status": { 25 | "type": "string", 26 | "enum": ["open", "closed", "archived"], 27 | "description": "Initial status of the conversation" 28 | }, 29 | "assignedTo": { 30 | "type": "string", 31 | "description": "User ID assigned to handle the conversation" 32 | }, 33 | "tags": { 34 | "type": "array", 35 | "items": { 36 | "type": "string" 37 | }, 38 | "description": "Tags associated with the conversation" 39 | }, 40 | "customFields": { 41 | "type": "object", 42 | "description": "Custom fields associated with the conversation" 43 | }, 44 | "createdAt": { 45 | "type": "string", 46 | "format": "date-time", 47 | "description": "Conversation creation timestamp" 48 | }, 49 | "updatedAt": { 50 | "type": "string", 51 | "format": "date-time", 52 | "description": "Last update timestamp" 53 | } 54 | }, 55 | "description": "Created conversation details" 56 | }, 57 | "success": { 58 | "type": "boolean", 59 | "description": "Whether the conversation was created successfully" 60 | } 61 | }, 62 | "version": 1 63 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/GetPipelineStages.test.ts: -------------------------------------------------------------------------------- 1 | import { getPipelineStages } from '../GenericFunctions'; 2 | 3 | const mockHighLevelApiRequest = jest.fn(); 4 | const mockGetNodeParameter = jest.fn(); 5 | const mockGetCurrentNodeParameter = jest.fn(); 6 | const mockGetCredentials = jest.fn(); 7 | 8 | const mockContext: any = { 9 | getNodeParameter: mockGetNodeParameter, 10 | getCurrentNodeParameter: mockGetCurrentNodeParameter, 11 | getCredentials: mockGetCredentials, 12 | helpers: { 13 | httpRequestWithAuthentication: mockHighLevelApiRequest, 14 | }, 15 | }; 16 | 17 | describe('getPipelineStages', () => { 18 | beforeEach(() => { 19 | jest.clearAllMocks(); 20 | }); 21 | 22 | it('should return pipeline stages for create operation', async () => { 23 | mockGetNodeParameter.mockReturnValue('create'); 24 | mockGetCurrentNodeParameter.mockReturnValue('pipeline-1'); 25 | mockHighLevelApiRequest.mockResolvedValue({ 26 | pipelines: [ 27 | { 28 | id: 'pipeline-1', 29 | stages: [ 30 | { id: 'stage-1', name: 'Stage 1' }, 31 | { id: 'stage-2', name: 'Stage 2' }, 32 | ], 33 | }, 34 | ], 35 | }); 36 | 37 | const response = await getPipelineStages.call(mockContext); 38 | 39 | expect(response).toEqual([ 40 | { name: 'Stage 1', value: 'stage-1' }, 41 | { name: 'Stage 2', value: 'stage-2' }, 42 | ]); 43 | }); 44 | 45 | it('should return pipeline stages for update operation', async () => { 46 | mockGetNodeParameter.mockImplementation((param) => { 47 | if (param === 'operation') return 'update'; 48 | if (param === 'updateFields.pipelineId') return 'pipeline-2'; 49 | return undefined; 50 | }); 51 | 52 | mockHighLevelApiRequest.mockResolvedValue({ 53 | pipelines: [ 54 | { 55 | id: 'pipeline-2', 56 | stages: [ 57 | { id: 'stage-3', name: 'Stage 3' }, 58 | { id: 'stage-4', name: 'Stage 4' }, 59 | ], 60 | }, 61 | ], 62 | }); 63 | 64 | const response = await getPipelineStages.call(mockContext); 65 | 66 | expect(response).toEqual([ 67 | { name: 'Stage 3', value: 'stage-3' }, 68 | { name: 'Stage 4', value: 'stage-4' }, 69 | ]); 70 | }); 71 | 72 | it('should return an empty array if pipeline is not found', async () => { 73 | mockGetNodeParameter.mockReturnValue('create'); 74 | mockGetCurrentNodeParameter.mockReturnValue('non-existent-pipeline'); 75 | mockHighLevelApiRequest.mockResolvedValue({ 76 | pipelines: [ 77 | { 78 | id: 'pipeline-1', 79 | stages: [{ id: 'stage-1', name: 'Stage 1' }], 80 | }, 81 | ], 82 | }); 83 | 84 | const response = await getPipelineStages.call(mockContext); 85 | 86 | expect(response).toEqual([]); 87 | }); 88 | }); 89 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/media/getFiles.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "files": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "id": { 10 | "type": "string" 11 | }, 12 | "name": { 13 | "type": "string" 14 | }, 15 | "type": { 16 | "type": "string" 17 | }, 18 | "size": { 19 | "type": "number" 20 | }, 21 | "url": { 22 | "type": "string" 23 | }, 24 | "thumbnailUrl": { 25 | "type": "string" 26 | }, 27 | "folderId": { 28 | "type": "string" 29 | }, 30 | "isFolder": { 31 | "type": "boolean" 32 | }, 33 | "mimeType": { 34 | "type": "string" 35 | }, 36 | "createdAt": { 37 | "type": "string" 38 | }, 39 | "updatedAt": { 40 | "type": "string" 41 | }, 42 | "createdBy": { 43 | "type": "string" 44 | }, 45 | "locationId": { 46 | "type": "string" 47 | }, 48 | "description": { 49 | "type": "string" 50 | }, 51 | "tags": { 52 | "type": "array", 53 | "items": { 54 | "type": "string" 55 | } 56 | }, 57 | "isPublic": { 58 | "type": "boolean" 59 | } 60 | } 61 | } 62 | }, 63 | "meta": { 64 | "type": "object", 65 | "properties": { 66 | "total": { 67 | "type": "number" 68 | }, 69 | "count": { 70 | "type": "number" 71 | }, 72 | "limit": { 73 | "type": "number" 74 | }, 75 | "offset": { 76 | "type": "number" 77 | } 78 | } 79 | } 80 | }, 81 | "version": 1 82 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customObjects/searchRecords.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "records": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "id": { 10 | "type": "string", 11 | "description": "Unique identifier for the record" 12 | }, 13 | "objectId": { 14 | "type": "string", 15 | "description": "ID of the custom object this record belongs to" 16 | }, 17 | "locationId": { 18 | "type": "string", 19 | "description": "The location ID where the record belongs" 20 | }, 21 | "data": { 22 | "type": "object", 23 | "description": "The record data according to the custom object schema" 24 | }, 25 | "createdAt": { 26 | "type": "string", 27 | "format": "date-time", 28 | "description": "Timestamp when the record was created" 29 | }, 30 | "updatedAt": { 31 | "type": "string", 32 | "format": "date-time", 33 | "description": "Timestamp when the record was last updated" 34 | } 35 | } 36 | }, 37 | "description": "Array of records matching the search criteria" 38 | }, 39 | "meta": { 40 | "type": "object", 41 | "properties": { 42 | "total": { 43 | "type": "integer", 44 | "description": "Total number of records matching the search" 45 | }, 46 | "currentPage": { 47 | "type": "integer", 48 | "description": "Current page number" 49 | }, 50 | "nextPage": { 51 | "type": "integer", 52 | "description": "Next page number" 53 | }, 54 | "prevPage": { 55 | "type": "integer", 56 | "description": "Previous page number" 57 | }, 58 | "totalPages": { 59 | "type": "integer", 60 | "description": "Total number of pages" 61 | } 62 | }, 63 | "description": "Pagination metadata" 64 | } 65 | }, 66 | "version": 1 67 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "n8n-nodes-highlevelv2", 3 | "version": "1.0.16", 4 | "description": "n8n community node for HighLevel v2 API integration - comprehensive CRM, marketing automation, and business management platform", 5 | "keywords": [ 6 | "n8n-community-node-package", 7 | "n8n", 8 | "highlevel", 9 | "highlevelv2", 10 | "crm", 11 | "marketing-automation", 12 | "business-management", 13 | "gohighlevel", 14 | "leadconnector" 15 | ], 16 | "license": "MIT", 17 | "homepage": "https://github.com/marioaldayuz/n8n-highlevel", 18 | "author": { 19 | "name": "Mario Aldayuz", 20 | "email": "mario@olliebot.ai" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "https://github.com/marioaldayuz/n8n-highlevel.git" 25 | }, 26 | "bugs": { 27 | "url": "https://github.com/marioaldayuz/n8n-highlevel/issues" 28 | }, 29 | "engines": { 30 | "node": ">=20.15", 31 | "npm": ">=10.0.0" 32 | }, 33 | "main": "index.js", 34 | "scripts": { 35 | "build": "npx rimraf dist && tsc && gulp build:icons", 36 | "dev": "tsc --watch", 37 | "format": "prettier nodes --write", 38 | "lint": "eslint nodes package.json", 39 | "lintfix": "eslint nodes package.json --fix", 40 | "test": "jest", 41 | "test:watch": "jest --watch", 42 | "test:coverage": "jest --coverage", 43 | "prepublishOnly": "npm run build" 44 | }, 45 | "files": [ 46 | "dist", 47 | "README.md", 48 | "LICENSE.md" 49 | ], 50 | "n8n": { 51 | "n8nNodesApiVersion": 1, 52 | "nodes": [ 53 | "dist/nodes/HighLevelV2/HighLevel.node.js" 54 | ] 55 | }, 56 | "dependencies": { 57 | "luxon": "^3.4.4" 58 | }, 59 | "devDependencies": { 60 | "@types/jest": "^29.5.12", 61 | "@types/luxon": "^3.4.2", 62 | "@types/node": "^20.11.24", 63 | "@typescript-eslint/eslint-plugin": "^7.18.0", 64 | "@typescript-eslint/parser": "^7.18.0", 65 | "eslint": "^8.57.0", 66 | "eslint-plugin-n8n-nodes-base": "^1.16.3", 67 | "gulp": "^5.0.0", 68 | "jest": "^29.7.0", 69 | "prettier": "^3.5.3", 70 | "rimraf": "^5.0.5", 71 | "ts-jest": "^29.1.2", 72 | "typescript": "^5.8.2" 73 | }, 74 | "peerDependencies": { 75 | "n8n-workflow": "*" 76 | }, 77 | "jest": { 78 | "preset": "ts-jest", 79 | "testEnvironment": "node", 80 | "roots": [ 81 | "/nodes" 82 | ], 83 | "testMatch": [ 84 | "**/*.test.ts" 85 | ], 86 | "collectCoverageFrom": [ 87 | "nodes/**/*.ts", 88 | "!nodes/**/*.test.ts", 89 | "!nodes/**/*.d.ts" 90 | ], 91 | "coverageDirectory": "coverage", 92 | "coverageReporters": [ 93 | "text", 94 | "lcov", 95 | "html" 96 | ] 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/objectAssociations/getAssociationByObjectKeys.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "id": { 5 | "type": "string", 6 | "description": "Unique identifier for the association" 7 | }, 8 | "locationId": { 9 | "type": "string", 10 | "description": "The location ID where the association belongs" 11 | }, 12 | "name": { 13 | "type": "string", 14 | "description": "Name of the association" 15 | }, 16 | "description": { 17 | "type": "string", 18 | "description": "Description of the association" 19 | }, 20 | "fromObjectType": { 21 | "type": "string", 22 | "description": "Type of the source object" 23 | }, 24 | "toObjectType": { 25 | "type": "string", 26 | "description": "Type of the target object" 27 | }, 28 | "cardinality": { 29 | "type": "string", 30 | "enum": ["ONE_TO_ONE", "ONE_TO_MANY", "MANY_TO_ONE", "MANY_TO_MANY"], 31 | "description": "Cardinality of the association" 32 | }, 33 | "relations": { 34 | "type": "array", 35 | "items": { 36 | "type": "object", 37 | "properties": { 38 | "id": { 39 | "type": "string", 40 | "description": "Relation ID" 41 | }, 42 | "fromObjectId": { 43 | "type": "string", 44 | "description": "Source object ID" 45 | }, 46 | "toObjectId": { 47 | "type": "string", 48 | "description": "Target object ID" 49 | }, 50 | "metadata": { 51 | "type": "object", 52 | "description": "Additional metadata" 53 | }, 54 | "createdAt": { 55 | "type": "string", 56 | "format": "date-time" 57 | } 58 | } 59 | }, 60 | "description": "Relations using this association" 61 | }, 62 | "createdAt": { 63 | "type": "string", 64 | "format": "date-time", 65 | "description": "Timestamp when the association was created" 66 | }, 67 | "updatedAt": { 68 | "type": "string", 69 | "format": "date-time", 70 | "description": "Timestamp when the association was last updated" 71 | } 72 | }, 73 | "version": 1 74 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/contact/update.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "additionalPhones": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "phone": { 10 | "type": "string" 11 | } 12 | } 13 | } 14 | }, 15 | "country": { 16 | "type": "string" 17 | }, 18 | "createdBy": { 19 | "type": "object", 20 | "properties": { 21 | "channel": { 22 | "type": "string" 23 | }, 24 | "source": { 25 | "type": "string" 26 | }, 27 | "sourceId": { 28 | "type": "string" 29 | }, 30 | "timestamp": { 31 | "type": "string" 32 | } 33 | } 34 | }, 35 | "customFields": { 36 | "type": "array", 37 | "items": { 38 | "type": "object", 39 | "properties": { 40 | "id": { 41 | "type": "string" 42 | } 43 | } 44 | } 45 | }, 46 | "dateAdded": { 47 | "type": "string" 48 | }, 49 | "dateUpdated": { 50 | "type": "string" 51 | }, 52 | "email": { 53 | "type": "string" 54 | }, 55 | "emailLowerCase": { 56 | "type": "string" 57 | }, 58 | "firstName": { 59 | "type": "string" 60 | }, 61 | "firstNameLowerCase": { 62 | "type": "string" 63 | }, 64 | "followers": { 65 | "type": "array", 66 | "items": { 67 | "type": "string" 68 | } 69 | }, 70 | "fullNameLowerCase": { 71 | "type": "string" 72 | }, 73 | "id": { 74 | "type": "string" 75 | }, 76 | "lastName": { 77 | "type": "string" 78 | }, 79 | "lastNameLowerCase": { 80 | "type": "string" 81 | }, 82 | "locationId": { 83 | "type": "string" 84 | }, 85 | "phone": { 86 | "type": "string" 87 | }, 88 | "tags": { 89 | "type": "array", 90 | "items": { 91 | "type": "string" 92 | } 93 | }, 94 | "type": { 95 | "type": "string" 96 | } 97 | }, 98 | "version": 1 99 | } 100 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/DateTimeToEpochPreSendAction.test.ts: -------------------------------------------------------------------------------- 1 | import type { IExecuteSingleFunctions, IHttpRequestOptions } from 'n8n-workflow'; 2 | 3 | import { dateTimeToEpochPreSendAction } from '../GenericFunctions'; 4 | 5 | describe('dateTimeToEpochPreSendAction', () => { 6 | let mockThis: Partial; 7 | 8 | beforeEach(() => { 9 | mockThis = {}; 10 | }); 11 | 12 | it('should convert startDate and endDate to epoch time', async () => { 13 | const requestOptions: IHttpRequestOptions = { 14 | url: 'https://example.com/api', 15 | qs: { 16 | startDate: '2024-12-25T00:00:00Z', 17 | endDate: '2024-12-26T00:00:00Z', 18 | }, 19 | }; 20 | 21 | const result = await dateTimeToEpochPreSendAction.call( 22 | mockThis as IExecuteSingleFunctions, 23 | requestOptions, 24 | ); 25 | 26 | expect(result.qs).toEqual({ 27 | startDate: new Date('2024-12-25T00:00:00Z').getTime(), 28 | endDate: new Date('2024-12-26T00:00:00Z').getTime(), 29 | }); 30 | }); 31 | 32 | it('should convert only startDate if endDate is not provided', async () => { 33 | const requestOptions: IHttpRequestOptions = { 34 | url: 'https://example.com/api', 35 | qs: { 36 | startDate: '2024-12-25T00:00:00Z', 37 | }, 38 | }; 39 | 40 | const result = await dateTimeToEpochPreSendAction.call( 41 | mockThis as IExecuteSingleFunctions, 42 | requestOptions, 43 | ); 44 | 45 | expect(result.qs).toEqual({ 46 | startDate: new Date('2024-12-25T00:00:00Z').getTime(), 47 | }); 48 | }); 49 | 50 | it('should convert only endDate if startDate is not provided', async () => { 51 | const requestOptions: IHttpRequestOptions = { 52 | url: 'https://example.com/api', 53 | qs: { 54 | endDate: '2024-12-26T00:00:00Z', 55 | }, 56 | }; 57 | 58 | const result = await dateTimeToEpochPreSendAction.call( 59 | mockThis as IExecuteSingleFunctions, 60 | requestOptions, 61 | ); 62 | 63 | expect(result.qs).toEqual({ 64 | endDate: new Date('2024-12-26T00:00:00Z').getTime(), 65 | }); 66 | }); 67 | 68 | it('should not modify requestOptions if neither startDate nor endDate are provided', async () => { 69 | const requestOptions: IHttpRequestOptions = { 70 | url: 'https://example.com/api', 71 | qs: {}, 72 | }; 73 | 74 | const result = await dateTimeToEpochPreSendAction.call( 75 | mockThis as IExecuteSingleFunctions, 76 | requestOptions, 77 | ); 78 | 79 | expect(result).toEqual(requestOptions); 80 | }); 81 | 82 | it('should not modify requestOptions if qs is undefined', async () => { 83 | const requestOptions: IHttpRequestOptions = { 84 | url: 'https://example.com/api', 85 | qs: undefined, 86 | }; 87 | 88 | const result = await dateTimeToEpochPreSendAction.call( 89 | mockThis as IExecuteSingleFunctions, 90 | requestOptions, 91 | ); 92 | 93 | expect(result).toEqual(requestOptions); 94 | }); 95 | }); 96 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/funnel/getFunnels.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "funnels": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "id": { 10 | "type": "string" 11 | }, 12 | "name": { 13 | "type": "string" 14 | }, 15 | "description": { 16 | "type": "string" 17 | }, 18 | "status": { 19 | "type": "string", 20 | "enum": ["active", "inactive", "draft"] 21 | }, 22 | "category": { 23 | "type": "string" 24 | }, 25 | "locationId": { 26 | "type": "string" 27 | }, 28 | "createdAt": { 29 | "type": "string" 30 | }, 31 | "updatedAt": { 32 | "type": "string" 33 | }, 34 | "createdBy": { 35 | "type": "string" 36 | }, 37 | "pageCount": { 38 | "type": "number" 39 | }, 40 | "conversionRate": { 41 | "type": "number" 42 | }, 43 | "totalViews": { 44 | "type": "number" 45 | }, 46 | "totalConversions": { 47 | "type": "number" 48 | }, 49 | "domain": { 50 | "type": "string" 51 | }, 52 | "subDomain": { 53 | "type": "string" 54 | }, 55 | "favicon": { 56 | "type": "string" 57 | }, 58 | "tags": { 59 | "type": "array", 60 | "items": { 61 | "type": "string" 62 | } 63 | } 64 | } 65 | } 66 | }, 67 | "meta": { 68 | "type": "object", 69 | "properties": { 70 | "total": { 71 | "type": "number" 72 | }, 73 | "count": { 74 | "type": "number" 75 | }, 76 | "limit": { 77 | "type": "number" 78 | }, 79 | "offset": { 80 | "type": "number" 81 | } 82 | } 83 | } 84 | }, 85 | "version": 1 86 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/saas/enableSaas.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "success": { 5 | "type": "boolean", 6 | "description": "Whether SaaS was successfully enabled" 7 | }, 8 | "message": { 9 | "type": "string", 10 | "description": "Success or error message" 11 | }, 12 | "location": { 13 | "type": "object", 14 | "properties": { 15 | "locationId": { 16 | "type": "string", 17 | "description": "ID of the location" 18 | }, 19 | "name": { 20 | "type": "string", 21 | "description": "Name of the location" 22 | }, 23 | "saasEnabled": { 24 | "type": "boolean", 25 | "description": "Current SaaS status (should be true after enabling)" 26 | }, 27 | "planId": { 28 | "type": "string", 29 | "description": "Assigned SaaS plan ID" 30 | }, 31 | "subscriptionId": { 32 | "type": "string", 33 | "description": "Created subscription ID" 34 | }, 35 | "enabledAt": { 36 | "type": "string", 37 | "format": "date-time", 38 | "description": "Timestamp when SaaS was enabled" 39 | }, 40 | "features": { 41 | "type": "array", 42 | "items": { 43 | "type": "string" 44 | }, 45 | "description": "List of enabled features" 46 | }, 47 | "limits": { 48 | "type": "object", 49 | "properties": { 50 | "users": { 51 | "type": "integer", 52 | "description": "Maximum number of users allowed" 53 | }, 54 | "contacts": { 55 | "type": "integer", 56 | "description": "Maximum number of contacts allowed" 57 | }, 58 | "apiCalls": { 59 | "type": "integer", 60 | "description": "Maximum API calls per month" 61 | }, 62 | "storage": { 63 | "type": "integer", 64 | "description": "Storage limit in GB" 65 | } 66 | }, 67 | "description": "Usage limits for the SaaS plan" 68 | } 69 | }, 70 | "description": "Details of the location with enabled SaaS" 71 | } 72 | }, 73 | "version": 1 74 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/saas/updateSubscription.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "subscription": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string", 9 | "description": "Subscription ID" 10 | }, 11 | "locationId": { 12 | "type": "string", 13 | "description": "Location ID associated with the subscription" 14 | }, 15 | "planId": { 16 | "type": "string", 17 | "description": "Updated SaaS plan ID" 18 | }, 19 | "status": { 20 | "type": "string", 21 | "enum": ["active", "paused", "cancelled", "past_due", "unpaid"], 22 | "description": "Current subscription status" 23 | }, 24 | "currentPeriodStart": { 25 | "type": "string", 26 | "format": "date-time", 27 | "description": "Current billing period start date" 28 | }, 29 | "currentPeriodEnd": { 30 | "type": "string", 31 | "format": "date-time", 32 | "description": "Current billing period end date" 33 | }, 34 | "trialEnd": { 35 | "type": "string", 36 | "format": "date-time", 37 | "description": "Trial period end date" 38 | }, 39 | "cancelAtPeriodEnd": { 40 | "type": "boolean", 41 | "description": "Whether the subscription will be cancelled at the end of the current period" 42 | }, 43 | "amount": { 44 | "type": "number", 45 | "description": "Subscription amount" 46 | }, 47 | "currency": { 48 | "type": "string", 49 | "description": "Currency code" 50 | }, 51 | "interval": { 52 | "type": "string", 53 | "enum": ["month", "year", "week", "day"], 54 | "description": "Billing interval" 55 | }, 56 | "intervalCount": { 57 | "type": "integer", 58 | "description": "Number of intervals between billings" 59 | }, 60 | "updatedAt": { 61 | "type": "string", 62 | "format": "date-time", 63 | "description": "Last update timestamp" 64 | } 65 | }, 66 | "description": "Updated subscription details" 67 | }, 68 | "success": { 69 | "type": "boolean", 70 | "description": "Whether the update was successful" 71 | } 72 | }, 73 | "version": 1 74 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/AddCustomFieldsPreSendAction.test.ts: -------------------------------------------------------------------------------- 1 | import type { IDataObject, IExecuteSingleFunctions, IHttpRequestOptions } from 'n8n-workflow'; 2 | 3 | import { addCustomFieldsPreSendAction } from '../GenericFunctions'; 4 | 5 | describe('addCustomFieldsPreSendAction', () => { 6 | let mockThis: any; 7 | 8 | beforeEach(() => { 9 | mockThis = { 10 | helpers: { 11 | httpRequest: jest.fn(), 12 | httpRequestWithAuthentication: jest.fn(), 13 | requestWithAuthenticationPaginated: jest.fn(), 14 | request: jest.fn(), 15 | requestWithAuthentication: jest.fn(), 16 | requestOAuth1: jest.fn(), 17 | requestOAuth2: jest.fn(), 18 | assertBinaryData: jest.fn(), 19 | getBinaryDataBuffer: jest.fn(), 20 | prepareBinaryData: jest.fn(), 21 | setBinaryDataBuffer: jest.fn(), 22 | copyBinaryFile: jest.fn(), 23 | binaryToBuffer: jest.fn(), 24 | binaryToString: jest.fn(), 25 | getBinaryPath: jest.fn(), 26 | getBinaryStream: jest.fn(), 27 | getBinaryMetadata: jest.fn(), 28 | createDeferredPromise: jest 29 | .fn() 30 | .mockReturnValue({ promise: Promise.resolve(), resolve: jest.fn(), reject: jest.fn() }), 31 | }, 32 | }; 33 | }); 34 | 35 | it('should format custom fields correctly when provided', async () => { 36 | const mockRequestOptions: IHttpRequestOptions = { 37 | body: { 38 | customFields: { 39 | values: [ 40 | { 41 | fieldId: { value: '123', cachedResultName: 'FieldName' }, 42 | fieldValue: 'TestValue', 43 | }, 44 | { 45 | fieldId: { value: '456' }, 46 | fieldValue: 'AnotherValue', 47 | }, 48 | ], 49 | }, 50 | } as IDataObject, 51 | url: '', 52 | }; 53 | 54 | const result = await addCustomFieldsPreSendAction.call( 55 | mockThis as IExecuteSingleFunctions, 56 | mockRequestOptions, 57 | ); 58 | 59 | expect((result.body as IDataObject).customFields).toEqual([ 60 | { id: '123', key: 'FieldName', field_value: 'TestValue' }, 61 | { id: '456', key: 'default_key', field_value: 'AnotherValue' }, 62 | ]); 63 | }); 64 | 65 | it('should not modify request body if customFields is not provided', async () => { 66 | const mockRequestOptions: IHttpRequestOptions = { 67 | body: { 68 | otherField: 'SomeValue', 69 | } as IDataObject, 70 | url: '', 71 | }; 72 | 73 | const result = await addCustomFieldsPreSendAction.call( 74 | mockThis as IExecuteSingleFunctions, 75 | mockRequestOptions, 76 | ); 77 | 78 | expect(result).toEqual(mockRequestOptions); 79 | }); 80 | 81 | it('should handle customFields with empty values', async () => { 82 | const mockRequestOptions: IHttpRequestOptions = { 83 | body: { 84 | customFields: { 85 | values: [], 86 | }, 87 | } as IDataObject, 88 | url: '', 89 | }; 90 | 91 | const result = await addCustomFieldsPreSendAction.call( 92 | mockThis as IExecuteSingleFunctions, 93 | mockRequestOptions, 94 | ); 95 | 96 | expect((result.body as IDataObject).customFields).toEqual([]); 97 | }); 98 | }); 99 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/contact/get.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "additionalPhones": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "phone": { 10 | "type": "string" 11 | }, 12 | "phoneLabel": { 13 | "type": "string" 14 | } 15 | } 16 | } 17 | }, 18 | "attributionSource": { 19 | "type": "object", 20 | "properties": { 21 | "medium": { 22 | "type": "string" 23 | }, 24 | "sessionSource": { 25 | "type": "string" 26 | } 27 | } 28 | }, 29 | "country": { 30 | "type": "string" 31 | }, 32 | "createdBy": { 33 | "type": "object", 34 | "properties": { 35 | "channel": { 36 | "type": "string" 37 | }, 38 | "source": { 39 | "type": "string" 40 | }, 41 | "sourceId": { 42 | "type": "string" 43 | }, 44 | "timestamp": { 45 | "type": "string" 46 | } 47 | } 48 | }, 49 | "customFields": { 50 | "type": "array", 51 | "items": { 52 | "type": "object", 53 | "properties": { 54 | "id": { 55 | "type": "string" 56 | } 57 | } 58 | } 59 | }, 60 | "dateAdded": { 61 | "type": "string" 62 | }, 63 | "dateUpdated": { 64 | "type": "string" 65 | }, 66 | "email": { 67 | "type": "string" 68 | }, 69 | "emailLowerCase": { 70 | "type": "string" 71 | }, 72 | "firstName": { 73 | "type": "string" 74 | }, 75 | "firstNameLowerCase": { 76 | "type": "string" 77 | }, 78 | "fullNameLowerCase": { 79 | "type": "string" 80 | }, 81 | "id": { 82 | "type": "string" 83 | }, 84 | "lastName": { 85 | "type": "string" 86 | }, 87 | "lastNameLowerCase": { 88 | "type": "string" 89 | }, 90 | "locationId": { 91 | "type": "string" 92 | }, 93 | "phone": { 94 | "type": "string" 95 | }, 96 | "tags": { 97 | "type": "array", 98 | "items": { 99 | "type": "string" 100 | } 101 | }, 102 | "type": { 103 | "type": "string" 104 | } 105 | }, 106 | "version": 1 107 | } 108 | -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/CalendarGroupOperations.test.ts: -------------------------------------------------------------------------------- 1 | // Mock data for Calendar Group operations testing 2 | 3 | // Mock functions for calendar group operations testing 4 | export const mockCalendarGroupResponse = { 5 | group: { 6 | id: 'group_123', 7 | name: 'Test Calendar Group', 8 | slug: 'test-calendar-group', 9 | description: 'A test calendar group for development', 10 | locationId: 'location_456', 11 | calendarIds: ['calendar_1', 'calendar_2', 'calendar_3'], 12 | isActive: true, 13 | teamId: 'team_789', 14 | createdAt: '2023-01-01T00:00:00.000Z', 15 | updatedAt: '2023-01-01T00:00:00.000Z', 16 | }, 17 | }; 18 | 19 | export const mockCalendarGroupsResponse = { 20 | groups: [ 21 | { 22 | id: 'group_123', 23 | name: 'Test Calendar Group', 24 | slug: 'test-calendar-group', 25 | description: 'A test calendar group for development', 26 | locationId: 'location_456', 27 | calendarIds: ['calendar_1', 'calendar_2'], 28 | isActive: true, 29 | teamId: 'team_789', 30 | createdAt: '2023-01-01T00:00:00.000Z', 31 | updatedAt: '2023-01-01T00:00:00.000Z', 32 | }, 33 | { 34 | id: 'group_456', 35 | name: 'Another Calendar Group', 36 | slug: 'another-calendar-group', 37 | description: 'Another test calendar group', 38 | locationId: 'location_456', 39 | calendarIds: ['calendar_3', 'calendar_4'], 40 | isActive: false, 41 | teamId: 'team_789', 42 | createdAt: '2023-01-02T00:00:00.000Z', 43 | updatedAt: '2023-01-02T00:00:00.000Z', 44 | }, 45 | ], 46 | total: 2, 47 | count: 2, 48 | }; 49 | 50 | export const mockCalendarGroupDeleteResponse = { 51 | success: true, 52 | message: 'Calendar group deleted successfully', 53 | }; 54 | 55 | export const mockCalendarGroupValidateResponse = { 56 | isValid: true, 57 | slug: 'test-calendar-group', 58 | message: 'Slug is available', 59 | suggestions: [], 60 | }; 61 | 62 | export const mockCalendarGroupValidateInvalidResponse = { 63 | isValid: false, 64 | slug: 'existing-group', 65 | message: 'Slug already exists', 66 | suggestions: ['existing-group-1', 'existing-group-2', 'existing-group-new'], 67 | }; 68 | 69 | // Test data for calendar group operations 70 | export const testCalendarGroupData = { 71 | create: { 72 | name: 'Test Calendar Group', 73 | slug: 'test-calendar-group', 74 | additionalFields: { 75 | description: 'A test calendar group for development', 76 | calendarIds: ['calendar_1', 'calendar_2'], 77 | isActive: true, 78 | teamId: 'team_789', 79 | }, 80 | }, 81 | update: { 82 | groupId: 'group_123', 83 | updateFields: { 84 | name: 'Updated Calendar Group', 85 | description: 'Updated description', 86 | isActive: false, 87 | }, 88 | }, 89 | delete: { 90 | groupId: 'group_123', 91 | }, 92 | disable: { 93 | groupId: 'group_123', 94 | }, 95 | validateSlug: { 96 | slug: 'test-calendar-group', 97 | }, 98 | getAll: { 99 | returnAll: false, 100 | limit: 10, 101 | additionalFields: { 102 | search: 'test', 103 | }, 104 | }, 105 | }; -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/CalendarResourceOperations.test.ts: -------------------------------------------------------------------------------- 1 | // Mock response data for calendar resource operations 2 | export const calendarResourceOperationsMockData = { 3 | create: { 4 | resource: { 5 | id: "resource_6669e4c3a0b142cc43a00e97", 6 | name: "Conference Room A", 7 | description: "Large conference room with projector and video conferencing capabilities", 8 | type: "room", 9 | quantity: 1, 10 | isActive: true, 11 | locationId: "location_123456789", 12 | createdAt: "2024-06-12T12:14:43.159Z", 13 | updatedAt: "2024-06-12T12:14:43.159Z" 14 | } 15 | }, 16 | get: { 17 | resource: { 18 | id: "resource_6669e4c3a0b142cc43a00e97", 19 | name: "Conference Room A", 20 | description: "Large conference room with projector and video conferencing capabilities", 21 | type: "room", 22 | quantity: 1, 23 | isActive: true, 24 | locationId: "location_123456789", 25 | createdAt: "2024-06-12T12:14:43.159Z", 26 | updatedAt: "2024-06-12T12:14:43.159Z" 27 | } 28 | }, 29 | update: { 30 | resource: { 31 | id: "resource_6669e4c3a0b142cc43a00e97", 32 | name: "Conference Room A - Updated", 33 | description: "Large conference room with projector and video conferencing capabilities - Updated description", 34 | type: "room", 35 | quantity: 2, 36 | isActive: true, 37 | locationId: "location_123456789", 38 | createdAt: "2024-06-12T12:14:43.159Z", 39 | updatedAt: "2024-06-12T12:20:15.242Z" 40 | } 41 | }, 42 | getAll: { 43 | resources: [ 44 | { 45 | id: "resource_6669e4c3a0b142cc43a00e97", 46 | name: "Conference Room A", 47 | description: "Large conference room with projector and video conferencing capabilities", 48 | type: "room", 49 | quantity: 1, 50 | isActive: true, 51 | locationId: "location_123456789", 52 | createdAt: "2024-06-12T12:14:43.159Z", 53 | updatedAt: "2024-06-12T12:14:43.159Z" 54 | }, 55 | { 56 | id: "resource_6669e4c3a0b142cc43a00e98", 57 | name: "Laptop - Dell XPS 15", 58 | description: "High-performance laptop for presentations and meetings", 59 | type: "equipment", 60 | quantity: 3, 61 | isActive: true, 62 | locationId: "location_123456789", 63 | createdAt: "2024-06-12T10:30:12.455Z", 64 | updatedAt: "2024-06-12T10:30:12.455Z" 65 | }, 66 | { 67 | id: "resource_6669e4c3a0b142cc43a00e99", 68 | name: "Meeting Room B", 69 | description: "Small meeting room perfect for team discussions", 70 | type: "room", 71 | quantity: 1, 72 | isActive: false, 73 | locationId: "location_123456789", 74 | createdAt: "2024-06-12T09:15:30.123Z", 75 | updatedAt: "2024-06-12T14:45:22.789Z" 76 | } 77 | ], 78 | meta: { 79 | total: 3, 80 | currentPage: 1, 81 | nextPage: null, 82 | prevPage: null, 83 | limit: 20 84 | } 85 | }, 86 | delete: { 87 | success: true, 88 | message: "Calendar resource deleted successfully" 89 | } 90 | }; -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/objectAssociations/getAllRelationsByRecordId.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "relations": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "id": { 10 | "type": "string", 11 | "description": "Unique identifier for the relation" 12 | }, 13 | "associationId": { 14 | "type": "string", 15 | "description": "ID of the association this relation belongs to" 16 | }, 17 | "fromObjectId": { 18 | "type": "string", 19 | "description": "ID of the source object" 20 | }, 21 | "toObjectId": { 22 | "type": "string", 23 | "description": "ID of the target object" 24 | }, 25 | "fromObjectType": { 26 | "type": "string", 27 | "description": "Type of the source object" 28 | }, 29 | "toObjectType": { 30 | "type": "string", 31 | "description": "Type of the target object" 32 | }, 33 | "metadata": { 34 | "type": "object", 35 | "description": "Additional metadata for the relation" 36 | }, 37 | "createdAt": { 38 | "type": "string", 39 | "format": "date-time", 40 | "description": "Timestamp when the relation was created" 41 | }, 42 | "updatedAt": { 43 | "type": "string", 44 | "format": "date-time", 45 | "description": "Timestamp when the relation was last updated" 46 | } 47 | } 48 | }, 49 | "description": "Array of relations matching the criteria" 50 | }, 51 | "meta": { 52 | "type": "object", 53 | "properties": { 54 | "total": { 55 | "type": "integer", 56 | "description": "Total number of relations" 57 | }, 58 | "currentPage": { 59 | "type": "integer", 60 | "description": "Current page number" 61 | }, 62 | "nextPage": { 63 | "type": "integer", 64 | "description": "Next page number" 65 | }, 66 | "prevPage": { 67 | "type": "integer", 68 | "description": "Previous page number" 69 | }, 70 | "totalPages": { 71 | "type": "integer", 72 | "description": "Total number of pages" 73 | } 74 | }, 75 | "description": "Pagination metadata" 76 | } 77 | }, 78 | "version": 1 79 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/customObjects/getAllObjects.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "objects": { 5 | "type": "array", 6 | "items": { 7 | "type": "object", 8 | "properties": { 9 | "id": { 10 | "type": "string", 11 | "description": "Unique identifier for the custom object" 12 | }, 13 | "locationId": { 14 | "type": "string", 15 | "description": "The location ID where the custom object belongs" 16 | }, 17 | "name": { 18 | "type": "string", 19 | "description": "Name of the custom object" 20 | }, 21 | "description": { 22 | "type": "string", 23 | "description": "Description of the custom object" 24 | }, 25 | "displayField": { 26 | "type": "string", 27 | "description": "Field to use as display name for records" 28 | }, 29 | "enableApiAccess": { 30 | "type": "boolean", 31 | "description": "Whether API access is enabled for this object" 32 | }, 33 | "recordCount": { 34 | "type": "integer", 35 | "description": "Total number of records in this custom object" 36 | }, 37 | "createdAt": { 38 | "type": "string", 39 | "format": "date-time", 40 | "description": "Timestamp when the custom object was created" 41 | }, 42 | "updatedAt": { 43 | "type": "string", 44 | "format": "date-time", 45 | "description": "Timestamp when the custom object was last updated" 46 | } 47 | } 48 | }, 49 | "description": "Array of custom object definitions" 50 | }, 51 | "meta": { 52 | "type": "object", 53 | "properties": { 54 | "total": { 55 | "type": "integer", 56 | "description": "Total number of custom objects" 57 | }, 58 | "currentPage": { 59 | "type": "integer", 60 | "description": "Current page number" 61 | }, 62 | "nextPage": { 63 | "type": "integer", 64 | "description": "Next page number" 65 | }, 66 | "prevPage": { 67 | "type": "integer", 68 | "description": "Previous page number" 69 | }, 70 | "totalPages": { 71 | "type": "integer", 72 | "description": "Total number of pages" 73 | } 74 | }, 75 | "description": "Pagination metadata" 76 | } 77 | }, 78 | "version": 1 79 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/socialPlanner/createPost.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "id": { 5 | "type": "string", 6 | "description": "Unique identifier for the created post" 7 | }, 8 | "locationId": { 9 | "type": "string", 10 | "description": "The location ID where the post was created" 11 | }, 12 | "content": { 13 | "type": "string", 14 | "description": "The content of the social media post" 15 | }, 16 | "socialAccounts": { 17 | "type": "array", 18 | "items": { 19 | "type": "string" 20 | }, 21 | "description": "List of social media platforms the post was created for" 22 | }, 23 | "mediaUrls": { 24 | "type": "array", 25 | "items": { 26 | "type": "string" 27 | }, 28 | "description": "List of media URLs attached to the post" 29 | }, 30 | "hashtags": { 31 | "type": "array", 32 | "items": { 33 | "type": "string" 34 | }, 35 | "description": "List of hashtags used in the post" 36 | }, 37 | "postType": { 38 | "type": "string", 39 | "enum": ["post", "story", "reel"], 40 | "description": "Type of social media post" 41 | }, 42 | "locationTag": { 43 | "type": "string", 44 | "description": "Location tag for the post" 45 | }, 46 | "status": { 47 | "type": "string", 48 | "enum": ["draft", "scheduled", "published", "failed"], 49 | "description": "Current status of the post" 50 | }, 51 | "publishedAt": { 52 | "type": "string", 53 | "format": "date-time", 54 | "description": "Timestamp when the post was published" 55 | }, 56 | "createdAt": { 57 | "type": "string", 58 | "format": "date-time", 59 | "description": "Timestamp when the post was created" 60 | }, 61 | "updatedAt": { 62 | "type": "string", 63 | "format": "date-time", 64 | "description": "Timestamp when the post was last updated" 65 | }, 66 | "analytics": { 67 | "type": "object", 68 | "properties": { 69 | "impressions": { 70 | "type": "number" 71 | }, 72 | "likes": { 73 | "type": "number" 74 | }, 75 | "shares": { 76 | "type": "number" 77 | }, 78 | "comments": { 79 | "type": "number" 80 | }, 81 | "clicks": { 82 | "type": "number" 83 | }, 84 | "reach": { 85 | "type": "number" 86 | }, 87 | "engagement": { 88 | "type": "number" 89 | } 90 | }, 91 | "description": "Analytics data for the post" 92 | } 93 | }, 94 | "required": ["id", "locationId", "content", "socialAccounts", "status"], 95 | "version": 1 96 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/conversation/sendMessage.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "message": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string", 9 | "description": "Unique identifier for the sent message" 10 | }, 11 | "conversationId": { 12 | "type": "string", 13 | "description": "Conversation ID this message belongs to" 14 | }, 15 | "locationId": { 16 | "type": "string", 17 | "description": "Location ID where the message was sent" 18 | }, 19 | "contactId": { 20 | "type": "string", 21 | "description": "Contact ID the message was sent to" 22 | }, 23 | "type": { 24 | "type": "string", 25 | "enum": ["SMS", "Email", "WhatsApp", "Phone", "Voicemail", "Chat", "Review", "Facebook", "Instagram"], 26 | "description": "Type of message sent" 27 | }, 28 | "direction": { 29 | "type": "string", 30 | "enum": ["outbound"], 31 | "description": "Direction of the message" 32 | }, 33 | "status": { 34 | "type": "string", 35 | "enum": ["sent", "pending", "scheduled", "failed"], 36 | "description": "Current status of the sent message" 37 | }, 38 | "body": { 39 | "type": "string", 40 | "description": "Message content that was sent" 41 | }, 42 | "subject": { 43 | "type": "string", 44 | "description": "Message subject (for emails)" 45 | }, 46 | "from": { 47 | "type": "string", 48 | "description": "Sender information" 49 | }, 50 | "to": { 51 | "type": "string", 52 | "description": "Recipient information" 53 | }, 54 | "scheduledDate": { 55 | "type": "string", 56 | "format": "date-time", 57 | "description": "Scheduled send date (if scheduled)" 58 | }, 59 | "sentAt": { 60 | "type": "string", 61 | "format": "date-time", 62 | "description": "When the message was sent" 63 | }, 64 | "createdAt": { 65 | "type": "string", 66 | "format": "date-time", 67 | "description": "Message creation timestamp" 68 | } 69 | }, 70 | "description": "Sent message details" 71 | }, 72 | "success": { 73 | "type": "boolean", 74 | "description": "Whether the message was sent successfully" 75 | }, 76 | "messageId": { 77 | "type": "string", 78 | "description": "ID of the sent message" 79 | } 80 | }, 81 | "version": 1 82 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/__schema__/v2.0.0/conversation/addInboundMessage.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "message": { 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "string", 9 | "description": "Unique identifier for the added inbound message" 10 | }, 11 | "conversationId": { 12 | "type": "string", 13 | "description": "Conversation ID this message was added to" 14 | }, 15 | "locationId": { 16 | "type": "string", 17 | "description": "Location ID where the message was received" 18 | }, 19 | "contactId": { 20 | "type": "string", 21 | "description": "Contact ID the message was received from" 22 | }, 23 | "type": { 24 | "type": "string", 25 | "enum": ["SMS", "Email", "WhatsApp", "Phone", "Voicemail", "Chat", "Review", "Facebook", "Instagram"], 26 | "description": "Type of inbound message" 27 | }, 28 | "direction": { 29 | "type": "string", 30 | "enum": ["inbound"], 31 | "description": "Direction of the message" 32 | }, 33 | "status": { 34 | "type": "string", 35 | "enum": ["received", "processed"], 36 | "description": "Status of the inbound message" 37 | }, 38 | "body": { 39 | "type": "string", 40 | "description": "Inbound message content" 41 | }, 42 | "subject": { 43 | "type": "string", 44 | "description": "Message subject (for emails)" 45 | }, 46 | "from": { 47 | "type": "string", 48 | "description": "Sender information" 49 | }, 50 | "to": { 51 | "type": "string", 52 | "description": "Recipient information" 53 | }, 54 | "metadata": { 55 | "type": "object", 56 | "description": "Additional message metadata" 57 | }, 58 | "receivedAt": { 59 | "type": "string", 60 | "format": "date-time", 61 | "description": "When the message was received" 62 | }, 63 | "createdAt": { 64 | "type": "string", 65 | "format": "date-time", 66 | "description": "Message creation timestamp" 67 | } 68 | }, 69 | "description": "Added inbound message details" 70 | }, 71 | "success": { 72 | "type": "boolean", 73 | "description": "Whether the inbound message was added successfully" 74 | }, 75 | "conversationUpdated": { 76 | "type": "boolean", 77 | "description": "Whether the conversation was updated with this message" 78 | } 79 | }, 80 | "version": 1 81 | } -------------------------------------------------------------------------------- /nodes/HighLevelV2/v2/test/HighLevelApiPagination.test.ts: -------------------------------------------------------------------------------- 1 | import type { IExecutePaginationFunctions } from 'n8n-workflow'; 2 | 3 | import { highLevelApiPagination } from '../GenericFunctions'; 4 | 5 | describe('highLevelApiPagination', () => { 6 | let mockContext: Partial; 7 | 8 | beforeEach(() => { 9 | mockContext = { 10 | getNodeParameter: jest.fn(), 11 | makeRoutingRequest: jest.fn(), 12 | }; 13 | }); 14 | 15 | it('should paginate and return all items when returnAll is true', async () => { 16 | (mockContext.getNodeParameter as jest.Mock).mockImplementation((parameter) => { 17 | if (parameter === 'resource') return 'contact'; 18 | if (parameter === 'returnAll') return true; 19 | return undefined; 20 | }); 21 | 22 | (mockContext.makeRoutingRequest as jest.Mock) 23 | .mockResolvedValueOnce([ 24 | { 25 | json: { 26 | contacts: [{ id: '1' }, { id: '2' }], 27 | meta: { startAfterId: '2', startAfter: 2, total: 4 }, 28 | }, 29 | }, 30 | ]) 31 | .mockResolvedValueOnce([ 32 | { 33 | json: { 34 | contacts: [{ id: '3' }, { id: '4' }], 35 | meta: { startAfterId: null, startAfter: null, total: 4 }, 36 | }, 37 | }, 38 | ]); 39 | 40 | const requestData = { options: { qs: {} } } as any; 41 | 42 | const result = await highLevelApiPagination.call( 43 | mockContext as IExecutePaginationFunctions, 44 | requestData, 45 | ); 46 | 47 | expect(result).toEqual([ 48 | { json: { id: '1' } }, 49 | { json: { id: '2' } }, 50 | { json: { id: '3' } }, 51 | { json: { id: '4' } }, 52 | ]); 53 | }); 54 | 55 | it('should return only the first page of items when returnAll is false', async () => { 56 | (mockContext.getNodeParameter as jest.Mock).mockImplementation((parameter) => { 57 | if (parameter === 'resource') return 'contact'; 58 | if (parameter === 'returnAll') return false; 59 | return undefined; 60 | }); 61 | 62 | (mockContext.makeRoutingRequest as jest.Mock).mockResolvedValueOnce([ 63 | { 64 | json: { 65 | contacts: [{ id: '1' }, { id: '2' }], 66 | meta: { startAfterId: '2', startAfter: 2, total: 4 }, 67 | }, 68 | }, 69 | ]); 70 | 71 | const requestData = { options: { qs: {} } } as any; 72 | 73 | const result = await highLevelApiPagination.call( 74 | mockContext as IExecutePaginationFunctions, 75 | requestData, 76 | ); 77 | 78 | expect(result).toEqual([{ json: { id: '1' } }, { json: { id: '2' } }]); 79 | }); 80 | 81 | it('should handle cases with no items', async () => { 82 | (mockContext.getNodeParameter as jest.Mock).mockImplementation((parameter) => { 83 | if (parameter === 'resource') return 'contact'; 84 | if (parameter === 'returnAll') return true; 85 | return undefined; 86 | }); 87 | 88 | (mockContext.makeRoutingRequest as jest.Mock).mockResolvedValueOnce([ 89 | { 90 | json: { 91 | contacts: [], 92 | meta: { startAfterId: null, startAfter: null, total: 0 }, 93 | }, 94 | }, 95 | ]); 96 | 97 | const requestData = { options: { qs: {} } } as any; 98 | 99 | const result = await highLevelApiPagination.call( 100 | mockContext as IExecutePaginationFunctions, 101 | requestData, 102 | ); 103 | 104 | expect(result).toEqual([]); 105 | }); 106 | }); 107 | --------------------------------------------------------------------------------