# nodes

node_type: n8n-nodes-base.HighLevel
name: HighLevel
display_name: Resource
description: Consume HighLevel API
category: transform
icon: file:highLevel.svg
code_hash: 325f12d22df387974941ce8e51c7dc1941ad49317ca47cd4916fde393a1635d0
documentation_url: https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.HighLevel
documentation_title: HighLevel node documentation
operations: []
api_methods: []
documentation_examples: []
templates: [{"name":"highlevel","description":"Templates for highlevel"}]
required_scopes: []
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
version: 1.0
extracted_at: 2025-06-09 15:18:08
updated_at: 2025-06-09 15:18:08
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HighLevel = void 0;
  const ContactDescription_1 = require("./description/ContactDescription");
  const OpportunityDescription_1 = require("./description/OpportunityDescription");
  const TaskDescription_1 = require("./description/TaskDescription");
  const GenericFunctions_1 = require("./GenericFunctions");
  const ressources = [
      {
          displayName: 'Resource',
          name: 'resource',
          type: 'options',
          noDataExpression: true,
          options: [
              {
                  name: 'Contact',
                  value: 'contact',
              },
              {
                  name: 'Opportunity',
                  value: 'opportunity',
              },
              {
                  name: 'Task',
                  value: 'task',
              },
          ],
          default: 'contact',
          required: true,
      },
  ];
  class HighLevel {
      constructor() {
          this.description = {
              displayName: 'HighLevel',
              name: 'highLevel',
              icon: 'file:highLevel.svg',
              group: ['transform'],
              version: 1,
              description: 'Consume HighLevel API',
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              defaults: {
                  name: 'HighLevel',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'highLevelApi',
                      required: true,
                  },
              ],
              requestDefaults: {
                  baseURL: 'https://rest.gohighlevel.com/v1',
                  headers: {
                      Accept: 'application/json',
                      'Content-Type': 'application/json',
                  },
              },
              requestOperations: {
                  pagination: GenericFunctions_1.highLevelApiPagination,
              },
              properties: [
                  ...ressources,
                  ...ContactDescription_1.contactOperations,
                  ...ContactDescription_1.contactNotes,
                  ...ContactDescription_1.contactFields,
                  ...OpportunityDescription_1.opportunityOperations,
                  ...OpportunityDescription_1.opportunityFields,
                  ...TaskDescription_1.taskOperations,
                  ...TaskDescription_1.taskFields,
              ],
          };
          this.methods = {
              loadOptions: {
                  getPipelineStages: GenericFunctions_1.getPipelineStages,
                  getUsers: GenericFunctions_1.getUsers,
                  getTimezones: GenericFunctions_1.getTimezones,
              },
          };
      }
  }
  exports.HighLevel = HighLevel;
  //# sourceMappingURL=HighLevel.node.js.map

credential_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HighLevelApi = void 0;
  class HighLevelApi {
      constructor() {
          this.name = 'highLevelApi';
          this.displayName = 'HighLevel API';
          this.documentationUrl = 'highLevel';
          this.properties = [
              {
                  displayName: 'API Key',
                  name: 'apiKey',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
              },
          ];
          this.authenticate = {
              type: 'generic',
              properties: {
                  headers: {
                      Authorization: '=Bearer {{$credentials.apiKey}}',
                  },
              },
          };
          this.test = {
              request: {
                  baseURL: 'https://rest.gohighlevel.com/v1',
                  url: '/custom-values/',
              },
          };
      }
  }
  exports.HighLevelApi = HighLevelApi;
  //# sourceMappingURL=HighLevelApi.credentials.js.map

  // --- Next Credential File ---

  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HighLevelApi = void 0;
  class HighLevelApi {
      constructor() {
          this.name = 'highLevelApi';
          this.displayName = 'HighLevel API';
          this.documentationUrl = 'highLevel';
          this.properties = [
              {
                  displayName: 'API Key',
                  name: 'apiKey',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
              },
          ];
          this.authenticate = {
              type: 'generic',
              properties: {
                  headers: {
                      Authorization: '=Bearer {{$credentials.apiKey}}',
                  },
              },
          };
          this.test = {
              request: {
                  baseURL: 'https://rest.gohighlevel.com/v1',
                  url: '/custom-values/',
              },
          };
      }
  }
  exports.HighLevelApi = HighLevelApi;
  //# sourceMappingURL=HighLevelApi.credentials.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: HighLevel node documentation
  description: Learn how to use the HighLevel node in n8n. Follow technical documentation to integrate HighLevel node into your workflows.
  contentType: [integration, reference]
  ---

  # HighLevel node

  Use the HighLevel node to automate work in HighLevel, and integrate HighLevel with other applications. n8n has built-in support for a wide range of HighLevel features, including creating, updating, deleting, and getting contacts, opportunities, and tasks, as well as booking appointments and getting free time slots in calendars. 

  On this page, you'll find a list of operations the HighLevel node supports and links to more resources.

  /// note | Credentials
  Refer to [HighLevel credentials](/integrations/builtin/credentials/highlevel.md) for guidance on setting up authentication. 
  ///

  ## Operations

  * Contact
  	* Create or update
  	* Delete
  	* Get
  	* Get many
  	* Update
  * Opportunity
  	* Create
  	* Delete
  	* Get
  	* Get many
  	* Update
  * Task
  	* Create
  	* Delete
  	* Get
  	* Get many
  	* Update
  * Calendar
  	* Book an appointment
  	* Get free slots

  ## Templates and examples

  <!-- see https://www.notion.so/n8n/Pull-in-templates-for-the-integrations-pages-37c716837b804d30a33b47475f6e3780 -->
  [[ templatesWidget(page.title, 'highlevel') ]]

  ## Related resources

  Refer to [HighLevel's API documentation and support forums](https://help.gohighlevel.com/support/solutions/articles/48001060529-highlevel-api){:target=_blank .external-link} for more information about the service.

  --8<-- "_snippets/integrations/builtin/app-nodes/operation-not-supported.md"

related_resources:
  [{"title":"HighLevel's API documentation and support forums","url":"https://help.gohighlevel.com/support/solutions/articles/48001060529-highlevel-api","type":"external"}]

example_workflow:
  {"name":"Resource Example Workflow","nodes":[{"parameters":{},"id":"2zvvmsxnx7hol7p17uymv9","name":"Resource","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.HomeAssistant
name: HomeAssistant
display_name: Home Assistant
description: Consume Home Assistant API
category: output
icon: file:homeAssistant.svg
code_hash: db530f5f43a4c0a938e63f71c6392dc711b44a2ecca9f17bc16c60b9b2d5896a
documentation_url: https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.HomeAssistant
documentation_title: Home Assistant node documentation
operations: []
api_methods: []
documentation_examples: []
templates: [{"name":"home-assistant","description":"Templates for home-assistant"}]
required_scopes: []
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
version: 1.0
extracted_at: 2025-06-09 15:18:08
updated_at: 2025-06-09 15:18:08
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HomeAssistant = void 0;
  const ConfigDescription_1 = require("./ConfigDescription");
  const ServiceDescription_1 = require("./ServiceDescription");
  const StateDescription_1 = require("./StateDescription");
  const EventDescription_1 = require("./EventDescription");
  const LogDescription_1 = require("./LogDescription");
  const TemplateDescription_1 = require("./TemplateDescription");
  const HistoryDescription_1 = require("./HistoryDescription");
  const CameraProxyDescription_1 = require("./CameraProxyDescription");
  const GenericFunctions_1 = require("./GenericFunctions");
  class HomeAssistant {
      constructor() {
          this.description = {
              displayName: 'Home Assistant',
              name: 'homeAssistant',
              icon: 'file:homeAssistant.svg',
              group: ['output'],
              version: 1,
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Consume Home Assistant API',
              defaults: {
                  name: 'Home Assistant',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'homeAssistantApi',
                      required: true,
                      testedBy: 'homeAssistantApiTest',
                  },
              ],
              properties: [
                  {
                      displayName: 'Resource',
                      name: 'resource',
                      type: 'options',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Camera Proxy',
                              value: 'cameraProxy',
                          },
                          {
                              name: 'Config',
                              value: 'config',
                          },
                          {
                              name: 'Event',
                              value: 'event',
                          },
                          {
                              name: 'Log',
                              value: 'log',
                          },
                          {
                              name: 'Service',
                              value: 'service',
                          },
                          {
                              name: 'State',
                              value: 'state',
                          },
                          {
                              name: 'Template',
                              value: 'template',
                          },
                      ],
                      default: 'config',
                  },
                  ...CameraProxyDescription_1.cameraProxyOperations,
                  ...CameraProxyDescription_1.cameraProxyFields,
                  ...ConfigDescription_1.configOperations,
                  ...EventDescription_1.eventOperations,
                  ...EventDescription_1.eventFields,
                  ...HistoryDescription_1.historyOperations,
                  ...HistoryDescription_1.historyFields,
                  ...LogDescription_1.logOperations,
                  ...LogDescription_1.logFields,
                  ...ServiceDescription_1.serviceOperations,
                  ...ServiceDescription_1.serviceFields,
                  ...StateDescription_1.stateOperations,
                  ...StateDescription_1.stateFields,
                  ...TemplateDescription_1.templateOperations,
                  ...TemplateDescription_1.templateFields,
              ],
          };
          this.methods = {
              credentialTest: {
                  async homeAssistantApiTest(credential) {
                      const credentials = credential.data;
                      const options = {
                          method: 'GET',
                          headers: {
                              Authorization: `Bearer ${credentials.accessToken}`,
                          },
                          uri: `${credentials.ssl === true ? 'https' : 'http'}://${credentials.host}:${credentials.port || '8123'}/api/`,
                          json: true,
                          timeout: 5000,
                      };
                      try {
                          const response = await this.helpers.request(options);
                          if (!response.message) {
                              return {
                                  status: 'Error',
                                  message: `Token is not valid: ${response.error}`,
                              };
                          }
                      }
                      catch (error) {
                          return {
                              status: 'Error',
                              message: `${error.statusCode === 401 ? 'Token is' : 'Settings are'} not valid: ${error}`,
                          };
                      }
                      return {
                          status: 'OK',
                          message: 'Authentication successful!',
                      };
                  },
              },
              loadOptions: {
                  async getAllEntities() {
                      return GenericFunctions_1.getHomeAssistantEntities.call(this);
                  },
                  async getCameraEntities() {
                      return GenericFunctions_1.getHomeAssistantEntities.call(this, 'camera');
                  },
                  async getDomains() {
                      return GenericFunctions_1.getHomeAssistantServices.call(this);
                  },
                  async getDomainServices() {
                      const currentDomain = this.getCurrentNodeParameter('domain');
                      if (currentDomain) {
                          return GenericFunctions_1.getHomeAssistantServices.call(this, currentDomain);
                      }
                      else {
                          return [];
                      }
                  },
              },
          };
      }
      async execute() {
          const items = this.getInputData();
          const returnData = [];
          const length = items.length;
          const resource = this.getNodeParameter('resource', 0);
          const operation = this.getNodeParameter('operation', 0);
          const qs = {};
          let responseData;
          for (let i = 0; i < length; i++) {
              try {
                  if (resource === 'config') {
                      if (operation === 'get') {
                          responseData = await GenericFunctions_1.homeAssistantApiRequest.call(this, 'GET', '/config');
                      }
                      else if (operation === 'check') {
                          responseData = await GenericFunctions_1.homeAssistantApiRequest.call(this, 'POST', '/config/core/check_config');
                      }
                  }
                  else if (resource === 'service') {
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', i);
                          responseData = (await GenericFunctions_1.homeAssistantApiRequest.call(this, 'GET', '/services'));
                          if (!returnAll) {
                              const limit = this.getNodeParameter('limit', i);
                              responseData = responseData.slice(0, limit);
                          }
                      }
                      else if (operation === 'call') {
                          const domain = this.getNodeParameter('domain', i);
                          const service = this.getNodeParameter('service', i);
                          const serviceAttributes = this.getNodeParameter('serviceAttributes', i);
                          const body = {};
                          if (Object.entries(serviceAttributes).length) {
                              if (serviceAttributes.attributes !== undefined) {
                                  serviceAttributes.attributes.map((attribute) => {
                                      body[attribute.name] = attribute.value;
                                  });
                              }
                          }
                          responseData = await GenericFunctions_1.homeAssistantApiRequest.call(this, 'POST', `/services/${domain}/${service}`, body);
                          if (Array.isArray(responseData) && responseData.length === 0) {
                              responseData = {};
                          }
                      }
                  }
                  else if (resource === 'state') {
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', i);
                          responseData = (await GenericFunctions_1.homeAssistantApiRequest.call(this, 'GET', '/states'));
                          if (!returnAll) {
                              const limit = this.getNodeParameter('limit', i);
                              responseData = responseData.slice(0, limit);
                          }
                      }
                      else if (operation === 'get') {
                          const entityId = this.getNodeParameter('entityId', i);
                          responseData = await GenericFunctions_1.homeAssistantApiRequest.call(this, 'GET', `/states/${entityId}`);
                      }
                      else if (operation === 'upsert') {
                          const entityId = this.getNodeParameter('entityId', i);
                          const state = this.getNodeParameter('state', i);
                          const stateAttributes = this.getNodeParameter('stateAttributes', i);
                          const body = {
                              state,
                              attributes: {},
                          };
                          if (Object.entries(stateAttributes).length) {
                              if (stateAttributes.attributes !== undefined) {
                                  stateAttributes.attributes.map((attribute) => {
                                      body.attributes[attribute.name] = attribute.value;
                                  });
                              }
                          }
                          responseData = await GenericFunctions_1.homeAssistantApiRequest.call(this, 'POST', `/states/${entityId}`, body);
                      }
                  }
                  else if (resource === 'event') {
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', i);
                          responseData = (await GenericFunctions_1.homeAssistantApiRequest.call(this, 'GET', '/events'));
                          if (!returnAll) {
                              const limit = this.getNodeParameter('limit', i);
                              responseData = responseData.slice(0, limit);
                          }
                      }
                      else if (operation === 'create') {
                          const eventType = this.getNodeParameter('eventType', i);
                          const eventAttributes = this.getNodeParameter('eventAttributes', i);
                          const body = {};
                          if (Object.entries(eventAttributes).length) {
                              if (eventAttributes.attributes !== undefined) {
                                  eventAttributes.attributes.map((attribute) => {
                                      body[attribute.name] = attribute.value;
                                  });
                              }
                          }
                          responseData = await GenericFunctions_1.homeAssistantApiRequest.call(this, 'POST', `/events/${eventType}`, body);
                      }
                  }
                  else if (resource === 'log') {
                      if (operation === 'getErroLogs') {
                          responseData = await GenericFunctions_1.homeAssistantApiRequest.call(this, 'GET', '/error_log');
                          if (responseData) {
                              responseData = {
                                  errorLog: responseData,
                              };
                          }
                      }
                      else if (operation === 'getLogbookEntries') {
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          let endpoint = '/logbook';
                          if (Object.entries(additionalFields).length) {
                              if (additionalFields.startTime) {
                                  endpoint = `/logbook/${additionalFields.startTime}`;
                              }
                              if (additionalFields.endTime) {
                                  qs.end_time = additionalFields.endTime;
                              }
                              if (additionalFields.entityId) {
                                  qs.entity = additionalFields.entityId;
                              }
                          }
                          responseData = await GenericFunctions_1.homeAssistantApiRequest.call(this, 'GET', endpoint, {}, qs);
                      }
                  }
                  else if (resource === 'template') {
                      if (operation === 'create') {
                          const body = {
                              template: this.getNodeParameter('template', i),
                          };
                          responseData = await GenericFunctions_1.homeAssistantApiRequest.call(this, 'POST', '/template', body);
                          if (responseData) {
                              responseData = { renderedTemplate: responseData };
                          }
                      }
                  }
                  else if (resource === 'history') {
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          let endpoint = '/history/period';
                          if (Object.entries(additionalFields).length) {
                              if (additionalFields.startTime) {
                                  endpoint = `/history/period/${additionalFields.startTime}`;
                              }
                              if (additionalFields.endTime) {
                                  qs.end_time = additionalFields.endTime;
                              }
                              if (additionalFields.entityIds) {
                                  qs.filter_entity_id = additionalFields.entityIds;
                              }
                              if (additionalFields.minimalResponse === true) {
                                  qs.minimal_response = additionalFields.minimalResponse;
                              }
                              if (additionalFields.significantChangesOnly === true) {
                                  qs.significant_changes_only = additionalFields.significantChangesOnly;
                              }
                          }
                          responseData = (await GenericFunctions_1.homeAssistantApiRequest.call(this, 'GET', endpoint, {}, qs));
                          if (!returnAll) {
                              const limit = this.getNodeParameter('limit', i);
                              responseData = responseData.slice(0, limit);
                          }
                      }
                  }
                  else if (resource === 'cameraProxy') {
                      if (operation === 'getScreenshot') {
                          const cameraEntityId = this.getNodeParameter('cameraEntityId', i);
                          const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i);
                          const endpoint = `/camera_proxy/${cameraEntityId}`;
                          let mimeType;
                          responseData = await GenericFunctions_1.homeAssistantApiRequest.call(this, 'GET', endpoint, {}, {}, undefined, {
                              encoding: null,
                              resolveWithFullResponse: true,
                          });
                          const newItem = {
                              json: items[i].json,
                              binary: {},
                          };
                          if (mimeType === undefined && responseData.headers['content-type']) {
                              mimeType = responseData.headers['content-type'];
                          }
                          if (items[i].binary !== undefined && newItem.binary) {
                              Object.assign(newItem.binary, items[i].binary);
                          }
                          items[i] = newItem;
                          const data = Buffer.from(responseData.body);
                          items[i].binary[dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data, 'screenshot.jpg', mimeType);
                      }
                  }
              }
              catch (error) {
                  if (this.continueOnFail()) {
                      if (resource === 'cameraProxy' && operation === 'get') {
                          items[i].json = { error: error.message };
                      }
                      else {
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ error: error.message }), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      continue;
                  }
                  throw error;
              }
              const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
              returnData.push(...executionData);
          }
          if (resource === 'cameraProxy' && operation === 'getScreenshot') {
              return [items];
          }
          else {
              return [returnData];
          }
      }
  }
  exports.HomeAssistant = HomeAssistant;
  //# sourceMappingURL=HomeAssistant.node.js.map

credential_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HomeAssistantApi = void 0;
  class HomeAssistantApi {
      constructor() {
          this.name = 'homeAssistantApi';
          this.displayName = 'Home Assistant API';
          this.documentationUrl = 'homeAssistant';
          this.properties = [
              {
                  displayName: 'Host',
                  name: 'host',
                  type: 'string',
                  default: '',
              },
              {
                  displayName: 'Port',
                  name: 'port',
                  type: 'number',
                  default: 8123,
              },
              {
                  displayName: 'SSL',
                  name: 'ssl',
                  type: 'boolean',
                  default: false,
              },
              {
                  displayName: 'Access Token',
                  name: 'accessToken',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
              },
          ];
      }
  }
  exports.HomeAssistantApi = HomeAssistantApi;
  //# sourceMappingURL=HomeAssistantApi.credentials.js.map

  // --- Next Credential File ---

  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HomeAssistantApi = void 0;
  class HomeAssistantApi {
      constructor() {
          this.name = 'homeAssistantApi';
          this.displayName = 'Home Assistant API';
          this.documentationUrl = 'homeAssistant';
          this.properties = [
              {
                  displayName: 'Host',
                  name: 'host',
                  type: 'string',
                  default: '',
              },
              {
                  displayName: 'Port',
                  name: 'port',
                  type: 'number',
                  default: 8123,
              },
              {
                  displayName: 'SSL',
                  name: 'ssl',
                  type: 'boolean',
                  default: false,
              },
              {
                  displayName: 'Access Token',
                  name: 'accessToken',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
              },
          ];
      }
  }
  exports.HomeAssistantApi = HomeAssistantApi;
  //# sourceMappingURL=HomeAssistantApi.credentials.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Home Assistant node documentation
  description: Learn how to use the Home Assistant node in n8n. Follow technical documentation to integrate Home Assistant node into your workflows.
  contentType: [integration, reference]
  priority: medium
  ---

  # Home Assistant node

  Use the Home Assistant node to automate work in Home Assistant, and integrate Home Assistant with other applications. n8n has built-in support for a wide range of Home Assistant features, including getting, creating, and checking camera proxies, configurations, logs, services, and templates. 

  On this page, you'll find a list of operations the Home Assistant node supports and links to more resources.

  /// note | Credentials
  Refer to [Home Assistant credentials](/integrations/builtin/credentials/homeassistant.md) for guidance on setting up authentication. 
  ///

  --8<-- "_snippets/integrations/builtin/app-nodes/ai-tools.md"

  ## Operations

  * Camera Proxy
      * Get the camera screenshot
  * Config
      * Get the configuration
      * Check the configuration
  * Event
      * Create an event
      * Get all events
  * Log
      * Get a log for a specific entity
      * Get all logs
  * Service
      * Call a service within a specific domain
      * Get all services
  * State
      * Create a new record, or update the current one if it already exists (upsert)
      * Get a state for a specific entity
      * Get all states
  * Template
      * Create a template

  ## Templates and examples

  <!-- see https://www.notion.so/n8n/Pull-in-templates-for-the-integrations-pages-37c716837b804d30a33b47475f6e3780 -->
  [[ templatesWidget(page.title, 'home-assistant') ]]

  ## Related resources

  Refer to [Home Assistant's documentation](https://developers.home-assistant.io/docs/api/rest/){:target=_blank .external-link} for more information about the service.

related_resources:
  [{"title":"Home Assistant's documentation","url":"https://developers.home-assistant.io/docs/api/rest/","type":"external"}]

example_workflow:
  {"name":"Home Assistant Example Workflow","nodes":[{"parameters":{},"id":"v8a79y0zagy4523y5z81","name":"Home Assistant","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.Grist
name: Grist
display_name: Grist
description: Consume the Grist API
category: input
icon: file:grist.svg
code_hash: e8f869266965538c4386d983c696a348cc0a78697e10318e33745fa5cc66ab9a
documentation_url: https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.Grist
documentation_title: Grist node documentation
operations: []
api_methods: []
documentation_examples: []
templates: [{"name":"grist","description":"Templates for grist"}]
related_resources: []
required_scopes: []
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
version: 1.0
extracted_at: 2025-06-09 15:18:08
updated_at: 2025-06-09 15:18:08
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Grist = void 0;
  const GenericFunctions_1 = require("./GenericFunctions");
  const OperationDescription_1 = require("./OperationDescription");
  class Grist {
      constructor() {
          this.description = {
              displayName: 'Grist',
              name: 'grist',
              icon: 'file:grist.svg',
              subtitle: '={{$parameter["operation"]}}',
              group: ['input'],
              version: 1,
              description: 'Consume the Grist API',
              defaults: {
                  name: 'Grist',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'gristApi',
                      required: true,
                      testedBy: 'gristApiTest',
                  },
              ],
              properties: OperationDescription_1.operationFields,
          };
          this.methods = {
              loadOptions: {
                  async getTableColumns() {
                      const docId = this.getNodeParameter('docId', 0);
                      const tableId = this.getNodeParameter('tableId', 0);
                      const endpoint = `/docs/${docId}/tables/${tableId}/columns`;
                      const { columns } = (await GenericFunctions_1.gristApiRequest.call(this, 'GET', endpoint));
                      return columns.map(({ id }) => ({ name: id, value: id }));
                  },
              },
              credentialTest: {
                  async gristApiTest(credential) {
                      const { apiKey, planType, customSubdomain, selfHostedUrl } = credential.data;
                      const endpoint = '/orgs';
                      const gristapiurl = planType === 'free'
                          ? `https://docs.getgrist.com/api${endpoint}`
                          : planType === 'paid'
                              ? `https://${customSubdomain}.getgrist.com/api${endpoint}`
                              : `${selfHostedUrl}/api${endpoint}`;
                      const options = {
                          headers: {
                              Authorization: `Bearer ${apiKey}`,
                          },
                          method: 'GET',
                          uri: gristapiurl,
                          qs: { limit: 1 },
                          json: true,
                      };
                      try {
                          await this.helpers.request(options);
                          return {
                              status: 'OK',
                              message: 'Authentication successful',
                          };
                      }
                      catch (error) {
                          return {
                              status: 'Error',
                              message: error.message,
                          };
                      }
                  },
              },
          };
      }
      async execute() {
          const items = this.getInputData();
          let responseData;
          const returnData = [];
          const operation = this.getNodeParameter('operation', 0);
          for (let i = 0; i < items.length; i++) {
              try {
                  if (operation === 'create') {
                      const body = { records: [] };
                      const dataToSend = this.getNodeParameter('dataToSend', 0);
                      if (dataToSend === 'autoMapInputs') {
                          const incomingKeys = Object.keys(items[i].json);
                          const rawInputsToIgnore = this.getNodeParameter('inputsToIgnore', i);
                          const inputsToIgnore = rawInputsToIgnore.split(',').map((c) => c.trim());
                          const fields = (0, GenericFunctions_1.parseAutoMappedInputs)(incomingKeys, inputsToIgnore, items[i].json);
                          body.records.push({ fields });
                      }
                      else if (dataToSend === 'defineInNode') {
                          const { properties } = this.getNodeParameter('fieldsToSend', i, []);
                          GenericFunctions_1.throwOnZeroDefinedFields.call(this, properties);
                          body.records.push({ fields: (0, GenericFunctions_1.parseDefinedFields)(properties) });
                      }
                      const docId = this.getNodeParameter('docId', 0);
                      const tableId = this.getNodeParameter('tableId', 0);
                      const endpoint = `/docs/${docId}/tables/${tableId}/records`;
                      responseData = await GenericFunctions_1.gristApiRequest.call(this, 'POST', endpoint, body);
                      responseData = {
                          id: responseData.records[0].id,
                          ...body.records[0].fields,
                      };
                  }
                  else if (operation === 'delete') {
                      const docId = this.getNodeParameter('docId', 0);
                      const tableId = this.getNodeParameter('tableId', 0);
                      const endpoint = `/docs/${docId}/tables/${tableId}/data/delete`;
                      const rawRowIds = this.getNodeParameter('rowId', i).toString();
                      const body = rawRowIds
                          .split(',')
                          .map((c) => c.trim())
                          .map(Number);
                      await GenericFunctions_1.gristApiRequest.call(this, 'POST', endpoint, body);
                      responseData = { success: true };
                  }
                  else if (operation === 'update') {
                      const body = { records: [] };
                      const rowId = this.getNodeParameter('rowId', i);
                      const dataToSend = this.getNodeParameter('dataToSend', 0);
                      if (dataToSend === 'autoMapInputs') {
                          const incomingKeys = Object.keys(items[i].json);
                          const rawInputsToIgnore = this.getNodeParameter('inputsToIgnore', i);
                          const inputsToIgnore = rawInputsToIgnore.split(',').map((c) => c.trim());
                          const fields = (0, GenericFunctions_1.parseAutoMappedInputs)(incomingKeys, inputsToIgnore, items[i].json);
                          body.records.push({ id: Number(rowId), fields });
                      }
                      else if (dataToSend === 'defineInNode') {
                          const { properties } = this.getNodeParameter('fieldsToSend', i, []);
                          GenericFunctions_1.throwOnZeroDefinedFields.call(this, properties);
                          const fields = (0, GenericFunctions_1.parseDefinedFields)(properties);
                          body.records.push({ id: Number(rowId), fields });
                      }
                      const docId = this.getNodeParameter('docId', 0);
                      const tableId = this.getNodeParameter('tableId', 0);
                      const endpoint = `/docs/${docId}/tables/${tableId}/records`;
                      await GenericFunctions_1.gristApiRequest.call(this, 'PATCH', endpoint, body);
                      responseData = {
                          id: rowId,
                          ...body.records[0].fields,
                      };
                  }
                  else if (operation === 'getAll') {
                      const docId = this.getNodeParameter('docId', 0);
                      const tableId = this.getNodeParameter('tableId', 0);
                      const endpoint = `/docs/${docId}/tables/${tableId}/records`;
                      const qs = {};
                      const returnAll = this.getNodeParameter('returnAll', i);
                      if (!returnAll) {
                          qs.limit = this.getNodeParameter('limit', i);
                      }
                      const { sort, filter } = this.getNodeParameter('additionalOptions', i);
                      if (sort === null || sort === void 0 ? void 0 : sort.sortProperties.length) {
                          qs.sort = (0, GenericFunctions_1.parseSortProperties)(sort.sortProperties);
                      }
                      if (filter === null || filter === void 0 ? void 0 : filter.filterProperties.length) {
                          const parsed = (0, GenericFunctions_1.parseFilterProperties)(filter.filterProperties);
                          qs.filter = JSON.stringify(parsed);
                      }
                      responseData = await GenericFunctions_1.gristApiRequest.call(this, 'GET', endpoint, {}, qs);
                      responseData = responseData.records.map((data) => {
                          return { id: data.id, ...data.fields };
                      });
                  }
              }
              catch (error) {
                  if (this.continueOnFail()) {
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ error: error.message }), { itemData: { item: i } });
                      returnData.push(...executionData);
                      continue;
                  }
                  throw error;
              }
              const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
              returnData.push(...executionData);
          }
          return [returnData];
      }
  }
  exports.Grist = Grist;
  //# sourceMappingURL=Grist.node.js.map

credential_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.GristApi = void 0;
  class GristApi {
      constructor() {
          this.name = 'gristApi';
          this.displayName = 'Grist API';
          this.documentationUrl = 'grist';
          this.properties = [
              {
                  displayName: 'API Key',
                  name: 'apiKey',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
                  required: true,
              },
              {
                  displayName: 'Plan Type',
                  name: 'planType',
                  type: 'options',
                  default: 'free',
                  options: [
                      {
                          name: 'Free',
                          value: 'free',
                      },
                      {
                          name: 'Paid',
                          value: 'paid',
                      },
                      {
                          name: 'Self-Hosted',
                          value: 'selfHosted',
                      },
                  ],
              },
              {
                  displayName: 'Custom Subdomain',
                  name: 'customSubdomain',
                  type: 'string',
                  default: '',
                  required: true,
                  description: 'Custom subdomain of your team',
                  displayOptions: {
                      show: {
                          planType: ['paid'],
                      },
                  },
              },
              {
                  displayName: 'Self-Hosted URL',
                  name: 'selfHostedUrl',
                  type: 'string',
                  default: '',
                  placeholder: 'http://localhost:8484',
                  required: true,
                  description: 'URL of your Grist instance. Include http/https without /api and no trailing slash.',
                  displayOptions: {
                      show: {
                          planType: ['selfHosted'],
                      },
                  },
              },
          ];
      }
  }
  exports.GristApi = GristApi;
  //# sourceMappingURL=GristApi.credentials.js.map

  // --- Next Credential File ---

  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.GristApi = void 0;
  class GristApi {
      constructor() {
          this.name = 'gristApi';
          this.displayName = 'Grist API';
          this.documentationUrl = 'grist';
          this.properties = [
              {
                  displayName: 'API Key',
                  name: 'apiKey',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
                  required: true,
              },
              {
                  displayName: 'Plan Type',
                  name: 'planType',
                  type: 'options',
                  default: 'free',
                  options: [
                      {
                          name: 'Free',
                          value: 'free',
                      },
                      {
                          name: 'Paid',
                          value: 'paid',
                      },
                      {
                          name: 'Self-Hosted',
                          value: 'selfHosted',
                      },
                  ],
              },
              {
                  displayName: 'Custom Subdomain',
                  name: 'customSubdomain',
                  type: 'string',
                  default: '',
                  required: true,
                  description: 'Custom subdomain of your team',
                  displayOptions: {
                      show: {
                          planType: ['paid'],
                      },
                  },
              },
              {
                  displayName: 'Self-Hosted URL',
                  name: 'selfHostedUrl',
                  type: 'string',
                  default: '',
                  placeholder: 'http://localhost:8484',
                  required: true,
                  description: 'URL of your Grist instance. Include http/https without /api and no trailing slash.',
                  displayOptions: {
                      show: {
                          planType: ['selfHosted'],
                      },
                  },
              },
          ];
      }
  }
  exports.GristApi = GristApi;
  //# sourceMappingURL=GristApi.credentials.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Grist node documentation
  description: Learn how to use the Grist node in n8n. Follow technical documentation to integrate Grist node into your workflows.
  contentType: [integration, reference]
  ---

  # Grist node

  Use the Grist node to automate work in Grist, and integrate Grist with other applications. n8n has built-in support for a wide range of Grist features, including creating, updating, deleting, and reading rows in a table. 

  On this page, you'll find a list of operations the Grist node supports and links to more resources.

  /// note | Credentials
  Refer to [Grist credentials](/integrations/builtin/credentials/grist.md) for guidance on setting up authentication. 
  ///

  ## Operations

  * Create rows in a table
  * Delete rows from a table
  * Read rows from a table
  * Update rows in a table

  ## Templates and examples

  <!-- see https://www.notion.so/n8n/Pull-in-templates-for-the-integrations-pages-37c716837b804d30a33b47475f6e3780 -->
  [[ templatesWidget(page.title, 'grist') ]]

  ## Get the Row ID

  To update or delete a particular record, you need the Row ID. There are two ways to get the Row ID:

  **Create a Row ID column in Grist**

  Create a new column in your Grist table with the formula `$id`.

  **Use the Get All operation**

  The **Get All** operation returns the Row ID of each record along with the fields.
   
  You can get it with the expression `{{$node["GristNodeName"].json["id"]}}`.


  ## Filter records when using the Get All operation

  - Select **Add Option** and select **Filter** from the dropdown list.
  - You can add filters for any number of columns. The result will only include records which match all the columns.
  - For each column, you can enter any number of values separated by commas. The result will include records which match any of the values for that column.

example_workflow:
  {"name":"Grist Example Workflow","nodes":[{"parameters":{},"id":"h9a70iygfmaef3xzesgzr9","name":"Grist","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.Harvest
name: Harvest
display_name: Harvest
description: Access data on Harvest
category: input
icon: file:harvest.png
code_hash: 9d20cceef719cdf7c26383c042364997d2be9dcd6083b1a6658b0fbc74462275
documentation_url: https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.Harvest
documentation_title: Harvest node documentation
operations: []
api_methods: []
documentation_examples: []
templates: [{"name":"harvest","description":"Templates for harvest"}]
related_resources: []
required_scopes: []
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
version: 1.0
extracted_at: 2025-06-09 15:18:08
updated_at: 2025-06-09 15:18:08
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Harvest = void 0;
  const n8n_workflow_1 = require("n8n-workflow");
  const ClientDescription_1 = require("./ClientDescription");
  const ContactDescription_1 = require("./ContactDescription");
  const CompanyDescription_1 = require("./CompanyDescription");
  const EstimateDescription_1 = require("./EstimateDescription");
  const ExpenseDescription_1 = require("./ExpenseDescription");
  const GenericFunctions_1 = require("./GenericFunctions");
  const InvoiceDescription_1 = require("./InvoiceDescription");
  const ProjectDescription_1 = require("./ProjectDescription");
  const TaskDescription_1 = require("./TaskDescription");
  const TimeEntryDescription_1 = require("./TimeEntryDescription");
  const UserDescription_1 = require("./UserDescription");
  class Harvest {
      constructor() {
          this.description = {
              displayName: 'Harvest',
              name: 'harvest',
              icon: 'file:harvest.png',
              group: ['input'],
              version: 1,
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Access data on Harvest',
              defaults: {
                  name: 'Harvest',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'harvestApi',
                      required: true,
                      displayOptions: {
                          show: {
                              authentication: ['accessToken'],
                          },
                      },
                  },
                  {
                      name: 'harvestOAuth2Api',
                      required: true,
                      displayOptions: {
                          show: {
                              authentication: ['oAuth2'],
                          },
                      },
                  },
              ],
              properties: [
                  {
                      displayName: 'Authentication',
                      name: 'authentication',
                      type: 'options',
                      options: [
                          {
                              name: 'Access Token',
                              value: 'accessToken',
                          },
                          {
                              name: 'OAuth2',
                              value: 'oAuth2',
                          },
                      ],
                      default: 'accessToken',
                  },
                  {
                      displayName: 'Resource',
                      name: 'resource',
                      type: 'options',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Client',
                              value: 'client',
                          },
                          {
                              name: 'Company',
                              value: 'company',
                          },
                          {
                              name: 'Contact',
                              value: 'contact',
                          },
                          {
                              name: 'Estimate',
                              value: 'estimate',
                          },
                          {
                              name: 'Expense',
                              value: 'expense',
                          },
                          {
                              name: 'Invoice',
                              value: 'invoice',
                          },
                          {
                              name: 'Project',
                              value: 'project',
                          },
                          {
                              name: 'Task',
                              value: 'task',
                          },
                          {
                              name: 'Time Entry',
                              value: 'timeEntry',
                          },
                          {
                              name: 'User',
                              value: 'user',
                          },
                      ],
                      default: 'task',
                  },
                  ...ClientDescription_1.clientOperations,
                  ...CompanyDescription_1.companyOperations,
                  ...ContactDescription_1.contactOperations,
                  ...EstimateDescription_1.estimateOperations,
                  ...ExpenseDescription_1.expenseOperations,
                  ...InvoiceDescription_1.invoiceOperations,
                  ...ProjectDescription_1.projectOperations,
                  ...TaskDescription_1.taskOperations,
                  ...TimeEntryDescription_1.timeEntryOperations,
                  ...UserDescription_1.userOperations,
                  {
                      displayName: 'Account Name or ID',
                      name: 'accountId',
                      type: 'options',
                      description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>',
                      required: true,
                      typeOptions: {
                          loadOptionsMethod: 'getAccounts',
                      },
                      default: '',
                  },
                  ...ClientDescription_1.clientFields,
                  ...ContactDescription_1.contactFields,
                  ...EstimateDescription_1.estimateFields,
                  ...ExpenseDescription_1.expenseFields,
                  ...InvoiceDescription_1.invoiceFields,
                  ...ProjectDescription_1.projectFields,
                  ...TaskDescription_1.taskFields,
                  ...TimeEntryDescription_1.timeEntryFields,
                  ...UserDescription_1.userFields,
              ],
          };
          this.methods = {
              loadOptions: {
                  async getAccounts() {
                      const returnData = [];
                      const { accounts } = await GenericFunctions_1.harvestApiRequest.call(this, 'GET', {}, '', {}, {}, 'https://id.getharvest.com/api/v2/accounts');
                      for (const account of accounts) {
                          const accountName = account.name;
                          const accountId = account.id;
                          returnData.push({
                              name: accountName,
                              value: accountId,
                          });
                      }
                      return returnData;
                  },
              },
          };
      }
      async execute() {
          const items = this.getInputData();
          const returnData = [];
          const resource = this.getNodeParameter('resource', 0);
          const operation = this.getNodeParameter('operation', 0);
          let endpoint = '';
          let requestMethod = '';
          let body;
          let qs;
          for (let i = 0; i < items.length; i++) {
              try {
                  body = {};
                  qs = {};
                  if (resource === 'timeEntry') {
                      if (operation === 'get') {
                          requestMethod = 'GET';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `time_entries/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'getAll') {
                          const responseData = await GenericFunctions_1.getAllResource.call(this, 'time_entries', i);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'createByStartEnd') {
                          requestMethod = 'POST';
                          endpoint = 'time_entries';
                          body.project_id = this.getNodeParameter('projectId', i);
                          body.task_id = this.getNodeParameter('taskId', i);
                          body.spent_date = this.getNodeParameter('spentDate', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          Object.assign(body, additionalFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'createByDuration') {
                          requestMethod = 'POST';
                          endpoint = 'time_entries';
                          body.project_id = this.getNodeParameter('projectId', i);
                          body.task_id = this.getNodeParameter('taskId', i);
                          body.spent_date = this.getNodeParameter('spentDate', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          Object.assign(body, additionalFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'delete') {
                          requestMethod = 'DELETE';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `time_entries/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'deleteExternal') {
                          requestMethod = 'DELETE';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `time_entries/${id}/external_reference`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'restartTime') {
                          requestMethod = 'PATCH';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `time_entries/${id}/restart`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'stopTime') {
                          requestMethod = 'PATCH';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `time_entries/${id}/stop`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'update') {
                          requestMethod = 'PATCH';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `time_entries/${id}`;
                          const updateFields = this.getNodeParameter('updateFields', i);
                          Object.assign(body, updateFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`, { itemIndex: i });
                      }
                  }
                  else if (resource === 'client') {
                      if (operation === 'get') {
                          requestMethod = 'GET';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `clients/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'getAll') {
                          const responseData = await GenericFunctions_1.getAllResource.call(this, 'clients', i);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'create') {
                          requestMethod = 'POST';
                          endpoint = 'clients';
                          body.name = this.getNodeParameter('name', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          Object.assign(body, additionalFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'update') {
                          requestMethod = 'PATCH';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `clients/${id}`;
                          const updateFields = this.getNodeParameter('updateFields', i);
                          Object.assign(qs, updateFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'delete') {
                          requestMethod = 'DELETE';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `clients/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`, { itemIndex: i });
                      }
                  }
                  else if (resource === 'project') {
                      if (operation === 'get') {
                          requestMethod = 'GET';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `projects/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'getAll') {
                          const responseData = await GenericFunctions_1.getAllResource.call(this, 'projects', i);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'create') {
                          requestMethod = 'POST';
                          endpoint = 'projects';
                          body.client_id = this.getNodeParameter('clientId', i);
                          body.name = this.getNodeParameter('name', i);
                          body.is_billable = this.getNodeParameter('isBillable', i);
                          body.bill_by = this.getNodeParameter('billBy', i);
                          body.budget_by = this.getNodeParameter('budgetBy', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          Object.assign(body, additionalFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'update') {
                          requestMethod = 'PATCH';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `projects/${id}`;
                          const updateFields = this.getNodeParameter('updateFields', i);
                          Object.assign(body, updateFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'delete') {
                          requestMethod = 'DELETE';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `projects/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`, { itemIndex: i });
                      }
                  }
                  else if (resource === 'user') {
                      if (operation === 'get') {
                          requestMethod = 'GET';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `users/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'getAll') {
                          const responseData = await GenericFunctions_1.getAllResource.call(this, 'users', i);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'me') {
                          requestMethod = 'GET';
                          endpoint = 'users/me';
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'create') {
                          requestMethod = 'POST';
                          endpoint = 'users';
                          body.first_name = this.getNodeParameter('firstName', i);
                          body.last_name = this.getNodeParameter('lastName', i);
                          body.email = this.getNodeParameter('email', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          Object.assign(body, additionalFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'update') {
                          requestMethod = 'PATCH';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `users/${id}`;
                          const updateFields = this.getNodeParameter('updateFields', i);
                          Object.assign(qs, updateFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'delete') {
                          requestMethod = 'DELETE';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `users/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`, { itemIndex: i });
                      }
                  }
                  else if (resource === 'contact') {
                      if (operation === 'get') {
                          requestMethod = 'GET';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `contacts/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'getAll') {
                          const responseData = await GenericFunctions_1.getAllResource.call(this, 'contacts', i);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'create') {
                          requestMethod = 'POST';
                          endpoint = 'contacts';
                          body.client_id = this.getNodeParameter('clientId', i);
                          body.first_name = this.getNodeParameter('firstName', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          Object.assign(body, additionalFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'update') {
                          requestMethod = 'PATCH';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `contacts/${id}`;
                          const updateFields = this.getNodeParameter('updateFields', i);
                          Object.assign(qs, updateFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'delete') {
                          requestMethod = 'DELETE';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `contacts/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`, { itemIndex: i });
                      }
                  }
                  else if (resource === 'company') {
                      if (operation === 'get') {
                          requestMethod = 'GET';
                          endpoint = 'company';
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`, { itemIndex: i });
                      }
                  }
                  else if (resource === 'task') {
                      if (operation === 'get') {
                          requestMethod = 'GET';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `tasks/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'getAll') {
                          const responseData = await GenericFunctions_1.getAllResource.call(this, 'tasks', i);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'create') {
                          requestMethod = 'POST';
                          endpoint = 'tasks';
                          body.name = this.getNodeParameter('name', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          Object.assign(body, additionalFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'update') {
                          requestMethod = 'PATCH';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `tasks/${id}`;
                          const updateFields = this.getNodeParameter('updateFields', i);
                          Object.assign(qs, updateFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'delete') {
                          requestMethod = 'DELETE';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `tasks/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`, { itemIndex: i });
                      }
                  }
                  else if (resource === 'invoice') {
                      if (operation === 'get') {
                          requestMethod = 'GET';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `invoices/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'getAll') {
                          const responseData = await GenericFunctions_1.getAllResource.call(this, 'invoices', i);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'create') {
                          requestMethod = 'POST';
                          endpoint = 'invoices';
                          body.client_id = this.getNodeParameter('clientId', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          Object.assign(body, additionalFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'update') {
                          requestMethod = 'PATCH';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `invoices/${id}`;
                          const updateFields = this.getNodeParameter('updateFields', i);
                          Object.assign(qs, updateFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'delete') {
                          requestMethod = 'DELETE';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `invoices/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`, { itemIndex: i });
                      }
                  }
                  else if (resource === 'expense') {
                      if (operation === 'get') {
                          requestMethod = 'GET';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `expenses/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'getAll') {
                          const responseData = await GenericFunctions_1.getAllResource.call(this, 'expenses', i);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'create') {
                          requestMethod = 'POST';
                          endpoint = 'expenses';
                          body.project_id = this.getNodeParameter('projectId', i);
                          body.expense_category_id = this.getNodeParameter('expenseCategoryId', i);
                          body.spent_date = this.getNodeParameter('spentDate', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          Object.assign(body, additionalFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'update') {
                          requestMethod = 'PATCH';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `expenses/${id}`;
                          const updateFields = this.getNodeParameter('updateFields', i);
                          Object.assign(qs, updateFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'delete') {
                          requestMethod = 'DELETE';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `expenses/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`, { itemIndex: i });
                      }
                  }
                  else if (resource === 'estimate') {
                      if (operation === 'get') {
                          requestMethod = 'GET';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `estimates/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'getAll') {
                          const responseData = await GenericFunctions_1.getAllResource.call(this, 'estimates', i);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'create') {
                          requestMethod = 'POST';
                          endpoint = 'estimates';
                          body.client_id = this.getNodeParameter('clientId', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          Object.assign(body, additionalFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'update') {
                          requestMethod = 'PATCH';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `estimates/${id}`;
                          const updateFields = this.getNodeParameter('updateFields', i);
                          Object.assign(qs, updateFields);
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else if (operation === 'delete') {
                          requestMethod = 'DELETE';
                          const id = this.getNodeParameter('id', i);
                          endpoint = `estimates/${id}`;
                          const responseData = await GenericFunctions_1.harvestApiRequest.call(this, requestMethod, qs, endpoint);
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`, { itemIndex: i });
                      }
                  }
                  else {
                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`, {
                          itemIndex: i,
                      });
                  }
              }
              catch (error) {
                  if (this.continueOnFail()) {
                      const executionErrorData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ error: error.message }), { itemData: { item: i } });
                      returnData.push(...executionErrorData);
                      continue;
                  }
                  throw error;
              }
          }
          return [returnData];
      }
  }
  exports.Harvest = Harvest;
  //# sourceMappingURL=Harvest.node.js.map

credential_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HarvestApi = void 0;
  class HarvestApi {
      constructor() {
          this.name = 'harvestApi';
          this.displayName = 'Harvest API';
          this.documentationUrl = 'harvest';
          this.properties = [
              {
                  displayName: 'Access Token',
                  name: 'accessToken',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
                  description: 'Visit your account details page, and grab the Access Token. See <a href="https://help.getharvest.com/api-v2/authentication-api/authentication/authentication/">Harvest Personal Access Tokens</a>.',
              },
          ];
      }
  }
  exports.HarvestApi = HarvestApi;
  //# sourceMappingURL=HarvestApi.credentials.js.map

  // --- Next Credential File ---

  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HarvestOAuth2Api = void 0;
  class HarvestOAuth2Api {
      constructor() {
          this.name = 'harvestOAuth2Api';
          this.extends = ['oAuth2Api'];
          this.displayName = 'Harvest OAuth2 API';
          this.documentationUrl = 'harvest';
          this.properties = [
              {
                  displayName: 'Grant Type',
                  name: 'grantType',
                  type: 'hidden',
                  default: 'authorizationCode',
              },
              {
                  displayName: 'Authorization URL',
                  name: 'authUrl',
                  type: 'hidden',
                  default: 'https://id.getharvest.com/oauth2/authorize',
                  required: true,
              },
              {
                  displayName: 'Access Token URL',
                  name: 'accessTokenUrl',
                  type: 'hidden',
                  default: 'https://id.getharvest.com/api/v2/oauth2/token',
                  required: true,
              },
              {
                  displayName: 'Scope',
                  name: 'scope',
                  type: 'hidden',
                  default: 'all',
              },
              {
                  displayName: 'Auth URI Query Parameters',
                  name: 'authQueryParameters',
                  type: 'hidden',
                  default: '',
              },
              {
                  displayName: 'Authentication',
                  name: 'authentication',
                  type: 'hidden',
                  default: 'body',
              },
          ];
      }
  }
  exports.HarvestOAuth2Api = HarvestOAuth2Api;
  //# sourceMappingURL=HarvestOAuth2Api.credentials.js.map

  // --- Next Credential File ---

  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HarvestApi = void 0;
  class HarvestApi {
      constructor() {
          this.name = 'harvestApi';
          this.displayName = 'Harvest API';
          this.documentationUrl = 'harvest';
          this.properties = [
              {
                  displayName: 'Access Token',
                  name: 'accessToken',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
                  description: 'Visit your account details page, and grab the Access Token. See <a href="https://help.getharvest.com/api-v2/authentication-api/authentication/authentication/">Harvest Personal Access Tokens</a>.',
              },
          ];
      }
  }
  exports.HarvestApi = HarvestApi;
  //# sourceMappingURL=HarvestApi.credentials.js.map

  // --- Next Credential File ---

  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HarvestOAuth2Api = void 0;
  class HarvestOAuth2Api {
      constructor() {
          this.name = 'harvestOAuth2Api';
          this.extends = ['oAuth2Api'];
          this.displayName = 'Harvest OAuth2 API';
          this.documentationUrl = 'harvest';
          this.properties = [
              {
                  displayName: 'Grant Type',
                  name: 'grantType',
                  type: 'hidden',
                  default: 'authorizationCode',
              },
              {
                  displayName: 'Authorization URL',
                  name: 'authUrl',
                  type: 'hidden',
                  default: 'https://id.getharvest.com/oauth2/authorize',
                  required: true,
              },
              {
                  displayName: 'Access Token URL',
                  name: 'accessTokenUrl',
                  type: 'hidden',
                  default: 'https://id.getharvest.com/api/v2/oauth2/token',
                  required: true,
              },
              {
                  displayName: 'Scope',
                  name: 'scope',
                  type: 'hidden',
                  default: 'all',
              },
              {
                  displayName: 'Auth URI Query Parameters',
                  name: 'authQueryParameters',
                  type: 'hidden',
                  default: '',
              },
              {
                  displayName: 'Authentication',
                  name: 'authentication',
                  type: 'hidden',
                  default: 'body',
              },
          ];
      }
  }
  exports.HarvestOAuth2Api = HarvestOAuth2Api;
  //# sourceMappingURL=HarvestOAuth2Api.credentials.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Harvest node documentation
  description: Learn how to use the Harvest node in n8n. Follow technical documentation to integrate Harvest node into your workflows.
  contentType: [integration, reference]
  ---

  # Harvest node

  Use the Harvest node to automate work in Harvest, and integrate Harvest with other applications. n8n has built-in support for a wide range of Harvest features, including creating, updating, deleting, and getting clients, contacts, invoices, tasks, expenses, users, and projects. 

  On this page, you'll find a list of operations the Harvest node supports and links to more resources.

  /// note | Credentials
  Refer to [Harvest credentials](/integrations/builtin/credentials/harvest.md) for guidance on setting up authentication. 
  ///

  ## Operations

  * Client
      * Create a client
      * Delete a client
      * Get data of a client
      * Get data of all clients
      * Update a client
  * Company
      * Retrieves the company for the currently authenticated user
  * Contact
      * Create a contact
      * Delete a contact
      * Get data of a contact
      * Get data of all contacts
      * Update a contact
  * Estimate
      * Create an estimate
      * Delete an estimate
      * Get data of an estimate
      * Get data of all estimates
      * Update an estimate
  * Expense
      * Get data of an expense
      * Get data of all expenses
      * Create an expense
      * Update an expense
      * Delete an expense
  * Invoice
      * Get data of an invoice
      * Get data of all invoices
      * Create an invoice
      * Update an invoice
      * Delete an invoice
  * Project
      * Create a project
      * Delete a project
      * Get data of a project
      * Get data of all projects
      * Update a project
  * Task
      * Create a task
      * Delete a task
      * Get data of a task
      * Get data of all tasks
      * Update a task
  * Time Entries
      * Create a time entry using duration
      * Create a time entry using start and end time
      * Delete a time entry
      * Delete a time entry's external reference.
      * Get data of a time entry
      * Get data of all time entries
      * Restart a time entry
      * Stop a time entry
      * Update a time entry
  * User
      * Create a user
      * Delete a user
      * Get data of a user
      * Get data of all users
      * Get data of authenticated user
      * Update a user

  ## Templates and examples

  <!-- see https://www.notion.so/n8n/Pull-in-templates-for-the-integrations-pages-37c716837b804d30a33b47475f6e3780 -->
  [[ templatesWidget(page.title, 'harvest') ]]

  --8<-- "_snippets/integrations/builtin/app-nodes/operation-not-supported.md"

example_workflow:
  {"name":"Harvest Example Workflow","nodes":[{"parameters":{},"id":"bbj6d16f5uaco132re02c","name":"Harvest","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.HelpScout
name: HelpScout
display_name: HelpScout
description: Consume HelpScout API
category: input
icon: file:helpScout.svg
code_hash: ed850f3e789d21697c107e859b43364714ce661c3158cea1742fa42285f570d5
documentation_url: https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.HelpScout
documentation_title: Help Scout node documentation
operations: []
api_methods: []
documentation_examples: []
templates: [{"name":"helpscout","description":"Templates for helpscout"}]
related_resources: []
required_scopes: []
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
version: 1.0
extracted_at: 2025-06-09 15:18:08
updated_at: 2025-06-09 15:18:08
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HelpScout = void 0;
  const n8n_workflow_1 = require("n8n-workflow");
  const CountriesCodes_1 = require("./CountriesCodes");
  const ConversationDescription_1 = require("./ConversationDescription");
  const CustomerDescription_1 = require("./CustomerDescription");
  const GenericFunctions_1 = require("./GenericFunctions");
  const MailboxDescription_1 = require("./MailboxDescription");
  const ThreadDescription_1 = require("./ThreadDescription");
  class HelpScout {
      constructor() {
          this.description = {
              displayName: 'HelpScout',
              name: 'helpScout',
              icon: 'file:helpScout.svg',
              group: ['input'],
              version: 1,
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Consume HelpScout API',
              defaults: {
                  name: 'HelpScout',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'helpScoutOAuth2Api',
                      required: true,
                  },
              ],
              properties: [
                  {
                      displayName: 'Resource',
                      name: 'resource',
                      type: 'options',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Conversation',
                              value: 'conversation',
                          },
                          {
                              name: 'Customer',
                              value: 'customer',
                          },
                          {
                              name: 'Mailbox',
                              value: 'mailbox',
                          },
                          {
                              name: 'Thread',
                              value: 'thread',
                          },
                      ],
                      default: 'conversation',
                  },
                  ...ConversationDescription_1.conversationOperations,
                  ...ConversationDescription_1.conversationFields,
                  ...CustomerDescription_1.customerOperations,
                  ...CustomerDescription_1.customerFields,
                  ...MailboxDescription_1.mailboxOperations,
                  ...MailboxDescription_1.mailboxFields,
                  ...ThreadDescription_1.threadOperations,
                  ...ThreadDescription_1.threadFields,
              ],
          };
          this.methods = {
              loadOptions: {
                  async getCountriesCodes() {
                      const returnData = [];
                      for (const countryCode of CountriesCodes_1.countriesCodes) {
                          const countryCodeName = `${countryCode.name} - ${countryCode.alpha2}`;
                          const countryCodeId = countryCode.alpha2;
                          returnData.push({
                              name: countryCodeName,
                              value: countryCodeId,
                          });
                      }
                      return returnData;
                  },
                  async getTags() {
                      const returnData = [];
                      const tags = await GenericFunctions_1.helpscoutApiRequestAllItems.call(this, '_embedded.tags', 'GET', '/v2/tags');
                      for (const tag of tags) {
                          const tagName = tag.name;
                          returnData.push({
                              name: tagName,
                              value: tagName,
                          });
                      }
                      return returnData;
                  },
                  async getMailboxes() {
                      const returnData = [];
                      const mailboxes = await GenericFunctions_1.helpscoutApiRequestAllItems.call(this, '_embedded.mailboxes', 'GET', '/v2/mailboxes');
                      for (const mailbox of mailboxes) {
                          const mailboxName = mailbox.name;
                          const mailboxId = mailbox.id;
                          returnData.push({
                              name: mailboxName,
                              value: mailboxId,
                          });
                      }
                      return returnData;
                  },
              },
          };
      }
      async execute() {
          var _a, _b;
          const items = this.getInputData();
          const returnData = [];
          const length = items.length;
          const qs = {};
          let responseData;
          const resource = this.getNodeParameter('resource', 0);
          const operation = this.getNodeParameter('operation', 0);
          for (let i = 0; i < length; i++) {
              try {
                  if (resource === 'conversation') {
                      if (operation === 'create') {
                          const mailboxId = this.getNodeParameter('mailboxId', i);
                          const status = this.getNodeParameter('status', i);
                          const subject = this.getNodeParameter('subject', i);
                          const type = this.getNodeParameter('type', i);
                          const resolveData = this.getNodeParameter('resolveData', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          const threads = this.getNodeParameter('threadsUi', i)
                              .threadsValues;
                          const body = {
                              mailboxId,
                              status,
                              subject,
                              type,
                          };
                          Object.assign(body, additionalFields);
                          if (additionalFields.customerId) {
                              body.customer = {
                                  id: additionalFields.customerId,
                              };
                              delete body.customerId;
                          }
                          if (additionalFields.customerEmail) {
                              body.customer = {
                                  email: additionalFields.customerEmail,
                              };
                              delete body.customerEmail;
                          }
                          if (body.customer === undefined) {
                              throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Either customer email or customer ID must be set', { itemIndex: i });
                          }
                          if (threads) {
                              for (let index = 0; index < threads.length; index++) {
                                  if (threads[index].type === '' || threads[index].text === '') {
                                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Chat Threads cannot be empty');
                                  }
                                  if (threads[index].type !== 'note') {
                                      threads[index].customer = body.customer;
                                  }
                              }
                              body.threads = threads;
                          }
                          responseData = await GenericFunctions_1.helpscoutApiRequest.call(this, 'POST', '/v2/conversations', body, qs, undefined, { resolveWithFullResponse: true });
                          const id = responseData.headers['resource-id'];
                          const uri = responseData.headers.location;
                          if (resolveData) {
                              responseData = await GenericFunctions_1.helpscoutApiRequest.call(this, 'GET', '', {}, {}, uri);
                          }
                          else {
                              responseData = {
                                  id,
                                  uri,
                              };
                          }
                      }
                      if (operation === 'delete') {
                          const conversationId = this.getNodeParameter('conversationId', i);
                          responseData = await GenericFunctions_1.helpscoutApiRequest.call(this, 'DELETE', `/v2/conversations/${conversationId}`);
                          responseData = { success: true };
                      }
                      if (operation === 'get') {
                          const conversationId = this.getNodeParameter('conversationId', i);
                          responseData = await GenericFunctions_1.helpscoutApiRequest.call(this, 'GET', `/v2/conversations/${conversationId}`);
                      }
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', i);
                          const options = this.getNodeParameter('options', i);
                          if (options.tags) {
                              qs.tag = options.tags.toString();
                          }
                          Object.assign(qs, options);
                          delete qs.tags;
                          if (returnAll) {
                              responseData = await GenericFunctions_1.helpscoutApiRequestAllItems.call(this, '_embedded.conversations', 'GET', '/v2/conversations', {}, qs);
                          }
                          else {
                              qs.limit = this.getNodeParameter('limit', i);
                              responseData = await GenericFunctions_1.helpscoutApiRequestAllItems.call(this, '_embedded.conversations', 'GET', '/v2/conversations', {}, qs);
                              responseData = responseData.splice(0, qs.limit);
                          }
                      }
                  }
                  if (resource === 'customer') {
                      if (operation === 'create') {
                          const resolveData = this.getNodeParameter('resolveData', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          const chats = this.getNodeParameter('chatsUi', i)
                              .chatsValues;
                          const address = this.getNodeParameter('addressUi', i)
                              .addressValue;
                          const emails = this.getNodeParameter('emailsUi', i)
                              .emailsValues;
                          const phones = this.getNodeParameter('phonesUi', i)
                              .phonesValues;
                          const socialProfiles = this.getNodeParameter('socialProfilesUi', i)
                              .socialProfilesValues;
                          const websites = this.getNodeParameter('websitesUi', i)
                              .websitesValues;
                          let body = {};
                          body = Object.assign({}, additionalFields);
                          if (body.age) {
                              body.age = body.age.toString();
                          }
                          if (chats) {
                              body.chats = chats;
                          }
                          if (address) {
                              body.address = address;
                              body.address.lines = [address.line1, address.line2];
                          }
                          if (emails) {
                              body.emails = emails;
                          }
                          if (phones) {
                              body.phones = phones;
                          }
                          if (socialProfiles) {
                              body.socialProfiles = socialProfiles;
                          }
                          if (websites) {
                              body.websites = websites;
                          }
                          if (Object.keys(body).length === 0) {
                              throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'You have to set at least one field', {
                                  itemIndex: i,
                              });
                          }
                          responseData = await GenericFunctions_1.helpscoutApiRequest.call(this, 'POST', '/v2/customers', body, qs, undefined, { resolveWithFullResponse: true });
                          const id = responseData.headers['resource-id'];
                          const uri = responseData.headers.location;
                          if (resolveData) {
                              responseData = await GenericFunctions_1.helpscoutApiRequest.call(this, 'GET', '', {}, {}, uri);
                          }
                          else {
                              responseData = {
                                  id,
                                  uri,
                              };
                          }
                      }
                      if (operation === 'properties') {
                          responseData = await GenericFunctions_1.helpscoutApiRequestAllItems.call(this, '_embedded.customer-properties', 'GET', '/v2/customer-properties', {}, qs);
                      }
                      if (operation === 'get') {
                          const customerId = this.getNodeParameter('customerId', i);
                          responseData = await GenericFunctions_1.helpscoutApiRequest.call(this, 'GET', `/v2/customers/${customerId}`);
                      }
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', i);
                          const options = this.getNodeParameter('options', i);
                          Object.assign(qs, options);
                          if (returnAll) {
                              responseData = await GenericFunctions_1.helpscoutApiRequestAllItems.call(this, '_embedded.customers', 'GET', '/v2/customers', {}, qs);
                          }
                          else {
                              qs.limit = this.getNodeParameter('limit', i);
                              responseData = await GenericFunctions_1.helpscoutApiRequestAllItems.call(this, '_embedded.customers', 'GET', '/v2/customers', {}, qs);
                              responseData = responseData.splice(0, qs.limit);
                          }
                      }
                      if (operation === 'update') {
                          const customerId = this.getNodeParameter('customerId', i);
                          const updateFields = this.getNodeParameter('updateFields', i);
                          let body = {};
                          body = Object.assign({}, updateFields);
                          if (body.age) {
                              body.age = body.age.toString();
                          }
                          if (Object.keys(body).length === 0) {
                              throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'You have to set at least one field', {
                                  itemIndex: i,
                              });
                          }
                          responseData = await GenericFunctions_1.helpscoutApiRequest.call(this, 'PUT', `/v2/customers/${customerId}`, body, qs, undefined, { resolveWithFullResponse: true });
                          responseData = { success: true };
                      }
                  }
                  if (resource === 'mailbox') {
                      if (operation === 'get') {
                          const mailboxId = this.getNodeParameter('mailboxId', i);
                          responseData = await GenericFunctions_1.helpscoutApiRequest.call(this, 'GET', `/v2/mailboxes/${mailboxId}`, {}, qs);
                      }
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', i);
                          if (returnAll) {
                              responseData = await GenericFunctions_1.helpscoutApiRequestAllItems.call(this, '_embedded.mailboxes', 'GET', '/v2/mailboxes', {}, qs);
                          }
                          else {
                              qs.limit = this.getNodeParameter('limit', i);
                              responseData = await GenericFunctions_1.helpscoutApiRequestAllItems.call(this, '_embedded.mailboxes', 'GET', '/v2/mailboxes', {}, qs);
                              responseData = responseData.splice(0, qs.limit);
                          }
                      }
                  }
                  if (resource === 'thread') {
                      if (operation === 'create') {
                          const conversationId = this.getNodeParameter('conversationId', i);
                          const text = this.getNodeParameter('text', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          const attachments = this.getNodeParameter('attachmentsUi', i);
                          const body = {
                              text,
                              attachments: [],
                          };
                          Object.assign(body, additionalFields);
                          if (additionalFields.customerId) {
                              body.customer = {
                                  id: additionalFields.customerId,
                              };
                              delete body.customerId;
                          }
                          if (additionalFields.customerEmail) {
                              body.customer = {
                                  email: additionalFields.customerEmail,
                              };
                              delete body.customerEmail;
                          }
                          if (body.customer === undefined) {
                              throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Either customer email or customer ID must be set', { itemIndex: i });
                          }
                          if (attachments) {
                              if (attachments.attachmentsValues &&
                                  attachments.attachmentsValues.length !== 0) {
                                  (_a = body.attachments) === null || _a === void 0 ? void 0 : _a.push.apply(body.attachments, attachments.attachmentsValues);
                              }
                              if (attachments.attachmentsBinary &&
                                  attachments.attachmentsBinary.length !== 0 &&
                                  items[i].binary) {
                                  const mapFunction = (value) => {
                                      const binaryProperty = items[i].binary[value.property];
                                      if (binaryProperty) {
                                          return {
                                              fileName: binaryProperty.fileName || 'unknown',
                                              data: binaryProperty.data,
                                              mimeType: binaryProperty.mimeType,
                                          };
                                      }
                                      else {
                                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Binary property ${value.property} does not exist on input`, { itemIndex: i });
                                      }
                                  };
                                  (_b = body.attachments) === null || _b === void 0 ? void 0 : _b.push.apply(body.attachments, attachments.attachmentsBinary.map(mapFunction));
                              }
                          }
                          responseData = await GenericFunctions_1.helpscoutApiRequest.call(this, 'POST', `/v2/conversations/${conversationId}/chats`, body);
                          responseData = { success: true };
                      }
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', i);
                          const conversationId = this.getNodeParameter('conversationId', i);
                          if (returnAll) {
                              responseData = await GenericFunctions_1.helpscoutApiRequestAllItems.call(this, '_embedded.threads', 'GET', `/v2/conversations/${conversationId}/threads`);
                          }
                          else {
                              qs.limit = this.getNodeParameter('limit', i);
                              responseData = await GenericFunctions_1.helpscoutApiRequestAllItems.call(this, '_embedded.threads', 'GET', `/v2/conversations/${conversationId}/threads`, {}, qs);
                              responseData = responseData.splice(0, qs.limit);
                          }
                      }
                  }
              }
              catch (error) {
                  if (this.continueOnFail()) {
                      const executionErrorData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ error: error.message }), { itemData: { item: i } });
                      returnData.push(...executionErrorData);
                      continue;
                  }
                  throw error;
              }
              const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
              returnData.push(...executionData);
          }
          return [returnData];
      }
  }
  exports.HelpScout = HelpScout;
  //# sourceMappingURL=HelpScout.node.js.map

credential_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HelpScoutOAuth2Api = void 0;
  class HelpScoutOAuth2Api {
      constructor() {
          this.name = 'helpScoutOAuth2Api';
          this.extends = ['oAuth2Api'];
          this.displayName = 'HelpScout OAuth2 API';
          this.documentationUrl = 'helpScout';
          this.properties = [
              {
                  displayName: 'Grant Type',
                  name: 'grantType',
                  type: 'hidden',
                  default: 'authorizationCode',
              },
              {
                  displayName: 'Authorization URL',
                  name: 'authUrl',
                  type: 'hidden',
                  default: 'https://secure.helpscout.net/authentication/authorizeClientApplication',
                  required: true,
              },
              {
                  displayName: 'Access Token URL',
                  name: 'accessTokenUrl',
                  type: 'hidden',
                  default: 'https://api.helpscout.net/v2/oauth2/token',
                  required: true,
              },
              {
                  displayName: 'Scope',
                  name: 'scope',
                  type: 'hidden',
                  default: '',
              },
              {
                  displayName: 'Auth URI Query Parameters',
                  name: 'authQueryParameters',
                  type: 'hidden',
                  default: '',
              },
              {
                  displayName: 'Authentication',
                  name: 'authentication',
                  type: 'hidden',
                  default: 'body',
              },
          ];
      }
  }
  exports.HelpScoutOAuth2Api = HelpScoutOAuth2Api;
  //# sourceMappingURL=HelpScoutOAuth2Api.credentials.js.map

  // --- Next Credential File ---

  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HelpScoutOAuth2Api = void 0;
  class HelpScoutOAuth2Api {
      constructor() {
          this.name = 'helpScoutOAuth2Api';
          this.extends = ['oAuth2Api'];
          this.displayName = 'HelpScout OAuth2 API';
          this.documentationUrl = 'helpScout';
          this.properties = [
              {
                  displayName: 'Grant Type',
                  name: 'grantType',
                  type: 'hidden',
                  default: 'authorizationCode',
              },
              {
                  displayName: 'Authorization URL',
                  name: 'authUrl',
                  type: 'hidden',
                  default: 'https://secure.helpscout.net/authentication/authorizeClientApplication',
                  required: true,
              },
              {
                  displayName: 'Access Token URL',
                  name: 'accessTokenUrl',
                  type: 'hidden',
                  default: 'https://api.helpscout.net/v2/oauth2/token',
                  required: true,
              },
              {
                  displayName: 'Scope',
                  name: 'scope',
                  type: 'hidden',
                  default: '',
              },
              {
                  displayName: 'Auth URI Query Parameters',
                  name: 'authQueryParameters',
                  type: 'hidden',
                  default: '',
              },
              {
                  displayName: 'Authentication',
                  name: 'authentication',
                  type: 'hidden',
                  default: 'body',
              },
          ];
      }
  }
  exports.HelpScoutOAuth2Api = HelpScoutOAuth2Api;
  //# sourceMappingURL=HelpScoutOAuth2Api.credentials.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Help Scout node documentation
  description: Learn how to use the Help Scout node in n8n. Follow technical documentation to integrate Help Scout node into your workflows.
  contentType: [integration, reference]
  ---

  # Help Scout node

  Use the Help Scout node to automate work in Help Scout, and integrate Help Scout with other applications. n8n has built-in support for a wide range of Help Scout features, including creating, updating, deleting, and getting conversations, and customers.

  On this page, you'll find a list of operations the Help Scout node supports and links to more resources.

  /// note | Credentials
  Refer to [Help Scout credentials](/integrations/builtin/credentials/helpscout.md) for guidance on setting up authentication. 
  ///

  ## Operations

  * Conversation
      * Create a new conversation
      * Delete a conversation
      * Get a conversation
      * Get all conversations
  * Customer
      * Create a new customer
      * Get a customer
      * Get all customers
      * Get customer property definitions
      * Update a customer
  * Mailbox
      * Get data of a mailbox
      * Get all mailboxes
  * Thread
      * Create a new chat thread
      * Get all chat threads

  ## Templates and examples

  <!-- see https://www.notion.so/n8n/Pull-in-templates-for-the-integrations-pages-37c716837b804d30a33b47475f6e3780 -->
  [[ templatesWidget(page.title, 'helpscout') ]]

  --8<-- "_snippets/integrations/builtin/app-nodes/operation-not-supported.md"

example_workflow:
  {"name":"HelpScout Example Workflow","nodes":[{"parameters":{},"id":"9uepwqiy28knrnhybyxx","name":"HelpScout","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.HtmlExtract
name: HtmlExtract
display_name: HTML Extract
description: Extracts data from HTML
category: transform
icon: fa:cut
code_hash: a9275186152c41bb3aea3d6c84c440e8b975b5b1e218d2bd3eafd12cc172cb7c
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
version: 1.0
extracted_at: 2025-06-09 15:18:09
updated_at: 2025-06-09 15:18:09
source_code:
  "use strict";
  var __importDefault = (this && this.__importDefault) || function (mod) {
      return (mod && mod.__esModule) ? mod : { "default": mod };
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HtmlExtract = void 0;
  const cheerio_1 = __importDefault(require("cheerio"));
  const n8n_workflow_1 = require("n8n-workflow");
  const get_1 = __importDefault(require("lodash/get"));
  const extractFunctions = {
      attribute: ($, valueData) => $.attr(valueData.attribute),
      html: ($, _valueData) => $.html() || undefined,
      text: ($, _valueData) => $.text(),
      value: ($, _valueData) => $.val(),
  };
  function getValue($, valueData, options) {
      const value = extractFunctions[valueData.returnValue]($, valueData);
      if (options.trimValues === false || value === undefined) {
          return value;
      }
      return value.trim();
  }
  class HtmlExtract {
      constructor() {
          this.description = {
              displayName: 'HTML Extract',
              name: 'htmlExtract',
              icon: 'fa:cut',
              group: ['transform'],
              version: 1,
              hidden: true,
              subtitle: '={{$parameter["sourceData"] + ": " + $parameter["dataPropertyName"]}}',
              description: 'Extracts data from HTML',
              defaults: {
                  name: 'HTML Extract',
                  color: '#333377',
              },
              inputs: ['main'],
              outputs: ['main'],
              properties: [
                  {
                      displayName: 'Source Data',
                      name: 'sourceData',
                      type: 'options',
                      options: [
                          {
                              name: 'Binary',
                              value: 'binary',
                          },
                          {
                              name: 'JSON',
                              value: 'json',
                          },
                      ],
                      default: 'json',
                      description: 'If HTML should be read from binary or JSON data',
                  },
                  {
                      displayName: 'Binary Property',
                      name: 'dataPropertyName',
                      type: 'string',
                      displayOptions: {
                          show: {
                              sourceData: ['binary'],
                          },
                      },
                      default: 'data',
                      required: true,
                      description: 'Name of the binary property in which the HTML to extract the data from can be found',
                  },
                  {
                      displayName: 'JSON Property',
                      name: 'dataPropertyName',
                      type: 'string',
                      displayOptions: {
                          show: {
                              sourceData: ['json'],
                          },
                      },
                      default: 'data',
                      required: true,
                      description: 'Name of the JSON property in which the HTML to extract the data from can be found. The property can either contain a string or an array of strings.',
                  },
                  {
                      displayName: 'Extraction Values',
                      name: 'extractionValues',
                      placeholder: 'Add Value',
                      type: 'fixedCollection',
                      typeOptions: {
                          multipleValues: true,
                      },
                      default: {},
                      options: [
                          {
                              name: 'values',
                              displayName: 'Values',
                              values: [
                                  {
                                      displayName: 'Key',
                                      name: 'key',
                                      type: 'string',
                                      default: '',
                                      description: 'The key under which the extracted value should be saved',
                                  },
                                  {
                                      displayName: 'CSS Selector',
                                      name: 'cssSelector',
                                      type: 'string',
                                      default: '',
                                      placeholder: '.price',
                                      description: 'The CSS selector to use',
                                  },
                                  {
                                      displayName: 'Return Value',
                                      name: 'returnValue',
                                      type: 'options',
                                      options: [
                                          {
                                              name: 'Attribute',
                                              value: 'attribute',
                                              description: 'Get an attribute value like "class" from an element',
                                          },
                                          {
                                              name: 'HTML',
                                              value: 'html',
                                              description: 'Get the HTML the element contains',
                                          },
                                          {
                                              name: 'Text',
                                              value: 'text',
                                              description: 'Get only the text content of the element',
                                          },
                                          {
                                              name: 'Value',
                                              value: 'value',
                                              description: 'Get value of an input, select or textarea',
                                          },
                                      ],
                                      default: 'text',
                                      description: 'What kind of data should be returned',
                                  },
                                  {
                                      displayName: 'Attribute',
                                      name: 'attribute',
                                      type: 'string',
                                      displayOptions: {
                                          show: {
                                              returnValue: ['attribute'],
                                          },
                                      },
                                      default: '',
                                      placeholder: 'class',
                                      description: 'The name of the attribute to return the value off',
                                  },
                                  {
                                      displayName: 'Return Array',
                                      name: 'returnArray',
                                      type: 'boolean',
                                      default: false,
                                      description: 'Whether to return the values as an array so if multiple ones get found they also get returned separately. If not set all will be returned as a single string.',
                                  },
                              ],
                          },
                      ],
                  },
                  {
                      displayName: 'Options',
                      name: 'options',
                      type: 'collection',
                      placeholder: 'Add Option',
                      default: {},
                      options: [
                          {
                              displayName: 'Trim Values',
                              name: 'trimValues',
                              type: 'boolean',
                              default: true,
                              description: 'Whether to remove automatically all spaces and newlines from the beginning and end of the values',
                          },
                      ],
                  },
              ],
          };
      }
      async execute() {
          const items = this.getInputData();
          const returnData = [];
          let item;
          for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
              try {
                  const dataPropertyName = this.getNodeParameter('dataPropertyName', itemIndex);
                  const extractionValues = this.getNodeParameter('extractionValues', itemIndex);
                  const options = this.getNodeParameter('options', itemIndex, {});
                  const sourceData = this.getNodeParameter('sourceData', itemIndex);
                  item = items[itemIndex];
                  let htmlArray = [];
                  if (sourceData === 'json') {
                      const data = (0, get_1.default)(item.json, dataPropertyName, undefined);
                      if (data === undefined) {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No property named "${dataPropertyName}" exists!`, { itemIndex });
                      }
                      htmlArray = data;
                  }
                  else {
                      this.helpers.assertBinaryData(itemIndex, dataPropertyName);
                      const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(itemIndex, dataPropertyName);
                      htmlArray = binaryDataBuffer.toString('utf-8');
                  }
                  if (!Array.isArray(htmlArray)) {
                      htmlArray = [htmlArray];
                  }
                  for (const html of htmlArray) {
                      const $ = cheerio_1.default.load(html);
                      const newItem = {
                          json: {},
                          pairedItem: {
                              item: itemIndex,
                          },
                      };
                      let htmlElement;
                      for (const valueData of extractionValues.values) {
                          htmlElement = $(valueData.cssSelector);
                          if (valueData.returnArray) {
                              newItem.json[valueData.key] = [];
                              htmlElement.each((i, el) => {
                                  newItem.json[valueData.key].push(getValue($(el), valueData, options));
                              });
                          }
                          else {
                              newItem.json[valueData.key] = getValue(htmlElement, valueData, options);
                          }
                      }
                      returnData.push(newItem);
                  }
              }
              catch (error) {
                  if (this.continueOnFail()) {
                      returnData.push({
                          json: {
                              error: error.message,
                          },
                          pairedItem: {
                              item: itemIndex,
                          },
                      });
                      continue;
                  }
                  throw error;
              }
          }
          return [returnData];
      }
  }
  exports.HtmlExtract = HtmlExtract;
  //# sourceMappingURL=HtmlExtract.node.js.map

example_workflow:
  {"name":"HTML Extract Example Workflow","nodes":[{"parameters":{},"id":"bo59fzvr9495qba0ahpcn","name":"HTML Extract","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.Html
name: Html
display_name: HTML
description: Work with HTML
category: transform
icon: file:html.svg
code_hash: 9531d0a56d4f238a5c8fd64ea0b1c85308c7aa09d60d54033bd0365cbf8ebbe4
documentation_url: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.Html
documentation_title: HTML
operations: []
api_methods: []
documentation_examples: []
templates: [{"name":"html","description":"Templates for html"}]
related_resources: []
required_scopes: []
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
version: 1.0
extracted_at: 2025-06-09 15:18:09
updated_at: 2025-06-09 15:18:09
source_code:
  "use strict";
  var __importDefault = (this && this.__importDefault) || function (mod) {
      return (mod && mod.__esModule) ? mod : { "default": mod };
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Html = exports.capitalizeHeader = void 0;
  const cheerio_1 = __importDefault(require("cheerio"));
  const n8n_workflow_1 = require("n8n-workflow");
  const placeholder_1 = require("./placeholder");
  const utils_1 = require("./utils");
  const utilities_1 = require("../../utils/utilities");
  const capitalizeHeader = (header, capitalize) => {
      if (!capitalize)
          return header;
      return header
          .split('_')
          .filter((word) => word)
          .map((word) => word[0].toUpperCase() + word.slice(1))
          .join(' ');
  };
  exports.capitalizeHeader = capitalizeHeader;
  class Html {
      constructor() {
          this.description = {
              displayName: 'HTML',
              name: 'html',
              icon: 'file:html.svg',
              group: ['transform'],
              version: 1,
              subtitle: '={{ $parameter["operation"] }}',
              description: 'Work with HTML',
              defaults: {
                  name: 'HTML',
              },
              inputs: ['main'],
              outputs: ['main'],
              parameterPane: 'wide',
              properties: [
                  {
                      displayName: 'Operation',
                      name: 'operation',
                      type: 'options',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Generate HTML Template',
                              value: 'generateHtmlTemplate',
                              action: 'Generate HTML template',
                          },
                          {
                              name: 'Extract HTML Content',
                              value: 'extractHtmlContent',
                              action: 'Extract HTML Content',
                          },
                          {
                              name: 'Convert to HTML Table',
                              value: 'convertToHtmlTable',
                              action: 'Convert to HTML Table',
                          },
                      ],
                      default: 'generateHtmlTemplate',
                  },
                  {
                      displayName: 'HTML Template',
                      name: 'html',
                      typeOptions: {
                          editor: 'htmlEditor',
                      },
                      type: 'string',
                      default: placeholder_1.placeholder,
                      noDataExpression: true,
                      description: 'HTML template to render',
                      displayOptions: {
                          show: {
                              operation: ['generateHtmlTemplate'],
                          },
                      },
                  },
                  {
                      displayName: '<b>Tips</b>: Type ctrl+space for completions. Use <code>{{ }}</code> for expressions and <code>&lt;style&gt;</code> tags for CSS. JS in <code>&lt;script&gt;</code> tags is included but not executed in n8n.',
                      name: 'notice',
                      type: 'notice',
                      default: '',
                      displayOptions: {
                          show: {
                              operation: ['generateHtmlTemplate'],
                          },
                      },
                  },
                  {
                      displayName: 'Source Data',
                      name: 'sourceData',
                      type: 'options',
                      options: [
                          {
                              name: 'Binary',
                              value: 'binary',
                          },
                          {
                              name: 'JSON',
                              value: 'json',
                          },
                      ],
                      default: 'json',
                      description: 'If HTML should be read from binary or JSON data',
                      displayOptions: {
                          show: {
                              operation: ['extractHtmlContent'],
                          },
                      },
                  },
                  {
                      displayName: 'Binary Property',
                      name: 'dataPropertyName',
                      type: 'string',
                      requiresDataPath: 'single',
                      displayOptions: {
                          show: {
                              operation: ['extractHtmlContent'],
                              sourceData: ['binary'],
                          },
                      },
                      default: 'data',
                      required: true,
                      description: 'Name of the binary property in which the HTML to extract the data from can be found',
                  },
                  {
                      displayName: 'JSON Property',
                      name: 'dataPropertyName',
                      type: 'string',
                      requiresDataPath: 'single',
                      displayOptions: {
                          show: {
                              operation: ['extractHtmlContent'],
                              sourceData: ['json'],
                          },
                      },
                      default: 'data',
                      required: true,
                      description: 'Name of the JSON property in which the HTML to extract the data from can be found. The property can either contain a string or an array of strings.',
                  },
                  {
                      displayName: 'Extraction Values',
                      name: 'extractionValues',
                      placeholder: 'Add Value',
                      type: 'fixedCollection',
                      typeOptions: {
                          multipleValues: true,
                      },
                      displayOptions: {
                          show: {
                              operation: ['extractHtmlContent'],
                          },
                      },
                      default: {},
                      options: [
                          {
                              name: 'values',
                              displayName: 'Values',
                              values: [
                                  {
                                      displayName: 'Key',
                                      name: 'key',
                                      type: 'string',
                                      default: '',
                                      description: 'The key under which the extracted value should be saved',
                                  },
                                  {
                                      displayName: 'CSS Selector',
                                      name: 'cssSelector',
                                      type: 'string',
                                      default: '',
                                      placeholder: '.price',
                                      description: 'The CSS selector to use',
                                  },
                                  {
                                      displayName: 'Return Value',
                                      name: 'returnValue',
                                      type: 'options',
                                      options: [
                                          {
                                              name: 'Attribute',
                                              value: 'attribute',
                                              description: 'Get an attribute value like "class" from an element',
                                          },
                                          {
                                              name: 'HTML',
                                              value: 'html',
                                              description: 'Get the HTML the element contains',
                                          },
                                          {
                                              name: 'Text',
                                              value: 'text',
                                              description: 'Get only the text content of the element',
                                          },
                                          {
                                              name: 'Value',
                                              value: 'value',
                                              description: 'Get value of an input, select or textarea',
                                          },
                                      ],
                                      default: 'text',
                                      description: 'What kind of data should be returned',
                                  },
                                  {
                                      displayName: 'Attribute',
                                      name: 'attribute',
                                      type: 'string',
                                      displayOptions: {
                                          show: {
                                              returnValue: ['attribute'],
                                          },
                                      },
                                      default: '',
                                      placeholder: 'class',
                                      description: 'The name of the attribute to return the value off',
                                  },
                                  {
                                      displayName: 'Return Array',
                                      name: 'returnArray',
                                      type: 'boolean',
                                      default: false,
                                      description: 'Whether to return the values as an array so if multiple ones get found they also get returned separately. If not set all will be returned as a single string.',
                                  },
                              ],
                          },
                      ],
                  },
                  {
                      displayName: 'Options',
                      name: 'options',
                      type: 'collection',
                      placeholder: 'Add Option',
                      default: {},
                      displayOptions: {
                          show: {
                              operation: ['extractHtmlContent'],
                          },
                      },
                      options: [
                          {
                              displayName: 'Trim Values',
                              name: 'trimValues',
                              type: 'boolean',
                              default: true,
                              description: 'Whether to remove automatically all spaces and newlines from the beginning and end of the values',
                          },
                      ],
                  },
                  {
                      displayName: 'Options',
                      name: 'options',
                      type: 'collection',
                      placeholder: 'Add Option',
                      default: {},
                      displayOptions: {
                          show: {
                              operation: ['convertToHtmlTable'],
                          },
                      },
                      options: [
                          {
                              displayName: 'Capitalize Headers',
                              name: 'capitalize',
                              type: 'boolean',
                              default: false,
                              description: 'Whether to capitalize the headers',
                          },
                          {
                              displayName: 'Custom Styling',
                              name: 'customStyling',
                              type: 'boolean',
                              default: false,
                              description: 'Whether to use custom styling',
                          },
                          {
                              displayName: 'Caption',
                              name: 'caption',
                              type: 'string',
                              default: '',
                              description: 'Caption to add to the table',
                          },
                          {
                              displayName: 'Table Attributes',
                              name: 'tableAttributes',
                              type: 'string',
                              default: '',
                              description: 'Attributes to attach to the table',
                              placeholder: 'e.g. style="padding:10px"',
                          },
                          {
                              displayName: 'Header Attributes',
                              name: 'headerAttributes',
                              type: 'string',
                              default: '',
                              description: 'Attributes to attach to the table header',
                              placeholder: 'e.g. style="padding:10px"',
                          },
                          {
                              displayName: 'Row Attributes',
                              name: 'rowAttributes',
                              type: 'string',
                              default: '',
                              description: 'Attributes to attach to the table row',
                              placeholder: 'e.g. style="padding:10px"',
                          },
                          {
                              displayName: 'Cell Attributes',
                              name: 'cellAttributes',
                              type: 'string',
                              default: '',
                              description: 'Attributes to attach to the table cell',
                              placeholder: 'e.g. style="padding:10px"',
                          },
                      ],
                  },
              ],
          };
      }
      async execute() {
          const items = this.getInputData();
          const operation = this.getNodeParameter('operation', 0);
          if (operation === 'convertToHtmlTable' && items.length) {
              let table = '';
              const options = this.getNodeParameter('options', 0);
              let tableStyle = '';
              let headerStyle = '';
              let cellStyle = '';
              if (!options.customStyling) {
                  tableStyle = "style='border-spacing:0; font-family:helvetica,arial,sans-serif'";
                  headerStyle =
                      "style='margin:0; padding:7px 20px 7px 0px; border-bottom:1px solid #eee; text-align:left; color:#888; font-weight:normal'";
                  cellStyle = "style='margin:0; padding:7px 20px 7px 0px; border-bottom:1px solid #eee'";
              }
              const tableAttributes = options.tableAttributes || '';
              const headerAttributes = options.headerAttributes || '';
              const itemsData = [];
              const itemsKeys = new Set();
              for (const entry of items) {
                  itemsData.push(entry.json);
                  for (const key of Object.keys(entry.json)) {
                      itemsKeys.add(key);
                  }
              }
              const headers = Array.from(itemsKeys);
              table += `<table ${tableStyle} ${tableAttributes}>`;
              if (options.caption) {
                  table += `<caption>${options.caption}</caption>`;
              }
              table += `<thead ${headerStyle} ${headerAttributes}>`;
              table += '<tr>';
              table += headers
                  .map((header) => '<th>' + (0, exports.capitalizeHeader)(header, options.capitalize) + '</th>')
                  .join('');
              table += '</tr>';
              table += '</thead>';
              table += '<tbody>';
              itemsData.forEach((entry, entryIndex) => {
                  const rowsAttributes = this.getNodeParameter('options.rowsAttributes', entryIndex, '');
                  table += `<tr  ${rowsAttributes}>`;
                  const cellsAttributes = this.getNodeParameter('options.cellAttributes', entryIndex, '');
                  table += headers
                      .map((header) => {
                      let td = `<td ${cellStyle} ${cellsAttributes}>`;
                      if (typeof entry[header] === 'boolean') {
                          const isChecked = entry[header] ? 'checked="checked"' : '';
                          td += `<input type="checkbox" ${isChecked}/>`;
                      }
                      else {
                          td += entry[header];
                      }
                      td += '</td>';
                      return td;
                  })
                      .join('');
                  table += '</tr>';
              });
              table += '</tbody>';
              table += '</table>';
              return [
                  [
                      {
                          json: { table },
                          pairedItem: items.map((_item, index) => ({
                              item: index,
                          })),
                      },
                  ],
              ];
          }
          let item;
          const returnData = [];
          for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
              try {
                  if (operation === 'generateHtmlTemplate') {
                      let html = this.getNodeParameter('html', itemIndex);
                      for (const resolvable of (0, utilities_1.getResolvables)(html)) {
                          html = html.replace(resolvable, this.evaluateExpression(resolvable, itemIndex));
                      }
                      const result = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ html }), {
                          itemData: { item: itemIndex },
                      });
                      returnData.push(...result);
                  }
                  else if (operation === 'extractHtmlContent') {
                      const dataPropertyName = this.getNodeParameter('dataPropertyName', itemIndex);
                      const extractionValues = this.getNodeParameter('extractionValues', itemIndex);
                      const options = this.getNodeParameter('options', itemIndex, {});
                      const sourceData = this.getNodeParameter('sourceData', itemIndex);
                      item = items[itemIndex];
                      let htmlArray = [];
                      if (sourceData === 'json') {
                          if (item.json[dataPropertyName] === undefined) {
                              throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No property named "${dataPropertyName}" exists!`, { itemIndex });
                          }
                          htmlArray = item.json[dataPropertyName];
                      }
                      else {
                          this.helpers.assertBinaryData(itemIndex, dataPropertyName);
                          const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(itemIndex, dataPropertyName);
                          htmlArray = binaryDataBuffer.toString('utf-8');
                      }
                      if (!Array.isArray(htmlArray)) {
                          htmlArray = [htmlArray];
                      }
                      for (const html of htmlArray) {
                          const $ = cheerio_1.default.load(html);
                          const newItem = {
                              json: {},
                              pairedItem: {
                                  item: itemIndex,
                              },
                          };
                          let htmlElement;
                          for (const valueData of extractionValues.values) {
                              htmlElement = $(valueData.cssSelector);
                              if (valueData.returnArray) {
                                  newItem.json[valueData.key] = [];
                                  htmlElement.each((i, el) => {
                                      newItem.json[valueData.key].push((0, utils_1.getValue)($(el), valueData, options));
                                  });
                              }
                              else {
                                  newItem.json[valueData.key] = (0, utils_1.getValue)(htmlElement, valueData, options);
                              }
                          }
                          returnData.push(newItem);
                      }
                  }
              }
              catch (error) {
                  if (this.continueOnFail()) {
                      returnData.push({
                          json: {
                              error: error.message,
                          },
                          pairedItem: {
                              item: itemIndex,
                          },
                      });
                      continue;
                  }
                  throw error;
              }
          }
          return [returnData];
      }
  }
  exports.Html = Html;
  //# sourceMappingURL=Html.node.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: HTML
  description: Documentation for the HTML node in n8n, a workflow automation platform. Includes guidance on usage, and links to examples.
  contentType: [integration, reference]
  priority: high
  ---

  # HTML

  The HTML node provides operations to help you work with HTML in n8n.

  /// note | HTML Extract node
  The HTML node replaces the HTML Extract node from version 0.213.0 on. If you're using an older version of n8n, you can still view the [HTML Extract node documentation](https://github.com/n8n-io/n8n-docs/blob/86fe33b681621e618e3adcab9a27e8605dbc23ad/docs/integrations/builtin/core-nodes/n8n-nodes-base.htmlextract.md){:target=_blank .external-link}.
  ///
  /// warning | Cross-site scripting
  When using the HTML node to generate an HTML template you can introduce [XSS (cross-site scripting)](https://owasp.org/www-community/attacks/xss/){:target=_blank .external-link}. This is a security risk. Be careful with un-trusted inputs.
  ///

  ## Operations

  * [**Generate HTML template**](#generate-html-template): Use this operation to create an HTML template. This allows you to take data from your workflow and output it as HTML.
  * [**Extract HTML content**](#extract-html-content): Extract contents from an HTML-formatted source. The source can be in JSON or a binary file (`.html`).
  * [**Convert to HTML Table**](#convert-to-html-table): Convert content to an HTML table.

  The node parameters and options depend on the operation you select. Refer to the sections below for more details on configuring each operation.

  ## Generate HTML template

  Create an HTML template. This allows you to take data from your workflow and output it as HTML. 

  You can include:

  * Standard HTML
  * CSS in `<style>` tags.
  * JavaScript in `<script>` tags. n8n doesn't execute the JavaScript.
  * Expressions, wrapped in `{{}}`.

  You can use [Expressions](/code/expressions.md) in the template, including n8n's [Built-in methods and variables](/code/builtin/overview.md). 

  ## Extract HTML Content

  Extract contents from an HTML-formatted source. The source can be in JSON or a binary file (`.html`).

  Use these parameters:

  ### Source Data

  Select the source type for your HTML content. Choose between:

  * **JSON**: If you select this source data, enter the **JSON Property**: the name of the input containing the HTML you want to extract. The property can contain a string or an array of strings.
  * **Binary**: If you select this source data, enter the **Input Binary Field**: the name of the input containing the HTML you want to extract. The property can contain a string or an array of strings.

  ### Extraction Values

  - **Key**: Enter the key to save the extracted value under.
  - **CSS Selector**: Enter the CSS selector to search for.
  - **Return Value**: Select the type of data to return. Choose from:
  	- **Attribute**: Return an attribute value like `class` from an element.
  		- If you select this option, enter the name of the **Attribute** to return the value of.
  	- **HTML**: Return the HTML that the element contains.
  	- **Text**: Return the text content of the element.
  		- If you choose this option, you can also enter a comma-separated list of selectors to skip in the **Skip Selectors**.
  	- **Value**: Return the value of an input, select, or text area.
  - **Return Array**: Choose whether to return multiple extraction values as an array (turned on) or as a single string (turned off).

  ### Extract HTML Content options

  You can also configure this operation with these options:

  * **Trim Values**: Controls whether to remove all spaces and newlines from the beginning and end of the values (turned on) or leaves them (turned off).
  * **Clean Up Text**: Controls whether to remove leading whitespaces, trailing whitespaces, and line breaks (newlines) and condense multiple consecutive whitespaces into a single space (turned on) or to leave them as-is (turned off).

  ## Convert to HTML Table

  This operation expects data from another node. It has no parameters. It includes these options:

  * **Capitalize Headers**: Controls whether to capitalize the table's headers (turned on) or not (turned off).
  * **Custom Styling**: Controls whether to use custom styling (turned on) or not (turned off).
  * **Caption**: Enter a caption to add to the table.
  * **Table Attributes**: Enter any attributes to apply to the `<table>`, such as style attributes.
  * **Header Attributes**: Enter any attributes to apply to the table's headers `<th>`.
  * **Row Attributes**: Enter any attributes to apply to the table's rows `<tr>`.
  * **Cell Attributes**: Enter any attributes to apply to the table's cells `<td>`.

  ## Templates and examples

  <!-- see https://www.notion.so/n8n/Pull-in-templates-for-the-integrations-pages-37c716837b804d30a33b47475f6e3780 -->
  [[ templatesWidget(page.title, 'html') ]]

example_workflow:
  {"name":"HTML Example Workflow","nodes":[{"parameters":{},"id":"tlw8lmm28ebhvgq1e1z89","name":"HTML","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.Hubspot
name: Hubspot
display_name: HubSpot
description: Consume HubSpot API
category: output
icon: file:hubspot.svg
code_hash: 548619ac567c0ab051e7b0e159df7fd6bc41234effe4ccb766c6ab62a9cbde8d
documentation_url: https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.Hubspot
documentation_title: HubSpot node documentation
operations: []
api_methods: []
documentation_examples: []
templates: [{"name":"hubspot","description":"Templates for hubspot"}]
related_resources: []
required_scopes: []
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-09 15:18:09
updated_at: 2025-06-09 15:18:09
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Hubspot = void 0;
  const n8n_workflow_1 = require("n8n-workflow");
  const HubspotV1_node_1 = require("./V1/HubspotV1.node");
  const HubspotV2_node_1 = require("./V2/HubspotV2.node");
  class Hubspot extends n8n_workflow_1.VersionedNodeType {
      constructor() {
          const baseDescription = {
              displayName: 'HubSpot',
              name: 'hubspot',
              icon: 'file:hubspot.svg',
              group: ['output'],
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Consume HubSpot API',
              defaultVersion: 2,
          };
          const nodeVersions = {
              1: new HubspotV1_node_1.HubspotV1(baseDescription),
              2: new HubspotV2_node_1.HubspotV2(baseDescription),
          };
          super(nodeVersions, baseDescription);
      }
  }
  exports.Hubspot = Hubspot;
  //# sourceMappingURL=Hubspot.node.js.map

credential_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HubspotApi = void 0;
  class HubspotApi {
      constructor() {
          this.name = 'hubspotApi';
          this.displayName = 'HubSpot API';
          this.documentationUrl = 'hubspot';
          this.properties = [
              {
                  displayName: 'On 30 November, 2022 Hubspot will remove API key support. You will have to connect to HubSpot using private app or Oauth2 auth method. <a target="_blank" href="https://developers.hubspot.com/changelog/upcoming-api-key-sunset">More details (HubSpot.com)</a>',
                  name: 'notice',
                  type: 'notice',
                  default: '',
              },
              {
                  displayName: 'API Key',
                  name: 'apiKey',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
              },
          ];
          this.authenticate = {
              type: 'generic',
              properties: {
                  qs: {
                      hapikey: '={{$credentials.apiKey}}',
                  },
              },
          };
          this.test = {
              request: {
                  baseURL: 'https://api.hubapi.com',
                  url: '/account-info/v3/details',
              },
          };
      }
  }
  exports.HubspotApi = HubspotApi;
  //# sourceMappingURL=HubspotApi.credentials.js.map

  // --- Next Credential File ---

  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HubspotOAuth2Api = void 0;
  const scopes = [
      'crm.lists.write',
      'crm.objects.contacts.read',
      'crm.objects.contacts.write',
      'crm.objects.companies.read',
      'crm.objects.companies.write',
      'crm.objects.deals.read',
      'crm.objects.deals.write',
      'crm.objects.owners.read',
      'crm.schemas.companies.read',
      'crm.schemas.contacts.read',
      'crm.schemas.deals.read',
      'forms',
      'tickets',
  ];
  class HubspotOAuth2Api {
      constructor() {
          this.name = 'hubspotOAuth2Api';
          this.extends = ['oAuth2Api'];
          this.displayName = 'HubSpot OAuth2 API';
          this.documentationUrl = 'hubspot';
          this.properties = [
              {
                  displayName: 'Grant Type',
                  name: 'grantType',
                  type: 'hidden',
                  default: 'authorizationCode',
              },
              {
                  displayName: 'Authorization URL',
                  name: 'authUrl',
                  type: 'hidden',
                  default: 'https://app.hubspot.com/oauth/authorize',
                  required: true,
              },
              {
                  displayName: 'Access Token URL',
                  name: 'accessTokenUrl',
                  type: 'hidden',
                  default: 'https://api.hubapi.com/oauth/v1/token',
                  required: true,
              },
              {
                  displayName: 'Scope',
                  name: 'scope',
                  type: 'hidden',
                  default: scopes.join(' '),
              },
              {
                  displayName: 'Auth URI Query Parameters',
                  name: 'authQueryParameters',
                  type: 'hidden',
                  default: 'grant_type=authorization_code',
              },
              {
                  displayName: 'Authentication',
                  name: 'authentication',
                  type: 'hidden',
                  default: 'body',
              },
          ];
      }
  }
  exports.HubspotOAuth2Api = HubspotOAuth2Api;
  //# sourceMappingURL=HubspotOAuth2Api.credentials.js.map

  // --- Next Credential File ---

  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HubspotApi = void 0;
  class HubspotApi {
      constructor() {
          this.name = 'hubspotApi';
          this.displayName = 'HubSpot API';
          this.documentationUrl = 'hubspot';
          this.properties = [
              {
                  displayName: 'On 30 November, 2022 Hubspot will remove API key support. You will have to connect to HubSpot using private app or Oauth2 auth method. <a target="_blank" href="https://developers.hubspot.com/changelog/upcoming-api-key-sunset">More details (HubSpot.com)</a>',
                  name: 'notice',
                  type: 'notice',
                  default: '',
              },
              {
                  displayName: 'API Key',
                  name: 'apiKey',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
              },
          ];
          this.authenticate = {
              type: 'generic',
              properties: {
                  qs: {
                      hapikey: '={{$credentials.apiKey}}',
                  },
              },
          };
          this.test = {
              request: {
                  baseURL: 'https://api.hubapi.com',
                  url: '/account-info/v3/details',
              },
          };
      }
  }
  exports.HubspotApi = HubspotApi;
  //# sourceMappingURL=HubspotApi.credentials.js.map

  // --- Next Credential File ---

  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HubspotOAuth2Api = void 0;
  const scopes = [
      'crm.lists.write',
      'crm.objects.contacts.read',
      'crm.objects.contacts.write',
      'crm.objects.companies.read',
      'crm.objects.companies.write',
      'crm.objects.deals.read',
      'crm.objects.deals.write',
      'crm.objects.owners.read',
      'crm.schemas.companies.read',
      'crm.schemas.contacts.read',
      'crm.schemas.deals.read',
      'forms',
      'tickets',
  ];
  class HubspotOAuth2Api {
      constructor() {
          this.name = 'hubspotOAuth2Api';
          this.extends = ['oAuth2Api'];
          this.displayName = 'HubSpot OAuth2 API';
          this.documentationUrl = 'hubspot';
          this.properties = [
              {
                  displayName: 'Grant Type',
                  name: 'grantType',
                  type: 'hidden',
                  default: 'authorizationCode',
              },
              {
                  displayName: 'Authorization URL',
                  name: 'authUrl',
                  type: 'hidden',
                  default: 'https://app.hubspot.com/oauth/authorize',
                  required: true,
              },
              {
                  displayName: 'Access Token URL',
                  name: 'accessTokenUrl',
                  type: 'hidden',
                  default: 'https://api.hubapi.com/oauth/v1/token',
                  required: true,
              },
              {
                  displayName: 'Scope',
                  name: 'scope',
                  type: 'hidden',
                  default: scopes.join(' '),
              },
              {
                  displayName: 'Auth URI Query Parameters',
                  name: 'authQueryParameters',
                  type: 'hidden',
                  default: 'grant_type=authorization_code',
              },
              {
                  displayName: 'Authentication',
                  name: 'authentication',
                  type: 'hidden',
                  default: 'body',
              },
          ];
      }
  }
  exports.HubspotOAuth2Api = HubspotOAuth2Api;
  //# sourceMappingURL=HubspotOAuth2Api.credentials.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: HubSpot node documentation
  description: Learn how to use the HubSpot node in n8n. Follow technical documentation to integrate HubSpot node into your workflows.
  contentType: [integration, reference]
  priority: medium
  ---

  # HubSpot node

  Use the HubSpot node to automate work in HubSpot, and integrate HubSpot with other applications. n8n has built-in support for a wide range of HubSpot features, including creating, updating, deleting, and getting contacts, deals, lists, engagements and companies. 

  On this page, you'll find a list of operations the HubSpot node supports and links to more resources.

  /// note | Credentials
  Refer to [HubSpot credentials](/integrations/builtin/credentials/hubspot.md) for guidance on setting up authentication. 
  ///

  --8<-- "_snippets/integrations/builtin/app-nodes/ai-tools.md"

  ## Operations

  * Contact
      * Create/Update a contact
      * Delete a contact
      * Get a contact
      * Get all contacts
      * Get recently created/updated contacts
      * Search contacts
  * Contact List
      * Add contact to a list
      * Remove a contact from a list
  * Company
      * Create a company
      * Delete a company
      * Get a company
      * Get all companies
      * Get recently created companies
      * Get recently modified companies
      * Search companies by domain
      * Update a company
  * Deal
      * Create a deal
      * Delete a deal
      * Get a deal
      * Get all deals
      * Get recently created deals
      * Get recently modified deals
      * Search deals
      * Update a deal
  * Engagement
      * Create an engagement
      * Delete an engagement
      * Get an engagement
      * Get all engagements
  * Form
      * Get all fields from a form
      * Submit data to a form
  * Ticket
      * Create a ticket
      * Delete a ticket
      * Get a ticket
      * Get all tickets
      * Update a ticket

  ## Templates and examples

  <!-- see https://www.notion.so/n8n/Pull-in-templates-for-the-integrations-pages-37c716837b804d30a33b47475f6e3780 -->
  [[ templatesWidget(page.title, 'hubspot') ]]

  --8<-- "_snippets/integrations/builtin/app-nodes/operation-not-supported.md"

example_workflow:
  {"name":"HubSpot Example Workflow","nodes":[{"parameters":{},"id":"88o9g7vxojlxpgbrveu1ze","name":"HubSpot","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.HttpRequest
name: HttpRequest
display_name: HTTP Request
description: Makes an HTTP request and returns the response data
category: output
icon: fa:at
code_hash: 5b5e2328474b7e85361c940dfe942e167b3f0057f38062f56d6b693f0a7ffe7e
documentation_title: HTTP Request Tool node documentation
operations: []
api_methods: []
documentation_examples: []
templates: [{"name":"http-request-tool","description":"Templates for http-request-tool"}]
related_resources: []
required_scopes: []
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-09 15:18:09
updated_at: 2025-06-09 15:18:09
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HttpRequest = void 0;
  const n8n_workflow_1 = require("n8n-workflow");
  const HttpRequestV1_node_1 = require("./V1/HttpRequestV1.node");
  const HttpRequestV2_node_1 = require("./V2/HttpRequestV2.node");
  const HttpRequestV3_node_1 = require("./V3/HttpRequestV3.node");
  class HttpRequest extends n8n_workflow_1.VersionedNodeType {
      constructor() {
          const baseDescription = {
              displayName: 'HTTP Request',
              name: 'httpRequest',
              icon: 'fa:at',
              group: ['output'],
              subtitle: '={{$parameter["requestMethod"] + ": " + $parameter["url"]}}',
              description: 'Makes an HTTP request and returns the response data',
              defaultVersion: 4.1,
          };
          const nodeVersions = {
              1: new HttpRequestV1_node_1.HttpRequestV1(baseDescription),
              2: new HttpRequestV2_node_1.HttpRequestV2(baseDescription),
              3: new HttpRequestV3_node_1.HttpRequestV3(baseDescription),
              4: new HttpRequestV3_node_1.HttpRequestV3(baseDescription),
              4.1: new HttpRequestV3_node_1.HttpRequestV3(baseDescription),
          };
          super(nodeVersions, baseDescription);
      }
  }
  exports.HttpRequest = HttpRequest;
  //# sourceMappingURL=HttpRequest.node.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: HTTP Request Tool node documentation
  description: Learn how to use the HTTP Request Tool node in n8n. Follow technical documentation to integrate HTTP Request Tool node into your workflows.
  search:
    exclude: true
  contentType: [integration, reference]
  ---

  # HTTP Request Tool node

  /// warning | Legacy tool version
  New instances of the HTTP Request tool node that you add to workflows use the standard [HTTP Request](/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/index.md) node as a tool. This page is describes the legacy, standalone HTTP Request tool node.

  You can identify which tool version is in your workflow by checking if the node has an **Add option** property when you open the node on the canvas. If that button is present, you're using the new version, not the one described on this page.
  ///

  The HTTP Request tool works just like the [HTTP Request](/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/index.md) node, but it's designed to be used with an [AI agent](/glossary.md#ai-agent) as a tool to collect information from a website or API.

  On this page, you'll find a list of operations the HTTP Request node supports and links to more resources.

  /// note | Credentials
  Refer to [HTTP Request credentials](/integrations/builtin/credentials/httprequest.md) for guidance on setting up authentication. 
  ///

  --8<-- "_snippets/integrations/builtin/cluster-nodes/sub-node-expression-resolution.md"

  ## Templates and examples

  <!-- see https://www.notion.so/n8n/Pull-in-templates-for-the-integrations-pages-37c716837b804d30a33b47475f6e3780 -->
  [[ templatesWidget(page.title, 'http-request-tool') ]]

  ## Related resources

  --8<-- "_snippets/integrations/builtin/cluster-nodes/tools-link.md"

  --8<-- "_snippets/integrations/builtin/cluster-nodes/langchain-overview-link.md"
  --8<-- "_glossary/ai-glossary.md"

documentation_url:
  https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolhttprequest

example_workflow:
  {"name":"HTTP Request Example Workflow","nodes":[{"parameters":{},"id":"f277p4zdjfdwsve77c23te","name":"HTTP Request","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.ItemLists
name: ItemLists
display_name: Item Lists
description: Helper for working with lists of items and transforming arrays
category: input
icon: file:itemLists.svg
code_hash: e750bcc12fe1f8b89195a70c6bb909c54066a02e91dbb0a0618e250b5dc9ec74
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-09 15:18:11
updated_at: 2025-06-09 15:18:11
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.ItemLists = void 0;
  const n8n_workflow_1 = require("n8n-workflow");
  const ItemListsV1_node_1 = require("./V1/ItemListsV1.node");
  const ItemListsV2_node_1 = require("./V2/ItemListsV2.node");
  const ItemListsV3_node_1 = require("./V3/ItemListsV3.node");
  class ItemLists extends n8n_workflow_1.VersionedNodeType {
      constructor() {
          const baseDescription = {
              displayName: 'Item Lists',
              name: 'itemLists',
              icon: 'file:itemLists.svg',
              group: ['input'],
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Helper for working with lists of items and transforming arrays',
              defaultVersion: 3,
          };
          const nodeVersions = {
              1: new ItemListsV1_node_1.ItemListsV1(baseDescription),
              2: new ItemListsV2_node_1.ItemListsV2(baseDescription),
              2.1: new ItemListsV2_node_1.ItemListsV2(baseDescription),
              2.2: new ItemListsV2_node_1.ItemListsV2(baseDescription),
              3: new ItemListsV3_node_1.ItemListsV3(baseDescription),
          };
          super(nodeVersions, baseDescription);
      }
  }
  exports.ItemLists = ItemLists;
  //# sourceMappingURL=ItemLists.node.js.map

example_workflow:
  {"name":"Item Lists Example Workflow","nodes":[{"parameters":{},"id":"pqmc3xdnh22nobpmhknga","name":"Item Lists","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.ICalendar
name: ICalendar
display_name: iCalendar
description: Create iCalendar file
category: input
icon: fa:calendar
code_hash: df6fb1c5955472887fe485c224bc5a433d19ff2a1938eeb576e0b133ef647720
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
version: 1.0
extracted_at: 2025-06-09 15:18:11
updated_at: 2025-06-09 15:18:11
source_code:
  "use strict";
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      var desc = Object.getOwnPropertyDescriptor(m, k);
      if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
        desc = { enumerable: true, get: function() { return m[k]; } };
      }
      Object.defineProperty(o, k2, desc);
  }) : (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      o[k2] = m[k];
  }));
  var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
      Object.defineProperty(o, "default", { enumerable: true, value: v });
  }) : function(o, v) {
      o["default"] = v;
  });
  var __importStar = (this && this.__importStar) || function (mod) {
      if (mod && mod.__esModule) return mod;
      var result = {};
      if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
      __setModuleDefault(result, mod);
      return result;
  };
  var __importDefault = (this && this.__importDefault) || function (mod) {
      return (mod && mod.__esModule) ? mod : { "default": mod };
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.ICalendar = void 0;
  const util_1 = require("util");
  const moment_timezone_1 = __importDefault(require("moment-timezone"));
  const ics = __importStar(require("ics"));
  const createEvent = (0, util_1.promisify)(ics.createEvent);
  class ICalendar {
      constructor() {
          this.description = {
              displayName: 'iCalendar',
              name: 'iCal',
              icon: 'fa:calendar',
              group: ['input'],
              version: 1,
              subtitle: '={{$parameter["operation"]}}',
              description: 'Create iCalendar file',
              defaults: {
                  name: 'iCalendar',
                  color: '#408000',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [],
              properties: [
                  {
                      displayName: 'Operation',
                      name: 'operation',
                      type: 'options',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Create Event File',
                              value: 'createEventFile',
                          },
                      ],
                      default: 'createEventFile',
                  },
                  {
                      displayName: 'Event Title',
                      name: 'title',
                      type: 'string',
                      default: '',
                  },
                  {
                      displayName: 'Start',
                      name: 'start',
                      type: 'dateTime',
                      default: '',
                      required: true,
                      description: 'Date and time at which the event begins. (For all-day events, the time will be ignored.).',
                  },
                  {
                      displayName: 'End',
                      name: 'end',
                      type: 'dateTime',
                      default: '',
                      required: true,
                      description: 'Date and time at which the event ends. (For all-day events, the time will be ignored.).',
                  },
                  {
                      displayName: 'All Day',
                      name: 'allDay',
                      type: 'boolean',
                      default: false,
                      description: 'Whether the event lasts all day or not',
                  },
                  {
                      displayName: 'Binary Property',
                      name: 'binaryPropertyName',
                      type: 'string',
                      default: 'data',
                      required: true,
                      description: 'The field that your iCalendar file will be available under in the output',
                  },
                  {
                      displayName: 'Additional Fields',
                      name: 'additionalFields',
                      type: 'collection',
                      placeholder: 'Add Field',
                      default: {},
                      displayOptions: {
                          show: {
                              operation: ['createEventFile'],
                          },
                      },
                      options: [
                          {
                              displayName: 'Attendees',
                              name: 'attendeesUi',
                              type: 'fixedCollection',
                              typeOptions: {
                                  multipleValues: true,
                              },
                              placeholder: 'Add Attendee',
                              default: {},
                              options: [
                                  {
                                      displayName: 'Attendees',
                                      name: 'attendeeValues',
                                      values: [
                                          {
                                              displayName: 'Name',
                                              name: 'name',
                                              type: 'string',
                                              required: true,
                                              default: '',
                                          },
                                          {
                                              displayName: 'Email',
                                              name: 'email',
                                              type: 'string',
                                              placeholder: 'name@email.com',
                                              required: true,
                                              default: '',
                                          },
                                          {
                                              displayName: 'RSVP',
                                              name: 'rsvp',
                                              type: 'boolean',
                                              default: false,
                                              description: 'Whether the attendee has to confirm attendance or not',
                                          },
                                      ],
                                  },
                              ],
                          },
                          {
                              displayName: 'Busy Status',
                              name: 'busyStatus',
                              type: 'options',
                              options: [
                                  {
                                      name: 'Busy',
                                      value: 'BUSY',
                                  },
                                  {
                                      name: 'Tentative',
                                      value: 'TENTATIVE',
                                  },
                              ],
                              default: '',
                              description: 'Used to specify busy status for Microsoft applications, like Outlook',
                          },
                          {
                              displayName: 'Calendar Name',
                              name: 'calName',
                              type: 'string',
                              default: '',
                              description: 'Specifies the calendar (not event) name. Used by Apple iCal and Microsoft Outlook (<a href="https://docs.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-oxcical/1da58449-b97e-46bd-b018-a1ce576f3e6d">spec</a>).',
                          },
                          {
                              displayName: 'Description',
                              name: 'description',
                              type: 'string',
                              default: '',
                          },
                          {
                              displayName: 'File Name',
                              name: 'fileName',
                              type: 'string',
                              default: '',
                              description: 'The name of the file to be generated. Default value is event.ics.',
                          },
                          {
                              displayName: 'Geolocation',
                              name: 'geolocationUi',
                              type: 'fixedCollection',
                              typeOptions: {
                                  multipleValues: false,
                              },
                              placeholder: 'Add Geolocation',
                              default: {},
                              options: [
                                  {
                                      displayName: 'Geolocation',
                                      name: 'geolocationValues',
                                      values: [
                                          {
                                              displayName: 'Latitude',
                                              name: 'lat',
                                              type: 'string',
                                              default: '',
                                          },
                                          {
                                              displayName: 'Longitude',
                                              name: 'lon',
                                              type: 'string',
                                              default: '',
                                          },
                                      ],
                                  },
                              ],
                          },
                          {
                              displayName: 'Location',
                              name: 'location',
                              type: 'string',
                              default: '',
                              description: 'The intended venue',
                          },
                          {
                              displayName: 'Recurrence Rule',
                              name: 'recurrenceRule',
                              type: 'string',
                              default: '',
                              description: 'A rule to define the repeat pattern of the event (RRULE). (<a href="https://icalendar.org/rrule-tool.html">Rule generator</a>).',
                          },
                          {
                              displayName: 'Organizer',
                              name: 'organizerUi',
                              type: 'fixedCollection',
                              typeOptions: {
                                  multipleValues: false,
                              },
                              placeholder: 'Add Organizer',
                              default: {},
                              options: [
                                  {
                                      displayName: 'Organizer',
                                      name: 'organizerValues',
                                      values: [
                                          {
                                              displayName: 'Name',
                                              name: 'name',
                                              type: 'string',
                                              default: '',
                                              required: true,
                                          },
                                          {
                                              displayName: 'Email',
                                              name: 'email',
                                              type: 'string',
                                              placeholder: 'name@email.com',
                                              default: '',
                                              required: true,
                                          },
                                      ],
                                  },
                              ],
                          },
                          {
                              displayName: 'Sequence',
                              name: 'sequence',
                              type: 'number',
                              default: 0,
                              description: 'When sending an update for an event (with the same uid), defines the revision sequence number',
                          },
                          {
                              displayName: 'Status',
                              name: 'status',
                              type: 'options',
                              options: [
                                  {
                                      name: 'Confirmed',
                                      value: 'CONFIRMED',
                                  },
                                  {
                                      name: 'Cancelled',
                                      value: 'CANCELLED',
                                  },
                                  {
                                      name: 'Tentative',
                                      value: 'TENTATIVE',
                                  },
                              ],
                              default: 'CONFIRMED',
                          },
                          {
                              displayName: 'UID',
                              name: 'uid',
                              type: 'string',
                              default: '',
                              description: 'Universally unique ID for the event (will be auto-generated if not specified here). Should be globally unique.',
                          },
                          {
                              displayName: 'URL',
                              name: 'url',
                              type: 'string',
                              default: '',
                              description: 'URL associated with event',
                          },
                      ],
                  },
              ],
          };
      }
      async execute() {
          const items = this.getInputData();
          const length = items.length;
          const returnData = [];
          const operation = this.getNodeParameter('operation', 0);
          if (operation === 'createEventFile') {
              for (let i = 0; i < length; i++) {
                  const title = this.getNodeParameter('title', i);
                  const allDay = this.getNodeParameter('allDay', i);
                  const start = this.getNodeParameter('start', i);
                  let end = this.getNodeParameter('end', i);
                  end = allDay ? (0, moment_timezone_1.default)(end).utc().add(1, 'day').format() : end;
                  const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
                  const additionalFields = this.getNodeParameter('additionalFields', i);
                  let fileName = 'event.ics';
                  const eventStart = (0, moment_timezone_1.default)(start)
                      .toArray()
                      .splice(0, allDay ? 3 : 6);
                  eventStart[1]++;
                  const eventEnd = (0, moment_timezone_1.default)(end)
                      .toArray()
                      .splice(0, allDay ? 3 : 6);
                  eventEnd[1]++;
                  if (additionalFields.fileName) {
                      fileName = additionalFields.fileName;
                  }
                  const data = {
                      title,
                      start: eventStart,
                      end: eventEnd,
                      startInputType: 'utc',
                      endInputType: 'utc',
                  };
                  if (additionalFields.geolocationUi) {
                      data.geo = additionalFields.geolocationUi
                          .geolocationValues;
                      delete additionalFields.geolocationUi;
                  }
                  if (additionalFields.organizerUi) {
                      data.organizer = additionalFields.organizerUi
                          .organizerValues;
                      delete additionalFields.organizerUi;
                  }
                  if (additionalFields.attendeesUi) {
                      data.attendees = additionalFields.attendeesUi
                          .attendeeValues;
                      delete additionalFields.attendeesUi;
                  }
                  Object.assign(data, additionalFields);
                  const buffer = Buffer.from((await createEvent(data)));
                  const binaryData = await this.helpers.prepareBinaryData(buffer, fileName, 'text/calendar');
                  returnData.push({
                      json: {},
                      binary: {
                          [binaryPropertyName]: binaryData,
                      },
                      pairedItem: {
                          item: i,
                      },
                  });
              }
          }
          return [returnData];
      }
  }
  exports.ICalendar = ICalendar;
  //# sourceMappingURL=ICalendar.node.js.map

example_workflow:
  {"name":"iCalendar Example Workflow","nodes":[{"parameters":{},"id":"ntp04jm5rs183bl9vaktmh","name":"iCalendar","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.Interval
name: Interval
display_name: Interval
description: Triggers the workflow in a given interval
category: Other
icon: fa:hourglass
code_hash: 395078df09873d83a3b69b11f17d73622c51e2d85584a0ce995738a764a1fe3c
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
version: 1.0
extracted_at: 2025-06-09 15:18:11
updated_at: 2025-06-09 15:18:11
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Interval = void 0;
  const n8n_workflow_1 = require("n8n-workflow");
  class Interval {
      constructor() {
          this.description = {
              displayName: 'Interval',
              name: 'interval',
              icon: 'fa:hourglass',
              group: ['trigger', 'schedule'],
              version: 1,
              hidden: true,
              description: 'Triggers the workflow in a given interval',
              eventTriggerDescription: '',
              activationMessage: 'Your interval trigger will now trigger executions on the schedule you have defined.',
              defaults: {
                  name: 'Interval',
                  color: '#00FF00',
              },
              inputs: [],
              outputs: ['main'],
              properties: [
                  {
                      displayName: 'This workflow will run on the schedule you define here once you <a data-key="activate">activate</a> it.<br><br>For testing, you can also trigger it manually: by going back to the canvas and clicking ‘execute workflow’',
                      name: 'notice',
                      type: 'notice',
                      default: '',
                  },
                  {
                      displayName: 'Interval',
                      name: 'interval',
                      type: 'number',
                      typeOptions: {
                          minValue: 1,
                      },
                      default: 1,
                      description: 'Interval value',
                  },
                  {
                      displayName: 'Unit',
                      name: 'unit',
                      type: 'options',
                      options: [
                          {
                              name: 'Seconds',
                              value: 'seconds',
                          },
                          {
                              name: 'Minutes',
                              value: 'minutes',
                          },
                          {
                              name: 'Hours',
                              value: 'hours',
                          },
                      ],
                      default: 'seconds',
                      description: 'Unit of the interval value',
                  },
              ],
          };
      }
      async trigger() {
          const interval = this.getNodeParameter('interval');
          const unit = this.getNodeParameter('unit');
          if (interval <= 0) {
              throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'The interval has to be set to at least 1 or higher!');
          }
          let intervalValue = interval;
          if (unit === 'minutes') {
              intervalValue *= 60;
          }
          if (unit === 'hours') {
              intervalValue *= 60 * 60;
          }
          const executeTrigger = () => {
              this.emit([this.helpers.returnJsonArray([{}])]);
          };
          intervalValue *= 1000;
          if (intervalValue > 2147483647) {
              throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'The interval value is too large.');
          }
          const intervalObj = setInterval(executeTrigger, intervalValue);
          async function closeFunction() {
              clearInterval(intervalObj);
          }
          async function manualTriggerFunction() {
              executeTrigger();
          }
          return {
              closeFunction,
              manualTriggerFunction,
          };
      }
  }
  exports.Interval = Interval;
  //# sourceMappingURL=Interval.node.js.map

example_workflow:
  {"name":"Interval Example Workflow","nodes":[{"parameters":{},"id":"dgw7zefysbofotk2500du7","name":"Interval","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.If
name: If
display_name: IF
description: Route items to different branches (true/false)
category: transform
icon: fa:map-signs
code_hash: 7910ed9177a946b76f04ca847defb81226c37c698e4cdb63913f038c6c257ee1
documentation_url: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.If
documentation_title: If
operations: []
api_methods: []
documentation_examples: []
templates: [{"name":"if","description":"Templates for if"}]
required_scopes: []
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
version: 1.0
extracted_at: 2025-06-09 15:18:11
updated_at: 2025-06-09 15:18:11
source_code:
  "use strict";
  var __importDefault = (this && this.__importDefault) || function (mod) {
      return (mod && mod.__esModule) ? mod : { "default": mod };
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.If = void 0;
  const moment_1 = __importDefault(require("moment"));
  const n8n_workflow_1 = require("n8n-workflow");
  class If {
      constructor() {
          this.description = {
              displayName: 'IF',
              name: 'if',
              icon: 'fa:map-signs',
              group: ['transform'],
              version: 1,
              description: 'Route items to different branches (true/false)',
              defaults: {
                  name: 'IF',
                  color: '#408000',
              },
              inputs: ['main'],
              outputs: ['main', 'main'],
              outputNames: ['true', 'false'],
              properties: [
                  {
                      displayName: 'Conditions',
                      name: 'conditions',
                      placeholder: 'Add Condition',
                      type: 'fixedCollection',
                      typeOptions: {
                          multipleValues: true,
                          sortable: true,
                      },
                      description: 'The type of values to compare',
                      default: {},
                      options: [
                          {
                              name: 'boolean',
                              displayName: 'Boolean',
                              values: [
                                  {
                                      displayName: 'Value 1',
                                      name: 'value1',
                                      type: 'boolean',
                                      default: false,
                                      description: 'The value to compare with the second one',
                                  },
                                  {
                                      displayName: 'Operation',
                                      name: 'operation',
                                      type: 'options',
                                      options: [
                                          {
                                              name: 'Equal',
                                              value: 'equal',
                                          },
                                          {
                                              name: 'Not Equal',
                                              value: 'notEqual',
                                          },
                                      ],
                                      default: 'equal',
                                      description: 'Operation to decide where the the data should be mapped to',
                                  },
                                  {
                                      displayName: 'Value 2',
                                      name: 'value2',
                                      type: 'boolean',
                                      default: false,
                                      description: 'The value to compare with the first one',
                                  },
                              ],
                          },
                          {
                              name: 'dateTime',
                              displayName: 'Date & Time',
                              values: [
                                  {
                                      displayName: 'Value 1',
                                      name: 'value1',
                                      type: 'dateTime',
                                      default: '',
                                      description: 'The value to compare with the second one',
                                  },
                                  {
                                      displayName: 'Operation',
                                      name: 'operation',
                                      type: 'options',
                                      options: [
                                          {
                                              name: 'Occurred After',
                                              value: 'after',
                                          },
                                          {
                                              name: 'Occurred Before',
                                              value: 'before',
                                          },
                                      ],
                                      default: 'after',
                                      description: 'Operation to decide where the the data should be mapped to',
                                  },
                                  {
                                      displayName: 'Value 2',
                                      name: 'value2',
                                      type: 'dateTime',
                                      default: '',
                                      description: 'The value to compare with the first one',
                                  },
                              ],
                          },
                          {
                              name: 'number',
                              displayName: 'Number',
                              values: [
                                  {
                                      displayName: 'Value 1',
                                      name: 'value1',
                                      type: 'number',
                                      default: 0,
                                      description: 'The value to compare with the second one',
                                  },
                                  {
                                      displayName: 'Operation',
                                      name: 'operation',
                                      type: 'options',
                                      noDataExpression: true,
                                      options: [
                                          {
                                              name: 'Smaller',
                                              value: 'smaller',
                                          },
                                          {
                                              name: 'Smaller or Equal',
                                              value: 'smallerEqual',
                                          },
                                          {
                                              name: 'Equal',
                                              value: 'equal',
                                          },
                                          {
                                              name: 'Not Equal',
                                              value: 'notEqual',
                                          },
                                          {
                                              name: 'Larger',
                                              value: 'larger',
                                          },
                                          {
                                              name: 'Larger or Equal',
                                              value: 'largerEqual',
                                          },
                                          {
                                              name: 'Is Empty',
                                              value: 'isEmpty',
                                          },
                                          {
                                              name: 'Is Not Empty',
                                              value: 'isNotEmpty',
                                          },
                                      ],
                                      default: 'smaller',
                                      description: 'Operation to decide where the the data should be mapped to',
                                  },
                                  {
                                      displayName: 'Value 2',
                                      name: 'value2',
                                      type: 'number',
                                      displayOptions: {
                                          hide: {
                                              operation: ['isEmpty', 'isNotEmpty'],
                                          },
                                      },
                                      default: 0,
                                      description: 'The value to compare with the first one',
                                  },
                              ],
                          },
                          {
                              name: 'string',
                              displayName: 'String',
                              values: [
                                  {
                                      displayName: 'Value 1',
                                      name: 'value1',
                                      type: 'string',
                                      default: '',
                                      description: 'The value to compare with the second one',
                                  },
                                  {
                                      displayName: 'Operation',
                                      name: 'operation',
                                      type: 'options',
                                      noDataExpression: true,
                                      options: [
                                          {
                                              name: 'Contains',
                                              value: 'contains',
                                          },
                                          {
                                              name: 'Not Contains',
                                              value: 'notContains',
                                          },
                                          {
                                              name: 'Ends With',
                                              value: 'endsWith',
                                          },
                                          {
                                              name: 'Not Ends With',
                                              value: 'notEndsWith',
                                          },
                                          {
                                              name: 'Equal',
                                              value: 'equal',
                                          },
                                          {
                                              name: 'Not Equal',
                                              value: 'notEqual',
                                          },
                                          {
                                              name: 'Regex Match',
                                              value: 'regex',
                                          },
                                          {
                                              name: 'Regex Not Match',
                                              value: 'notRegex',
                                          },
                                          {
                                              name: 'Starts With',
                                              value: 'startsWith',
                                          },
                                          {
                                              name: 'Not Starts With',
                                              value: 'notStartsWith',
                                          },
                                          {
                                              name: 'Is Empty',
                                              value: 'isEmpty',
                                          },
                                          {
                                              name: 'Is Not Empty',
                                              value: 'isNotEmpty',
                                          },
                                      ],
                                      default: 'equal',
                                      description: 'Operation to decide where the the data should be mapped to',
                                  },
                                  {
                                      displayName: 'Value 2',
                                      name: 'value2',
                                      type: 'string',
                                      displayOptions: {
                                          hide: {
                                              operation: ['isEmpty', 'isNotEmpty', 'regex', 'notRegex'],
                                          },
                                      },
                                      default: '',
                                      description: 'The value to compare with the first one',
                                  },
                                  {
                                      displayName: 'Regex',
                                      name: 'value2',
                                      type: 'string',
                                      displayOptions: {
                                          show: {
                                              operation: ['regex', 'notRegex'],
                                          },
                                      },
                                      default: '',
                                      placeholder: '/text/i',
                                      description: 'The regex which has to match',
                                  },
                              ],
                          },
                      ],
                  },
                  {
                      displayName: 'Combine',
                      name: 'combineOperation',
                      type: 'options',
                      options: [
                          {
                              name: 'ALL',
                              description: 'Only if all conditions are met it goes into "true" branch',
                              value: 'all',
                          },
                          {
                              name: 'ANY',
                              description: 'If any of the conditions is met it goes into "true" branch',
                              value: 'any',
                          },
                      ],
                      default: 'all',
                      description: 'If multiple rules got set this settings decides if it is true as soon as ANY condition matches or only if ALL get meet',
                  },
              ],
          };
      }
      async execute() {
          const returnDataTrue = [];
          const returnDataFalse = [];
          const items = this.getInputData();
          let item;
          let combineOperation;
          const isDateObject = (value) => Object.prototype.toString.call(value) === '[object Date]';
          const isDateInvalid = (value) => (value === null || value === void 0 ? void 0 : value.toString()) === 'Invalid Date';
          const compareOperationFunctions = {
              after: (value1, value2) => (value1 || 0) > (value2 || 0),
              before: (value1, value2) => (value1 || 0) < (value2 || 0),
              contains: (value1, value2) => (value1 || '').toString().includes((value2 || '').toString()),
              notContains: (value1, value2) => !(value1 || '').toString().includes((value2 || '').toString()),
              endsWith: (value1, value2) => value1.endsWith(value2),
              notEndsWith: (value1, value2) => !value1.endsWith(value2),
              equal: (value1, value2) => value1 === value2,
              notEqual: (value1, value2) => value1 !== value2,
              larger: (value1, value2) => (value1 || 0) > (value2 || 0),
              largerEqual: (value1, value2) => (value1 || 0) >= (value2 || 0),
              smaller: (value1, value2) => (value1 || 0) < (value2 || 0),
              smallerEqual: (value1, value2) => (value1 || 0) <= (value2 || 0),
              startsWith: (value1, value2) => value1.startsWith(value2),
              notStartsWith: (value1, value2) => !value1.startsWith(value2),
              isEmpty: (value1) => [undefined, null, '', NaN].includes(value1) ||
                  (typeof value1 === 'object' && value1 !== null && !isDateObject(value1)
                      ? Object.entries(value1).length === 0
                      : false) ||
                  (isDateObject(value1) && isDateInvalid(value1)),
              isNotEmpty: (value1) => !([undefined, null, '', NaN].includes(value1) ||
                  (typeof value1 === 'object' && value1 !== null && !isDateObject(value1)
                      ? Object.entries(value1).length === 0
                      : false) ||
                  (isDateObject(value1) && isDateInvalid(value1))),
              regex: (value1, value2) => {
                  const regexMatch = (value2 || '').toString().match(new RegExp('^/(.*?)/([gimusy]*)$'));
                  let regex;
                  if (!regexMatch) {
                      regex = new RegExp((value2 || '').toString());
                  }
                  else if (regexMatch.length === 1) {
                      regex = new RegExp(regexMatch[1]);
                  }
                  else {
                      regex = new RegExp(regexMatch[1], regexMatch[2]);
                  }
                  return !!(value1 || '').toString().match(regex);
              },
              notRegex: (value1, value2) => {
                  const regexMatch = (value2 || '').toString().match(new RegExp('^/(.*?)/([gimusy]*)$'));
                  let regex;
                  if (!regexMatch) {
                      regex = new RegExp((value2 || '').toString());
                  }
                  else if (regexMatch.length === 1) {
                      regex = new RegExp(regexMatch[1]);
                  }
                  else {
                      regex = new RegExp(regexMatch[1], regexMatch[2]);
                  }
                  return !(value1 || '').toString().match(regex);
              },
          };
          const convertDateTime = (value) => {
              let returnValue = undefined;
              if (typeof value === 'string') {
                  returnValue = new Date(value).getTime();
              }
              else if (typeof value === 'number') {
                  returnValue = value;
              }
              if (moment_1.default.isMoment(value)) {
                  returnValue = value.unix();
              }
              if (value instanceof Date) {
                  returnValue = value.getTime();
              }
              if (returnValue === undefined || isNaN(returnValue)) {
                  throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The value "${value}" is not a valid DateTime.`);
              }
              return returnValue;
          };
          const dataTypes = ['boolean', 'dateTime', 'number', 'string'];
          let dataType;
          let compareOperationResult;
          let value1, value2;
          itemLoop: for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
              item = items[itemIndex];
              let compareData;
              combineOperation = this.getNodeParameter('combineOperation', itemIndex);
              for (dataType of dataTypes) {
                  for (compareData of this.getNodeParameter(`conditions.${dataType}`, itemIndex, [])) {
                      value1 = compareData.value1;
                      value2 = compareData.value2;
                      if (dataType === 'dateTime') {
                          value1 = convertDateTime(value1);
                          value2 = convertDateTime(value2);
                      }
                      compareOperationResult = compareOperationFunctions[compareData.operation](value1, value2);
                      if (compareOperationResult && combineOperation === 'any') {
                          returnDataTrue.push(item);
                          continue itemLoop;
                      }
                      else if (!compareOperationResult && combineOperation === 'all') {
                          returnDataFalse.push(item);
                          continue itemLoop;
                      }
                  }
              }
              if (item.pairedItem === undefined) {
                  item.pairedItem = [{ item: itemIndex }];
              }
              if (combineOperation === 'all') {
                  returnDataTrue.push(item);
              }
              else {
                  returnDataFalse.push(item);
              }
          }
          return [returnDataTrue, returnDataFalse];
      }
  }
  exports.If = If;
  //# sourceMappingURL=If.node.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: If
  description: Documentation for the If node in n8n, a workflow automation platform. Includes guidance on usage, and links to examples.
  contentType: [integration, reference]
  priority: critical
  tags:
    - if
    - if node
    - If
    - If node
  hide:
    - tags
  ---

  # If

  Use the If node to split a workflow conditionally based on comparison operations.

  ## Add conditions

  Create comparison **Conditions** for your If node.

  - Use the data type dropdown to select the data type and comparison operation type for your condition. For example, to filter for dates after a particular date, select **Date & Time > is after**.
  - The fields and values to enter into the condition change based on the data type and comparison you select. Refer to [Available data type comparisons](#available-data-type-comparisons) for a full list of all comparisons by data type.

  Select **Add condition** to create more conditions.

  ### Combining conditions

  You can choose to keep data:

  * When it meets all conditions: Create two or more conditions and select **AND** in the dropdown between them.
  * When it meets any of the conditions: Create two or more conditions and select **OR** in the dropdown between them.

  ## Templates and examples

  <!-- see https://www.notion.so/n8n/Pull-in-templates-for-the-integrations-pages-37c716837b804d30a33b47475f6e3780 -->
  [[ templatesWidget(page.title, 'if') ]]

  ## Branch execution with If and Merge nodes

  --8<-- "_snippets/integrations/builtin/core-nodes/merge/if-merge-branch-execution.md"

  ## Related resources

  Refer to [Splitting with conditionals](/flow-logic/splitting.md) for more information on using conditionals to create complex logic in n8n.

  If you need more than two conditional outputs, use the [Switch node](/integrations/builtin/core-nodes/n8n-nodes-base.switch.md).

  --8<-- "_snippets/integrations/builtin/core-nodes/data-types.md"

related_resources:
  [{"title":"Splitting with conditionals","url":"/flow-logic/splitting.md","type":"documentation"},{"title":"Switch node","url":"/integrations/builtin/core-nodes/n8n-nodes-base.switch.md","type":"documentation"}]

example_workflow:
  {"name":"IF Example Workflow","nodes":[{"parameters":{},"id":"4yaru8xwqh3rbtas3dk8n","name":"IF","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.Hunter
name: Hunter
display_name: Hunter
description: Consume Hunter API
category: output
icon: file:hunter.png
code_hash: 51c8bda9ec8694acf0c9362ae3c4ede9dc8e3fcf9b20e8b4d42731ce83b2c983
documentation_url: https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.Hunter
documentation_title: Hunter node documentation
operations: []
api_methods: []
documentation_examples: []
templates: [{"name":"hunter","description":"Templates for hunter"}]
related_resources: []
required_scopes: []
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
version: 1.0
extracted_at: 2025-06-09 15:18:11
updated_at: 2025-06-09 15:18:11
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Hunter = void 0;
  const GenericFunctions_1 = require("./GenericFunctions");
  class Hunter {
      constructor() {
          this.description = {
              displayName: 'Hunter',
              name: 'hunter',
              icon: 'file:hunter.png',
              group: ['output'],
              version: 1,
              subtitle: '={{$parameter["operation"]}}',
              description: 'Consume Hunter API',
              defaults: {
                  name: 'Hunter',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'hunterApi',
                      required: true,
                  },
              ],
              properties: [
                  {
                      displayName: 'Operation',
                      name: 'operation',
                      type: 'options',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Domain Search',
                              value: 'domainSearch',
                              description: 'Get every email address found on the internet using a given domain name, with sources',
                              action: 'Get every email address found on the internet using a given domain name, with sources',
                          },
                          {
                              name: 'Email Finder',
                              value: 'emailFinder',
                              description: 'Generate or retrieve the most likely email address from a domain name, a first name and a last name',
                              action: 'Generate or retrieve the most likely email address from a domain name, a first name and a last name',
                          },
                          {
                              name: 'Email Verifier',
                              value: 'emailVerifier',
                              description: 'Verify the deliverability of an email address',
                              action: 'Verify the deliverability of an email address',
                          },
                      ],
                      default: 'domainSearch',
                      description: 'Operation to consume',
                  },
                  {
                      displayName: 'Domain',
                      name: 'domain',
                      type: 'string',
                      displayOptions: {
                          show: {
                              operation: ['domainSearch'],
                          },
                      },
                      default: '',
                      required: true,
                      description: 'Domain name from which you want to find the email addresses. For example, "stripe.com".',
                  },
                  {
                      displayName: 'Only Emails',
                      name: 'onlyEmails',
                      type: 'boolean',
                      displayOptions: {
                          show: {
                              operation: ['domainSearch'],
                          },
                      },
                      default: true,
                      description: 'Whether to return only the the found emails',
                  },
                  {
                      displayName: 'Return All',
                      name: 'returnAll',
                      type: 'boolean',
                      displayOptions: {
                          show: {
                              operation: ['domainSearch'],
                          },
                      },
                      default: false,
                      description: 'Whether to return all results or only up to a given limit',
                  },
                  {
                      displayName: 'Limit',
                      name: 'limit',
                      type: 'number',
                      displayOptions: {
                          show: {
                              operation: ['domainSearch'],
                              returnAll: [false],
                          },
                      },
                      typeOptions: {
                          minValue: 1,
                          maxValue: 100,
                      },
                      default: 100,
                      description: 'Max number of results to return',
                  },
                  {
                      displayName: 'Filters',
                      name: 'filters',
                      type: 'collection',
                      placeholder: 'Add Filter',
                      default: {},
                      displayOptions: {
                          show: {
                              operation: ['domainSearch'],
                          },
                      },
                      options: [
                          {
                              displayName: 'Type',
                              name: 'type',
                              type: 'options',
                              default: '',
                              options: [
                                  {
                                      name: 'Personal',
                                      value: 'personal',
                                  },
                                  {
                                      name: 'Generic',
                                      value: 'generic',
                                  },
                              ],
                          },
                          {
                              displayName: 'Seniority',
                              name: 'seniority',
                              type: 'multiOptions',
                              default: [],
                              options: [
                                  {
                                      name: 'Junior',
                                      value: 'junior',
                                  },
                                  {
                                      name: 'Senior',
                                      value: 'senior',
                                  },
                                  {
                                      name: 'Executive',
                                      value: 'executive',
                                  },
                              ],
                          },
                          {
                              displayName: 'Department',
                              name: 'department',
                              type: 'multiOptions',
                              default: [],
                              options: [
                                  {
                                      name: 'Communication',
                                      value: 'communication',
                                  },
                                  {
                                      name: 'Executive',
                                      value: 'executive',
                                  },
                                  {
                                      name: 'Finance',
                                      value: 'finance',
                                  },
                                  {
                                      name: 'HR',
                                      value: 'hr',
                                  },
                                  {
                                      name: 'IT',
                                      value: 'it',
                                  },
                                  {
                                      name: 'Legal',
                                      value: 'legal',
                                  },
                                  {
                                      name: 'Management',
                                      value: 'management',
                                  },
                                  {
                                      name: 'Marketing',
                                      value: 'marketing',
                                  },
                                  {
                                      name: 'Sales',
                                      value: 'sales',
                                  },
                                  {
                                      name: 'Support',
                                      value: 'support',
                                  },
                              ],
                          },
                      ],
                  },
                  {
                      displayName: 'Domain',
                      name: 'domain',
                      type: 'string',
                      default: '',
                      displayOptions: {
                          show: {
                              operation: ['emailFinder'],
                          },
                      },
                      required: true,
                      description: 'Domain name from which you want to find the email addresses. For example, "stripe.com".',
                  },
                  {
                      displayName: 'First Name',
                      name: 'firstname',
                      type: 'string',
                      displayOptions: {
                          show: {
                              operation: ['emailFinder'],
                          },
                      },
                      default: '',
                      required: true,
                      description: "The person's first name. It doesn't need to be in lowercase.",
                  },
                  {
                      displayName: 'Last Name',
                      name: 'lastname',
                      type: 'string',
                      displayOptions: {
                          show: {
                              operation: ['emailFinder'],
                          },
                      },
                      default: '',
                      required: true,
                      description: "The person's last name. It doesn't need to be in lowercase.",
                  },
                  {
                      displayName: 'Email',
                      name: 'email',
                      type: 'string',
                      placeholder: 'name@email.com',
                      displayOptions: {
                          show: {
                              operation: ['emailVerifier'],
                          },
                      },
                      default: '',
                      required: true,
                      description: 'The email address you want to verify',
                  },
              ],
          };
      }
      async execute() {
          const items = this.getInputData();
          const returnData = [];
          const length = items.length;
          const qs = {};
          let responseData;
          for (let i = 0; i < length; i++) {
              try {
                  const operation = this.getNodeParameter('operation', 0);
                  if (operation === 'domainSearch') {
                      const returnAll = this.getNodeParameter('returnAll', i);
                      const filters = this.getNodeParameter('filters', i);
                      const domain = this.getNodeParameter('domain', i);
                      const onlyEmails = this.getNodeParameter('onlyEmails', i, false);
                      qs.domain = domain;
                      if (filters.type) {
                          qs.type = filters.type;
                      }
                      if (filters.seniority) {
                          qs.seniority = filters.seniority.join(',');
                      }
                      if (filters.department) {
                          qs.department = filters.department.join(',');
                      }
                      if (returnAll) {
                          responseData = await GenericFunctions_1.hunterApiRequestAllItems.call(this, 'data', 'GET', '/domain-search', {}, qs);
                          if (!onlyEmails) {
                              let tempReturnData = {};
                              for (let index = 0; index < responseData.length; index++) {
                                  if (index === 0) {
                                      tempReturnData = responseData[index];
                                      continue;
                                  }
                                  tempReturnData.emails.push.apply(tempReturnData.emails, responseData[index].emails);
                              }
                              responseData = tempReturnData;
                          }
                      }
                      else {
                          const limit = this.getNodeParameter('limit', i);
                          qs.limit = limit;
                          responseData = await GenericFunctions_1.hunterApiRequest.call(this, 'GET', '/domain-search', {}, qs);
                          responseData = responseData.data;
                      }
                      if (onlyEmails) {
                          let tempReturnData = [];
                          if (Array.isArray(responseData)) {
                              for (const data of responseData) {
                                  tempReturnData.push.apply(tempReturnData, data.emails);
                              }
                          }
                          else {
                              tempReturnData = responseData.emails;
                          }
                          responseData = tempReturnData;
                      }
                  }
                  if (operation === 'emailFinder') {
                      const domain = this.getNodeParameter('domain', i);
                      const firstname = this.getNodeParameter('firstname', i);
                      const lastname = this.getNodeParameter('lastname', i);
                      qs.first_name = firstname;
                      qs.last_name = lastname;
                      qs.domain = domain;
                      responseData = await GenericFunctions_1.hunterApiRequest.call(this, 'GET', '/email-finder', {}, qs);
                      responseData = responseData.data;
                  }
                  if (operation === 'emailVerifier') {
                      const email = this.getNodeParameter('email', i);
                      qs.email = email;
                      responseData = await GenericFunctions_1.hunterApiRequest.call(this, 'GET', '/email-verifier', {}, qs);
                      responseData = responseData.data;
                  }
                  const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                  returnData.push(...executionData);
              }
              catch (error) {
                  if (this.continueOnFail()) {
                      const executionErrorData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ error: error.message }), { itemData: { item: i } });
                      returnData.push(...executionErrorData);
                      continue;
                  }
                  throw error;
              }
          }
          return [returnData];
      }
  }
  exports.Hunter = Hunter;
  //# sourceMappingURL=Hunter.node.js.map

credential_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HunterApi = void 0;
  class HunterApi {
      constructor() {
          this.name = 'hunterApi';
          this.displayName = 'Hunter API';
          this.documentationUrl = 'hunter';
          this.properties = [
              {
                  displayName: 'API Key',
                  name: 'apiKey',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
              },
          ];
      }
  }
  exports.HunterApi = HunterApi;
  //# sourceMappingURL=HunterApi.credentials.js.map

  // --- Next Credential File ---

  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HunterApi = void 0;
  class HunterApi {
      constructor() {
          this.name = 'hunterApi';
          this.displayName = 'Hunter API';
          this.documentationUrl = 'hunter';
          this.properties = [
              {
                  displayName: 'API Key',
                  name: 'apiKey',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
              },
          ];
      }
  }
  exports.HunterApi = HunterApi;
  //# sourceMappingURL=HunterApi.credentials.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Hunter node documentation
  description: Learn how to use the Hunter node in n8n. Follow technical documentation to integrate Hunter node into your workflows.
  contentType: [integration, reference]
  ---

  # Hunter node

  Use the Hunter node to automate work in Hunter, and integrate Hunter with other applications. n8n has built-in support for a wide range of Hunter features, including getting, generating, and verifying email addresses. 

  On this page, you'll find a list of operations the Hunter node supports and links to more resources.

  /// note | Credentials
  Refer to [Hunter credentials](/integrations/builtin/credentials/hunter.md) for guidance on setting up authentication. 
  ///

  ## Operations

  * Get every email address found on the internet using a given domain name, with sources
  * Generate or retrieve the most likely email address from a domain name, a first name and a last name
  * Verify the deliverability of an email address

  ## Templates and examples

  <!-- see https://www.notion.so/n8n/Pull-in-templates-for-the-integrations-pages-37c716837b804d30a33b47475f6e3780 -->
  [[ templatesWidget(page.title, 'hunter') ]]

example_workflow:
  {"name":"Hunter Example Workflow","nodes":[{"parameters":{},"id":"o8gccn070ne6bxi0wce1eq","name":"Hunter","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.Intercom
name: Intercom
display_name: Intercom
description: Consume Intercom API
category: output
icon: file:intercom.png
code_hash: be4c08e687ac6d523ea522d1b9f22155077485762de518664618a8a40f427844
documentation_url: https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.Intercom
documentation_title: Intercom node documentation
operations: []
api_methods: []
documentation_examples: []
templates: [{"name":"intercom","description":"Templates for intercom"}]
related_resources: []
required_scopes: []
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
version: 1.0
extracted_at: 2025-06-09 15:18:11
updated_at: 2025-06-09 15:18:11
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Intercom = void 0;
  const n8n_workflow_1 = require("n8n-workflow");
  const LeadDescription_1 = require("./LeadDescription");
  const GenericFunctions_1 = require("./GenericFunctions");
  const UserDescription_1 = require("./UserDescription");
  const CompanyDescription_1 = require("./CompanyDescription");
  class Intercom {
      constructor() {
          this.description = {
              displayName: 'Intercom',
              name: 'intercom',
              icon: 'file:intercom.png',
              group: ['output'],
              version: 1,
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Consume Intercom API',
              defaults: {
                  name: 'Intercom',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'intercomApi',
                      required: true,
                  },
              ],
              properties: [
                  {
                      displayName: 'Resource',
                      name: 'resource',
                      type: 'options',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Company',
                              value: 'company',
                              description: 'Companies allow you to represent commercial organizations using your product',
                          },
                          {
                              name: 'Lead',
                              value: 'lead',
                              description: 'Leads are useful for representing logged-out users of your application',
                          },
                          {
                              name: 'User',
                              value: 'user',
                              description: 'The Users resource is the primary way of interacting with Intercom',
                          },
                      ],
                      default: 'user',
                  },
                  ...LeadDescription_1.leadOperations,
                  ...UserDescription_1.userOperations,
                  ...CompanyDescription_1.companyOperations,
                  ...UserDescription_1.userFields,
                  ...LeadDescription_1.leadFields,
                  ...CompanyDescription_1.companyFields,
              ],
          };
          this.methods = {
              loadOptions: {
                  async getCompanies() {
                      const returnData = [];
                      let response;
                      try {
                          response = await GenericFunctions_1.intercomApiRequest.call(this, '/companies', 'GET');
                      }
                      catch (error) {
                          throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
                      }
                      const companies = response.companies;
                      for (const company of companies) {
                          const companyName = company.name;
                          const companyId = company.company_id;
                          returnData.push({
                              name: companyName,
                              value: companyId,
                          });
                      }
                      return returnData;
                  },
              },
          };
      }
      async execute() {
          const items = this.getInputData();
          const returnData = [];
          const length = items.length;
          let qs;
          let responseData;
          for (let i = 0; i < length; i++) {
              try {
                  qs = {};
                  const resource = this.getNodeParameter('resource', 0);
                  const operation = this.getNodeParameter('operation', 0);
                  if (resource === 'lead') {
                      if (operation === 'create' || operation === 'update') {
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          const jsonActive = this.getNodeParameter('jsonParameters', i);
                          const body = {};
                          if (operation === 'create') {
                              body.email = this.getNodeParameter('email', i);
                          }
                          if (additionalFields.email) {
                              body.email = additionalFields.email;
                          }
                          if (additionalFields.phone) {
                              body.phone = additionalFields.phone;
                          }
                          if (additionalFields.name) {
                              body.name = additionalFields.name;
                          }
                          if (additionalFields.unsubscribedFromEmails) {
                              body.unsubscribed_from_emails = additionalFields.unsubscribedFromEmails;
                          }
                          if (additionalFields.updateLastRequestAt) {
                              body.update_last_request_at = additionalFields.updateLastRequestAt;
                          }
                          if (additionalFields.utmSource) {
                              body.utm_source = additionalFields.utmSource;
                          }
                          if (additionalFields.utmMedium) {
                              body.utm_medium = additionalFields.utmMedium;
                          }
                          if (additionalFields.utmCampaign) {
                              body.utm_campaign = additionalFields.utmCampaign;
                          }
                          if (additionalFields.utmTerm) {
                              body.utm_term = additionalFields.utmTerm;
                          }
                          if (additionalFields.utmContent) {
                              body.utm_content = additionalFields.utmContent;
                          }
                          if (additionalFields.avatar) {
                              const avatar = {
                                  type: 'avatar',
                                  image_url: additionalFields.avatar,
                              };
                              body.avatar = avatar;
                          }
                          if (additionalFields.companies) {
                              const companies = [];
                              additionalFields.companies.forEach((o) => {
                                  const company = {};
                                  company.company_id = o;
                                  companies.push(company);
                              });
                              body.companies = companies;
                          }
                          if (!jsonActive) {
                              const customAttributesValues = this.getNodeParameter('customAttributesUi', i).customAttributesValues;
                              if (customAttributesValues) {
                                  const customAttributes = {};
                                  for (let index = 0; index < customAttributesValues.length; index++) {
                                      customAttributes[customAttributesValues[index].name] =
                                          customAttributesValues[index].value;
                                  }
                                  body.custom_attributes = customAttributes;
                              }
                          }
                          else {
                              const customAttributesJson = (0, GenericFunctions_1.validateJSON)(this.getNodeParameter('customAttributesJson', i));
                              if (customAttributesJson) {
                                  body.custom_attributes = customAttributesJson;
                              }
                          }
                          if (operation === 'update') {
                              const updateBy = this.getNodeParameter('updateBy', 0);
                              const value = this.getNodeParameter('value', i);
                              if (updateBy === 'userId') {
                                  body.user_id = value;
                              }
                              if (updateBy === 'id') {
                                  body.id = value;
                              }
                          }
                          try {
                              responseData = await GenericFunctions_1.intercomApiRequest.call(this, '/contacts', 'POST', body);
                          }
                          catch (error) {
                              throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
                          }
                      }
                      if (operation === 'get') {
                          const selectBy = this.getNodeParameter('selectBy', 0);
                          const value = this.getNodeParameter('value', i);
                          if (selectBy === 'email') {
                              qs.email = value;
                          }
                          if (selectBy === 'userId') {
                              qs.user_id = value;
                          }
                          if (selectBy === 'phone') {
                              qs.phone = value;
                          }
                          try {
                              if (selectBy === 'id') {
                                  responseData = await GenericFunctions_1.intercomApiRequest.call(this, `/contacts/${value}`, 'GET');
                              }
                              else {
                                  responseData = await GenericFunctions_1.intercomApiRequest.call(this, '/contacts', 'GET', {}, qs);
                                  responseData = responseData.contacts;
                              }
                          }
                          catch (error) {
                              throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
                          }
                      }
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', i);
                          const filters = this.getNodeParameter('filters', i);
                          Object.assign(qs, filters);
                          try {
                              if (returnAll) {
                                  responseData = await GenericFunctions_1.intercomApiRequestAllItems.call(this, 'contacts', '/contacts', 'GET', {}, qs);
                              }
                              else {
                                  qs.per_page = this.getNodeParameter('limit', i);
                                  responseData = await GenericFunctions_1.intercomApiRequest.call(this, '/contacts', 'GET', {}, qs);
                                  responseData = responseData.contacts;
                              }
                          }
                          catch (error) {
                              throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
                          }
                      }
                      if (operation === 'delete') {
                          const deleteBy = this.getNodeParameter('deleteBy', 0);
                          const value = this.getNodeParameter('value', i);
                          try {
                              if (deleteBy === 'id') {
                                  responseData = await GenericFunctions_1.intercomApiRequest.call(this, `/contacts/${value}`, 'DELETE');
                              }
                              else {
                                  qs.user_id = value;
                                  responseData = await GenericFunctions_1.intercomApiRequest.call(this, '/contacts', 'DELETE', {}, qs);
                              }
                          }
                          catch (error) {
                              throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
                          }
                      }
                  }
                  if (resource === 'user') {
                      if (operation === 'create' || operation === 'update') {
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          const jsonActive = this.getNodeParameter('jsonParameters', i);
                          const body = {};
                          if (operation === 'create') {
                              const identifierType = this.getNodeParameter('identifierType', i);
                              if (identifierType === 'email') {
                                  body.email = this.getNodeParameter('idValue', i);
                              }
                              else if (identifierType === 'userId') {
                                  body.user_id = this.getNodeParameter('idValue', i);
                              }
                          }
                          if (additionalFields.email) {
                              body.email = additionalFields.email;
                          }
                          if (additionalFields.userId) {
                              body.user_id = additionalFields.userId;
                          }
                          if (additionalFields.phone) {
                              body.phone = additionalFields.phone;
                          }
                          if (additionalFields.name) {
                              body.name = additionalFields.name;
                          }
                          if (additionalFields.unsubscribedFromEmails) {
                              body.unsubscribed_from_emails = additionalFields.unsubscribedFromEmails;
                          }
                          if (additionalFields.updateLastRequestAt) {
                              body.update_last_request_at = additionalFields.updateLastRequestAt;
                          }
                          if (additionalFields.sessionCount) {
                              body.session_count = additionalFields.sessionCount;
                          }
                          if (additionalFields.avatar) {
                              const avatar = {
                                  type: 'avatar',
                                  image_url: additionalFields.avatar,
                              };
                              body.avatar = avatar;
                          }
                          if (additionalFields.utmSource) {
                              body.utm_source = additionalFields.utmSource;
                          }
                          if (additionalFields.utmMedium) {
                              body.utm_medium = additionalFields.utmMedium;
                          }
                          if (additionalFields.utmCampaign) {
                              body.utm_campaign = additionalFields.utmCampaign;
                          }
                          if (additionalFields.utmTerm) {
                              body.utm_term = additionalFields.utmTerm;
                          }
                          if (additionalFields.utmContent) {
                              body.utm_content = additionalFields.utmContent;
                          }
                          if (additionalFields.companies) {
                              const companies = [];
                              additionalFields.companies.forEach((o) => {
                                  const company = {};
                                  company.company_id = o;
                                  companies.push(company);
                              });
                              body.companies = companies;
                          }
                          if (additionalFields.sessionCount) {
                              body.session_count = additionalFields.sessionCount;
                          }
                          if (!jsonActive) {
                              const customAttributesValues = this.getNodeParameter('customAttributesUi', i).customAttributesValues;
                              if (customAttributesValues) {
                                  const customAttributes = {};
                                  for (let index = 0; index < customAttributesValues.length; index++) {
                                      customAttributes[customAttributesValues[index].name] =
                                          customAttributesValues[index].value;
                                  }
                                  body.custom_attributes = customAttributes;
                              }
                          }
                          else {
                              const customAttributesJson = (0, GenericFunctions_1.validateJSON)(this.getNodeParameter('customAttributesJson', i));
                              if (customAttributesJson) {
                                  body.custom_attributes = customAttributesJson;
                              }
                          }
                          if (operation === 'update') {
                              const updateBy = this.getNodeParameter('updateBy', 0);
                              const value = this.getNodeParameter('value', i);
                              if (updateBy === 'userId') {
                                  body.user_id = value;
                              }
                              if (updateBy === 'id') {
                                  body.id = value;
                              }
                              if (updateBy === 'email') {
                                  body.email = value;
                              }
                          }
                          try {
                              responseData = await GenericFunctions_1.intercomApiRequest.call(this, '/users', 'POST', body, qs);
                          }
                          catch (error) {
                              throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
                          }
                      }
                      if (operation === 'get') {
                          const selectBy = this.getNodeParameter('selectBy', 0);
                          const value = this.getNodeParameter('value', i);
                          if (selectBy === 'userId') {
                              qs.user_id = value;
                          }
                          try {
                              if (selectBy === 'id') {
                                  responseData = await GenericFunctions_1.intercomApiRequest.call(this, `/users/${value}`, 'GET', {}, qs);
                              }
                              else {
                                  responseData = await GenericFunctions_1.intercomApiRequest.call(this, '/users', 'GET', {}, qs);
                              }
                          }
                          catch (error) {
                              throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
                          }
                      }
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', i);
                          const filters = this.getNodeParameter('filters', i);
                          Object.assign(qs, filters);
                          try {
                              if (returnAll) {
                                  responseData = await GenericFunctions_1.intercomApiRequestAllItems.call(this, 'users', '/users', 'GET', {}, qs);
                              }
                              else {
                                  qs.per_page = this.getNodeParameter('limit', i);
                                  responseData = await GenericFunctions_1.intercomApiRequest.call(this, '/users', 'GET', {}, qs);
                                  responseData = responseData.users;
                              }
                          }
                          catch (error) {
                              throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
                          }
                      }
                      if (operation === 'delete') {
                          const id = this.getNodeParameter('id', i);
                          try {
                              responseData = await GenericFunctions_1.intercomApiRequest.call(this, `/users/${id}`, 'DELETE');
                          }
                          catch (error) {
                              throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Intercom Error: ${JSON.stringify(error)}`, { itemIndex: i });
                          }
                      }
                  }
                  if (resource === 'company') {
                      if (operation === 'create' || operation === 'update') {
                          const id = this.getNodeParameter('companyId', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          const jsonActive = this.getNodeParameter('jsonParameters', i);
                          const body = {
                              company_id: id,
                          };
                          if (additionalFields.monthlySpend) {
                              body.monthly_spend = additionalFields.monthlySpend;
                          }
                          if (additionalFields.name) {
                              body.name = additionalFields.name;
                          }
                          if (additionalFields.plan) {
                              body.plan = additionalFields.plan;
                          }
                          if (additionalFields.size) {
                              body.size = additionalFields.size;
                          }
                          if (additionalFields.website) {
                              body.website = additionalFields.website;
                          }
                          if (additionalFields.industry) {
                              body.industry = additionalFields.industry;
                          }
                          if (!jsonActive) {
                              const customAttributesValues = this.getNodeParameter('customAttributesUi', i).customAttributesValues;
                              if (customAttributesValues) {
                                  const customAttributes = {};
                                  for (let index = 0; index < customAttributesValues.length; index++) {
                                      customAttributes[customAttributesValues[index].name] =
                                          customAttributesValues[index].value;
                                  }
                                  body.custom_attributes = customAttributes;
                              }
                          }
                          else {
                              const customAttributesJson = (0, GenericFunctions_1.validateJSON)(this.getNodeParameter('customAttributesJson', i));
                              if (customAttributesJson) {
                                  body.custom_attributes = customAttributesJson;
                              }
                          }
                          try {
                              responseData = await GenericFunctions_1.intercomApiRequest.call(this, '/companies', 'POST', body, qs);
                          }
                          catch (error) {
                              throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Intercom Error: ${JSON.stringify(error)}`, { itemIndex: i });
                          }
                      }
                      if (operation === 'get') {
                          const selectBy = this.getNodeParameter('selectBy', 0);
                          const value = this.getNodeParameter('value', i);
                          if (selectBy === 'companyId') {
                              qs.company_id = value;
                          }
                          if (selectBy === 'name') {
                              qs.name = value;
                          }
                          try {
                              if (selectBy === 'id') {
                                  responseData = await GenericFunctions_1.intercomApiRequest.call(this, `/companies/${value}`, 'GET', {}, qs);
                              }
                              else {
                                  responseData = await GenericFunctions_1.intercomApiRequest.call(this, '/companies', 'GET', {}, qs);
                              }
                          }
                          catch (error) {
                              throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Intercom Error: ${JSON.stringify(error)}`, { itemIndex: i });
                          }
                      }
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', i);
                          const filters = this.getNodeParameter('filters', i);
                          Object.assign(qs, filters);
                          try {
                              if (returnAll) {
                                  responseData = await GenericFunctions_1.intercomApiRequestAllItems.call(this, 'companies', '/companies', 'GET', {}, qs);
                              }
                              else {
                                  qs.per_page = this.getNodeParameter('limit', i);
                                  responseData = await GenericFunctions_1.intercomApiRequest.call(this, '/companies', 'GET', {}, qs);
                                  responseData = responseData.companies;
                              }
                          }
                          catch (error) {
                              throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Intercom Error: ${JSON.stringify(error)}`, { itemIndex: i });
                          }
                      }
                      if (operation === 'users') {
                          const listBy = this.getNodeParameter('listBy', 0);
                          const value = this.getNodeParameter('value', i);
                          const returnAll = this.getNodeParameter('returnAll', i);
                          if (listBy === 'companyId') {
                              qs.company_id = value;
                          }
                          try {
                              if (listBy === 'id') {
                                  if (returnAll) {
                                      responseData = await GenericFunctions_1.intercomApiRequestAllItems.call(this, 'users', `/companies/${value}/users`, 'GET', {}, qs);
                                  }
                                  else {
                                      qs.per_page = this.getNodeParameter('limit', i);
                                      responseData = await GenericFunctions_1.intercomApiRequest.call(this, `/companies/${value}/users`, 'GET', {}, qs);
                                      responseData = responseData.users;
                                  }
                              }
                              else {
                                  qs.type = 'users';
                                  if (returnAll) {
                                      responseData = await GenericFunctions_1.intercomApiRequestAllItems.call(this, 'users', '/companies', 'GET', {}, qs);
                                  }
                                  else {
                                      qs.per_page = this.getNodeParameter('limit', i);
                                      responseData = await GenericFunctions_1.intercomApiRequest.call(this, '/companies', 'GET', {}, qs);
                                      responseData = responseData.users;
                                  }
                              }
                          }
                          catch (error) {
                              throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Intercom Error: ${JSON.stringify(error)}`, { itemIndex: i });
                          }
                      }
                  }
                  const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                  returnData.push(...executionData);
              }
              catch (error) {
                  if (this.continueOnFail()) {
                      const executionErrorData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ error: error.message }), { itemData: { item: i } });
                      returnData.push(...executionErrorData);
                      continue;
                  }
                  throw error;
              }
          }
          return [returnData];
      }
  }
  exports.Intercom = Intercom;
  //# sourceMappingURL=Intercom.node.js.map

credential_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.IntercomApi = void 0;
  class IntercomApi {
      constructor() {
          this.name = 'intercomApi';
          this.displayName = 'Intercom API';
          this.documentationUrl = 'intercom';
          this.properties = [
              {
                  displayName: 'API Key',
                  name: 'apiKey',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
              },
          ];
      }
  }
  exports.IntercomApi = IntercomApi;
  //# sourceMappingURL=IntercomApi.credentials.js.map

  // --- Next Credential File ---

  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.IntercomApi = void 0;
  class IntercomApi {
      constructor() {
          this.name = 'intercomApi';
          this.displayName = 'Intercom API';
          this.documentationUrl = 'intercom';
          this.properties = [
              {
                  displayName: 'API Key',
                  name: 'apiKey',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
              },
          ];
      }
  }
  exports.IntercomApi = IntercomApi;
  //# sourceMappingURL=IntercomApi.credentials.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Intercom node documentation
  description: Learn how to use the Intercom node in n8n. Follow technical documentation to integrate Intercom node into your workflows.
  contentType: [integration, reference]
  ---

  # Intercom node

  Use the Intercom node to automate work in Intercom, and integrate Intercom with other applications. n8n has built-in support for a wide range of Intercom features, including creating, updating, deleting, and getting companies, leads, and users. 

  On this page, you'll find a list of operations the Intercom node supports and links to more resources.

  /// note | Credentials
  Refer to [Intercom credentials](/integrations/builtin/credentials/intercom.md) for guidance on setting up authentication. 
  ///

  ## Operations

  * Company
      * Create a new company
      * Get data of a company
      * Get data of all companies
      * Update a company
      * List company's users
  * Lead
      * Create a new lead
      * Delete a lead
      * Get data of a lead
      * Get data of all leads
      * Update new lead
  * User
      * Create a new user
      * Delete a user
      * Get data of a user
      * Get data of all users
      * Update a user

  ## Templates and examples

  <!-- see https://www.notion.so/n8n/Pull-in-templates-for-the-integrations-pages-37c716837b804d30a33b47475f6e3780 -->
  [[ templatesWidget(page.title, 'intercom') ]]

example_workflow:
  {"name":"Intercom Example Workflow","nodes":[{"parameters":{},"id":"1zgc5otrbuobxbcu3qkv2q","name":"Intercom","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.HumanticAi
name: HumanticAi
display_name: Humantic AI
description: Consume Humantic AI API
category: output
icon: file:humanticai.png
code_hash: 69db54d109872cfec14f9e3f14deca42e166db38a65653b5caea041513f67f2b
documentation_url: https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.HumanticAi
documentation_title: Humantic AI node documentation
operations: []
api_methods: []
documentation_examples: []
templates: [{"name":"humantic-ai","description":"Templates for humantic-ai"}]
related_resources: []
required_scopes: []
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
version: 1.0
extracted_at: 2025-06-09 15:18:11
updated_at: 2025-06-09 15:18:11
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HumanticAi = void 0;
  const GenericFunctions_1 = require("./GenericFunctions");
  const ProfileDescription_1 = require("./ProfileDescription");
  class HumanticAi {
      constructor() {
          this.description = {
              displayName: 'Humantic AI',
              name: 'humanticAi',
              icon: 'file:humanticai.png',
              group: ['output'],
              version: 1,
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Consume Humantic AI API',
              defaults: {
                  name: 'Humantic AI',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'humanticAiApi',
                      required: true,
                  },
              ],
              properties: [
                  {
                      displayName: 'Resource',
                      name: 'resource',
                      type: 'options',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Profile',
                              value: 'profile',
                          },
                      ],
                      default: 'profile',
                  },
                  ...ProfileDescription_1.profileOperations,
                  ...ProfileDescription_1.profileFields,
              ],
          };
      }
      async execute() {
          const items = this.getInputData();
          const returnData = [];
          const length = items.length;
          const qs = {};
          let responseData;
          const resource = this.getNodeParameter('resource', 0);
          const operation = this.getNodeParameter('operation', 0);
          for (let i = 0; i < length; i++) {
              if (resource === 'profile') {
                  if (operation === 'create') {
                      const userId = this.getNodeParameter('userId', i);
                      const sendResume = this.getNodeParameter('sendResume', i);
                      qs.userid = userId;
                      if (sendResume) {
                          const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
                          const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName);
                          const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
                          responseData = await GenericFunctions_1.humanticAiApiRequest.call(this, 'POST', '/user-profile/create', {}, qs, {
                              formData: {
                                  resume: {
                                      value: binaryDataBuffer,
                                      options: {
                                          filename: binaryData.fileName,
                                      },
                                  },
                              },
                          });
                      }
                      else {
                          responseData = await GenericFunctions_1.humanticAiApiRequest.call(this, 'GET', '/user-profile/create', {}, qs);
                      }
                      if (responseData.data !== undefined) {
                          responseData = responseData.data;
                      }
                      else {
                          delete responseData.usage_stats;
                      }
                  }
                  if (operation === 'get') {
                      const userId = this.getNodeParameter('userId', i);
                      const options = this.getNodeParameter('options', i);
                      qs.userid = userId;
                      if (options.persona) {
                          qs.persona = options.persona.join(',');
                      }
                      responseData = await GenericFunctions_1.humanticAiApiRequest.call(this, 'GET', '/user-profile', {}, qs);
                      responseData = responseData.results;
                  }
                  if (operation === 'update') {
                      const userId = this.getNodeParameter('userId', i);
                      const sendResume = this.getNodeParameter('sendResume', i);
                      qs.userid = userId;
                      if (sendResume) {
                          const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
                          const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName);
                          const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
                          responseData = await GenericFunctions_1.humanticAiApiRequest.call(this, 'POST', '/user-profile/create', {}, qs, {
                              formData: {
                                  resume: {
                                      value: binaryDataBuffer,
                                      options: {
                                          filename: binaryData.fileName,
                                      },
                                  },
                              },
                          });
                          responseData = responseData.data;
                      }
                      else {
                          const text = this.getNodeParameter('text', i);
                          const body = {
                              text,
                          };
                          qs.userid = userId;
                          responseData = await GenericFunctions_1.humanticAiApiRequest.call(this, 'POST', '/user-profile/create', body, qs);
                          responseData = responseData.data;
                      }
                  }
              }
              if (Array.isArray(responseData)) {
                  returnData.push.apply(returnData, responseData);
              }
              else {
                  returnData.push(responseData);
              }
          }
          return [this.helpers.returnJsonArray(returnData)];
      }
  }
  exports.HumanticAi = HumanticAi;
  //# sourceMappingURL=HumanticAi.node.js.map

credential_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HumanticAiApi = void 0;
  class HumanticAiApi {
      constructor() {
          this.name = 'humanticAiApi';
          this.displayName = 'Humantic AI API';
          this.documentationUrl = 'humanticAi';
          this.properties = [
              {
                  displayName: 'API Key',
                  name: 'apiKey',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
              },
          ];
      }
  }
  exports.HumanticAiApi = HumanticAiApi;
  //# sourceMappingURL=HumanticAiApi.credentials.js.map

  // --- Next Credential File ---

  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.HumanticAiApi = void 0;
  class HumanticAiApi {
      constructor() {
          this.name = 'humanticAiApi';
          this.displayName = 'Humantic AI API';
          this.documentationUrl = 'humanticAi';
          this.properties = [
              {
                  displayName: 'API Key',
                  name: 'apiKey',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
              },
          ];
      }
  }
  exports.HumanticAiApi = HumanticAiApi;
  //# sourceMappingURL=HumanticAiApi.credentials.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Humantic AI node documentation
  description: Learn how to use the Humantic AI node in n8n. Follow technical documentation to integrate Humantic AI node into your workflows.
  contentType: [integration, reference]
  ---

  # Humantic AI node

  Use the Humantic AI node to automate work in Humantic AI, and integrate Humantic AI with other applications. n8n has built-in support for a wide range of Humantic AI features, including creating, retrieving, and updating profiles. 

  On this page, you'll find a list of operations the Humantic AI node supports and links to more resources.

  /// note | Credentials
  Refer to [Humantic AI credentials](/integrations/builtin/credentials/humanticai.md) for guidance on setting up authentication. 
  ///

  ## Operations

  * Profile
      * Create a profile
      * Retrieve a profile
      * Update a profile

  ## Templates and examples

  <!-- see https://www.notion.so/n8n/Pull-in-templates-for-the-integrations-pages-37c716837b804d30a33b47475f6e3780 -->
  [[ templatesWidget(page.title, 'humantic-ai') ]]

example_workflow:
  {"name":"Humantic AI Example Workflow","nodes":[{"parameters":{},"id":"fw9diukklytr55opuv55gr","name":"Humantic AI","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.InvoiceNinja
name: InvoiceNinja
display_name: Invoice Ninja
description: Consume Invoice Ninja API
category: output
icon: file:invoiceNinja.svg
code_hash: e826788255190576d2864bc51ab1a171463e343e67140ef1c5119c78e49acd8f
documentation_url: https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.InvoiceNinja
documentation_title: Invoice Ninja node documentation
operations: []
api_methods: []
documentation_examples: []
templates: [{"name":"invoice-ninja","description":"Templates for invoice-ninja"}]
related_resources: []
required_scopes: []
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-09 15:18:11
updated_at: 2025-06-09 15:18:11
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.InvoiceNinja = void 0;
  const GenericFunctions_1 = require("./GenericFunctions");
  const ClientDescription_1 = require("./ClientDescription");
  const InvoiceDescription_1 = require("./InvoiceDescription");
  const ISOCountryCodes_1 = require("./ISOCountryCodes");
  const TaskDescription_1 = require("./TaskDescription");
  const PaymentDescription_1 = require("./PaymentDescription");
  const ExpenseDescription_1 = require("./ExpenseDescription");
  const QuoteDescription_1 = require("./QuoteDescription");
  class InvoiceNinja {
      constructor() {
          this.description = {
              displayName: 'Invoice Ninja',
              name: 'invoiceNinja',
              icon: 'file:invoiceNinja.svg',
              group: ['output'],
              version: [1, 2],
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Consume Invoice Ninja API',
              defaults: {
                  name: 'Invoice Ninja',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'invoiceNinjaApi',
                      required: true,
                  },
              ],
              properties: [
                  {
                      displayName: 'API Version',
                      name: 'apiVersion',
                      type: 'options',
                      isNodeSetting: true,
                      displayOptions: {
                          show: {
                              '@version': [1],
                          },
                      },
                      options: [
                          {
                              name: 'Version 4',
                              value: 'v4',
                          },
                          {
                              name: 'Version 5',
                              value: 'v5',
                          },
                      ],
                      default: 'v4',
                  },
                  {
                      displayName: 'API Version',
                      name: 'apiVersion',
                      type: 'options',
                      isNodeSetting: true,
                      displayOptions: {
                          show: {
                              '@version': [2],
                          },
                      },
                      options: [
                          {
                              name: 'Version 4',
                              value: 'v4',
                          },
                          {
                              name: 'Version 5',
                              value: 'v5',
                          },
                      ],
                      default: 'v5',
                  },
                  {
                      displayName: 'Resource',
                      name: 'resource',
                      type: 'options',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Client',
                              value: 'client',
                          },
                          {
                              name: 'Expense',
                              value: 'expense',
                          },
                          {
                              name: 'Invoice',
                              value: 'invoice',
                          },
                          {
                              name: 'Payment',
                              value: 'payment',
                          },
                          {
                              name: 'Quote',
                              value: 'quote',
                          },
                          {
                              name: 'Task',
                              value: 'task',
                          },
                      ],
                      default: 'client',
                  },
                  ...ClientDescription_1.clientOperations,
                  ...ClientDescription_1.clientFields,
                  ...InvoiceDescription_1.invoiceOperations,
                  ...InvoiceDescription_1.invoiceFields,
                  ...TaskDescription_1.taskOperations,
                  ...TaskDescription_1.taskFields,
                  ...PaymentDescription_1.paymentOperations,
                  ...PaymentDescription_1.paymentFields,
                  ...ExpenseDescription_1.expenseOperations,
                  ...ExpenseDescription_1.expenseFields,
                  ...QuoteDescription_1.quoteOperations,
                  ...QuoteDescription_1.quoteFields,
              ],
          };
          this.methods = {
              loadOptions: {
                  async getClients() {
                      const returnData = [];
                      const clients = await GenericFunctions_1.invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/clients');
                      for (const client of clients) {
                          const clientName = client.display_name;
                          const clientId = client.id;
                          returnData.push({
                              name: clientName,
                              value: clientId,
                          });
                      }
                      return returnData;
                  },
                  async getProjects() {
                      const returnData = [];
                      const projects = await GenericFunctions_1.invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/projects');
                      for (const project of projects) {
                          const projectName = project.name;
                          const projectId = project.id;
                          returnData.push({
                              name: projectName,
                              value: projectId,
                          });
                      }
                      return returnData;
                  },
                  async getInvoices() {
                      const returnData = [];
                      const invoices = await GenericFunctions_1.invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/invoices');
                      for (const invoice of invoices) {
                          const invoiceName = (invoice.invoice_number || invoice.number);
                          const invoiceId = invoice.id;
                          returnData.push({
                              name: invoiceName,
                              value: invoiceId,
                          });
                      }
                      return returnData;
                  },
                  async getCountryCodes() {
                      const returnData = [];
                      for (let i = 0; i < ISOCountryCodes_1.countryCodes.length; i++) {
                          const countryName = ISOCountryCodes_1.countryCodes[i].name;
                          const countryId = ISOCountryCodes_1.countryCodes[i].numeric;
                          returnData.push({
                              name: countryName,
                              value: countryId,
                          });
                      }
                      return returnData;
                  },
                  async getVendors() {
                      const returnData = [];
                      const vendors = await GenericFunctions_1.invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/vendors');
                      for (const vendor of vendors) {
                          const vendorName = vendor.name;
                          const vendorId = vendor.id;
                          returnData.push({
                              name: vendorName,
                              value: vendorId,
                          });
                      }
                      return returnData;
                  },
                  async getExpenseCategories() {
                      const returnData = [];
                      const categories = await GenericFunctions_1.invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/expense_categories');
                      for (const category of categories) {
                          const categoryName = category.name;
                          const categoryId = category.id;
                          returnData.push({
                              name: categoryName,
                              value: categoryId,
                          });
                      }
                      return returnData;
                  },
              },
          };
      }
      async execute() {
          var _a;
          const items = this.getInputData();
          const returnData = [];
          const length = items.length;
          const qs = {};
          let responseData;
          const resource = this.getNodeParameter('resource', 0);
          const operation = this.getNodeParameter('operation', 0);
          const apiVersion = this.getNodeParameter('apiVersion', 0);
          for (let i = 0; i < length; i++) {
              try {
                  if (resource === 'client') {
                      if (operation === 'create') {
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          const body = {};
                          if (additionalFields.clientName) {
                              body.name = additionalFields.clientName;
                          }
                          if (additionalFields.clientName) {
                              body.name = additionalFields.clientName;
                          }
                          if (additionalFields.idNumber) {
                              body.id_number = additionalFields.idNumber;
                          }
                          if (additionalFields.idNumber) {
                              body.id_number = additionalFields.idNumber;
                          }
                          if (additionalFields.privateNotes) {
                              body.private_notes = additionalFields.privateNotes;
                          }
                          if (additionalFields.vatNumber) {
                              body.vat_number = additionalFields.vatNumber;
                          }
                          if (additionalFields.workPhone) {
                              body.work_phone = additionalFields.workPhone;
                          }
                          if (additionalFields.website) {
                              body.website = additionalFields.website;
                          }
                          const contactsValues = this.getNodeParameter('contactsUi', i)
                              .contacstValues;
                          if (contactsValues) {
                              const contacts = [];
                              for (const contactValue of contactsValues) {
                                  const contact = {
                                      first_name: contactValue.firstName,
                                      last_name: contactValue.lastName,
                                      email: contactValue.email,
                                      phone: contactValue.phone,
                                  };
                                  contacts.push(contact);
                              }
                              body.contacts = contacts;
                          }
                          const shippingAddressValue = this.getNodeParameter('shippingAddressUi', i).shippingAddressValue;
                          if (shippingAddressValue) {
                              body.shipping_address1 = shippingAddressValue.streetAddress;
                              body.shipping_address2 = shippingAddressValue.aptSuite;
                              body.shipping_city = shippingAddressValue.city;
                              body.shipping_state = shippingAddressValue.state;
                              body.shipping_postal_code = shippingAddressValue.postalCode;
                              body.shipping_country_id = parseInt(shippingAddressValue.countryCode, 10);
                          }
                          const billingAddressValue = this.getNodeParameter('billingAddressUi', i).billingAddressValue;
                          if (billingAddressValue) {
                              body.address1 = billingAddressValue.streetAddress;
                              body.address2 = billingAddressValue.aptSuite;
                              body.city = billingAddressValue.city;
                              body.state = billingAddressValue.state;
                              body.postal_code = billingAddressValue.postalCode;
                              body.country_id = parseInt(billingAddressValue.countryCode, 10);
                          }
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'POST', '/clients', body);
                          responseData = responseData.data;
                      }
                      if (operation === 'get') {
                          const clientId = this.getNodeParameter('clientId', i);
                          const options = this.getNodeParameter('options', i);
                          if (options.include) {
                              qs.include = options.include;
                          }
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'GET', `/clients/${clientId}`, {}, qs);
                          responseData = responseData.data;
                      }
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', 0);
                          const options = this.getNodeParameter('options', i);
                          if (options.include) {
                              qs.include = options.include;
                          }
                          if (returnAll) {
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/clients', {}, qs);
                          }
                          else {
                              qs.per_page = this.getNodeParameter('limit', 0);
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'GET', '/clients', {}, qs);
                              responseData = responseData.data;
                          }
                      }
                      if (operation === 'delete') {
                          const clientId = this.getNodeParameter('clientId', i);
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'DELETE', `/clients/${clientId}`);
                          responseData = responseData.data;
                      }
                  }
                  if (resource === 'invoice') {
                      if (operation === 'create') {
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          const body = {};
                          if (additionalFields.email) {
                              body.email = additionalFields.email;
                          }
                          if (additionalFields.client) {
                              body.client_id = additionalFields.client;
                          }
                          if (additionalFields.autoBill) {
                              body.auto_bill = additionalFields.autoBill;
                          }
                          if (additionalFields.customValue1) {
                              body.custom_value1 = additionalFields.customValue1;
                          }
                          if (additionalFields.customValue2) {
                              body.custom_value2 = additionalFields.customValue2;
                          }
                          if (additionalFields.dueDate) {
                              body.due_date = additionalFields.dueDate;
                          }
                          if (additionalFields.invoiceDate) {
                              body.invoice_date = additionalFields.invoiceDate;
                          }
                          if (additionalFields.invoiceNumber) {
                              body.invoice_number = additionalFields.invoiceNumber;
                          }
                          if (additionalFields.invoiceStatus) {
                              body.invoice_status_id = additionalFields.invoiceStatus;
                          }
                          if (additionalFields.isAmountDiscount) {
                              body.is_amount_discount = additionalFields.isAmountDiscount;
                          }
                          if (additionalFields.partial) {
                              body.partial = additionalFields.partial;
                          }
                          if (additionalFields.partialDueDate) {
                              body.partial_due_date = additionalFields.partialDueDate;
                          }
                          if (additionalFields.poNumber) {
                              body.po_number = additionalFields.poNumber;
                          }
                          if (additionalFields.privateNotes) {
                              body.private_notes = additionalFields.privateNotes;
                          }
                          if (additionalFields.publicNotes) {
                              body.public_notes = additionalFields.publicNotes;
                          }
                          if (additionalFields.taxName1) {
                              body.tax_name1 = additionalFields.taxName1;
                          }
                          if (additionalFields.taxName2) {
                              body.tax_name2 = additionalFields.taxName2;
                          }
                          if (additionalFields.taxtRate1) {
                              body.tax_rate1 = additionalFields.taxtRate1;
                          }
                          if (additionalFields.taxtRate2) {
                              body.tax_rate2 = additionalFields.taxtRate2;
                          }
                          if (additionalFields.discount) {
                              body.discount = additionalFields.discount;
                          }
                          if (additionalFields.paid) {
                              body.paid = additionalFields.paid;
                          }
                          if (additionalFields.emailInvoice) {
                              body.email_invoice = additionalFields.emailInvoice;
                          }
                          const invoceItemsValues = this.getNodeParameter('invoiceItemsUi', i)
                              .invoiceItemsValues;
                          if (invoceItemsValues) {
                              const invoiceItems = [];
                              for (const itemValue of invoceItemsValues) {
                                  const item = {
                                      cost: itemValue.cost,
                                      notes: itemValue.description,
                                      product_key: itemValue.service,
                                      tax_rate1: itemValue.taxRate1,
                                      tax_rate2: itemValue.taxRate2,
                                      tax_name1: itemValue.taxName1,
                                      tax_name2: itemValue.taxName2,
                                  };
                                  if (apiVersion === 'v4') {
                                      item.qty = itemValue.hours;
                                  }
                                  if (apiVersion === 'v5') {
                                      item.quantity = itemValue.hours;
                                  }
                                  invoiceItems.push(item);
                              }
                              if (apiVersion === 'v4') {
                                  body.invoice_items = invoiceItems;
                              }
                              if (apiVersion === 'v5') {
                                  body.line_items = invoiceItems;
                              }
                          }
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'POST', '/invoices', body);
                          responseData = responseData.data;
                      }
                      if (operation === 'email') {
                          const invoiceId = this.getNodeParameter('invoiceId', i);
                          if (apiVersion === 'v4') {
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'POST', '/email_invoice', {
                                  id: invoiceId,
                              });
                          }
                          if (apiVersion === 'v5') {
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'GET', `/invoices/${invoiceId}/email`);
                          }
                      }
                      if (operation === 'get') {
                          const invoiceId = this.getNodeParameter('invoiceId', i);
                          const options = this.getNodeParameter('options', i);
                          if (options.include) {
                              qs.include = options.include;
                          }
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'GET', `/invoices/${invoiceId}`, {}, qs);
                          responseData = responseData.data;
                      }
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', 0);
                          const options = this.getNodeParameter('options', i);
                          if (options.include) {
                              qs.include = options.include;
                          }
                          if (options.invoiceNumber) {
                              qs.invoice_number = options.invoiceNumber;
                          }
                          if (returnAll) {
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/invoices', {}, qs);
                          }
                          else {
                              qs.per_page = this.getNodeParameter('limit', 0);
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'GET', '/invoices', {}, qs);
                              responseData = responseData.data;
                          }
                      }
                      if (operation === 'delete') {
                          const invoiceId = this.getNodeParameter('invoiceId', i);
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'DELETE', `/invoices/${invoiceId}`);
                          responseData = responseData.data;
                      }
                  }
                  if (resource === 'task') {
                      if (operation === 'create') {
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          const body = {};
                          if (additionalFields.client) {
                              body.client_id = additionalFields.client;
                          }
                          if (additionalFields.project) {
                              body.project_id = additionalFields.project;
                          }
                          if (additionalFields.customValue1) {
                              body.custom_value1 = additionalFields.customValue1;
                          }
                          if (additionalFields.customValue2) {
                              body.custom_value2 = additionalFields.customValue2;
                          }
                          if (additionalFields.description) {
                              body.description = additionalFields.description;
                          }
                          const timeLogsValues = this.getNodeParameter('timeLogsUi', i)
                              .timeLogsValues;
                          if (timeLogsValues) {
                              const logs = [];
                              for (const logValue of timeLogsValues) {
                                  let from = 0, to;
                                  if (logValue.startDate) {
                                      from = new Date(logValue.startDate).getTime() / 1000;
                                  }
                                  if (logValue.endDate) {
                                      to = new Date(logValue.endDate).getTime() / 1000;
                                  }
                                  if (logValue.duration) {
                                      to = from + logValue.duration * 3600;
                                  }
                                  logs.push([from, to]);
                              }
                              body.time_log = JSON.stringify(logs);
                          }
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'POST', '/tasks', body);
                          responseData = responseData.data;
                      }
                      if (operation === 'get') {
                          const taskId = this.getNodeParameter('taskId', i);
                          const options = this.getNodeParameter('options', i);
                          if (options.include) {
                              qs.include = options.include;
                          }
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'GET', `/tasks/${taskId}`, {}, qs);
                          responseData = responseData.data;
                      }
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', 0);
                          const options = this.getNodeParameter('options', i);
                          if (options.include) {
                              qs.include = options.include;
                          }
                          if (returnAll) {
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/tasks', {}, qs);
                          }
                          else {
                              qs.per_page = this.getNodeParameter('limit', 0);
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'GET', '/tasks', {}, qs);
                              responseData = responseData.data;
                          }
                      }
                      if (operation === 'delete') {
                          const taskId = this.getNodeParameter('taskId', i);
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'DELETE', `/tasks/${taskId}`);
                          responseData = responseData.data;
                      }
                  }
                  if (resource === 'payment') {
                      if (operation === 'create') {
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          const invoice = this.getNodeParameter('invoice', i);
                          const client = (_a = (await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'GET', `/invoices/${invoice}`, {}, qs)).data) === null || _a === void 0 ? void 0 : _a.client_id;
                          const amount = this.getNodeParameter('amount', i);
                          const body = {
                              invoice_id: invoice,
                              amount,
                              client_id: client,
                          };
                          if (additionalFields.paymentType) {
                              body.payment_type_id = additionalFields.paymentType;
                          }
                          if (additionalFields.transferReference) {
                              body.transaction_reference = additionalFields.transferReference;
                          }
                          if (additionalFields.privateNotes) {
                              body.private_notes = additionalFields.privateNotes;
                          }
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'POST', '/payments', body);
                          responseData = responseData.data;
                      }
                      if (operation === 'get') {
                          const paymentId = this.getNodeParameter('paymentId', i);
                          const options = this.getNodeParameter('options', i);
                          if (options.include) {
                              qs.include = options.include;
                          }
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'GET', `/payments/${paymentId}`, {}, qs);
                          responseData = responseData.data;
                      }
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', 0);
                          const options = this.getNodeParameter('options', i);
                          if (options.include) {
                              qs.include = options.include;
                          }
                          if (returnAll) {
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/payments', {}, qs);
                          }
                          else {
                              qs.per_page = this.getNodeParameter('limit', 0);
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'GET', '/payments', {}, qs);
                              responseData = responseData.data;
                          }
                      }
                      if (operation === 'delete') {
                          const paymentId = this.getNodeParameter('paymentId', i);
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'DELETE', `/payments/${paymentId}`);
                          responseData = responseData.data;
                      }
                  }
                  if (resource === 'expense') {
                      if (operation === 'create') {
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          const body = {};
                          if (additionalFields.amount) {
                              body.amount = additionalFields.amount;
                          }
                          if (additionalFields.billable) {
                              body.should_be_invoiced = additionalFields.billable;
                          }
                          if (additionalFields.client) {
                              body.client_id = additionalFields.client;
                          }
                          if (additionalFields.customValue1) {
                              body.custom_value1 = additionalFields.customValue1;
                          }
                          if (additionalFields.customValue2) {
                              body.custom_value2 = additionalFields.customValue2;
                          }
                          if (additionalFields.category) {
                              body.expense_category_id = additionalFields.category;
                          }
                          if (additionalFields.expenseDate) {
                              body.expense_date = additionalFields.expenseDate;
                          }
                          if (additionalFields.paymentDate) {
                              body.payment_date = additionalFields.paymentDate;
                          }
                          if (additionalFields.paymentType) {
                              body.payment_type_id = additionalFields.paymentType;
                          }
                          if (additionalFields.publicNotes) {
                              body.public_notes = additionalFields.publicNotes;
                          }
                          if (additionalFields.privateNotes) {
                              body.private_notes = additionalFields.privateNotes;
                          }
                          if (additionalFields.taxName1) {
                              body.tax_name1 = additionalFields.taxName1;
                          }
                          if (additionalFields.taxName2) {
                              body.tax_name2 = additionalFields.taxName2;
                          }
                          if (additionalFields.taxRate1) {
                              body.tax_rate1 = additionalFields.taxRate1;
                          }
                          if (additionalFields.taxRate2) {
                              body.tax_rate2 = additionalFields.taxRate2;
                          }
                          if (additionalFields.transactionReference) {
                              body.transaction_reference = additionalFields.transactionReference;
                          }
                          if (additionalFields.vendor) {
                              body.vendor_id = additionalFields.vendor;
                          }
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'POST', '/expenses', body);
                          responseData = responseData.data;
                      }
                      if (operation === 'get') {
                          const expenseId = this.getNodeParameter('expenseId', i);
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'GET', `/expenses/${expenseId}`, {}, qs);
                          responseData = responseData.data;
                      }
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', 0);
                          if (returnAll) {
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/expenses', {}, qs);
                          }
                          else {
                              qs.per_page = this.getNodeParameter('limit', 0);
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'GET', '/expenses', {}, qs);
                              responseData = responseData.data;
                          }
                      }
                      if (operation === 'delete') {
                          const expenseId = this.getNodeParameter('expenseId', i);
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'DELETE', `/expenses/${expenseId}`);
                          responseData = responseData.data;
                      }
                  }
                  if (resource === 'quote') {
                      const resourceEndpoint = apiVersion === 'v4' ? '/invoices' : '/quotes';
                      if (operation === 'create') {
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          const body = {
                              is_quote: true,
                          };
                          if (additionalFields.client) {
                              body.client_id = additionalFields.client;
                          }
                          if (additionalFields.email) {
                              body.email = additionalFields.email;
                          }
                          if (additionalFields.autoBill) {
                              body.auto_bill = additionalFields.autoBill;
                          }
                          if (additionalFields.customValue1) {
                              body.custom_value1 = additionalFields.customValue1;
                          }
                          if (additionalFields.customValue2) {
                              body.custom_value2 = additionalFields.customValue2;
                          }
                          if (additionalFields.dueDate) {
                              body.due_date = additionalFields.dueDate;
                          }
                          if (additionalFields.quouteDate) {
                              body.invoice_date = additionalFields.quouteDate;
                          }
                          if (additionalFields.quoteNumber) {
                              body.invoice_number = additionalFields.quoteNumber;
                          }
                          if (additionalFields.invoiceStatus) {
                              body.invoice_status_id = additionalFields.invoiceStatus;
                          }
                          if (additionalFields.isAmountDiscount) {
                              body.is_amount_discount = additionalFields.isAmountDiscount;
                          }
                          if (additionalFields.partial) {
                              body.partial = additionalFields.partial;
                          }
                          if (additionalFields.partialDueDate) {
                              body.partial_due_date = additionalFields.partialDueDate;
                          }
                          if (additionalFields.poNumber) {
                              body.po_number = additionalFields.poNumber;
                          }
                          if (additionalFields.privateNotes) {
                              body.private_notes = additionalFields.privateNotes;
                          }
                          if (additionalFields.publicNotes) {
                              body.public_notes = additionalFields.publicNotes;
                          }
                          if (additionalFields.taxName1) {
                              body.tax_name1 = additionalFields.taxName1;
                          }
                          if (additionalFields.taxName2) {
                              body.tax_name2 = additionalFields.taxName2;
                          }
                          if (additionalFields.taxtRate1) {
                              body.tax_rate1 = additionalFields.taxtRate1;
                          }
                          if (additionalFields.taxtRate2) {
                              body.tax_rate2 = additionalFields.taxtRate2;
                          }
                          if (additionalFields.discount) {
                              body.discount = additionalFields.discount;
                          }
                          if (additionalFields.paid) {
                              body.paid = additionalFields.paid;
                          }
                          if (additionalFields.emailQuote) {
                              body.email_invoice = additionalFields.emailQuote;
                          }
                          const invoceItemsValues = this.getNodeParameter('invoiceItemsUi', i)
                              .invoiceItemsValues;
                          if (invoceItemsValues) {
                              const invoiceItems = [];
                              for (const itemValue of invoceItemsValues) {
                                  const item = {
                                      cost: itemValue.cost,
                                      notes: itemValue.description,
                                      product_key: itemValue.service,
                                      tax_rate1: itemValue.taxRate1,
                                      tax_rate2: itemValue.taxRate2,
                                      tax_name1: itemValue.taxName1,
                                      tax_name2: itemValue.taxName2,
                                  };
                                  if (apiVersion === 'v4') {
                                      item.qty = itemValue.hours;
                                  }
                                  if (apiVersion === 'v5') {
                                      item.quantity = itemValue.hours;
                                  }
                                  invoiceItems.push(item);
                              }
                              if (apiVersion === 'v4') {
                                  body.invoice_items = invoiceItems;
                              }
                              if (apiVersion === 'v5') {
                                  body.line_items = invoiceItems;
                              }
                          }
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'POST', resourceEndpoint, body);
                          responseData = responseData.data;
                      }
                      if (operation === 'email') {
                          const quoteId = this.getNodeParameter('quoteId', i);
                          if (apiVersion === 'v4') {
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'POST', '/email_invoice', {
                                  id: quoteId,
                              });
                          }
                          if (apiVersion === 'v5') {
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'GET', `/quotes/${quoteId}/email`);
                          }
                      }
                      if (operation === 'get') {
                          const quoteId = this.getNodeParameter('quoteId', i);
                          const options = this.getNodeParameter('options', i);
                          if (options.include) {
                              qs.include = options.include;
                          }
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'GET', `${resourceEndpoint}/${quoteId}`, {}, qs);
                          responseData = responseData.data;
                      }
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', 0);
                          const options = this.getNodeParameter('options', i);
                          if (options.include) {
                              qs.include = options.include;
                          }
                          if (options.invoiceNumber) {
                              qs.invoice_number = options.invoiceNumber;
                          }
                          if (returnAll) {
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/quotes', {}, qs);
                          }
                          else {
                              qs.per_page = this.getNodeParameter('limit', 0);
                              responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'GET', '/quotes', {}, qs);
                              responseData = responseData.data;
                          }
                      }
                      if (operation === 'delete') {
                          const quoteId = this.getNodeParameter('quoteId', i);
                          responseData = await GenericFunctions_1.invoiceNinjaApiRequest.call(this, 'DELETE', `${resourceEndpoint}/${quoteId}`);
                          responseData = responseData.data;
                      }
                  }
                  const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                  returnData.push(...executionData);
              }
              catch (error) {
                  if (this.continueOnFail()) {
                      const executionErrorData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ error: error.message }), { itemData: { item: i } });
                      returnData.push(...executionErrorData);
                      continue;
                  }
                  throw error;
              }
          }
          return [returnData];
      }
  }
  exports.InvoiceNinja = InvoiceNinja;
  //# sourceMappingURL=InvoiceNinja.node.js.map

credential_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.InvoiceNinjaApi = void 0;
  class InvoiceNinjaApi {
      constructor() {
          this.name = 'invoiceNinjaApi';
          this.displayName = 'Invoice Ninja API';
          this.documentationUrl = 'invoiceNinja';
          this.properties = [
              {
                  displayName: 'URL',
                  name: 'url',
                  type: 'string',
                  default: '',
                  hint: 'Default URL for v4 is https://app.invoiceninja.com, for v5 it is https://invoicing.co',
              },
              {
                  displayName: 'API Token',
                  name: 'apiToken',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
              },
              {
                  displayName: 'Secret',
                  name: 'secret',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
                  hint: 'This is optional, enter only if you did set a secret in your app and only if you are using v5',
              },
          ];
          this.test = {
              request: {
                  baseURL: '={{$credentials?.url}}',
                  url: '/api/v1/clients',
                  method: 'GET',
              },
          };
      }
      async authenticate(credentials, requestOptions) {
          const VERSION_5_TOKEN_LENGTH = 64;
          const { apiToken, secret } = credentials;
          const tokenLength = apiToken.length;
          if (tokenLength < VERSION_5_TOKEN_LENGTH) {
              requestOptions.headers = {
                  Accept: 'application/json',
                  'X-Ninja-Token': apiToken,
              };
          }
          else {
              requestOptions.headers = {
                  'Content-Type': 'application/json',
                  'X-API-TOKEN': apiToken,
                  'X-Requested-With': 'XMLHttpRequest',
                  'X-API-SECRET': secret || '',
              };
          }
          return requestOptions;
      }
  }
  exports.InvoiceNinjaApi = InvoiceNinjaApi;
  //# sourceMappingURL=InvoiceNinjaApi.credentials.js.map

  // --- Next Credential File ---

  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.InvoiceNinjaApi = void 0;
  class InvoiceNinjaApi {
      constructor() {
          this.name = 'invoiceNinjaApi';
          this.displayName = 'Invoice Ninja API';
          this.documentationUrl = 'invoiceNinja';
          this.properties = [
              {
                  displayName: 'URL',
                  name: 'url',
                  type: 'string',
                  default: '',
                  hint: 'Default URL for v4 is https://app.invoiceninja.com, for v5 it is https://invoicing.co',
              },
              {
                  displayName: 'API Token',
                  name: 'apiToken',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
              },
              {
                  displayName: 'Secret',
                  name: 'secret',
                  type: 'string',
                  typeOptions: { password: true },
                  default: '',
                  hint: 'This is optional, enter only if you did set a secret in your app and only if you are using v5',
              },
          ];
          this.test = {
              request: {
                  baseURL: '={{$credentials?.url}}',
                  url: '/api/v1/clients',
                  method: 'GET',
              },
          };
      }
      async authenticate(credentials, requestOptions) {
          const VERSION_5_TOKEN_LENGTH = 64;
          const { apiToken, secret } = credentials;
          const tokenLength = apiToken.length;
          if (tokenLength < VERSION_5_TOKEN_LENGTH) {
              requestOptions.headers = {
                  Accept: 'application/json',
                  'X-Ninja-Token': apiToken,
              };
          }
          else {
              requestOptions.headers = {
                  'Content-Type': 'application/json',
                  'X-API-TOKEN': apiToken,
                  'X-Requested-With': 'XMLHttpRequest',
                  'X-API-SECRET': secret || '',
              };
          }
          return requestOptions;
      }
  }
  exports.InvoiceNinjaApi = InvoiceNinjaApi;
  //# sourceMappingURL=InvoiceNinjaApi.credentials.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Invoice Ninja node documentation
  description: Learn how to use the Invoice Ninja node in n8n. Follow technical documentation to integrate Invoice Ninja node into your workflows.
  contentType: [integration, reference]
  ---

  # Invoice Ninja node

  Use the Invoice Ninja node to automate work in Invoice Ninja, and integrate Invoice Ninja with other applications. n8n has built-in support for a wide range of Invoice Ninja features, including creating, updating, deleting, and getting clients, expense, invoice, payments and quotes. 

  On this page, you'll find a list of operations the Invoice Ninja node supports and links to more resources.

  /// note | Credentials
  Refer to [Invoice Ninja credentials](/integrations/builtin/credentials/invoiceninja.md) for guidance on setting up authentication. 
  ///

  ## Operations

  * Client
      * Create a new client
      * Delete a client
      * Get data of a client
      * Get data of all clients
  * Expense
      * Create a new expense
      * Delete an expense
      * Get data of an expense
      * Get data of all expenses
  * Invoice
      * Create a new invoice
      * Delete a invoice
      * Email an invoice
      * Get data of a invoice
      * Get data of all invoices
  * Payment
      * Create a new payment
      * Delete a payment
      * Get data of a payment
      * Get data of all payments
  * Quote
      * Create a new quote
      * Delete a quote
      * Email an quote
      * Get data of a quote
      * Get data of all quotes
  * Task
      * Create a new task
      * Delete a task
      * Get data of a task
      * Get data of all tasks

  ## Templates and examples

  <!-- see https://www.notion.so/n8n/Pull-in-templates-for-the-integrations-pages-37c716837b804d30a33b47475f6e3780 -->
  [[ templatesWidget(page.title, 'invoice-ninja') ]]

  --8<-- "_snippets/integrations/builtin/app-nodes/operation-not-supported.md"

example_workflow:
  {"name":"Invoice Ninja Example Workflow","nodes":[{"parameters":{},"id":"tu7kok2ze8mdyflih3hx27","name":"Invoice Ninja","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.Kafka
name: Kafka
display_name: Kafka
description: Sends messages to a Kafka topic
category: transform
icon: file:kafka.svg
code_hash: 74c45cee3cedf2f42356b732d5025dcedca4654fe4a2c472ffc62e2d27715f7f
documentation_url: https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.Kafka
documentation_title: Kafka node documentation
operations: []
api_methods: []
documentation_examples: []
templates: [{"name":"kafka","description":"Templates for kafka"}]
related_resources: []
required_scopes: []
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
version: 1.0
extracted_at: 2025-06-09 15:18:12
updated_at: 2025-06-09 15:18:12
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Kafka = void 0;
  const kafkajs_1 = require("kafkajs");
  const confluent_schema_registry_1 = require("@kafkajs/confluent-schema-registry");
  const n8n_workflow_1 = require("n8n-workflow");
  const utilities_1 = require("../../utils/utilities");
  class Kafka {
      constructor() {
          this.description = {
              displayName: 'Kafka',
              name: 'kafka',
              icon: 'file:kafka.svg',
              group: ['transform'],
              version: 1,
              description: 'Sends messages to a Kafka topic',
              defaults: {
                  name: 'Kafka',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'kafka',
                      required: true,
                      testedBy: 'kafkaConnectionTest',
                  },
              ],
              properties: [
                  {
                      displayName: 'Topic',
                      name: 'topic',
                      type: 'string',
                      default: '',
                      placeholder: 'topic-name',
                      description: 'Name of the queue of topic to publish to',
                  },
                  {
                      displayName: 'Send Input Data',
                      name: 'sendInputData',
                      type: 'boolean',
                      default: true,
                      description: 'Whether to send the the data the node receives as JSON to Kafka',
                  },
                  {
                      displayName: 'Message',
                      name: 'message',
                      type: 'string',
                      displayOptions: {
                          show: {
                              sendInputData: [false],
                          },
                      },
                      default: '',
                      description: 'The message to be sent',
                  },
                  {
                      displayName: 'JSON Parameters',
                      name: 'jsonParameters',
                      type: 'boolean',
                      default: false,
                  },
                  {
                      displayName: 'Use Schema Registry',
                      name: 'useSchemaRegistry',
                      type: 'boolean',
                      default: false,
                      description: 'Whether to use Confluent Schema Registry',
                  },
                  {
                      displayName: 'Schema Registry URL',
                      name: 'schemaRegistryUrl',
                      type: 'string',
                      required: true,
                      displayOptions: {
                          show: {
                              useSchemaRegistry: [true],
                          },
                      },
                      placeholder: 'https://schema-registry-domain:8081',
                      default: '',
                      description: 'URL of the schema registry',
                  },
                  {
                      displayName: 'Use Key',
                      name: 'useKey',
                      type: 'boolean',
                      default: false,
                      description: 'Whether to use a message key',
                  },
                  {
                      displayName: 'Key',
                      name: 'key',
                      type: 'string',
                      required: true,
                      displayOptions: {
                          show: {
                              useKey: [true],
                          },
                      },
                      placeholder: '',
                      default: '',
                      description: 'The message key',
                  },
                  {
                      displayName: 'Event Name',
                      name: 'eventName',
                      type: 'string',
                      required: true,
                      displayOptions: {
                          show: {
                              useSchemaRegistry: [true],
                          },
                      },
                      default: '',
                      description: 'Namespace and Name of Schema in Schema Registry (namespace.name)',
                  },
                  {
                      displayName: 'Headers',
                      name: 'headersUi',
                      placeholder: 'Add Header',
                      type: 'fixedCollection',
                      displayOptions: {
                          show: {
                              jsonParameters: [false],
                          },
                      },
                      typeOptions: {
                          multipleValues: true,
                      },
                      default: {},
                      options: [
                          {
                              name: 'headerValues',
                              displayName: 'Header',
                              values: [
                                  {
                                      displayName: 'Key',
                                      name: 'key',
                                      type: 'string',
                                      default: '',
                                  },
                                  {
                                      displayName: 'Value',
                                      name: 'value',
                                      type: 'string',
                                      default: '',
                                  },
                              ],
                          },
                      ],
                  },
                  {
                      displayName: 'Headers (JSON)',
                      name: 'headerParametersJson',
                      type: 'json',
                      displayOptions: {
                          show: {
                              jsonParameters: [true],
                          },
                      },
                      default: '',
                      description: 'Header parameters as JSON (flat object)',
                  },
                  {
                      displayName: 'Options',
                      name: 'options',
                      type: 'collection',
                      default: {},
                      placeholder: 'Add Option',
                      options: [
                          {
                              displayName: 'Acks',
                              name: 'acks',
                              type: 'boolean',
                              default: false,
                              description: 'Whether or not producer must wait for acknowledgement from all replicas',
                          },
                          {
                              displayName: 'Compression',
                              name: 'compression',
                              type: 'boolean',
                              default: false,
                              description: 'Whether to send the data in a compressed format using the GZIP codec',
                          },
                          {
                              displayName: 'Timeout',
                              name: 'timeout',
                              type: 'number',
                              default: 30000,
                              description: 'The time to await a response in ms',
                          },
                      ],
                  },
              ],
          };
          this.methods = {
              credentialTest: {
                  async kafkaConnectionTest(credential) {
                      const credentials = credential.data;
                      try {
                          const brokers = (credentials.brokers || '')
                              .split(',')
                              .map((item) => item.trim());
                          const clientId = credentials.clientId;
                          const ssl = credentials.ssl;
                          const config = {
                              clientId,
                              brokers,
                              ssl,
                          };
                          if (credentials.authentication === true) {
                              if (!(credentials.username && credentials.password)) {
                                  throw Error('Username and password are required for authentication');
                              }
                              config.sasl = {
                                  username: credentials.username,
                                  password: credentials.password,
                                  mechanism: credentials.saslMechanism,
                              };
                          }
                          const kafka = new kafkajs_1.Kafka(config);
                          await kafka.admin().connect();
                          await kafka.admin().disconnect();
                          return {
                              status: 'OK',
                              message: 'Authentication successful',
                          };
                      }
                      catch (error) {
                          return {
                              status: 'Error',
                              message: error.message,
                          };
                      }
                  },
              },
          };
      }
      async execute() {
          const items = this.getInputData();
          const itemData = (0, utilities_1.generatePairedItemData)(items.length);
          const length = items.length;
          const topicMessages = [];
          let responseData;
          try {
              const options = this.getNodeParameter('options', 0);
              const sendInputData = this.getNodeParameter('sendInputData', 0);
              const useSchemaRegistry = this.getNodeParameter('useSchemaRegistry', 0);
              const timeout = options.timeout;
              let compression = kafkajs_1.CompressionTypes.None;
              const acks = options.acks === true ? 1 : 0;
              if (options.compression === true) {
                  compression = kafkajs_1.CompressionTypes.GZIP;
              }
              const credentials = await this.getCredentials('kafka');
              const brokers = (credentials.brokers || '').split(',').map((item) => item.trim());
              const clientId = credentials.clientId;
              const ssl = credentials.ssl;
              const config = {
                  clientId,
                  brokers,
                  ssl,
              };
              if (credentials.authentication === true) {
                  if (!(credentials.username && credentials.password)) {
                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Username and password are required for authentication');
                  }
                  config.sasl = {
                      username: credentials.username,
                      password: credentials.password,
                      mechanism: credentials.saslMechanism,
                  };
              }
              const kafka = new kafkajs_1.Kafka(config);
              const producer = kafka.producer();
              await producer.connect();
              let message;
              for (let i = 0; i < length; i++) {
                  if (sendInputData) {
                      message = JSON.stringify(items[i].json);
                  }
                  else {
                      message = this.getNodeParameter('message', i);
                  }
                  if (useSchemaRegistry) {
                      try {
                          const schemaRegistryUrl = this.getNodeParameter('schemaRegistryUrl', 0);
                          const eventName = this.getNodeParameter('eventName', 0);
                          const registry = new confluent_schema_registry_1.SchemaRegistry({ host: schemaRegistryUrl });
                          const id = await registry.getLatestSchemaId(eventName);
                          message = await registry.encode(id, JSON.parse(message));
                      }
                      catch (exception) {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Verify your Schema Registry configuration');
                      }
                  }
                  const topic = this.getNodeParameter('topic', i);
                  const jsonParameters = this.getNodeParameter('jsonParameters', i);
                  const useKey = this.getNodeParameter('useKey', i);
                  const key = useKey ? this.getNodeParameter('key', i) : null;
                  let headers;
                  if (jsonParameters) {
                      headers = this.getNodeParameter('headerParametersJson', i);
                      try {
                          headers = JSON.parse(headers);
                      }
                      catch (exception) {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Headers must be a valid json');
                      }
                  }
                  else {
                      const values = this.getNodeParameter('headersUi', i)
                          .headerValues;
                      headers = {};
                      if (values !== undefined) {
                          for (const value of values) {
                              headers[value.key] = value.value;
                          }
                      }
                  }
                  topicMessages.push({
                      topic,
                      messages: [
                          {
                              value: message,
                              headers,
                              key,
                          },
                      ],
                  });
              }
              responseData = await producer.sendBatch({
                  topicMessages,
                  timeout,
                  compression,
                  acks,
              });
              if (responseData.length === 0) {
                  responseData.push({
                      success: true,
                  });
              }
              await producer.disconnect();
              const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData });
              return [executionData];
          }
          catch (error) {
              if (this.continueOnFail()) {
                  return [[{ json: { error: error.message }, pairedItem: itemData }]];
              }
              else {
                  throw error;
              }
          }
      }
  }
  exports.Kafka = Kafka;
  //# sourceMappingURL=Kafka.node.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Kafka node documentation
  description: Learn how to use the Kafka node in n8n. Follow technical documentation to integrate Kafka node into your workflows.
  contentType: [integration, reference]
  priority: medium
  ---

  # Kafka node

  Use the Kafka node to automate work in Kafka, and integrate Kafka with other applications. n8n has built-in support for a wide range of Kafka features, including sending messages. 

  On this page, you'll find a list of operations the Kafka node supports and links to more resources.

  /// note | Credentials
  Refer to [Kafka credentials](/integrations/builtin/credentials/kafka.md) for guidance on setting up authentication. 
  ///

  --8<-- "_snippets/integrations/builtin/app-nodes/ai-tools.md"

  ## Operations

  - Send message

  ## Templates and examples

  <!-- see https://www.notion.so/n8n/Pull-in-templates-for-the-integrations-pages-37c716837b804d30a33b47475f6e3780 -->
  [[ templatesWidget(page.title, 'kafka') ]]

example_workflow:
  {"name":"Kafka Example Workflow","nodes":[{"parameters":{},"id":"vtpqzon84nar4z1u69d1g","name":"Kafka","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


node_type: n8n-nodes-base.Jira
name: Jira
display_name: Jira Software
description: Consume Jira Software API
category: output
icon: file:jira.svg
code_hash: 4e93fa0d77ac1881853591e98dea6a0effa65338c59c3a2097a06ff8c8d34278
documentation_url: https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.Jira
documentation_title: Jira Software node documentation
operations: []
api_methods: []
documentation_examples: []
templates: [{"name":"jira-software","description":"Templates for jira-software"}]
required_scopes: []
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
version: 1.0
extracted_at: 2025-06-09 15:18:12
updated_at: 2025-06-09 15:18:12
source_code:
  "use strict";
  var __importDefault = (this && this.__importDefault) || function (mod) {
      return (mod && mod.__esModule) ? mod : { "default": mod };
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Jira = void 0;
  const mergeWith_1 = __importDefault(require("lodash/mergeWith"));
  const n8n_workflow_1 = require("n8n-workflow");
  const GenericFunctions_1 = require("./GenericFunctions");
  const IssueAttachmentDescription_1 = require("./IssueAttachmentDescription");
  const IssueCommentDescription_1 = require("./IssueCommentDescription");
  const IssueDescription_1 = require("./IssueDescription");
  const UserDescription_1 = require("./UserDescription");
  class Jira {
      constructor() {
          this.description = {
              displayName: 'Jira Software',
              name: 'jira',
              icon: 'file:jira.svg',
              group: ['output'],
              version: 1,
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Consume Jira Software API',
              defaults: {
                  name: 'Jira Software',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'jiraSoftwareCloudApi',
                      required: true,
                      displayOptions: {
                          show: {
                              jiraVersion: ['cloud'],
                          },
                      },
                  },
                  {
                      name: 'jiraSoftwareServerApi',
                      required: true,
                      displayOptions: {
                          show: {
                              jiraVersion: ['server'],
                          },
                      },
                  },
              ],
              properties: [
                  {
                      displayName: 'Jira Version',
                      name: 'jiraVersion',
                      type: 'options',
                      options: [
                          {
                              name: 'Cloud',
                              value: 'cloud',
                          },
                          {
                              name: 'Server (Self Hosted)',
                              value: 'server',
                          },
                      ],
                      default: 'cloud',
                  },
                  {
                      displayName: 'Resource',
                      name: 'resource',
                      type: 'options',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Issue',
                              value: 'issue',
                              description: 'Creates an issue or, where the option to create subtasks is enabled in Jira, a subtask',
                          },
                          {
                              name: 'Issue Attachment',
                              value: 'issueAttachment',
                              description: 'Add, remove, and get an attachment from an issue',
                          },
                          {
                              name: 'Issue Comment',
                              value: 'issueComment',
                              description: 'Get, create, update, and delete a comment from an issue',
                          },
                          {
                              name: 'User',
                              value: 'user',
                              description: 'Get, create and delete a user',
                          },
                      ],
                      default: 'issue',
                  },
                  ...IssueDescription_1.issueOperations,
                  ...IssueDescription_1.issueFields,
                  ...IssueAttachmentDescription_1.issueAttachmentOperations,
                  ...IssueAttachmentDescription_1.issueAttachmentFields,
                  ...IssueCommentDescription_1.issueCommentOperations,
                  ...IssueCommentDescription_1.issueCommentFields,
                  ...UserDescription_1.userOperations,
                  ...UserDescription_1.userFields,
              ],
          };
          this.methods = {
              listSearch: {
                  async getProjects(filter) {
                      const returnData = [];
                      const jiraVersion = this.getCurrentNodeParameter('jiraVersion');
                      let endpoint = '';
                      let projects;
                      if (jiraVersion === 'server') {
                          endpoint = '/api/2/project';
                          projects = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, endpoint, 'GET');
                      }
                      else {
                          endpoint = '/api/2/project/search';
                          projects = await GenericFunctions_1.jiraSoftwareCloudApiRequestAllItems.call(this, 'values', endpoint, 'GET');
                      }
                      if (projects.values && Array.isArray(projects.values)) {
                          projects = projects.values;
                      }
                      for (const project of projects) {
                          const projectName = project.name;
                          const projectId = project.id;
                          returnData.push({
                              name: projectName,
                              value: projectId,
                          });
                      }
                      return { results: (0, GenericFunctions_1.filterSortSearchListItems)(returnData, filter) };
                  },
                  async getIssueTypes() {
                      const projectId = this.getCurrentNodeParameter('project', { extractValue: true });
                      const returnData = [];
                      const { issueTypes } = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/2/project/${projectId}`, 'GET');
                      for (const issueType of issueTypes) {
                          const issueTypeName = issueType.name;
                          const issueTypeId = issueType.id;
                          returnData.push({
                              name: issueTypeName,
                              value: issueTypeId,
                          });
                      }
                      returnData.sort((a, b) => {
                          if (a.name < b.name) {
                              return -1;
                          }
                          if (a.name > b.name) {
                              return 1;
                          }
                          return 0;
                      });
                      return { results: returnData };
                  },
                  async getUsers(filter) {
                      const users = await GenericFunctions_1.getUsers.call(this);
                      return { results: (0, GenericFunctions_1.filterSortSearchListItems)(users, filter) };
                  },
                  async getPriorities() {
                      const returnData = [];
                      const priorities = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, '/api/2/priority', 'GET');
                      for (const priority of priorities) {
                          const priorityName = priority.name;
                          const priorityId = priority.id;
                          returnData.push({
                              name: priorityName,
                              value: priorityId,
                          });
                      }
                      returnData.sort((a, b) => {
                          if (a.name < b.name) {
                              return -1;
                          }
                          if (a.name > b.name) {
                              return 1;
                          }
                          return 0;
                      });
                      return { results: returnData };
                  },
                  async getTransitions() {
                      const returnData = [];
                      const issueKey = this.getCurrentNodeParameter('issueKey');
                      const transitions = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}/transitions`, 'GET');
                      for (const transition of transitions.transitions) {
                          returnData.push({
                              name: transition.name,
                              value: transition.id,
                          });
                      }
                      returnData.sort((a, b) => {
                          if (a.name < b.name) {
                              return -1;
                          }
                          if (a.name > b.name) {
                              return 1;
                          }
                          return 0;
                      });
                      return { results: returnData };
                  },
                  async getCustomFields() {
                      const returnData = [];
                      const operation = this.getCurrentNodeParameter('operation');
                      let projectId;
                      let issueTypeId;
                      if (operation === 'create') {
                          projectId = this.getCurrentNodeParameter('project', { extractValue: true });
                          issueTypeId = this.getCurrentNodeParameter('issueType', { extractValue: true });
                      }
                      else {
                          const issueKey = this.getCurrentNodeParameter('issueKey');
                          const res = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}`, 'GET', {}, {});
                          projectId = res.fields.project.id;
                          issueTypeId = res.fields.issuetype.id;
                      }
                      const res = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/createmeta?projectIds=${projectId}&issueTypeIds=${issueTypeId}&expand=projects.issuetypes.fields`, 'GET');
                      const fields = res.projects
                          .find((o) => o.id === projectId)
                          .issuetypes.find((o) => o.id === issueTypeId).fields;
                      for (const key of Object.keys(fields)) {
                          const field = fields[key];
                          if (field.schema && Object.keys(field.schema).includes('customId')) {
                              returnData.push({
                                  name: field.name,
                                  value: field.key || field.fieldId,
                              });
                          }
                      }
                      return { results: returnData };
                  },
              },
              loadOptions: {
                  async getLabels() {
                      const returnData = [];
                      const labels = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, '/api/2/label', 'GET');
                      for (const label of labels.values) {
                          const labelName = label;
                          const labelId = label;
                          returnData.push({
                              name: labelName,
                              value: labelId,
                          });
                      }
                      returnData.sort((a, b) => {
                          if (a.name < b.name) {
                              return -1;
                          }
                          if (a.name > b.name) {
                              return 1;
                          }
                          return 0;
                      });
                      return returnData;
                  },
                  async getUsers() {
                      return GenericFunctions_1.getUsers.call(this);
                  },
                  async getGroups() {
                      const returnData = [];
                      const groups = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, '/api/2/groups/picker', 'GET');
                      for (const group of groups.groups) {
                          const groupName = group.name;
                          const groupId = group.name;
                          returnData.push({
                              name: groupName,
                              value: groupId,
                          });
                      }
                      returnData.sort((a, b) => {
                          if (a.name < b.name) {
                              return -1;
                          }
                          if (a.name > b.name) {
                              return 1;
                          }
                          return 0;
                      });
                      return returnData;
                  },
                  async getProjectComponents() {
                      const returnData = [];
                      const project = this.getCurrentNodeParameter('project', { extractValue: true });
                      const { values: components } = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/2/project/${project}/component`, 'GET');
                      for (const component of components) {
                          returnData.push({
                              name: component.name,
                              value: component.id,
                          });
                      }
                      returnData.sort((a, b) => {
                          if (a.name < b.name) {
                              return -1;
                          }
                          if (a.name > b.name) {
                              return 1;
                          }
                          return 0;
                      });
                      return returnData;
                  },
              },
          };
      }
      async execute() {
          const items = this.getInputData();
          const returnData = [];
          const length = items.length;
          let responseData;
          const qs = {};
          const resource = this.getNodeParameter('resource', 0);
          const operation = this.getNodeParameter('operation', 0);
          const jiraVersion = this.getNodeParameter('jiraVersion', 0);
          if (resource === 'issue') {
              if (operation === 'create') {
                  for (let i = 0; i < length; i++) {
                      const summary = this.getNodeParameter('summary', i);
                      const projectId = this.getNodeParameter('project', i, '', {
                          extractValue: true,
                      });
                      const issueTypeId = this.getNodeParameter('issueType', i, '', {
                          extractValue: true,
                      });
                      const additionalFields = this.getNodeParameter('additionalFields', i);
                      const assignee = this.getNodeParameter('additionalFields.assignee', i, '', {
                          extractValue: true,
                      });
                      if (assignee)
                          additionalFields.assignee = assignee;
                      const reporter = this.getNodeParameter('additionalFields.reporter', i, '', {
                          extractValue: true,
                      });
                      if (reporter)
                          additionalFields.reporter = reporter;
                      const priority = this.getNodeParameter('additionalFields.priority', i, '', {
                          extractValue: true,
                      });
                      if (priority)
                          additionalFields.priority = priority;
                      const body = {};
                      const fields = {
                          summary,
                          project: {
                              id: projectId,
                          },
                          issuetype: {
                              id: issueTypeId,
                          },
                      };
                      if (additionalFields.labels) {
                          fields.labels = additionalFields.labels;
                      }
                      if (additionalFields.serverLabels) {
                          fields.labels = additionalFields.serverLabels;
                      }
                      if (additionalFields.priority) {
                          fields.priority = {
                              id: additionalFields.priority,
                          };
                      }
                      if (additionalFields.assignee) {
                          if (jiraVersion === 'server') {
                              fields.assignee = {
                                  name: additionalFields.assignee,
                              };
                          }
                          else {
                              fields.assignee = {
                                  id: additionalFields.assignee,
                              };
                          }
                      }
                      if (additionalFields.reporter) {
                          if (jiraVersion === 'server') {
                              fields.reporter = {
                                  name: additionalFields.reporter,
                              };
                          }
                          else {
                              fields.reporter = {
                                  id: additionalFields.reporter,
                              };
                          }
                      }
                      if (additionalFields.description) {
                          fields.description = additionalFields.description;
                      }
                      if (additionalFields.updateHistory) {
                          qs.updateHistory = additionalFields.updateHistory;
                      }
                      if (additionalFields.componentIds) {
                          fields.components = additionalFields.componentIds.map((id) => ({ id }));
                      }
                      if (additionalFields.customFieldsUi) {
                          const customFields = additionalFields.customFieldsUi
                              .customFieldsValues;
                          if (customFields) {
                              customFields.forEach((cf) => {
                                  if (typeof cf.fieldId !== 'string') {
                                      cf.fieldId = cf.fieldId.value.trim();
                                  }
                              });
                              const data = customFields.reduce((obj, value) => Object.assign(obj, { [`${value.fieldId}`]: value.fieldValue }), {});
                              Object.assign(fields, data);
                          }
                      }
                      const issueTypes = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, '/api/2/issuetype', 'GET', body, qs);
                      const subtaskIssues = [];
                      for (const issueType of issueTypes) {
                          if (issueType.subtask) {
                              subtaskIssues.push(issueType.id);
                          }
                      }
                      if (!additionalFields.parentIssueKey && subtaskIssues.includes(issueTypeId)) {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'You must define a Parent Issue Key when Issue type is sub-task', { itemIndex: i });
                      }
                      else if (additionalFields.parentIssueKey && subtaskIssues.includes(issueTypeId)) {
                          fields.parent = {
                              key: additionalFields.parentIssueKey.toUpperCase(),
                          };
                      }
                      body.fields = fields;
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, '/api/2/issue', 'POST', body);
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
              if (operation === 'update') {
                  for (let i = 0; i < length; i++) {
                      const issueKey = this.getNodeParameter('issueKey', i);
                      const updateFields = this.getNodeParameter('updateFields', i);
                      const assignee = this.getNodeParameter('updateFields.assignee', i, '', {
                          extractValue: true,
                      });
                      if (assignee)
                          updateFields.assignee = assignee;
                      const reporter = this.getNodeParameter('updateFields.reporter', i, '', {
                          extractValue: true,
                      });
                      if (reporter)
                          updateFields.reporter = reporter;
                      const priority = this.getNodeParameter('updateFields.priority', i, '', {
                          extractValue: true,
                      });
                      if (priority)
                          updateFields.priority = priority;
                      const statusId = this.getNodeParameter('updateFields.statusId', i, '', {
                          extractValue: true,
                      });
                      if (statusId)
                          updateFields.statusId = statusId;
                      const body = {};
                      const fields = {};
                      if (updateFields.summary) {
                          fields.summary = updateFields.summary;
                      }
                      if (updateFields.issueType) {
                          fields.issuetype = {
                              id: updateFields.issueType,
                          };
                      }
                      if (updateFields.labels) {
                          fields.labels = updateFields.labels;
                      }
                      if (updateFields.serverLabels) {
                          fields.labels = updateFields.serverLabels;
                      }
                      if (updateFields.priority) {
                          fields.priority = {
                              id: updateFields.priority,
                          };
                      }
                      if (updateFields.assignee) {
                          if (jiraVersion === 'server') {
                              fields.assignee = {
                                  name: updateFields.assignee,
                              };
                          }
                          else {
                              fields.assignee = {
                                  id: updateFields.assignee,
                              };
                          }
                      }
                      if (updateFields.reporter) {
                          if (jiraVersion === 'server') {
                              fields.reporter = {
                                  name: updateFields.reporter,
                              };
                          }
                          else {
                              fields.reporter = {
                                  id: updateFields.reporter,
                              };
                          }
                      }
                      if (updateFields.description) {
                          fields.description = updateFields.description;
                      }
                      if (updateFields.customFieldsUi) {
                          const customFields = updateFields.customFieldsUi
                              .customFieldsValues;
                          if (customFields) {
                              customFields.forEach((cf) => {
                                  if (typeof cf.fieldId !== 'string') {
                                      cf.fieldId = cf.fieldId.value.trim();
                                  }
                              });
                              const data = customFields.reduce((obj, value) => Object.assign(obj, { [`${value.fieldId}`]: value.fieldValue }), {});
                              Object.assign(fields, data);
                          }
                      }
                      const issueTypes = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, '/api/2/issuetype', 'GET', body);
                      const subtaskIssues = [];
                      for (const issueType of issueTypes) {
                          if (issueType.subtask) {
                              subtaskIssues.push(issueType.id);
                          }
                      }
                      if (!updateFields.parentIssueKey && subtaskIssues.includes(updateFields.issueType)) {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'You must define a Parent Issue Key when Issue type is sub-task', { itemIndex: i });
                      }
                      else if (updateFields.parentIssueKey &&
                          subtaskIssues.includes(updateFields.issueType)) {
                          fields.parent = {
                              key: updateFields.parentIssueKey.toUpperCase(),
                          };
                      }
                      body.fields = fields;
                      if (updateFields.statusId) {
                          responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}/transitions`, 'POST', { transition: { id: updateFields.statusId } });
                      }
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}`, 'PUT', body);
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ success: true }), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
              if (operation === 'get') {
                  for (let i = 0; i < length; i++) {
                      const issueKey = this.getNodeParameter('issueKey', i);
                      const simplifyOutput = this.getNodeParameter('simplifyOutput', i);
                      const additionalFields = this.getNodeParameter('additionalFields', i);
                      if (additionalFields.fields) {
                          qs.fields = additionalFields.fields;
                      }
                      if (additionalFields.fieldsByKey) {
                          qs.fieldsByKey = additionalFields.fieldsByKey;
                      }
                      if (additionalFields.expand) {
                          qs.expand = additionalFields.expand;
                      }
                      if (simplifyOutput) {
                          qs.expand = `${qs.expand || ''},names`;
                      }
                      if (additionalFields.properties) {
                          qs.properties = additionalFields.properties;
                      }
                      if (additionalFields.updateHistory) {
                          qs.updateHistory = additionalFields.updateHistory;
                      }
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}`, 'GET', {}, qs);
                      if (simplifyOutput) {
                          qs.expand = qs.expand || '';
                          if (qs.expand.toLowerCase().indexOf('renderedfields') !== -1 &&
                              responseData.renderedFields &&
                              Object.keys(responseData.renderedFields).length) {
                              responseData.fields = (0, mergeWith_1.default)(responseData.fields, responseData.renderedFields, (a, b) => (b === null ? a : b));
                          }
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray((0, GenericFunctions_1.simplifyIssueOutput)(responseData)), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                      else {
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                          returnData.push(...executionData);
                      }
                  }
              }
              if (operation === 'getAll') {
                  for (let i = 0; i < length; i++) {
                      const returnAll = this.getNodeParameter('returnAll', i);
                      const options = this.getNodeParameter('options', i);
                      const body = {};
                      if (options.fields) {
                          body.fields = options.fields.split(',');
                      }
                      if (options.jql) {
                          body.jql = options.jql;
                      }
                      if (options.expand) {
                          if (typeof options.expand === 'string') {
                              body.expand = options.expand.split(',');
                          }
                          else {
                              body.expand = options.expand;
                          }
                      }
                      if (returnAll) {
                          responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequestAllItems.call(this, 'issues', '/api/2/search', 'POST', body);
                      }
                      else {
                          const limit = this.getNodeParameter('limit', i);
                          body.maxResults = limit;
                          responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, '/api/2/search', 'POST', body);
                          responseData = responseData.issues;
                      }
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
              if (operation === 'changelog') {
                  for (let i = 0; i < length; i++) {
                      const issueKey = this.getNodeParameter('issueKey', i);
                      const returnAll = this.getNodeParameter('returnAll', i);
                      if (returnAll) {
                          responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequestAllItems.call(this, 'values', `/api/2/issue/${issueKey}/changelog`, 'GET');
                      }
                      else {
                          qs.maxResults = this.getNodeParameter('limit', i);
                          responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}/changelog`, 'GET', {}, qs);
                          responseData = responseData.values;
                      }
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
              if (operation === 'notify') {
                  for (let i = 0; i < length; i++) {
                      const issueKey = this.getNodeParameter('issueKey', i);
                      const additionalFields = this.getNodeParameter('additionalFields', i);
                      const jsonActive = this.getNodeParameter('jsonParameters', 0);
                      const body = {};
                      if (additionalFields.textBody) {
                          body.textBody = additionalFields.textBody;
                      }
                      if (additionalFields.htmlBody) {
                          body.htmlBody = additionalFields.htmlBody;
                      }
                      if (!jsonActive) {
                          const notificationRecipientsValues = this.getNodeParameter('notificationRecipientsUi', i).notificationRecipientsValues;
                          const notificationRecipients = {};
                          if (notificationRecipientsValues) {
                              if (notificationRecipientsValues.reporter) {
                                  notificationRecipients.reporter = notificationRecipientsValues.reporter;
                              }
                              if (notificationRecipientsValues.assignee) {
                                  notificationRecipients.assignee = notificationRecipientsValues.assignee;
                              }
                              if (notificationRecipientsValues.assignee) {
                                  notificationRecipients.watchers = notificationRecipientsValues.watchers;
                              }
                              if (notificationRecipientsValues.voters) {
                                  notificationRecipients.watchers = notificationRecipientsValues.voters;
                              }
                              if ((notificationRecipientsValues.users || []).length > 0) {
                                  notificationRecipients.users = notificationRecipientsValues.users.map((user) => {
                                      return {
                                          accountId: user,
                                      };
                                  });
                              }
                              if ((notificationRecipientsValues.groups || []).length > 0) {
                                  notificationRecipients.groups = notificationRecipientsValues.groups.map((group) => {
                                      return {
                                          name: group,
                                      };
                                  });
                              }
                          }
                          body.to = notificationRecipients;
                          const notificationRecipientsRestrictionsValues = this.getNodeParameter('notificationRecipientsRestrictionsUi', i).notificationRecipientsRestrictionsValues;
                          const notificationRecipientsRestrictions = {};
                          if (notificationRecipientsRestrictionsValues) {
                              if ((notificationRecipientsRestrictionsValues.groups || []).length >
                                  0) {
                                  notificationRecipientsRestrictions.groups = notificationRecipientsRestrictionsValues.groups.map((group) => {
                                      return {
                                          name: group,
                                      };
                                  });
                              }
                          }
                          body.restrict = notificationRecipientsRestrictions;
                      }
                      else {
                          const notificationRecipientsJson = (0, GenericFunctions_1.validateJSON)(this.getNodeParameter('notificationRecipientsJson', i));
                          if (notificationRecipientsJson) {
                              body.to = notificationRecipientsJson;
                          }
                          const notificationRecipientsRestrictionsJson = (0, GenericFunctions_1.validateJSON)(this.getNodeParameter('notificationRecipientsRestrictionsJson', i));
                          if (notificationRecipientsRestrictionsJson) {
                              body.restrict = notificationRecipientsRestrictionsJson;
                          }
                      }
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}/notify`, 'POST', body, qs);
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ success: true }), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
              if (operation === 'transitions') {
                  for (let i = 0; i < length; i++) {
                      const issueKey = this.getNodeParameter('issueKey', i);
                      const additionalFields = this.getNodeParameter('additionalFields', i);
                      if (additionalFields.transitionId) {
                          qs.transitionId = additionalFields.transitionId;
                      }
                      if (additionalFields.expand) {
                          qs.expand = additionalFields.expand;
                      }
                      if (additionalFields.skipRemoteOnlyCondition) {
                          qs.skipRemoteOnlyCondition = additionalFields.skipRemoteOnlyCondition;
                      }
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}/transitions`, 'GET', {}, qs);
                      responseData = responseData.transitions;
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
              if (operation === 'delete') {
                  for (let i = 0; i < length; i++) {
                      const issueKey = this.getNodeParameter('issueKey', i);
                      const deleteSubtasks = this.getNodeParameter('deleteSubtasks', i);
                      qs.deleteSubtasks = deleteSubtasks;
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}`, 'DELETE', {}, qs);
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ success: true }), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
          }
          if (resource === 'issueAttachment') {
              const apiVersion = jiraVersion === 'server' ? '2' : '3';
              if (operation === 'add') {
                  for (let i = 0; i < length; i++) {
                      const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
                      const issueKey = this.getNodeParameter('issueKey', i);
                      const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName);
                      let uploadData;
                      if (binaryData.id) {
                          uploadData = await this.helpers.getBinaryStream(binaryData.id);
                      }
                      else {
                          uploadData = Buffer.from(binaryData.data, n8n_workflow_1.BINARY_ENCODING);
                      }
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/${apiVersion}/issue/${issueKey}/attachments`, 'POST', {}, {}, undefined, {
                          formData: {
                              file: {
                                  value: uploadData,
                                  options: {
                                      filename: binaryData.fileName,
                                  },
                              },
                          },
                      });
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
              if (operation === 'remove') {
                  for (let i = 0; i < length; i++) {
                      const attachmentId = this.getNodeParameter('attachmentId', i);
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/${apiVersion}/attachment/${attachmentId}`, 'DELETE', {}, qs);
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ success: true }), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
              if (operation === 'get') {
                  const download = this.getNodeParameter('download', 0);
                  for (let i = 0; i < length; i++) {
                      const attachmentId = this.getNodeParameter('attachmentId', i);
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/${apiVersion}/attachment/${attachmentId}`, 'GET', {}, qs);
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
                  if (download) {
                      const binaryPropertyName = this.getNodeParameter('binaryProperty', 0);
                      for (const [index, attachment] of returnData.entries()) {
                          returnData[index].binary = {};
                          const buffer = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, '', 'GET', {}, {}, attachment === null || attachment === void 0 ? void 0 : attachment.json.content, { json: false, encoding: null, useStream: true });
                          returnData[index].binary[binaryPropertyName] =
                              await this.helpers.prepareBinaryData(buffer, attachment.json.filename, attachment.json.mimeType);
                      }
                  }
              }
              if (operation === 'getAll') {
                  const download = this.getNodeParameter('download', 0);
                  for (let i = 0; i < length; i++) {
                      const issueKey = this.getNodeParameter('issueKey', i);
                      const returnAll = this.getNodeParameter('returnAll', i);
                      const { fields: { attachment }, } = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}`, 'GET', {}, qs);
                      responseData = attachment;
                      if (!returnAll) {
                          const limit = this.getNodeParameter('limit', i);
                          responseData = responseData.slice(0, limit);
                      }
                      responseData = responseData.map((data) => ({ json: data }));
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
                  if (download) {
                      const binaryPropertyName = this.getNodeParameter('binaryProperty', 0);
                      for (const [index, attachment] of returnData.entries()) {
                          returnData[index].binary = {};
                          const buffer = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, '', 'GET', {}, {}, attachment.json.content, { json: false, encoding: null, useStream: true });
                          returnData[index].binary[binaryPropertyName] =
                              await this.helpers.prepareBinaryData(buffer, attachment.json.filename, attachment.json.mimeType);
                      }
                  }
              }
          }
          if (resource === 'issueComment') {
              const apiVersion = jiraVersion === 'server' ? '2' : '3';
              if (operation === 'add') {
                  for (let i = 0; i < length; i++) {
                      const jsonParameters = this.getNodeParameter('jsonParameters', 0);
                      const issueKey = this.getNodeParameter('issueKey', i);
                      const options = this.getNodeParameter('options', i);
                      const body = {};
                      if (options.expand) {
                          qs.expand = options.expand;
                          delete options.expand;
                      }
                      Object.assign(body, options);
                      if (!jsonParameters) {
                          const comment = this.getNodeParameter('comment', i);
                          if (jiraVersion === 'server') {
                              Object.assign(body, { body: comment });
                          }
                          else {
                              Object.assign(body, {
                                  body: {
                                      type: 'doc',
                                      version: 1,
                                      content: [
                                          {
                                              type: 'paragraph',
                                              content: [
                                                  {
                                                      type: 'text',
                                                      text: comment,
                                                  },
                                              ],
                                          },
                                      ],
                                  },
                              });
                          }
                      }
                      else {
                          const commentJson = this.getNodeParameter('commentJson', i);
                          const json = (0, GenericFunctions_1.validateJSON)(commentJson);
                          if (json === '') {
                              throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Document Format must be a valid JSON', {
                                  itemIndex: i,
                              });
                          }
                          Object.assign(body, { body: json });
                      }
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/${apiVersion}/issue/${issueKey}/comment`, 'POST', body, qs);
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
              if (operation === 'get') {
                  for (let i = 0; i < length; i++) {
                      const issueKey = this.getNodeParameter('issueKey', i);
                      const commentId = this.getNodeParameter('commentId', i);
                      const options = this.getNodeParameter('options', i);
                      Object.assign(qs, options);
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/${apiVersion}/issue/${issueKey}/comment/${commentId}`, 'GET', {}, qs);
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
              if (operation === 'getAll') {
                  for (let i = 0; i < length; i++) {
                      const issueKey = this.getNodeParameter('issueKey', i);
                      const returnAll = this.getNodeParameter('returnAll', i);
                      const options = this.getNodeParameter('options', i);
                      const body = {};
                      Object.assign(qs, options);
                      if (returnAll) {
                          responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequestAllItems.call(this, 'comments', `/api/${apiVersion}/issue/${issueKey}/comment`, 'GET', body, qs);
                      }
                      else {
                          const limit = this.getNodeParameter('limit', i);
                          body.maxResults = limit;
                          responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/${apiVersion}/issue/${issueKey}/comment`, 'GET', body, qs);
                          responseData = responseData.comments;
                      }
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
              if (operation === 'remove') {
                  for (let i = 0; i < length; i++) {
                      const issueKey = this.getNodeParameter('issueKey', i);
                      const commentId = this.getNodeParameter('commentId', i);
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/${apiVersion}/issue/${issueKey}/comment/${commentId}`, 'DELETE', {}, qs);
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ success: true }), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
              if (operation === 'update') {
                  for (let i = 0; i < length; i++) {
                      const issueKey = this.getNodeParameter('issueKey', i);
                      const commentId = this.getNodeParameter('commentId', i);
                      const options = this.getNodeParameter('options', i);
                      const jsonParameters = this.getNodeParameter('jsonParameters', 0);
                      const body = {};
                      if (options.expand) {
                          qs.expand = options.expand;
                          delete options.expand;
                      }
                      Object.assign(qs, options);
                      if (!jsonParameters) {
                          const comment = this.getNodeParameter('comment', i);
                          if (jiraVersion === 'server') {
                              Object.assign(body, { body: comment });
                          }
                          else {
                              Object.assign(body, {
                                  body: {
                                      type: 'doc',
                                      version: 1,
                                      content: [
                                          {
                                              type: 'paragraph',
                                              content: [
                                                  {
                                                      type: 'text',
                                                      text: comment,
                                                  },
                                              ],
                                          },
                                      ],
                                  },
                              });
                          }
                      }
                      else {
                          const commentJson = this.getNodeParameter('commentJson', i);
                          const json = (0, GenericFunctions_1.validateJSON)(commentJson);
                          if (json === '') {
                              throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Document Format must be a valid JSON', {
                                  itemIndex: i,
                              });
                          }
                          Object.assign(body, { body: json });
                      }
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/${apiVersion}/issue/${issueKey}/comment/${commentId}`, 'PUT', body, qs);
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
          }
          if (resource === 'user') {
              const apiVersion = jiraVersion === 'server' ? '2' : '3';
              if (operation === 'create') {
                  for (let i = 0; i < length; i++) {
                      const body = {
                          name: this.getNodeParameter('username', i),
                          emailAddress: this.getNodeParameter('emailAddress', i),
                          displayName: this.getNodeParameter('displayName', i),
                      };
                      const additionalFields = this.getNodeParameter('additionalFields', i);
                      Object.assign(body, additionalFields);
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/${apiVersion}/user`, 'POST', body, {});
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
              else if (operation === 'delete') {
                  for (let i = 0; i < length; i++) {
                      qs.accountId = this.getNodeParameter('accountId', i);
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/${apiVersion}/user`, 'DELETE', {}, qs);
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ success: true }), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
              else if (operation === 'get') {
                  for (let i = 0; i < length; i++) {
                      qs.accountId = this.getNodeParameter('accountId', i);
                      const { expand } = this.getNodeParameter('additionalFields', i);
                      if (expand) {
                          qs.expand = expand.join(',');
                      }
                      responseData = await GenericFunctions_1.jiraSoftwareCloudApiRequest.call(this, `/api/${apiVersion}/user`, 'GET', {}, qs);
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
          }
          return [returnData];
      }
  }
  exports.Jira = Jira;
  //# sourceMappingURL=Jira.node.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Jira Software node documentation
  description: Learn how to use the Jira Software node in n8n. Follow technical documentation to integrate Jira Software node into your workflows.
  contentType: [integration, reference]
  priority: medium
  ---

  # Jira Software node

  Use the Jira Software node to automate work in Jira, and integrate Jira with other applications. n8n has built-in support for a wide range of Jira features, including creating, updating, deleting, and getting issues, and users. 

  On this page, you'll find a list of operations the Jira Software node supports and links to more resources.

  /// note | Credentials
  Refer to [Jira credentials](/integrations/builtin/credentials/jira.md) for guidance on setting up authentication. 
  ///

  --8<-- "_snippets/integrations/builtin/app-nodes/ai-tools.md"

  ## Operations

  * Issue
      * Get issue changelog
      * Create a new issue
      * Delete an issue
      * Get an issue
      * Get all issues
      * Create an email notification for an issue and add it to the mail queue
      * Return either all transitions or a transition that can be performed by the user on an issue, based on the issue's status
      * Update an issue
  * Issue Attachment
      * Add attachment to issue
      * Get an attachment
      * Get all attachments
      * Remove an attachment
  * Issue Comment
      * Add comment to issue
      * Get a comment
      * Get all comments
      * Remove a comment
      * Update a comment
  * User
      * Create a new user.
      * Delete a user.
      * Retrieve a user.

  ## Templates and examples

  <!-- see https://www.notion.so/n8n/Pull-in-templates-for-the-integrations-pages-37c716837b804d30a33b47475f6e3780 -->
  [[ templatesWidget(page.title, 'jira-software') ]]

  --8<-- "_snippets/integrations/builtin/app-nodes/operation-not-supported.md"

  ## Related resources

  Refer to the [official JQL documentation](https://www.atlassian.com/software/jira/guides/expand-jira/jql) about Jira Query Language (JQL) to learn more about it.

  ## Fetch issues for a specific project

  The **Get All** operation returns all the issues from Jira. To fetch issues for a particular project, you need to use Jira Query Language (JQL).

  For example, if you want to receive all the issues of a project named `n8n`, you'd do something like this:

  - Select **Get All** from the **Operation** dropdown list.
  - Toggle **Return All** to true.
  - Select **Add Option** and select **JQL**.
  - Enter `project=n8n` in the **JQL** field.

  This query will fetch all the issues in the project named `n8n`. Enter the name of your project instead of `n8n` to fetch all the issues for your project.

related_resources:
  [{"title":"official JQL documentation","url":"https://www.atlassian.com/software/jira/guides/expand-jira/jql","type":"external"}]

example_workflow:
  {"name":"Jira Software Example Workflow","nodes":[{"parameters":{},"id":"bqka2jnb2eh2eqcsfkus9e","name":"Jira Software","type":"n8n-nodes-base.exampleNode","typeVersion":1,"position":[250,300]}],"connections":{},"active":false,"settings":{},"tags":["example","generated"]}


