# nodes

node_type: n8n-nodes-base.ExecuteWorkflowTrigger
name: ExecuteWorkflowTrigger
display_name: Execute Workflow Trigger
description: Helpers for calling other n8n workflows. Used for designing modular, microservice-like workflows.
category: Other
code_hash: f1d84b2742ef34b0a1cb589ca488d87263fbd1890f844cd1a964c4221a0eefd5
documentation_url: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflowtrigger
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-08 08:05:21
updated_at: 2025-06-08 08:05:21
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.ExecuteWorkflowTrigger = void 0;
  class ExecuteWorkflowTrigger {
      constructor() {
          this.description = {
              displayName: 'Execute Workflow Trigger',
              name: 'executeWorkflowTrigger',
              icon: 'fa:sign-out-alt',
              group: ['trigger'],
              version: 1,
              description: 'Helpers for calling other n8n workflows. Used for designing modular, microservice-like workflows.',
              eventTriggerDescription: '',
              maxNodes: 1,
              defaults: {
                  name: 'Execute Workflow Trigger',
                  color: '#ff6d5a',
              },
              inputs: [],
              outputs: ['main'],
              properties: [
                  {
                      displayName: "When an ‘execute workflow’ node calls this workflow, the execution starts here. Any data passed into the 'execute workflow' node will be output by this node.",
                      name: 'notice',
                      type: 'notice',
                      default: '',
                  },
                  {
                      displayName: 'Events',
                      name: 'events',
                      type: 'hidden',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Workflow Call',
                              value: 'worklfow_call',
                              description: 'When called by another workflow using Execute Workflow Trigger',
                              action: 'When Called by Another Workflow',
                          },
                      ],
                      default: 'worklfow_call',
                  },
              ],
          };
      }
      async execute() {
          return [this.getInputData()];
      }
  }
  exports.ExecuteWorkflowTrigger = ExecuteWorkflowTrigger;
  //# sourceMappingURL=ExecuteWorkflowTrigger.node.js.map

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

  # Execute Sub-workflow Trigger node

  Use this node to start a workflow in response to another workflow. It should be the first node in the workflow.

  n8n allows you to call workflows from other workflows. This is useful if you want to:

  * Reuse a workflow: for example, you could have multiple workflows pulling and processing data from different sources, then have all those workflows call a single workflow that generates a report.
  * Break large workflows into smaller components.

  ## Usage

  This node runs in response to a call from the [Execute Sub-workflow](/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflow.md) or [Call n8n Workflow Tool](/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolworkflow.md) nodes.

  --8<-- "_snippets/flow-logic/subworkflow-usage.md"

  ## Templates and examples

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

  ## How data passes between workflows

  --8<-- "_snippets/flow-logic/subworkflow-data-flow.md"

example_workflow:
  {"nodes":[{"parameters":{},"type":"n8n-nodes-base.node","typeVersion":1,"position":[220,120],"id":"6ed556d9-2306-44c2-a2b1-084c397488b7","name":"Node"}],"connections":{"Node":{"main":[[]]}},"pinData":{},"meta":{"templateCredsSetupCompleted":true,"instanceId":"d46f939bb91d3603f40cdbb30148ea005e14495fc82f3f01fa0638f916e113bf"}}


node_type: n8n-nodes-base.ExecutionData
name: ExecutionData
display_name: Execution Data
description: Add execution data for search
category: Other
code_hash: 8d02375f5d0b6c49c900adcf415e46aead0c89e0033ccff2456c4ba5bb2ed769
documentation_url: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.executiondata
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-08 08:05:21
updated_at: 2025-06-08 08:05:21
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.ExecutionData = void 0;
  class ExecutionData {
      constructor() {
          this.description = {
              displayName: 'Execution Data',
              name: 'executionData',
              icon: 'fa:tasks',
              group: ['input'],
              version: 1,
              description: 'Add execution data for search',
              defaults: {
                  name: 'Execution Data',
                  color: '#29A568',
              },
              inputs: ['main'],
              outputs: ['main'],
              properties: [
                  {
                      displayName: "Use this node to save fields you want to use later to easily find an execution (e.g. a user ID). You'll be able to search by this data in the 'executions' tab.<br>This feature is available on our Pro and Enterprise plans. <a href='https://n8n.io/pricing/' target='_blank'>More Info</a>.",
                      name: 'notice',
                      type: 'notice',
                      default: '',
                  },
                  {
                      displayName: 'Operation',
                      name: 'operation',
                      type: 'options',
                      default: 'save',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Save Execution Data for Search',
                              value: 'save',
                              action: 'Save execution data for search',
                          },
                      ],
                  },
                  {
                      displayName: 'Data to Save',
                      name: 'dataToSave',
                      placeholder: 'Add Saved Field',
                      type: 'fixedCollection',
                      typeOptions: {
                          multipleValueButtonText: 'Add Saved Field',
                          multipleValues: true,
                      },
                      displayOptions: {
                          show: {
                              operation: ['save'],
                          },
                      },
                      default: {},
                      options: [
                          {
                              displayName: 'Values',
                              name: 'values',
                              values: [
                                  {
                                      displayName: 'Key',
                                      name: 'key',
                                      type: 'string',
                                      default: '',
                                      placeholder: 'e.g. myKey',
                                  },
                                  {
                                      displayName: 'Value',
                                      name: 'value',
                                      type: 'string',
                                      default: '',
                                      placeholder: 'e.g. myValue',
                                  },
                              ],
                          },
                      ],
                  },
              ],
          };
      }
      async execute() {
          const context = this.getWorkflowDataProxy(0);
          const items = this.getInputData();
          const operations = this.getNodeParameter('operation', 0);
          if (operations === 'save') {
              for (let i = 0; i < items.length; i++) {
                  const dataToSave = this.getNodeParameter('dataToSave', i, {}).values ||
                      [];
                  const values = dataToSave.reduce((acc, { key, value }) => {
                      acc[key] = value;
                      return acc;
                  }, {});
                  context.$execution.customData.setAll(values);
              }
          }
          return [items];
      }
  }
  exports.ExecutionData = ExecutionData;
  //# sourceMappingURL=ExecutionData.node.js.map

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

  # Execution Data

  Use this node to save metadata for workflow executions. You can then search by this data in the **Executions** list.

  You can retrieve custom execution data during workflow execution using the Code node. Refer to [Custom executions data](/workflows/executions/custom-executions-data.md) for more information.

  /// info | Feature availability
  Available on Pro and Enterprise plans.
  ///

  ## Operations

  * Save Execution Data for Search

  ## Data to Save

  Add a **Saved Field** for each key/value pair of metadata you'd like to save.

  ## Limitations

  The Execution Data node has the following restrictions when storing execution metadata:

  * `key`: limited to 50 characters
  * `value`: limited to 512 characters

  If either the `key` or `value` exceed the above limitations, n8n truncates to their maximum length and outputs a log entry.

  ## Templates and examples

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

example_workflow:
  {"nodes":[{"parameters":{},"type":"n8n-nodes-base.node","typeVersion":1,"position":[220,120],"id":"1cc6bd6b-0064-402d-8a6b-4faa2856b716","name":"Node"}],"connections":{"Node":{"main":[[]]}},"pinData":{},"meta":{"templateCredsSetupCompleted":true,"instanceId":"dfc0939f8c4b6240c34422998e0ebbc61a0311040868e41f3a74c14a0e7a4984"}}


node_type: n8n-nodes-base.FileMaker
name: FileMaker
display_name: FileMaker
description: Retrieve data from the FileMaker data API
category: Other
code_hash: d3aa71438148e0dd63bebb11eaff551e9d6e0435bea93d1946b143f720183540
documentation_url: https://docs.n8n.io/integrations/builtin/credentials/filemaker
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-08 08:05:21
updated_at: 2025-06-08 08:05:21
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.FileMaker = void 0;
  const n8n_workflow_1 = require("n8n-workflow");
  const GenericFunctions_1 = require("./GenericFunctions");
  class FileMaker {
      constructor() {
          this.description = {
              displayName: 'FileMaker',
              name: 'filemaker',
              icon: 'file:filemaker.png',
              group: ['input'],
              version: 1,
              description: 'Retrieve data from the FileMaker data API',
              defaults: {
                  name: 'FileMaker',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'fileMaker',
                      required: true,
                  },
              ],
              properties: [
                  {
                      displayName: 'Action',
                      name: 'action',
                      type: 'options',
                      default: 'record',
                      options: [
                          {
                              name: 'Create Record',
                              value: 'create',
                          },
                          {
                              name: 'Delete Record',
                              value: 'delete',
                          },
                          {
                              name: 'Duplicate Record',
                              value: 'duplicate',
                          },
                          {
                              name: 'Edit Record',
                              value: 'edit',
                          },
                          {
                              name: 'Find Records',
                              value: 'find',
                          },
                          {
                              name: 'Get Records',
                              value: 'records',
                          },
                          {
                              name: 'Get Records By ID',
                              value: 'record',
                          },
                          {
                              name: 'Perform Script',
                              value: 'performscript',
                          },
                      ],
                  },
                  {
                      displayName: 'Layout Name or ID',
                      name: 'layout',
                      type: 'options',
                      typeOptions: {
                          loadOptionsMethod: 'getLayouts',
                      },
                      options: [],
                      default: '',
                      required: true,
                      displayOptions: {},
                      placeholder: 'Layout Name',
                      description: 'FileMaker Layout Name. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                  },
                  {
                      displayName: 'Record ID',
                      name: 'recid',
                      type: 'number',
                      default: '',
                      required: true,
                      displayOptions: {
                          show: {
                              action: ['record', 'edit', 'delete', 'duplicate'],
                          },
                      },
                      placeholder: 'Record ID',
                      description: 'Internal Record ID returned by get (recordid)',
                  },
                  {
                      displayName: 'Offset',
                      name: 'offset',
                      placeholder: '0',
                      description: 'The record number of the first record in the range of records',
                      type: 'number',
                      default: 1,
                      displayOptions: {
                          show: {
                              action: ['find', 'records'],
                          },
                      },
                  },
                  {
                      displayName: 'Limit',
                      name: 'limit',
                      placeholder: '100',
                      description: 'Max number of results to return',
                      type: 'number',
                      typeOptions: {
                          minValue: 1,
                      },
                      default: 100,
                      displayOptions: {
                          show: {
                              action: ['find', 'records'],
                          },
                      },
                  },
                  {
                      displayName: 'Get Portals',
                      name: 'getPortals',
                      type: 'boolean',
                      default: false,
                      description: 'Whether to get portal data as well',
                      displayOptions: {
                          show: {
                              action: ['record', 'records', 'find'],
                          },
                      },
                  },
                  {
                      displayName: 'Portals Name or ID',
                      name: 'portals',
                      type: 'options',
                      typeOptions: {
                          multipleValues: true,
                          multipleValueButtonText: 'Add portal',
                          loadOptionsMethod: 'getPortals',
                      },
                      options: [],
                      default: [],
                      displayOptions: {
                          show: {
                              action: ['record', 'records', 'find'],
                              getPortals: [true],
                          },
                      },
                      placeholder: 'Portals',
                      description: 'The portal result set to return. Use the portal object name or portal table name. If this parameter is omitted, the API will return all portal objects and records in the layout. For best performance, pass the portal object name or portal table name. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                  },
                  {
                      displayName: 'Response Layout Name or ID',
                      name: 'responseLayout',
                      type: 'options',
                      description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>',
                      typeOptions: {
                          loadOptionsMethod: 'getResponseLayouts',
                      },
                      options: [],
                      default: '',
                      displayOptions: {
                          show: {
                              action: ['find'],
                          },
                      },
                  },
                  {
                      displayName: 'Queries',
                      name: 'queries',
                      placeholder: 'Add query',
                      type: 'fixedCollection',
                      typeOptions: {
                          multipleValues: true,
                      },
                      displayOptions: {
                          show: {
                              action: ['find'],
                          },
                      },
                      default: {},
                      options: [
                          {
                              name: 'query',
                              displayName: 'Query',
                              values: [
                                  {
                                      displayName: 'Fields',
                                      name: 'fields',
                                      placeholder: 'Add field',
                                      type: 'fixedCollection',
                                      default: {},
                                      typeOptions: {
                                          multipleValues: true,
                                      },
                                      options: [
                                          {
                                              name: 'field',
                                              displayName: 'Field',
                                              values: [
                                                  {
                                                      displayName: 'Field Name or ID',
                                                      name: 'name',
                                                      type: 'options',
                                                      default: '',
                                                      typeOptions: {
                                                          loadOptionsMethod: 'getFields',
                                                      },
                                                      options: [],
                                                      description: 'Search Field. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                                                  },
                                                  {
                                                      displayName: 'Value',
                                                      name: 'value',
                                                      type: 'string',
                                                      default: '',
                                                      description: 'Value to search',
                                                  },
                                              ],
                                          },
                                      ],
                                      description: 'Field Name',
                                  },
                                  {
                                      displayName: 'Omit',
                                      name: 'omit',
                                      type: 'boolean',
                                      default: false,
                                  },
                              ],
                          },
                      ],
                  },
                  {
                      displayName: 'Sort Data?',
                      name: 'setSort',
                      type: 'boolean',
                      default: false,
                      description: 'Whether to sort data',
                      displayOptions: {
                          show: {
                              action: ['find', 'record', 'records'],
                          },
                      },
                  },
                  {
                      displayName: 'Sort',
                      name: 'sortParametersUi',
                      placeholder: 'Add Sort Rules',
                      type: 'fixedCollection',
                      typeOptions: {
                          multipleValues: true,
                      },
                      displayOptions: {
                          show: {
                              setSort: [true],
                              action: ['find', 'records'],
                          },
                      },
                      description: 'Sort rules',
                      default: {},
                      options: [
                          {
                              name: 'rules',
                              displayName: 'Rules',
                              values: [
                                  {
                                      displayName: 'Field Name or ID',
                                      name: 'name',
                                      type: 'options',
                                      default: '',
                                      typeOptions: {
                                          loadOptionsMethod: 'getFields',
                                      },
                                      options: [],
                                      description: 'Field Name. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                                  },
                                  {
                                      displayName: 'Order',
                                      name: 'value',
                                      type: 'options',
                                      default: 'ascend',
                                      options: [
                                          {
                                              name: 'Ascend',
                                              value: 'ascend',
                                          },
                                          {
                                              name: 'Descend',
                                              value: 'descend',
                                          },
                                      ],
                                      description: 'Sort order',
                                  },
                              ],
                          },
                      ],
                  },
                  {
                      displayName: 'Before Find Script',
                      name: 'setScriptBefore',
                      type: 'boolean',
                      default: false,
                      description: 'Whether to define a script to be run before the action specified by the API call and after the subsequent sort',
                      displayOptions: {
                          show: {
                              action: ['find', 'record', 'records'],
                          },
                      },
                  },
                  {
                      displayName: 'Script Name or ID',
                      name: 'scriptBefore',
                      type: 'options',
                      typeOptions: {
                          loadOptionsMethod: 'getScripts',
                      },
                      options: [],
                      default: '',
                      required: true,
                      displayOptions: {
                          show: {
                              action: ['find', 'record', 'records'],
                              setScriptBefore: [true],
                          },
                      },
                      placeholder: 'Script Name',
                      description: 'The name of the FileMaker script to be run after the action specified by the API call and after the subsequent sort. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                  },
                  {
                      displayName: 'Script Parameter',
                      name: 'scriptBeforeParam',
                      type: 'string',
                      default: '',
                      displayOptions: {
                          show: {
                              action: ['find', 'record', 'records'],
                              setScriptBefore: [true],
                          },
                      },
                      placeholder: 'Script Parameters',
                      description: 'A parameter for the FileMaker script',
                  },
                  {
                      displayName: 'Before Sort Script',
                      name: 'setScriptSort',
                      type: 'boolean',
                      default: false,
                      description: 'Whether to define a script to be run after the action specified by the API call but before the subsequent sort',
                      displayOptions: {
                          show: {
                              action: ['find', 'record', 'records'],
                          },
                      },
                  },
                  {
                      displayName: 'Script Name or ID',
                      name: 'scriptSort',
                      type: 'options',
                      typeOptions: {
                          loadOptionsMethod: 'getScripts',
                      },
                      options: [],
                      default: '',
                      required: true,
                      displayOptions: {
                          show: {
                              action: ['find', 'record', 'records'],
                              setScriptSort: [true],
                          },
                      },
                      placeholder: 'Script Name',
                      description: 'The name of the FileMaker script to be run after the action specified by the API call but before the subsequent sort. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                  },
                  {
                      displayName: 'Script Parameter',
                      name: 'scriptSortParam',
                      type: 'string',
                      default: '',
                      displayOptions: {
                          show: {
                              action: ['find', 'record', 'records'],
                              setScriptSort: [true],
                          },
                      },
                      placeholder: 'Script Parameters',
                      description: 'A parameter for the FileMaker script',
                  },
                  {
                      displayName: 'After Sort Script',
                      name: 'setScriptAfter',
                      type: 'boolean',
                      default: false,
                      description: 'Whether to define a script to be run after the action specified by the API call but before the subsequent sort',
                      displayOptions: {
                          show: {
                              action: ['find', 'record', 'records'],
                          },
                      },
                  },
                  {
                      displayName: 'Script Name or ID',
                      name: 'scriptAfter',
                      type: 'options',
                      typeOptions: {
                          loadOptionsMethod: 'getScripts',
                      },
                      options: [],
                      default: '',
                      required: true,
                      displayOptions: {
                          show: {
                              action: ['find', 'record', 'records'],
                              setScriptAfter: [true],
                          },
                      },
                      placeholder: 'Script Name',
                      description: 'The name of the FileMaker script to be run after the action specified by the API call and after the subsequent sort. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                  },
                  {
                      displayName: 'Script Parameter',
                      name: 'scriptAfterParam',
                      type: 'string',
                      default: '',
                      displayOptions: {
                          show: {
                              action: ['find', 'record', 'records'],
                              setScriptAfter: [true],
                          },
                      },
                      placeholder: 'Script Parameters',
                      description: 'A parameter for the FileMaker script',
                  },
                  {
                      displayName: 'Mod ID',
                      name: 'modId',
                      description: 'The last modification ID. When you use modId, a record is edited only when the modId matches.',
                      type: 'number',
                      default: '',
                      displayOptions: {
                          show: {
                              action: ['edit'],
                          },
                      },
                  },
                  {
                      displayName: 'Fields',
                      name: 'fieldsParametersUi',
                      placeholder: 'Add field',
                      type: 'fixedCollection',
                      typeOptions: {
                          multipleValues: true,
                      },
                      displayOptions: {
                          show: {
                              action: ['create', 'edit'],
                          },
                      },
                      description: 'Fields to define',
                      default: {},
                      options: [
                          {
                              name: 'fields',
                              displayName: 'Fields',
                              values: [
                                  {
                                      displayName: 'Field Name or ID',
                                      name: 'name',
                                      type: 'options',
                                      default: '',
                                      typeOptions: {
                                          loadOptionsMethod: 'getFields',
                                      },
                                      options: [],
                                      description: 'Field Name. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                                  },
                                  {
                                      displayName: 'Value',
                                      name: 'value',
                                      type: 'string',
                                      default: '',
                                  },
                              ],
                          },
                      ],
                  },
                  {
                      displayName: 'Script Name or ID',
                      name: 'script',
                      type: 'options',
                      typeOptions: {
                          loadOptionsMethod: 'getScripts',
                      },
                      options: [],
                      default: '',
                      required: true,
                      displayOptions: {
                          show: {
                              action: ['performscript'],
                          },
                      },
                      placeholder: 'Script Name',
                      description: 'The name of the FileMaker script to be run. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                  },
                  {
                      displayName: 'Script Parameter',
                      name: 'scriptParam',
                      type: 'string',
                      default: '',
                      displayOptions: {
                          show: {
                              action: ['performscript'],
                          },
                      },
                      placeholder: 'Script Parameters',
                      description: 'A parameter for the FileMaker script',
                  },
              ],
          };
          this.methods = {
              loadOptions: {
                  async getLayouts() {
                      let returnData;
                      try {
                          returnData = await GenericFunctions_1.layoutsApiRequest.call(this);
                      }
                      catch (error) {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), error);
                      }
                      return returnData;
                  },
                  async getResponseLayouts() {
                      const returnData = [];
                      returnData.push({
                          name: 'Use main layout',
                          value: '',
                      });
                      let layouts;
                      try {
                          layouts = await GenericFunctions_1.layoutsApiRequest.call(this);
                      }
                      catch (error) {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), error);
                      }
                      for (const layout of layouts) {
                          returnData.push({
                              name: layout.name,
                              value: layout.name,
                          });
                      }
                      return returnData;
                  },
                  async getFields() {
                      const returnData = [];
                      let fields;
                      try {
                          fields = await GenericFunctions_1.getFields.call(this);
                      }
                      catch (error) {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), error);
                      }
                      for (const field of fields) {
                          returnData.push({
                              name: field.name,
                              value: field.name,
                          });
                      }
                      return returnData;
                  },
                  async getScripts() {
                      const returnData = [];
                      let scripts;
                      try {
                          scripts = await GenericFunctions_1.getScripts.call(this);
                      }
                      catch (error) {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), error);
                      }
                      for (const script of scripts) {
                          if (!script.isFolder) {
                              returnData.push({
                                  name: script.name,
                                  value: script.name,
                              });
                          }
                      }
                      return returnData;
                  },
                  async getPortals() {
                      const returnData = [];
                      let portals;
                      try {
                          portals = await GenericFunctions_1.getPortals.call(this);
                      }
                      catch (error) {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), error);
                      }
                      Object.keys(portals).forEach((portal) => {
                          returnData.push({
                              name: portal,
                              value: portal,
                          });
                      });
                      return returnData;
                  },
              },
          };
      }
      async execute() {
          const items = this.getInputData();
          const returnData = [];
          const credentials = await this.getCredentials('fileMaker');
          let token;
          try {
              token = await GenericFunctions_1.getToken.call(this);
          }
          catch (error) {
              throw new n8n_workflow_1.NodeOperationError(this.getNode(), error);
          }
          let requestOptions;
          const host = credentials.host;
          const database = credentials.db;
          const url = `https://${host}/fmi/data/v1`;
          const action = this.getNodeParameter('action', 0);
          try {
              for (let i = 0; i < items.length; i++) {
                  requestOptions = {
                      uri: '',
                      headers: {
                          Authorization: `Bearer ${token}`,
                      },
                      method: 'GET',
                      json: true,
                  };
                  const layout = this.getNodeParameter('layout', i);
                  if (action === 'record') {
                      const recid = this.getNodeParameter('recid', i);
                      requestOptions.uri = url + `/databases/${database}/layouts/${layout}/records/${recid}`;
                      requestOptions.qs = {
                          portal: JSON.stringify(GenericFunctions_1.parsePortals.call(this, i)),
                          ...GenericFunctions_1.parseScripts.call(this, i),
                      };
                  }
                  else if (action === 'records') {
                      requestOptions.uri = url + `/databases/${database}/layouts/${layout}/records`;
                      requestOptions.qs = {
                          _offset: this.getNodeParameter('offset', i),
                          _limit: this.getNodeParameter('limit', i),
                          portal: JSON.stringify(GenericFunctions_1.parsePortals.call(this, i)),
                          ...GenericFunctions_1.parseScripts.call(this, i),
                      };
                      const sort = GenericFunctions_1.parseSort.call(this, i);
                      if (sort) {
                          requestOptions.body.sort = sort;
                      }
                  }
                  else if (action === 'find') {
                      requestOptions.uri = url + `/databases/${database}/layouts/${layout}/_find`;
                      requestOptions.method = 'POST';
                      requestOptions.body = {
                          query: GenericFunctions_1.parseQuery.call(this, i),
                          offset: this.getNodeParameter('offset', i),
                          limit: this.getNodeParameter('limit', i),
                          'layout.response': this.getNodeParameter('responseLayout', i),
                          ...GenericFunctions_1.parseScripts.call(this, i),
                      };
                      const sort = GenericFunctions_1.parseSort.call(this, i);
                      if (sort) {
                          requestOptions.body.sort = sort;
                      }
                  }
                  else if (action === 'create') {
                      requestOptions.uri = url + `/databases/${database}/layouts/${layout}/records`;
                      requestOptions.method = 'POST';
                      requestOptions.headers['Content-Type'] = 'application/json';
                      requestOptions.body = {
                          fieldData: { ...GenericFunctions_1.parseFields.call(this, i) },
                          portalData: {},
                          ...GenericFunctions_1.parseScripts.call(this, i),
                      };
                  }
                  else if (action === 'edit') {
                      const recid = this.getNodeParameter('recid', i);
                      requestOptions.uri = url + `/databases/${database}/layouts/${layout}/records/${recid}`;
                      requestOptions.method = 'PATCH';
                      requestOptions.headers['Content-Type'] = 'application/json';
                      requestOptions.body = {
                          fieldData: { ...GenericFunctions_1.parseFields.call(this, i) },
                          portalData: {},
                          ...GenericFunctions_1.parseScripts.call(this, i),
                      };
                  }
                  else if (action === 'performscript') {
                      const scriptName = this.getNodeParameter('script', i);
                      requestOptions.uri =
                          url + `/databases/${database}/layouts/${layout}/script/${scriptName}`;
                      requestOptions.qs = {
                          'script.param': this.getNodeParameter('scriptParam', i),
                      };
                  }
                  else if (action === 'duplicate') {
                      const recid = this.getNodeParameter('recid', i);
                      requestOptions.uri = url + `/databases/${database}/layouts/${layout}/records/${recid}`;
                      requestOptions.method = 'POST';
                      requestOptions.headers['Content-Type'] = 'application/json';
                      requestOptions.qs = {
                          ...GenericFunctions_1.parseScripts.call(this, i),
                      };
                  }
                  else if (action === 'delete') {
                      const recid = this.getNodeParameter('recid', i);
                      requestOptions.uri = url + `/databases/${database}/layouts/${layout}/records/${recid}`;
                      requestOptions.method = 'DELETE';
                      requestOptions.qs = {
                          ...GenericFunctions_1.parseScripts.call(this, i),
                      };
                  }
                  else {
                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The action "${action}" is not implemented yet!`, { itemIndex: i });
                  }
                  let response;
                  try {
                      response = await this.helpers.request(requestOptions);
                  }
                  catch (error) {
                      response = error.error;
                  }
                  if (typeof response === 'string') {
                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'DataAPI response body is not valid JSON. Is the DataAPI enabled?', { itemIndex: i });
                  }
                  returnData.push({ json: response });
              }
          }
          catch (error) {
              if (error.node) {
                  throw error;
              }
              throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The action "${error.message}" is not implemented yet!`);
          }
          await GenericFunctions_1.logout.call(this, token);
          return [returnData];
      }
  }
  exports.FileMaker = FileMaker;
  //# sourceMappingURL=FileMaker.node.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: FileMaker credentials
  description: Documentation for FileMaker credentials. Use these credentials to authenticate FileMaker in n8n, a workflow automation platform.
  contentType: [integration, reference]
  priority: medium
  ---

  # FileMaker credentials

  You can use these credentials to authenticate the following nodes:

  - [FileMaker](/integrations/builtin/app-nodes/n8n-nodes-base.filemaker.md)

  ## Prerequisites

  - Create a user account on a [FileMaker Server](https://www.claris.com/filemaker/){:target=_blank .external-link} with the `fmrest` extended privilege to [Access the FileMaker Data API](https://help.claris.com/en/data-api-guide/content/enable-access.html){:target=_blank .external-link}.
  - Ensure the FileMaker Server can use the [FileMaker Data API](https://help.claris.com/en/data-api-guide/content/index.html){:target=_blank .external-link}:
      1. Prepare your database for FileMaker Data API access using FileMaker Pro. You can create a database or prepare an existing database.
          - Refer to [Prepare databases for FileMaker Data API access](https://help.claris.com/en/data-api-guide/content/prepare-databases-for-access.html){:target=_blank .external-link} for more information.
      1. Write code that calls FileMaker Data API methods to find, create, edit, duplicate, and delete records in a hosted database.
          - Refer to [Write FileMaker Data API calls](https://help.claris.com/en/data-api-guide/content/write-data-api-calls.html){:target=_blank .external-link} for more information.
      1. Host your solution with FileMaker Data API access enabled.
          - Refer to [Host a FileMaker Data API solution](https://help.claris.com/en/data-api-guide/content/host-data-api-app.html){:target=_blank .external-link} for more information.
      1. Test that FileMaker Data API access is working.
          - Refer to [Test the FileMaker Data API solution](https://help.claris.com/en/data-api-guide/content/test-data-api-app.html){:target=_blank .external-link} for more information.
      1. Monitor your hosted solution using Admin Console.
          - Refer to [Monitor FileMaker Data API solutions](https://help.claris.com/en/data-api-guide/content/monitor-data-api-app.html){:target=_blank .external-link} for more information.

  ## Supported authentication methods

  - Database connection

  ## Related resources

  Refer to [FileMaker's Data API Guide](https://help.claris.com/en/data-api-guide/content/index.html){:target=_blank .external-link} for more information about the service.

  ## Using database connection

  To configure this credential:

  1. Enter the **Host** name or IP address of your FileMaker Server.
  2. Enter the **Database** name. This should match the database name as it appears in the **Databases** list within FileMaker.
  3. Enter the user account **Login** for the account with the `fmrest` extended privilege. Refer to the previous [Prerequisites](#prerequisites) section for more information.
  4. Enter the **Password** for that user account.

example_workflow:
  {"nodes":[{"parameters":{},"type":"n8n-nodes-base.node","typeVersion":1,"position":[220,120],"id":"038b56a7-c646-455f-82a6-81f9a9dab256","name":"Node"}],"connections":{"Node":{"main":[[]]}},"pinData":{},"meta":{"templateCredsSetupCompleted":true,"instanceId":"5af5ce11985dce6ebfd6104c7da24a50a8116e8900bcec75369241dcf9fca26a"}}


node_type: n8n-nodes-base.Filter
name: Filter
display_name: Filter
description: Filter out incoming items based on given conditions
category: Other
code_hash: 324befe1651cf4734fd44ebfdf5945e1d61541c5a1bab2eb2d2ba218e3b66ff2
documentation_url: https://docs.n8n.io/data/data-filtering
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-08 08:05:21
updated_at: 2025-06-08 08:05:21
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Filter = void 0;
  const GenericFunctions_1 = require("./GenericFunctions");
  class Filter {
      constructor() {
          this.description = {
              displayName: 'Filter',
              name: 'filter',
              icon: 'fa:filter',
              group: ['transform'],
              version: 1,
              description: 'Filter out incoming items based on given conditions',
              defaults: {
                  name: 'Filter',
                  color: '#229eff',
              },
              inputs: ['main'],
              outputs: ['main'],
              outputNames: ['Kept', 'Discarded'],
              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 Conditions',
                      name: 'combineConditions',
                      type: 'options',
                      options: [
                          {
                              name: 'AND',
                              description: 'Items are passed to the next node only if they meet all the conditions',
                              value: 'AND',
                          },
                          {
                              name: 'OR',
                              description: 'Items are passed to the next node if they meet at least one condition',
                              value: 'OR',
                          },
                      ],
                      default: 'AND',
                      description: 'How to combine the conditions: AND requires all conditions to be true, OR requires at least one condition to be true',
                  },
              ],
          };
      }
      async execute() {
          const returnDataTrue = [];
          const returnDataFalse = [];
          const items = this.getInputData();
          const dataTypes = ['boolean', 'dateTime', 'number', 'string'];
          itemLoop: for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
              const item = items[itemIndex];
              const combineConditions = this.getNodeParameter('combineConditions', itemIndex);
              for (const dataType of dataTypes) {
                  const typeConditions = this.getNodeParameter(`conditions.${dataType}`, itemIndex, []);
                  for (const condition of typeConditions) {
                      let value1 = condition.value1;
                      let value2 = condition.value2;
                      if (dataType === 'dateTime') {
                          const node = this.getNode();
                          value1 = (0, GenericFunctions_1.convertDateTime)(node, value1);
                          value2 = (0, GenericFunctions_1.convertDateTime)(node, value2);
                      }
                      const compareResult = GenericFunctions_1.compareOperationFunctions[condition.operation](value1, value2);
                      if (item.pairedItem === undefined) {
                          item.pairedItem = [{ item: itemIndex }];
                      }
                      if (compareResult && combineConditions === 'OR') {
                          returnDataTrue.push(item);
                          continue itemLoop;
                      }
                      if (!compareResult && combineConditions === 'AND') {
                          returnDataFalse.push(item);
                          continue itemLoop;
                      }
                  }
              }
              if (combineConditions === 'AND') {
                  returnDataTrue.push(item);
              }
              else {
                  returnDataFalse.push(item);
              }
          }
          return [returnDataTrue, returnDataFalse];
      }
  }
  exports.Filter = Filter;
  //# sourceMappingURL=Filter.node.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  contentType: howto
  ---

  # Data filtering

  /// info | Feature availability
  Available on Cloud Pro and Enterprise plans.
  ///

  Search and filter data in the node **INPUT** and **OUTPUT** panels. Use this to check your node's data.

  To search:

  1. In a node, select **Search** <span class="inline-image">![Search icon](/_images/common-icons/search.png){.off-glb}</span> in the **INPUT** or **OUTPUT** panel.
  1. Enter your search term.

  n8n filters as you type your search, displaying the objects or rows containing the term.

  Filtering is purely visual: n8n doesn't change or delete data. The filter resets when you close and reopen the node.

example_workflow:
  {"nodes":[{"parameters":{},"type":"n8n-nodes-base.node","typeVersion":1,"position":[220,120],"id":"0fc0a182-6aa1-421e-b08e-d11c0f086f59","name":"Node"}],"connections":{"Node":{"main":[[]]}},"pinData":{},"meta":{"templateCredsSetupCompleted":true,"instanceId":"e4a41280e7527667d8193ea3e235856948cf07ce6471f5eae04f7847f35d810e"}}


node_type: n8n-nodes-base.Flow
name: Flow
display_name: Flow
description: Consume Flow API
category: Other
code_hash: 13e12903da5094fffdebbe6511f4f7eb7f1f7fad727f27793a64b523a553783e
documentation_url: https://docs.n8n.io/data/data-flow-nodes
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-08 08:05:21
updated_at: 2025-06-08 08:05:21
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Flow = void 0;
  const n8n_workflow_1 = require("n8n-workflow");
  const GenericFunctions_1 = require("./GenericFunctions");
  const TaskDescription_1 = require("./TaskDescription");
  class Flow {
      constructor() {
          this.description = {
              displayName: 'Flow',
              name: 'flow',
              icon: 'file:flow.png',
              group: ['output'],
              version: 1,
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Consume Flow API',
              defaults: {
                  name: 'Flow',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'flowApi',
                      required: true,
                  },
              ],
              properties: [
                  {
                      displayName: 'Resource',
                      name: 'resource',
                      type: 'options',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Task',
                              value: 'task',
                              description: 'Tasks are units of work that can be private or assigned to a list. Through this endpoint, you can manipulate your tasks in Flow, including creating new ones.',
                          },
                      ],
                      default: 'task',
                  },
                  ...TaskDescription_1.taskOperations,
                  ...TaskDescription_1.taskFields,
              ],
          };
      }
      async execute() {
          const credentials = await this.getCredentials('flowApi');
          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);
          for (let i = 0; i < length; i++) {
              if (resource === 'task') {
                  if (operation === 'create') {
                      const workspaceId = this.getNodeParameter('workspaceId', i);
                      const name = this.getNodeParameter('name', i);
                      const additionalFields = this.getNodeParameter('additionalFields', i);
                      const body = {
                          organization_id: credentials.organizationId,
                      };
                      const task = {
                          name,
                          workspace_id: parseInt(workspaceId, 10),
                      };
                      if (additionalFields.ownerId) {
                          task.owner_id = parseInt(additionalFields.ownerId, 10);
                      }
                      if (additionalFields.listId) {
                          task.list_id = parseInt(additionalFields.listId, 10);
                      }
                      if (additionalFields.startsOn) {
                          task.starts_on = additionalFields.startsOn;
                      }
                      if (additionalFields.dueOn) {
                          task.due_on = additionalFields.dueOn;
                      }
                      if (additionalFields.mirrorParentSubscribers) {
                          task.mirror_parent_subscribers = additionalFields.mirrorParentSubscribers;
                      }
                      if (additionalFields.mirrorParentTags) {
                          task.mirror_parent_tags = additionalFields.mirrorParentTags;
                      }
                      if (additionalFields.noteContent) {
                          task.note_content = additionalFields.noteContent;
                      }
                      if (additionalFields.noteMimeType) {
                          task.note_mime_type = additionalFields.noteMimeType;
                      }
                      if (additionalFields.parentId) {
                          task.parent_id = parseInt(additionalFields.parentId, 10);
                      }
                      if (additionalFields.positionList) {
                          task.position_list = additionalFields.positionList;
                      }
                      if (additionalFields.positionUpcoming) {
                          task.position_upcoming = additionalFields.positionUpcoming;
                      }
                      if (additionalFields.position) {
                          task.position = additionalFields.position;
                      }
                      if (additionalFields.sectionId) {
                          task.section_id = additionalFields.sectionId;
                      }
                      if (additionalFields.tags) {
                          task.tags = additionalFields.tags.split(',');
                      }
                      body.task = task;
                      try {
                          responseData = await GenericFunctions_1.flowApiRequest.call(this, 'POST', '/tasks', body);
                          responseData = responseData.task;
                      }
                      catch (error) {
                          throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
                      }
                  }
                  if (operation === 'update') {
                      const workspaceId = this.getNodeParameter('workspaceId', i);
                      const taskId = this.getNodeParameter('taskId', i);
                      const updateFields = this.getNodeParameter('updateFields', i);
                      const body = {
                          organization_id: credentials.organizationId,
                      };
                      const task = {
                          workspace_id: parseInt(workspaceId, 10),
                          id: parseInt(taskId, 10),
                      };
                      if (updateFields.name) {
                          task.name = updateFields.name;
                      }
                      if (updateFields.ownerId) {
                          task.owner_id = parseInt(updateFields.ownerId, 10);
                      }
                      if (updateFields.listId) {
                          task.list_id = parseInt(updateFields.listId, 10);
                      }
                      if (updateFields.startsOn) {
                          task.starts_on = updateFields.startsOn;
                      }
                      if (updateFields.dueOn) {
                          task.due_on = updateFields.dueOn;
                      }
                      if (updateFields.mirrorParentSubscribers) {
                          task.mirror_parent_subscribers = updateFields.mirrorParentSubscribers;
                      }
                      if (updateFields.mirrorParentTags) {
                          task.mirror_parent_tags = updateFields.mirrorParentTags;
                      }
                      if (updateFields.noteContent) {
                          task.note_content = updateFields.noteContent;
                      }
                      if (updateFields.noteMimeType) {
                          task.note_mime_type = updateFields.noteMimeType;
                      }
                      if (updateFields.parentId) {
                          task.parent_id = parseInt(updateFields.parentId, 10);
                      }
                      if (updateFields.positionList) {
                          task.position_list = updateFields.positionList;
                      }
                      if (updateFields.positionUpcoming) {
                          task.position_upcoming = updateFields.positionUpcoming;
                      }
                      if (updateFields.position) {
                          task.position = updateFields.position;
                      }
                      if (updateFields.sectionId) {
                          task.section_id = updateFields.sectionId;
                      }
                      if (updateFields.tags) {
                          task.tags = updateFields.tags.split(',');
                      }
                      if (updateFields.completed) {
                          task.completed = updateFields.completed;
                      }
                      body.task = task;
                      try {
                          responseData = await GenericFunctions_1.flowApiRequest.call(this, 'PUT', `/tasks/${taskId}`, body);
                          responseData = responseData.task;
                      }
                      catch (error) {
                          throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
                      }
                  }
                  if (operation === 'get') {
                      const taskId = this.getNodeParameter('taskId', i);
                      const filters = this.getNodeParameter('filters', i);
                      qs.organization_id = credentials.organizationId;
                      if (filters.include) {
                          qs.include = filters.include.join(',');
                      }
                      try {
                          responseData = await GenericFunctions_1.flowApiRequest.call(this, 'GET', `/tasks/${taskId}`, {}, 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);
                      qs.organization_id = credentials.organizationId;
                      if (filters.include) {
                          qs.include = filters.include.join(',');
                      }
                      if (filters.order) {
                          qs.order = filters.order;
                      }
                      if (filters.workspaceId) {
                          qs.workspace_id = filters.workspaceId;
                      }
                      if (filters.createdBefore) {
                          qs.created_before = filters.createdBefore;
                      }
                      if (filters.createdAfter) {
                          qs.created_after = filters.createdAfter;
                      }
                      if (filters.updateBefore) {
                          qs.updated_before = filters.updateBefore;
                      }
                      if (filters.updateAfter) {
                          qs.updated_after = filters.updateAfter;
                      }
                      if (filters.deleted) {
                          qs.deleted = filters.deleted;
                      }
                      if (filters.cleared) {
                          qs.cleared = filters.cleared;
                      }
                      try {
                          if (returnAll) {
                              responseData = await GenericFunctions_1.FlowApiRequestAllItems.call(this, 'tasks', 'GET', '/tasks', {}, qs);
                          }
                          else {
                              qs.limit = this.getNodeParameter('limit', i);
                              responseData = await GenericFunctions_1.flowApiRequest.call(this, 'GET', '/tasks', {}, qs);
                              responseData = responseData.tasks;
                          }
                      }
                      catch (error) {
                          throw new n8n_workflow_1.NodeApiError(this.getNode(), error, { itemIndex: i });
                      }
                  }
              }
              const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
              returnData.push(...executionData);
          }
          return [returnData];
      }
  }
  exports.Flow = Flow;
  //# sourceMappingURL=Flow.node.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Data flow within nodes
  description: How nodes process data items.
  contentType: explanation
  ---

  # Data flow within nodes

  --8<-- "_snippets/flow-logic/data-flow-nodes.md"

example_workflow:
  {"nodes":[{"parameters":{},"type":"n8n-nodes-base.node","typeVersion":1,"position":[220,120],"id":"53281f72-714a-4248-875e-1d86068f7bf7","name":"Node"}],"connections":{"Node":{"main":[[]]}},"pinData":{},"meta":{"templateCredsSetupCompleted":true,"instanceId":"72699b1d7b6fa82960d13955b04ec95b7bfbb70cd1cbde31b00885cb87158dca"}}


node_type: n8n-nodes-base.FunctionItem
name: FunctionItem
display_name: Function Item
description: Run custom function code which gets executed once per item
category: Other
code_hash: e5ce3a8474ce7c5363fafd8d914cdcb00613f5c8d7b7e78ba676a1298080ed20
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-08 08:05:21
updated_at: 2025-06-08 08:05:21
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.FunctionItem = void 0;
  const vm2_1 = require("@n8n/vm2");
  const n8n_workflow_1 = require("n8n-workflow");
  const JavaScriptSandbox_1 = require("../Code/JavaScriptSandbox");
  class FunctionItem {
      constructor() {
          this.description = {
              displayName: 'Function Item',
              name: 'functionItem',
              hidden: true,
              icon: 'fa:code',
              group: ['transform'],
              version: 1,
              description: 'Run custom function code which gets executed once per item',
              defaults: {
                  name: 'Function Item',
                  color: '#ddbb33',
              },
              inputs: ['main'],
              outputs: ['main'],
              properties: [
                  {
                      displayName: 'A newer version of this node type is available, called the ‘Code’ node',
                      name: 'notice',
                      type: 'notice',
                      default: '',
                  },
                  {
                      displayName: 'JavaScript Code',
                      name: 'functionCode',
                      typeOptions: {
                          alwaysOpenEditWindow: true,
                          codeAutocomplete: 'functionItem',
                          editor: 'code',
                          rows: 10,
                      },
                      type: 'string',
                      default: `// Code here will run once per input item.
  // More info and help: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.functionitem/
  // Tip: You can use luxon for dates and $jmespath for querying JSON structures

  // Add a new field called 'myNewField' to the JSON of the item
  item.myNewField = 1;

  // You can write logs to the browser console
  console.log('Done!');

  return item;`,
                      description: 'The JavaScript code to execute for each item',
                      noDataExpression: true,
                  },
              ],
          };
      }
      async execute() {
          const items = this.getInputData();
          const returnData = [];
          const length = items.length;
          let item;
          const cleanupData = (inputData) => {
              Object.keys(inputData).map((key) => {
                  if (inputData[key] !== null && typeof inputData[key] === 'object') {
                      if (inputData[key].constructor.name === 'Object') {
                          inputData[key] = cleanupData(inputData[key]);
                      }
                      else {
                          inputData[key] = (0, n8n_workflow_1.deepCopy)(inputData[key]);
                      }
                  }
              });
              return inputData;
          };
          for (let itemIndex = 0; itemIndex < length; itemIndex++) {
              const mode = this.getMode();
              try {
                  item = items[itemIndex];
                  item.index = itemIndex;
                  item = (0, n8n_workflow_1.deepCopy)(item);
                  const sandbox = {
                      getBinaryData: () => {
                          if (mode === 'manual') {
                              this.sendMessageToUI('getBinaryData(...) is deprecated and will be removed in a future version. Please consider switching to getBinaryDataAsync(...) instead.');
                          }
                          return item.binary;
                      },
                      setBinaryData: async (data) => {
                          if (mode === 'manual') {
                              this.sendMessageToUI('setBinaryData(...) is deprecated and will be removed in a future version. Please consider switching to setBinaryDataAsync(...) instead.');
                          }
                          item.binary = data;
                      },
                      getNodeParameter: this.getNodeParameter,
                      getWorkflowStaticData: this.getWorkflowStaticData,
                      helpers: this.helpers,
                      item: item.json,
                      getBinaryDataAsync: async () => {
                          var _a;
                          if ((item === null || item === void 0 ? void 0 : item.binary) && (item === null || item === void 0 ? void 0 : item.index) !== undefined && (item === null || item === void 0 ? void 0 : item.index) !== null) {
                              for (const binaryPropertyName of Object.keys(item.binary)) {
                                  item.binary[binaryPropertyName].data = (_a = (await this.helpers.getBinaryDataBuffer(item.index, binaryPropertyName))) === null || _a === void 0 ? void 0 : _a.toString('base64');
                              }
                          }
                          return item.binary;
                      },
                      setBinaryDataAsync: async (data) => {
                          if (!data) {
                              throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No data was provided to setBinaryDataAsync (data: IBinaryKeyData).');
                          }
                          for (const binaryPropertyName of Object.keys(data)) {
                              const binaryItem = data[binaryPropertyName];
                              data[binaryPropertyName] = await this.helpers.setBinaryDataBuffer(binaryItem, Buffer.from(binaryItem.data, 'base64'));
                          }
                          item.binary = data;
                      },
                  };
                  const dataProxy = this.getWorkflowDataProxy(itemIndex);
                  Object.assign(sandbox, dataProxy);
                  const options = {
                      console: mode === 'manual' ? 'redirect' : 'inherit',
                      sandbox,
                      require: JavaScriptSandbox_1.vmResolver,
                  };
                  const vm = new vm2_1.NodeVM(options);
                  if (mode === 'manual') {
                      vm.on('console.log', this.sendMessageToUI);
                  }
                  const functionCode = this.getNodeParameter('functionCode', itemIndex);
                  let jsonData;
                  try {
                      jsonData = await vm.run(`module.exports = async function() {${functionCode}\n}()`, __dirname);
                  }
                  catch (error) {
                      if (this.continueOnFail()) {
                          returnData.push({ json: { error: error.message } });
                          continue;
                      }
                      else {
                          const stackLines = error.stack.split('\n');
                          if (stackLines.length > 0) {
                              stackLines.shift();
                              const lineParts = stackLines
                                  .find((line) => line.includes('FunctionItem'))
                                  .split(':');
                              if (lineParts.length > 2) {
                                  const lineNumber = lineParts.splice(-2, 1);
                                  if (!isNaN(lineNumber)) {
                                      error.message = `${error.message} [Line ${lineNumber} | Item Index: ${itemIndex}]`;
                                      throw error;
                                  }
                              }
                          }
                          error.message = `${error.message} [Item Index: ${itemIndex}]`;
                          throw error;
                      }
                  }
                  if (jsonData === undefined) {
                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No data got returned. Always an object has to be returned!');
                  }
                  const returnItem = {
                      json: cleanupData(jsonData),
                      pairedItem: {
                          item: itemIndex,
                      },
                  };
                  if (item.binary) {
                      returnItem.binary = item.binary;
                  }
                  returnData.push(returnItem);
              }
              catch (error) {
                  if (this.continueOnFail()) {
                      returnData.push({
                          json: {
                              error: error.message,
                          },
                          pairedItem: {
                              item: itemIndex,
                          },
                      });
                      continue;
                  }
                  throw error;
              }
          }
          return [returnData];
      }
  }
  exports.FunctionItem = FunctionItem;
  //# sourceMappingURL=FunctionItem.node.js.map

example_workflow:
  {"nodes":[{"parameters":{},"type":"n8n-nodes-base.node","typeVersion":1,"position":[220,120],"id":"61b19968-a08f-40d4-9f7f-c53ab72021fc","name":"Node"}],"connections":{"Node":{"main":[[]]}},"pinData":{},"meta":{"templateCredsSetupCompleted":true,"instanceId":"3e1e864dc9f171cb4fd2b74d3fd8dcc8373e7683f0c6749be5b42f0f0f2b57d9"}}


node_type: n8n-nodes-base.Freshdesk
name: Freshdesk
display_name: Freshdesk
description: Consume Freshdesk API
category: Other
code_hash: 5c97877007443b2a5ca13fab7df7ab3f76815b48ced24af2f187af803817d81c
documentation_url: https://docs.n8n.io/integrations/builtin/credentials/freshdesk
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-08 08:05:21
updated_at: 2025-06-08 08:05:21
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Freshdesk = void 0;
  const n8n_workflow_1 = require("n8n-workflow");
  const GenericFunctions_1 = require("./GenericFunctions");
  const ContactDescription_1 = require("./ContactDescription");
  var Status;
  (function (Status) {
      Status[Status["Open"] = 2] = "Open";
      Status[Status["Pending"] = 3] = "Pending";
      Status[Status["Resolved"] = 4] = "Resolved";
      Status[Status["Closed"] = 5] = "Closed";
  })(Status || (Status = {}));
  var Priority;
  (function (Priority) {
      Priority[Priority["Low"] = 1] = "Low";
      Priority[Priority["Medium"] = 2] = "Medium";
      Priority[Priority["High"] = 3] = "High";
      Priority[Priority["Urgent"] = 4] = "Urgent";
  })(Priority || (Priority = {}));
  var Source;
  (function (Source) {
      Source[Source["Email"] = 1] = "Email";
      Source[Source["Portal"] = 2] = "Portal";
      Source[Source["Phone"] = 3] = "Phone";
      Source[Source["Chat"] = 7] = "Chat";
      Source[Source["Mobihelp"] = 8] = "Mobihelp";
      Source[Source["FeedbackWidget"] = 9] = "FeedbackWidget";
      Source[Source["OutboundEmail"] = 10] = "OutboundEmail";
  })(Source || (Source = {}));
  class Freshdesk {
      constructor() {
          this.description = {
              displayName: 'Freshdesk',
              name: 'freshdesk',
              icon: 'file:freshdesk.png',
              group: ['output'],
              version: 1,
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Consume Freshdesk API',
              defaults: {
                  name: 'Freshdesk',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'freshdeskApi',
                      required: true,
                  },
              ],
              properties: [
                  {
                      displayName: 'Resource',
                      name: 'resource',
                      type: 'options',
                      noDataExpression: true,
                      required: true,
                      options: [
                          {
                              name: 'Contact',
                              value: 'contact',
                          },
                          {
                              name: 'Ticket',
                              value: 'ticket',
                          },
                      ],
                      default: 'ticket',
                  },
                  {
                      displayName: 'Operation',
                      name: 'operation',
                      type: 'options',
                      noDataExpression: true,
                      required: true,
                      displayOptions: {
                          show: {
                              resource: ['ticket'],
                          },
                      },
                      options: [
                          {
                              name: 'Create',
                              value: 'create',
                              description: 'Create a new ticket',
                              action: 'Create a ticket',
                          },
                          {
                              name: 'Delete',
                              value: 'delete',
                              description: 'Delete a ticket',
                              action: 'Delete a ticket',
                          },
                          {
                              name: 'Get',
                              value: 'get',
                              description: 'Get a ticket',
                              action: 'Get a ticket',
                          },
                          {
                              name: 'Get Many',
                              value: 'getAll',
                              description: 'Get many tickets',
                              action: 'Get many tickets',
                          },
                          {
                              name: 'Update',
                              value: 'update',
                              description: 'Update a ticket',
                              action: 'Update a ticket',
                          },
                      ],
                      default: 'create',
                  },
                  {
                      displayName: 'Requester Identification',
                      name: 'requester',
                      type: 'options',
                      required: true,
                      displayOptions: {
                          show: {
                              resource: ['ticket'],
                              operation: ['create'],
                          },
                      },
                      options: [
                          {
                              name: 'Email',
                              value: 'email',
                              description: 'Email address of the requester. If no contact exists with this email address in Freshdesk, it will be added as a new contact.',
                          },
                          {
                              name: 'Facebook ID',
                              value: 'facebookId',
                              description: 'Facebook ID of the requester. If no contact exists with this facebook_id, then a new contact will be created.',
                          },
                          {
                              name: 'Phone',
                              value: 'phone',
                              description: 'Phone number of the requester. If no contact exists with this phone number in Freshdesk, it will be added as a new contact. If the phone number is set and the email address is not, then the name attribute is mandatory.',
                          },
                          {
                              name: 'Requester ID',
                              value: 'requesterId',
                              description: "User ID of the requester. For existing contacts, the requester_id can be passed instead of the requester's email.",
                          },
                          {
                              name: 'Twitter ID',
                              value: 'twitterId',
                              description: 'Twitter handle of the requester. If no contact exists with this handle in Freshdesk, it will be added as a new contact.',
                          },
                          {
                              name: 'Unique External ID',
                              value: 'uniqueExternalId',
                              description: 'External ID of the requester. If no contact exists with this external ID in Freshdesk, they will be added as a new contact.',
                          },
                      ],
                      default: 'requesterId',
                  },
                  {
                      displayName: 'Value',
                      name: 'requesterIdentificationValue',
                      type: 'string',
                      required: true,
                      displayOptions: {
                          show: {
                              resource: ['ticket'],
                              operation: ['create'],
                          },
                      },
                      default: '',
                      description: 'Value of the identification selected',
                  },
                  {
                      displayName: 'Status',
                      name: 'status',
                      type: 'options',
                      required: true,
                      displayOptions: {
                          show: {
                              resource: ['ticket'],
                              operation: ['create'],
                          },
                      },
                      options: [
                          {
                              name: 'Closed',
                              value: 'closed',
                          },
                          {
                              name: 'Open',
                              value: 'open',
                          },
                          {
                              name: 'Pending',
                              value: 'pending',
                          },
                          {
                              name: 'Resolved',
                              value: 'resolved',
                          },
                      ],
                      default: 'pending',
                  },
                  {
                      displayName: 'Priority',
                      name: 'priority',
                      type: 'options',
                      required: true,
                      displayOptions: {
                          show: {
                              resource: ['ticket'],
                              operation: ['create'],
                          },
                      },
                      options: [
                          {
                              name: 'Low',
                              value: 'low',
                          },
                          {
                              name: 'Medium',
                              value: 'medium',
                          },
                          {
                              name: 'High',
                              value: 'high',
                          },
                          {
                              name: 'Urgent',
                              value: 'urgent',
                          },
                      ],
                      default: 'low',
                  },
                  {
                      displayName: 'Source',
                      name: 'source',
                      type: 'options',
                      required: true,
                      displayOptions: {
                          show: {
                              resource: ['ticket'],
                              operation: ['create'],
                          },
                      },
                      options: [
                          {
                              name: 'Chat',
                              value: 'chat',
                          },
                          {
                              name: 'Email',
                              value: 'email',
                          },
                          {
                              name: 'Feedback Widget',
                              value: 'feedbackWidget',
                          },
                          {
                              name: 'Mobihelp',
                              value: 'mobileHelp',
                          },
                          {
                              name: 'Outbound Email',
                              value: 'OutboundEmail',
                          },
                          {
                              name: 'Phone',
                              value: 'phone',
                          },
                          {
                              name: 'Portal',
                              value: 'portal',
                          },
                      ],
                      default: 'portal',
                      description: 'The channel through which the ticket was created',
                  },
                  {
                      displayName: 'Options',
                      name: 'options',
                      type: 'collection',
                      placeholder: 'Add Option',
                      default: {},
                      displayOptions: {
                          show: {
                              resource: ['ticket'],
                              operation: ['create'],
                          },
                      },
                      options: [
                          {
                              displayName: 'Agent Name or ID',
                              name: 'agent',
                              type: 'options',
                              default: '',
                              typeOptions: {
                                  loadOptionsMethod: 'getAgents',
                              },
                              description: 'ID of the agent to whom the ticket has been assigned. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                          },
                          {
                              displayName: 'CC Emails',
                              name: 'ccEmails',
                              type: 'string',
                              default: '',
                              description: "Separated by a comma (,) email addresses added in the 'cc' field of the incoming ticket email",
                          },
                          {
                              displayName: 'Company Name or ID',
                              name: 'company',
                              type: 'options',
                              default: '',
                              typeOptions: {
                                  loadOptionsMethod: 'getCompanies',
                              },
                              description: 'Company ID of the requester. This attribute can only be set if the Multiple Companies feature is enabled (Estate plan and above). Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                          },
                          {
                              displayName: 'Description',
                              name: 'description',
                              type: 'string',
                              default: '',
                              typeOptions: {
                                  rows: 5,
                              },
                              description: 'HTML content of the ticket',
                          },
                          {
                              displayName: 'Due By',
                              name: 'dueBy',
                              type: 'dateTime',
                              default: '',
                              description: 'Timestamp that denotes when the ticket is due to be resolved',
                          },
                          {
                              displayName: 'Email Config ID',
                              name: 'emailConfigId',
                              type: 'number',
                              default: '',
                              description: "ID of email config which is used for this ticket. (i.e., support@yourcompany.com/sales@yourcompany.com) If product_id is given and email_config_id is not given, product's primary email_config_id will be set.",
                          },
                          {
                              displayName: 'FR Due By',
                              name: 'frDueBy',
                              type: 'dateTime',
                              default: '',
                              description: 'Timestamp that denotes when the first response is due',
                          },
                          {
                              displayName: 'Group Name or ID',
                              name: 'group',
                              type: 'options',
                              default: '',
                              typeOptions: {
                                  loadOptionsMethod: 'getGroups',
                              },
                              description: 'ID of the group to which the ticket has been assigned. The default value is the ID of the group that is associated with the given email_config_id. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                          },
                          {
                              displayName: 'Name',
                              name: 'name',
                              type: 'string',
                              default: '',
                              placeholder: '',
                              description: 'Name of the requester',
                          },
                          {
                              displayName: 'Product Name or ID',
                              name: 'product',
                              type: 'options',
                              default: '',
                              typeOptions: {
                                  loadOptionsMethod: 'getProducts',
                              },
                              description: 'ID of the product to which the ticket is associated. It will be ignored if the email_config_id attribute is set in the request. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                          },
                          {
                              displayName: 'Subject',
                              name: 'subject',
                              type: 'string',
                              default: '',
                              placeholder: '',
                              description: 'Subject of the ticket',
                          },
                          {
                              displayName: 'Tags',
                              name: 'tags',
                              type: 'string',
                              default: '',
                              description: 'Separated by a comma (,) tags that have been associated with the ticket',
                          },
                          {
                              displayName: 'Type',
                              name: 'type',
                              type: 'options',
                              default: 'Question',
                              description: 'Helps categorize the ticket according to the different kinds of issues your support team deals with',
                              options: [
                                  {
                                      name: 'Feature Request',
                                      value: 'Feature Request',
                                  },
                                  {
                                      name: 'Incident',
                                      value: 'Incident',
                                  },
                                  {
                                      name: 'Problem',
                                      value: 'Problem',
                                  },
                                  {
                                      name: 'Question',
                                      value: 'Question',
                                  },
                                  {
                                      name: 'Refund',
                                      value: 'Refund',
                                  },
                              ],
                          },
                      ],
                  },
                  {
                      displayName: 'Ticket ID',
                      name: 'ticketId',
                      type: 'string',
                      required: true,
                      displayOptions: {
                          show: {
                              resource: ['ticket'],
                              operation: ['update'],
                          },
                      },
                      default: '',
                  },
                  {
                      displayName: 'Update Fields',
                      name: 'updateFields',
                      type: 'collection',
                      placeholder: 'Add Field',
                      default: {},
                      displayOptions: {
                          show: {
                              resource: ['ticket'],
                              operation: ['update'],
                          },
                      },
                      options: [
                          {
                              displayName: 'Agent Name or ID',
                              name: 'agent',
                              type: 'options',
                              default: '',
                              typeOptions: {
                                  loadOptionsMethod: 'getAgents',
                              },
                              description: 'ID of the agent to whom the ticket has been assigned. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                          },
                          {
                              displayName: 'CC Emails',
                              name: 'ccEmails',
                              type: 'string',
                              default: '',
                              description: "Separated by a comma (,) email addresses added in the 'cc' field of the incoming ticket email",
                          },
                          {
                              displayName: 'Company Name or ID',
                              name: 'company',
                              type: 'options',
                              default: '',
                              typeOptions: {
                                  loadOptionsMethod: 'getCompanies',
                              },
                              description: 'Company ID of the requester. This attribute can only be set if the Multiple Companies feature is enabled (Estate plan and above). Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                          },
                          {
                              displayName: 'Due By',
                              name: 'dueBy',
                              type: 'dateTime',
                              default: '',
                              description: 'Timestamp that denotes when the ticket is due to be resolved',
                          },
                          {
                              displayName: 'Email Config ID',
                              name: 'emailConfigId',
                              type: 'number',
                              default: '',
                              description: "ID of email config which is used for this ticket. (i.e., support@yourcompany.com/sales@yourcompany.com) If product_id is given and email_config_id is not given, product's primary email_config_id will be set.",
                          },
                          {
                              displayName: 'FR Due By',
                              name: 'frDueBy',
                              type: 'dateTime',
                              default: '',
                              description: 'Timestamp that denotes when the first response is due',
                          },
                          {
                              displayName: 'Group Name or ID',
                              name: 'group',
                              type: 'options',
                              default: '',
                              typeOptions: {
                                  loadOptionsMethod: 'getGroups',
                              },
                              description: 'ID of the group to which the ticket has been assigned. The default value is the ID of the group that is associated with the given email_config_id. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                          },
                          {
                              displayName: 'Name',
                              name: 'name',
                              type: 'string',
                              default: '',
                              placeholder: '',
                              description: 'Name of the requester',
                          },
                          {
                              displayName: 'Product Name or ID',
                              name: 'product',
                              type: 'options',
                              default: '',
                              typeOptions: {
                                  loadOptionsMethod: 'getProducts',
                              },
                              description: 'ID of the product to which the ticket is associated. It will be ignored if the email_config_id attribute is set in the request. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
                          },
                          {
                              displayName: 'Priority',
                              name: 'priority',
                              type: 'options',
                              options: [
                                  {
                                      name: 'Low',
                                      value: 'low',
                                  },
                                  {
                                      name: 'Medium',
                                      value: 'medium',
                                  },
                                  {
                                      name: 'High',
                                      value: 'high',
                                  },
                                  {
                                      name: 'Urgent',
                                      value: 'urgent',
                                  },
                              ],
                              default: 'low',
                          },
                          {
                              displayName: 'Requester Identification',
                              name: 'requester',
                              type: 'options',
                              options: [
                                  {
                                      name: 'Email',
                                      value: 'email',
                                      description: 'Email address of the requester. If no contact exists with this email address in Freshdesk, it will be added as a new contact.',
                                  },
                                  {
                                      name: 'Facebook ID',
                                      value: 'facebookId',
                                      description: 'Facebook ID of the requester. If no contact exists with this facebook_id, then a new contact will be created.',
                                  },
                                  {
                                      name: 'Phone',
                                      value: 'phone',
                                      description: 'Phone number of the requester. If no contact exists with this phone number in Freshdesk, it will be added as a new contact. If the phone number is set and the email address is not, then the name attribute is mandatory.',
                                  },
                                  {
                                      name: 'Requester ID',
                                      value: 'requesterId',
                                      description: "User ID of the requester. For existing contacts, the requester_id can be passed instead of the requester's email.",
                                  },
                                  {
                                      name: 'Twitter ID',
                                      value: 'twitterId',
                                      description: 'Twitter handle of the requester. If no contact exists with this handle in Freshdesk, it will be added as a new contact.',
                                  },
                                  {
                                      name: 'Unique External ID',
                                      value: 'uniqueExternalId',
                                      description: 'External ID of the requester. If no contact exists with this external ID in Freshdesk, they will be added as a new contact.',
                                  },
                              ],
                              default: 'requesterId',
                          },
                          {
                              displayName: 'Requester Value',
                              name: 'requesterIdentificationValue',
                              type: 'string',
                              default: '',
                              description: 'Value of the identification selected',
                          },
                          {
                              displayName: 'Status',
                              name: 'status',
                              type: 'options',
                              options: [
                                  {
                                      name: 'Open',
                                      value: 'open',
                                  },
                                  {
                                      name: 'Pending',
                                      value: 'pending',
                                  },
                                  {
                                      name: 'Resolved',
                                      value: 'resolved',
                                  },
                                  {
                                      name: 'Closed',
                                      value: 'closed',
                                  },
                              ],
                              default: 'pending',
                          },
                          {
                              displayName: 'Source',
                              name: 'source',
                              type: 'options',
                              options: [
                                  {
                                      name: 'Chat',
                                      value: 'chat',
                                  },
                                  {
                                      name: 'Email',
                                      value: 'email',
                                  },
                                  {
                                      name: 'Feedback Widget',
                                      value: 'feedbackWidget',
                                  },
                                  {
                                      name: 'Mobihelp',
                                      value: 'mobileHelp',
                                  },
                                  {
                                      name: 'Outbound Email',
                                      value: 'OutboundEmail',
                                  },
                                  {
                                      name: 'Phone',
                                      value: 'phone',
                                  },
                                  {
                                      name: 'Portal',
                                      value: 'portal',
                                  },
                              ],
                              default: 'portal',
                              description: 'The channel through which the ticket was created',
                          },
                          {
                              displayName: 'Tags',
                              name: 'tags',
                              type: 'string',
                              default: '',
                              description: 'Separated by a comma (,) tags that have been associated with the ticket',
                          },
                          {
                              displayName: 'Type',
                              name: 'type',
                              type: 'options',
                              default: 'Question',
                              description: 'Helps categorize the ticket according to the different kinds of issues your support team deals with',
                              options: [
                                  {
                                      name: 'Feature Request',
                                      value: 'Feature Request',
                                  },
                                  {
                                      name: 'Incident',
                                      value: 'Incident',
                                  },
                                  {
                                      name: 'Problem',
                                      value: 'Problem',
                                  },
                                  {
                                      name: 'Question',
                                      value: 'Question',
                                  },
                                  {
                                      name: 'Refund',
                                      value: 'Refund',
                                  },
                              ],
                          },
                      ],
                  },
                  {
                      displayName: 'Ticket ID',
                      name: 'ticketId',
                      type: 'string',
                      required: true,
                      displayOptions: {
                          show: {
                              resource: ['ticket'],
                              operation: ['get'],
                          },
                      },
                      default: '',
                  },
                  {
                      displayName: 'Return All',
                      name: 'returnAll',
                      type: 'boolean',
                      displayOptions: {
                          show: {
                              resource: ['ticket'],
                              operation: ['getAll'],
                          },
                      },
                      default: false,
                      description: 'Whether to return all results or only up to a given limit',
                  },
                  {
                      displayName: 'Limit',
                      name: 'limit',
                      type: 'number',
                      displayOptions: {
                          show: {
                              resource: ['ticket'],
                              operation: ['getAll'],
                              returnAll: [false],
                          },
                      },
                      typeOptions: {
                          minValue: 1,
                          maxValue: 10,
                      },
                      default: 5,
                      description: 'Max number of results to return',
                  },
                  {
                      displayName: 'Options',
                      name: 'options',
                      type: 'collection',
                      placeholder: 'Add Option',
                      default: {},
                      displayOptions: {
                          show: {
                              resource: ['ticket'],
                              operation: ['getAll'],
                          },
                      },
                      options: [
                          {
                              displayName: 'Company ID',
                              name: 'companyId',
                              type: 'string',
                              default: '',
                          },
                          {
                              displayName: 'Include',
                              name: 'include',
                              type: 'multiOptions',
                              options: [
                                  {
                                      name: 'Company',
                                      value: 'company',
                                  },
                                  {
                                      name: 'Description',
                                      value: 'description',
                                  },
                                  {
                                      name: 'Requester',
                                      value: 'requester',
                                  },
                                  {
                                      name: 'Stats',
                                      value: 'stats',
                                  },
                              ],
                              default: [],
                          },
                          {
                              displayName: 'Order',
                              name: 'order',
                              type: 'options',
                              options: [
                                  {
                                      name: 'ASC',
                                      value: 'asc',
                                  },
                                  {
                                      name: 'DESC',
                                      value: 'desc',
                                  },
                              ],
                              default: 'desc',
                              description: 'Order sort attribute ascending or descending',
                          },
                          {
                              displayName: 'Order By',
                              name: 'orderBy',
                              type: 'options',
                              options: [
                                  {
                                      name: 'Created At',
                                      value: 'createdAt',
                                  },
                                  {
                                      name: 'Due By',
                                      value: 'dueBy',
                                  },
                                  {
                                      name: 'Updated At',
                                      value: 'updatedAt',
                                  },
                              ],
                              default: '',
                              description: 'Sort collection by object attribute',
                          },
                          {
                              displayName: 'Requester Email',
                              name: 'requesterEmail',
                              type: 'string',
                              default: '',
                          },
                          {
                              displayName: 'Requester ID',
                              name: 'requesterId',
                              type: 'string',
                              default: '',
                          },
                          {
                              displayName: 'Updated Since',
                              name: 'updatedSince',
                              type: 'dateTime',
                              default: '',
                          },
                      ],
                  },
                  {
                      displayName: 'Ticket ID',
                      name: 'ticketId',
                      type: 'string',
                      required: true,
                      displayOptions: {
                          show: {
                              resource: ['ticket'],
                              operation: ['delete'],
                          },
                      },
                      default: '',
                  },
                  ...ContactDescription_1.contactOperations,
                  ...ContactDescription_1.contactFields,
              ],
          };
          this.methods = {
              loadOptions: {
                  async getAgents() {
                      const returnData = [];
                      const agents = await GenericFunctions_1.freshdeskApiRequest.call(this, 'GET', '/agents');
                      for (const agent of agents) {
                          const agentName = agent.contact.name;
                          const agentId = agent.id;
                          returnData.push({
                              name: agentName,
                              value: agentId,
                          });
                      }
                      return returnData;
                  },
                  async getGroups() {
                      const returnData = [];
                      const groups = await GenericFunctions_1.freshdeskApiRequest.call(this, 'GET', '/groups');
                      for (const group of groups) {
                          const groupName = group.name;
                          const groupId = group.id;
                          returnData.push({
                              name: groupName,
                              value: groupId,
                          });
                      }
                      return returnData;
                  },
                  async getProducts() {
                      const returnData = [];
                      const products = await GenericFunctions_1.freshdeskApiRequest.call(this, 'GET', '/products');
                      for (const product of products) {
                          const productName = product.name;
                          const productId = product.id;
                          returnData.push({
                              name: productName,
                              value: productId,
                          });
                      }
                      return returnData;
                  },
                  async getCompanies() {
                      const returnData = [];
                      const companies = await GenericFunctions_1.freshdeskApiRequest.call(this, 'GET', '/companies');
                      for (const company of companies) {
                          const companyName = company.name;
                          const companyId = company.id;
                          returnData.push({
                              name: companyName,
                              value: companyId,
                          });
                      }
                      return returnData;
                  },
              },
          };
      }
      async execute() {
          const items = this.getInputData();
          const returnData = [];
          let responseData;
          const qs = {};
          const resource = this.getNodeParameter('resource', 0);
          const operation = this.getNodeParameter('operation', 0);
          for (let i = 0; i < items.length; i++) {
              try {
                  if (resource === 'ticket') {
                      if (operation === 'create') {
                          const requester = this.getNodeParameter('requester', i);
                          const value = this.getNodeParameter('requesterIdentificationValue', i);
                          const status = this.getNodeParameter('status', i);
                          const priority = this.getNodeParameter('priority', i);
                          const source = this.getNodeParameter('source', i);
                          const options = this.getNodeParameter('options', i);
                          const body = {
                              status: Status[(0, GenericFunctions_1.capitalize)(status)],
                              priority: Priority[(0, GenericFunctions_1.capitalize)(priority)],
                              source: Source[(0, GenericFunctions_1.capitalize)(source)],
                          };
                          if (requester === 'requesterId') {
                              if (isNaN(value)) {
                                  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Requester Id must be a number', {
                                      itemIndex: i,
                                  });
                              }
                              body.requester_id = parseInt(value, 10);
                          }
                          else if (requester === 'email') {
                              body.email = value;
                          }
                          else if (requester === 'facebookId') {
                              body.facebook_id = value;
                          }
                          else if (requester === 'phone') {
                              body.phone = value;
                          }
                          else if (requester === 'twitterId') {
                              body.twitter_id = value;
                          }
                          else if (requester === 'uniqueExternalId') {
                              body.unique_external_id = value;
                          }
                          if (options.name) {
                              body.name = options.name;
                          }
                          if (options.subject) {
                              body.subject = options.subject;
                          }
                          else {
                              body.subject = 'null';
                          }
                          if (options.type) {
                              body.type = options.type;
                          }
                          if (options.description) {
                              body.description = options.description;
                          }
                          else {
                              body.description = 'null';
                          }
                          if (options.agent) {
                              body.responder_id = options.agent;
                          }
                          if (options.company) {
                              body.company_id = options.company;
                          }
                          if (options.product) {
                              body.product_id = options.product;
                          }
                          if (options.group) {
                              body.group_id = options.group;
                          }
                          if (options.frDueBy) {
                              body.fr_due_by = options.frDueBy;
                          }
                          if (options.emailConfigId) {
                              body.email_config_id = options.emailConfigId;
                          }
                          if (options.dueBy) {
                              body.due_by = options.dueBy;
                          }
                          if (options.tags) {
                              body.tags = options.tags.split(',');
                          }
                          if (options.ccEmails) {
                              body.cc_emails = options.ccEmails.split(',');
                          }
                          responseData = await GenericFunctions_1.freshdeskApiRequest.call(this, 'POST', '/tickets', body);
                      }
                      if (operation === 'update') {
                          const ticketId = this.getNodeParameter('ticketId', i);
                          const updateFields = this.getNodeParameter('updateFields', i);
                          const body = {};
                          if (updateFields.requester) {
                              const value = updateFields.requesterIdentificationValue;
                              if (updateFields.requester === 'requesterId') {
                                  if (isNaN(parseInt(value, 10))) {
                                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Requester Id must be a number', {
                                          itemIndex: i,
                                      });
                                  }
                                  body.requester_id = parseInt(value, 10);
                              }
                              else if (updateFields.requester === 'email') {
                                  body.email = value;
                              }
                              else if (updateFields.requester === 'facebookId') {
                                  body.facebook_id = value;
                              }
                              else if (updateFields.requester === 'phone') {
                                  body.phone = value;
                              }
                              else if (updateFields.requester === 'twitterId') {
                                  body.twitter_id = value;
                              }
                              else if (updateFields.requester === 'uniqueExternalId') {
                                  body.unique_external_id = value;
                              }
                          }
                          if (updateFields.status) {
                              body.status = Status[(0, GenericFunctions_1.capitalize)(updateFields.status)];
                          }
                          if (updateFields.priority) {
                              body.priority = Priority[(0, GenericFunctions_1.capitalize)(updateFields.priority)];
                          }
                          if (updateFields.source) {
                              body.source = Source[(0, GenericFunctions_1.capitalize)(updateFields.source)];
                          }
                          if (updateFields.name) {
                              body.name = updateFields.name;
                          }
                          if (updateFields.type) {
                              body.type = updateFields.type;
                          }
                          if (updateFields.agent) {
                              body.responder_id = updateFields.agent;
                          }
                          if (updateFields.company) {
                              body.company_id = updateFields.company;
                          }
                          if (updateFields.product) {
                              body.product_id = updateFields.product;
                          }
                          if (updateFields.group) {
                              body.group_id = updateFields.group;
                          }
                          if (updateFields.frDueBy) {
                              body.fr_due_by = updateFields.frDueBy;
                          }
                          if (updateFields.emailConfigId) {
                              body.email_config_id = updateFields.emailConfigId;
                          }
                          if (updateFields.dueBy) {
                              body.due_by = updateFields.dueBy;
                          }
                          if (updateFields.tags) {
                              body.tags = updateFields.tags.split(',');
                          }
                          if (updateFields.ccEmails) {
                              body.cc_emails = updateFields.ccEmails.split(',');
                          }
                          responseData = await GenericFunctions_1.freshdeskApiRequest.call(this, 'PUT', `/tickets/${ticketId}`, body);
                      }
                      if (operation === 'get') {
                          const ticketId = this.getNodeParameter('ticketId', i);
                          responseData = await GenericFunctions_1.freshdeskApiRequest.call(this, 'GET', `/tickets/${ticketId}`);
                      }
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', i);
                          const options = this.getNodeParameter('options', i);
                          if (options.requesterId) {
                              qs.requester_id = options.requesterId;
                          }
                          if (options.requesterEmail) {
                              qs.email = options.requesterEmail;
                          }
                          if (options.companyId) {
                              qs.company_id = options.companyId;
                          }
                          if (options.updatedSince) {
                              qs.updated_since = options.updatedSince;
                          }
                          if (options.orderBy) {
                              qs.order_by = options.orderBy;
                          }
                          if (options.order) {
                              qs.order_type = options.order;
                          }
                          if (options.include) {
                              if (options.include.length !== 0) {
                                  qs.include = options.include.join(',');
                              }
                          }
                          if (returnAll) {
                              responseData = await GenericFunctions_1.freshdeskApiRequestAllItems.call(this, 'GET', '/tickets', {}, qs);
                          }
                          else {
                              qs.per_page = this.getNodeParameter('limit', i);
                              responseData = await GenericFunctions_1.freshdeskApiRequest.call(this, 'GET', '/tickets', {}, qs);
                          }
                      }
                      if (operation === 'delete') {
                          const ticketId = this.getNodeParameter('ticketId', i);
                          responseData = await GenericFunctions_1.freshdeskApiRequest.call(this, 'DELETE', `/tickets/${ticketId}`);
                      }
                  }
                  else if (resource === 'contact') {
                      if (operation === 'create') {
                          const name = this.getNodeParameter('name', i);
                          const email = this.getNodeParameter('email', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i, {});
                          if (additionalFields.customFields) {
                              const metadata = additionalFields.customFields
                                  .customField;
                              additionalFields.custom_fields = {};
                              for (const data of metadata) {
                                  additionalFields.custom_fields[data.name] = data.value;
                              }
                              delete additionalFields.customFields;
                          }
                          const body = additionalFields;
                          body.name = name;
                          if (email) {
                              body.email = email;
                          }
                          responseData = await GenericFunctions_1.freshdeskApiRequest.call(this, 'POST', '/contacts', body);
                      }
                      else if (operation === 'delete') {
                          const contactId = this.getNodeParameter('contactId', i);
                          responseData = await GenericFunctions_1.freshdeskApiRequest.call(this, 'DELETE', `/contacts/${contactId}`, {});
                      }
                      else if (operation === 'get') {
                          const contactId = this.getNodeParameter('contactId', i);
                          responseData = await GenericFunctions_1.freshdeskApiRequest.call(this, 'GET', `/contacts/${contactId}`, {});
                      }
                      else if (operation === 'getAll') {
                          const filters = this.getNodeParameter('filters', i, {});
                          responseData = await GenericFunctions_1.freshdeskApiRequest.call(this, 'GET', '/contacts', {}, filters);
                      }
                      else if (operation === 'update') {
                          const contactId = this.getNodeParameter('contactId', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i, {});
                          if (additionalFields.customFields) {
                              const metadata = additionalFields.customFields
                                  .customField;
                              additionalFields.custom_fields = {};
                              for (const data of metadata) {
                                  additionalFields.custom_fields[data.name] = data.value;
                              }
                              delete additionalFields.customFields;
                          }
                          const body = additionalFields;
                          responseData = await GenericFunctions_1.freshdeskApiRequest.call(this, 'PUT', `/contacts/${contactId}`, body);
                      }
                  }
                  if (!Array.isArray(responseData) && responseData === undefined) {
                      responseData = {
                          success: true,
                      };
                  }
                  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.Freshdesk = Freshdesk;
  //# sourceMappingURL=Freshdesk.node.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Freshdesk credentials
  description: Documentation for Freshdesk credentials. Use these credentials to authenticate Freshdesk in n8n, a workflow automation platform.
  contentType: [integration, reference]
  ---

  # Freshdesk credentials

  You can use these credentials to authenticate the following nodes:

  - [Freshdesk](/integrations/builtin/app-nodes/n8n-nodes-base.freshdesk.md)

  ## Prerequisites

  Create a [Freshdesk](https://freshdesk.com/){:target=_blank .external-link} account.

  ## Supported authentication methods

  - API key

  ## Related resources

  Refer to [Freshdesk's API documentation](https://developers.freshdesk.com/api/){:target=_blank .external-link} for more information about the service.

  ## Using API key

  To configure this credential, you'll need:

  - An **API Key**: Refer to the [Freshdesk API authenticaton documentation](https://developers.freshdesk.com/api/#authentication){:target=_blank .external-link} for detailed instructions on getting your API key.
  - A Freshdesk **Domain**: Use the subdomain of your Freshdesk account. This is part of the URL, for example `https://<subdomain>.freshdesk.com`. So if you access Freshdesk through `https://n8n.freshdesk.com`, enter `n8n` as your **Domain**.

example_workflow:
  {"nodes":[{"parameters":{},"type":"n8n-nodes-base.node","typeVersion":1,"position":[220,120],"id":"adc21b89-6685-4960-aece-aa7a0410867d","name":"Node"}],"connections":{"Node":{"main":[[]]}},"pinData":{},"meta":{"templateCredsSetupCompleted":true,"instanceId":"ce40eec683d8b324f5e4105daf3b3692f0cb51a023a08af681e830f53332b734"}}


node_type: n8n-nodes-base.Freshservice
name: Freshservice
display_name: Freshservice
description: Consume the Freshservice API
category: Other
code_hash: 1bed84ee0d2e0bae1d67c9bfa28f817c5051798f27c18b1b33574e1f94a576c0
documentation_url: https://docs.n8n.io/integrations/builtin/credentials/freshservice
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-08 08:05:21
updated_at: 2025-06-08 08:05:21
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Freshservice = void 0;
  const GenericFunctions_1 = require("./GenericFunctions");
  const descriptions_1 = require("./descriptions");
  const moment_timezone_1 = require("moment-timezone");
  class Freshservice {
      constructor() {
          this.description = {
              displayName: 'Freshservice',
              name: 'freshservice',
              icon: 'file:freshservice.svg',
              group: ['transform'],
              version: 1,
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Consume the Freshservice API',
              defaults: {
                  name: 'Freshservice',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'freshserviceApi',
                      required: true,
                  },
              ],
              properties: [
                  {
                      displayName: 'Resource',
                      name: 'resource',
                      type: 'options',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Agent',
                              value: 'agent',
                          },
                          {
                              name: 'Agent Group',
                              value: 'agentGroup',
                          },
                          {
                              name: 'Agent Role',
                              value: 'agentRole',
                          },
                          {
                              name: 'Announcement',
                              value: 'announcement',
                          },
                          {
                              name: 'Asset Type',
                              value: 'assetType',
                          },
                          {
                              name: 'Change',
                              value: 'change',
                          },
                          {
                              name: 'Department',
                              value: 'department',
                          },
                          {
                              name: 'Location',
                              value: 'location',
                          },
                          {
                              name: 'Problem',
                              value: 'problem',
                          },
                          {
                              name: 'Product',
                              value: 'product',
                          },
                          {
                              name: 'Release',
                              value: 'release',
                          },
                          {
                              name: 'Requester',
                              value: 'requester',
                          },
                          {
                              name: 'Requester Group',
                              value: 'requesterGroup',
                          },
                          {
                              name: 'Software',
                              value: 'software',
                          },
                          {
                              name: 'Ticket',
                              value: 'ticket',
                          },
                      ],
                      default: 'agent',
                  },
                  ...descriptions_1.agentOperations,
                  ...descriptions_1.agentFields,
                  ...descriptions_1.agentGroupOperations,
                  ...descriptions_1.agentGroupFields,
                  ...descriptions_1.agentRoleOperations,
                  ...descriptions_1.agentRoleFields,
                  ...descriptions_1.announcementOperations,
                  ...descriptions_1.announcementFields,
                  ...descriptions_1.assetTypeOperations,
                  ...descriptions_1.assetTypeFields,
                  ...descriptions_1.changeOperations,
                  ...descriptions_1.changeFields,
                  ...descriptions_1.departmentOperations,
                  ...descriptions_1.departmentFields,
                  ...descriptions_1.locationOperations,
                  ...descriptions_1.locationFields,
                  ...descriptions_1.problemOperations,
                  ...descriptions_1.problemFields,
                  ...descriptions_1.productOperations,
                  ...descriptions_1.productFields,
                  ...descriptions_1.releaseOperations,
                  ...descriptions_1.releaseFields,
                  ...descriptions_1.requesterOperations,
                  ...descriptions_1.requesterFields,
                  ...descriptions_1.requesterGroupOperations,
                  ...descriptions_1.requesterGroupFields,
                  ...descriptions_1.softwareOperations,
                  ...descriptions_1.softwareFields,
                  ...descriptions_1.ticketOperations,
                  ...descriptions_1.ticketFields,
              ],
          };
          this.methods = {
              loadOptions: {
                  async getAgents() {
                      const { agents } = (await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', '/agents'));
                      return (0, GenericFunctions_1.toUserOptions)(agents.filter((agent) => agent.active));
                  },
                  async getAgentGroups() {
                      const { groups } = (await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', '/groups'));
                      return (0, GenericFunctions_1.toOptions)(groups);
                  },
                  async getAgentRoles() {
                      const { roles } = (await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', '/roles'));
                      return (0, GenericFunctions_1.toOptions)(roles);
                  },
                  async getAssetTypes() {
                      const { asset_types } = (await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', '/asset_types'));
                      return (0, GenericFunctions_1.toOptions)(asset_types);
                  },
                  async getAssetTypeFields() {
                      const assetType = this.getCurrentNodeParameter('assetTypeId');
                      const { asset_type_fields } = (await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', `/asset_types/${assetType}/fields`));
                      let fields = [];
                      fields = fields
                          .concat(...asset_type_fields.map((data) => data.fields))
                          .map((data) => ({ name: data.label, id: data.name }));
                      return (0, GenericFunctions_1.toOptions)(fields);
                  },
                  async getDepartments() {
                      const { departments } = (await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', '/departments'));
                      return (0, GenericFunctions_1.toOptions)(departments);
                  },
                  async getLocations() {
                      const { locations } = (await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', '/locations'));
                      return (0, GenericFunctions_1.toOptions)(locations);
                  },
                  async getRequesters() {
                      const { requesters } = (await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', '/requesters'));
                      return (0, GenericFunctions_1.toUserOptions)(requesters);
                  },
              },
          };
      }
      async execute() {
          var _a;
          const items = this.getInputData();
          const returnData = [];
          const resource = this.getNodeParameter('resource', 0);
          const operation = this.getNodeParameter('operation', 0);
          const defaultTimezone = this.getTimezone();
          let responseData;
          for (let i = 0; i < items.length; i++) {
              try {
                  if (resource === 'agent') {
                      if (operation === 'create') {
                          const body = {
                              email: this.getNodeParameter('email', i),
                              first_name: this.getNodeParameter('firstName', i),
                          };
                          const roles = this.getNodeParameter('roles', i);
                          GenericFunctions_1.validateAssignmentScopeGroup.call(this, roles);
                          GenericFunctions_1.sanitizeAssignmentScopeGroup.call(this, roles);
                          Object.assign(body, (0, GenericFunctions_1.adjustAgentRoles)(roles));
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              Object.assign(body, additionalFields);
                          }
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'POST', '/agents', body);
                      }
                      else if (operation === 'delete') {
                          const agentId = this.getNodeParameter('agentId', i);
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'DELETE', `/agents/${agentId}`);
                      }
                      else if (operation === 'get') {
                          const agentId = this.getNodeParameter('agentId', i);
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', `/agents/${agentId}`);
                      }
                      else if (operation === 'getAll') {
                          const qs = {};
                          const filters = this.getNodeParameter('filters', i);
                          if (Object.keys(filters).length) {
                              Object.assign(qs, (0, GenericFunctions_1.formatFilters)(filters));
                          }
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/agents', {}, qs);
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          GenericFunctions_1.validateUpdateFields.call(this, updateFields, resource);
                          Object.assign(body, updateFields);
                          const agentId = this.getNodeParameter('agentId', i);
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'PUT', `/agents/${agentId}`, body);
                      }
                  }
                  else if (resource === 'agentGroup') {
                      if (operation === 'create') {
                          const body = {
                              name: this.getNodeParameter('name', i),
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              Object.assign(body, additionalFields);
                          }
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'POST', '/groups', body);
                      }
                      else if (operation === 'delete') {
                          const agentGroupId = this.getNodeParameter('agentGroupId', i);
                          const endpoint = `/groups/${agentGroupId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'DELETE', endpoint);
                      }
                      else if (operation === 'get') {
                          const agentGroupId = this.getNodeParameter('agentGroupId', i);
                          const endpoint = `/groups/${agentGroupId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', endpoint);
                      }
                      else if (operation === 'getAll') {
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/groups');
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          GenericFunctions_1.validateUpdateFields.call(this, updateFields, resource);
                          Object.assign(body, updateFields);
                          const agentGroupId = this.getNodeParameter('agentGroupId', i);
                          const endpoint = `/groups/${agentGroupId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'PUT', endpoint, body);
                      }
                  }
                  else if (resource === 'agentRole') {
                      if (operation === 'get') {
                          const agentRoleId = this.getNodeParameter('agentRoleId', i);
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', `/roles/${agentRoleId}`);
                      }
                      else if (operation === 'getAll') {
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/roles');
                      }
                  }
                  else if (resource === 'announcement') {
                      if (operation === 'create') {
                          const visibleFrom = this.getNodeParameter('visibleFrom', i);
                          const body = {
                              title: this.getNodeParameter('title', i),
                              body_html: this.getNodeParameter('bodyHtml', i),
                              visibility: this.getNodeParameter('visibility', i),
                              visible_from: (0, moment_timezone_1.tz)(visibleFrom, defaultTimezone),
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              const { visible_till, additional_emails, ...rest } = additionalFields;
                              Object.assign(body, {
                                  ...(additional_emails && { additional_emails: (0, GenericFunctions_1.toArray)(additional_emails) }),
                                  ...(visible_till && { visible_till: (0, moment_timezone_1.tz)(visible_till, defaultTimezone) }),
                                  ...rest,
                              });
                          }
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'POST', '/announcements', body);
                      }
                      else if (operation === 'delete') {
                          const announcementId = this.getNodeParameter('announcementId', i);
                          const endpoint = `/announcements/${announcementId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'DELETE', endpoint);
                      }
                      else if (operation === 'get') {
                          const announcementId = this.getNodeParameter('announcementId', i);
                          const endpoint = `/announcements/${announcementId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', endpoint);
                      }
                      else if (operation === 'getAll') {
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/announcements');
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          GenericFunctions_1.validateUpdateFields.call(this, updateFields, resource);
                          const { visible_till, additional_emails, ...rest } = updateFields;
                          Object.assign(body, {
                              ...(additional_emails && { additional_emails: (0, GenericFunctions_1.toArray)(additional_emails) }),
                              ...(visible_till && { visible_till: (0, moment_timezone_1.tz)(visible_till, defaultTimezone) }),
                              ...rest,
                          });
                          const announcementId = this.getNodeParameter('announcementId', i);
                          const endpoint = `/announcements/${announcementId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'PUT', endpoint, body);
                      }
                  }
                  else if (resource === 'asset') {
                      if (operation === 'create') {
                          const body = {
                              asset_type_id: this.getNodeParameter('assetTypeId', i),
                              name: this.getNodeParameter('name', i),
                          };
                          const assetFields = this.getNodeParameter('assetFieldsUi.assetFieldValue', i, []);
                          Object.assign(body, {
                              type_fields: assetFields.reduce((obj, value) => Object.assign(obj, { [`${value.name}`]: value.value }), {}),
                          });
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'POST', '/assets', body);
                      }
                      else if (operation === 'delete') {
                          const assetDisplayId = this.getNodeParameter('assetDisplayId', i);
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'DELETE', `/assets/${assetDisplayId}`);
                      }
                      else if (operation === 'get') {
                          const assetDisplayId = this.getNodeParameter('assetDisplayId', i);
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', `/assets/${assetDisplayId}`);
                      }
                      else if (operation === 'getAll') {
                          const qs = {};
                          const filters = this.getNodeParameter('filters', i);
                          if (Object.keys(filters).length) {
                              Object.assign(qs, (0, GenericFunctions_1.formatFilters)(filters));
                          }
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/assets', {}, qs);
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          GenericFunctions_1.validateUpdateFields.call(this, updateFields, resource);
                          Object.assign(body, updateFields);
                          const assetDisplayId = this.getNodeParameter('assetDisplayId', i);
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'PUT', `/assets/${assetDisplayId}`, body);
                      }
                  }
                  else if (resource === 'assetType') {
                      if (operation === 'create') {
                          const body = {
                              name: this.getNodeParameter('name', i),
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              Object.assign(body, additionalFields);
                          }
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'POST', '/asset_types', body);
                      }
                      else if (operation === 'delete') {
                          const assetTypeId = this.getNodeParameter('assetTypeId', i);
                          const endpoint = `/asset_types/${assetTypeId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'DELETE', endpoint);
                      }
                      else if (operation === 'get') {
                          const assetTypeId = this.getNodeParameter('assetTypeId', i);
                          const endpoint = `/asset_types/${assetTypeId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', endpoint);
                      }
                      else if (operation === 'getAll') {
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/asset_types');
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          GenericFunctions_1.validateUpdateFields.call(this, updateFields, resource);
                          Object.assign(body, updateFields);
                          const assetTypeId = this.getNodeParameter('assetTypeId', i);
                          const endpoint = `/asset_types/${assetTypeId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'PUT', endpoint, body);
                      }
                  }
                  else if (resource === 'change') {
                      if (operation === 'create') {
                          const body = {
                              requester_id: this.getNodeParameter('requesterId', i),
                              subject: this.getNodeParameter('subject', i),
                              planned_start_date: this.getNodeParameter('plannedStartDate', i),
                              planned_end_date: this.getNodeParameter('plannedEndDate', i),
                              status: 1,
                              priority: 1,
                              impact: 1,
                              risk: 1,
                              change_type: 1,
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              Object.assign(body, additionalFields);
                          }
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'POST', '/changes', body);
                      }
                      else if (operation === 'delete') {
                          const changeId = this.getNodeParameter('changeId', i);
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'DELETE', `/changes/${changeId}`);
                      }
                      else if (operation === 'get') {
                          const changeId = this.getNodeParameter('changeId', i);
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', `/changes/${changeId}`);
                      }
                      else if (operation === 'getAll') {
                          const qs = {};
                          const filters = this.getNodeParameter('filters', i);
                          if (Object.keys(filters).length) {
                              Object.assign(qs, (0, GenericFunctions_1.formatFilters)(filters));
                          }
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/changes', {}, qs);
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          GenericFunctions_1.validateUpdateFields.call(this, updateFields, resource);
                          Object.assign(body, updateFields);
                          const changeId = this.getNodeParameter('changeId', i);
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'PUT', `/changes/${changeId}`, body);
                      }
                  }
                  else if (resource === 'department') {
                      if (operation === 'create') {
                          const body = {
                              name: this.getNodeParameter('name', i),
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              const { domains, ...rest } = additionalFields;
                              Object.assign(body, {
                                  ...(domains && { domains: (0, GenericFunctions_1.toArray)(domains) }),
                                  ...rest,
                              });
                          }
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'POST', '/departments', body);
                      }
                      else if (operation === 'delete') {
                          const departmentId = this.getNodeParameter('departmentId', i);
                          const endpoint = `/departments/${departmentId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'DELETE', endpoint);
                      }
                      else if (operation === 'get') {
                          const departmentId = this.getNodeParameter('departmentId', i);
                          const endpoint = `/departments/${departmentId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', endpoint);
                      }
                      else if (operation === 'getAll') {
                          const qs = {};
                          const filters = this.getNodeParameter('filters', i);
                          if (Object.keys(filters).length) {
                              Object.assign(qs, (0, GenericFunctions_1.formatFilters)(filters));
                          }
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/departments', {}, qs);
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          GenericFunctions_1.validateUpdateFields.call(this, updateFields, resource);
                          const { domains, ...rest } = updateFields;
                          Object.assign(body, {
                              ...(domains && { domains: (0, GenericFunctions_1.toArray)(domains) }),
                              ...rest,
                          });
                          const departmentId = this.getNodeParameter('departmentId', i);
                          const endpoint = `/departments/${departmentId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'PUT', endpoint, body);
                      }
                  }
                  else if (resource === 'location') {
                      if (operation === 'create') {
                          const body = {
                              name: this.getNodeParameter('name', i),
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              Object.assign(body, (0, GenericFunctions_1.adjustAddress)(additionalFields));
                          }
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'POST', '/locations', body);
                      }
                      else if (operation === 'delete') {
                          const locationId = this.getNodeParameter('locationId', i);
                          const endpoint = `/locations/${locationId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'DELETE', endpoint);
                      }
                      else if (operation === 'get') {
                          const locationId = this.getNodeParameter('locationId', i);
                          const endpoint = `/locations/${locationId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', endpoint);
                      }
                      else if (operation === 'getAll') {
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/locations');
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          GenericFunctions_1.validateUpdateFields.call(this, updateFields, resource);
                          Object.assign(body, (0, GenericFunctions_1.adjustAddress)(updateFields));
                          const locationId = this.getNodeParameter('locationId', i);
                          const endpoint = `/locations/${locationId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'PUT', endpoint, body);
                      }
                  }
                  else if (resource === 'problem') {
                      if (operation === 'create') {
                          const body = {
                              subject: this.getNodeParameter('subject', i),
                              requester_id: this.getNodeParameter('requesterId', i),
                              due_by: this.getNodeParameter('dueBy', i),
                              status: 1,
                              priority: 1,
                              impact: 1,
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              Object.assign(body, additionalFields);
                          }
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'POST', '/problems', body);
                      }
                      else if (operation === 'delete') {
                          const problemId = this.getNodeParameter('problemId', i);
                          const endpoint = `/problems/${problemId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'DELETE', endpoint);
                      }
                      else if (operation === 'get') {
                          const problemId = this.getNodeParameter('problemId', i);
                          const endpoint = `/problems/${problemId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', endpoint);
                      }
                      else if (operation === 'getAll') {
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/problems');
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          GenericFunctions_1.validateUpdateFields.call(this, updateFields, resource);
                          Object.assign(body, updateFields);
                          const problemId = this.getNodeParameter('problemId', i);
                          const endpoint = `/problems/${problemId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'PUT', endpoint, body);
                      }
                  }
                  else if (resource === 'product') {
                      if (operation === 'create') {
                          const body = {
                              asset_type_id: this.getNodeParameter('assetTypeId', i),
                              name: this.getNodeParameter('name', i),
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              Object.assign(body, additionalFields);
                          }
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'POST', '/products', body);
                      }
                      else if (operation === 'delete') {
                          const productId = this.getNodeParameter('productId', i);
                          const endpoint = `/products/${productId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'DELETE', endpoint);
                      }
                      else if (operation === 'get') {
                          const productId = this.getNodeParameter('productId', i);
                          const endpoint = `/products/${productId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', endpoint);
                      }
                      else if (operation === 'getAll') {
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/products');
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          Object.assign(body, updateFields);
                          const productId = this.getNodeParameter('productId', i);
                          const endpoint = `/products/${productId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'PUT', endpoint, body);
                      }
                  }
                  else if (resource === 'release') {
                      if (operation === 'create') {
                          const body = {
                              subject: this.getNodeParameter('subject', i),
                              release_type: this.getNodeParameter('releaseType', i),
                              status: this.getNodeParameter('status', i),
                              priority: this.getNodeParameter('priority', i),
                              planned_start_date: this.getNodeParameter('plannedStartDate', i),
                              planned_end_date: this.getNodeParameter('plannedEndDate', i),
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              Object.assign(body, additionalFields);
                          }
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'POST', '/releases', body);
                      }
                      else if (operation === 'delete') {
                          const releaseId = this.getNodeParameter('releaseId', i);
                          const endpoint = `/releases/${releaseId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'DELETE', endpoint);
                      }
                      else if (operation === 'get') {
                          const releaseId = this.getNodeParameter('releaseId', i);
                          const endpoint = `/releases/${releaseId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', endpoint);
                      }
                      else if (operation === 'getAll') {
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/releases');
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          Object.assign(body, updateFields);
                          const releaseId = this.getNodeParameter('releaseId', i);
                          const endpoint = `/releases/${releaseId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'PUT', endpoint, body);
                      }
                  }
                  else if (resource === 'requester') {
                      if (operation === 'create') {
                          const body = {
                              first_name: this.getNodeParameter('firstName', i),
                              primary_email: this.getNodeParameter('primaryEmail', i),
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              const { secondary_emails, ...rest } = additionalFields;
                              Object.assign(body, {
                                  ...(secondary_emails && { secondary_emails: (0, GenericFunctions_1.toArray)(secondary_emails) }),
                                  ...rest,
                              });
                          }
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'POST', '/requesters', body);
                      }
                      else if (operation === 'delete') {
                          const requesterId = this.getNodeParameter('requesterId', i);
                          const endpoint = `/requesters/${requesterId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'DELETE', endpoint);
                      }
                      else if (operation === 'get') {
                          const requesterId = this.getNodeParameter('requesterId', i);
                          const endpoint = `/requesters/${requesterId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', endpoint);
                      }
                      else if (operation === 'getAll') {
                          const qs = {};
                          const filters = this.getNodeParameter('filters', i);
                          if (Object.keys(filters).length) {
                              Object.assign(qs, (0, GenericFunctions_1.formatFilters)(filters));
                          }
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/requesters', {}, qs);
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          GenericFunctions_1.validateUpdateFields.call(this, updateFields, resource);
                          const { secondary_emails, ...rest } = updateFields;
                          Object.assign(body, {
                              ...(secondary_emails && { secondary_emails: (0, GenericFunctions_1.toArray)(secondary_emails) }),
                              ...rest,
                          });
                          const requesterId = this.getNodeParameter('requesterId', i);
                          const endpoint = `/requesters/${requesterId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'PUT', endpoint, body);
                      }
                  }
                  else if (resource === 'requesterGroup') {
                      if (operation === 'create') {
                          const body = {
                              name: this.getNodeParameter('name', i),
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              Object.assign(body, additionalFields);
                          }
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'POST', '/requester_groups', body);
                      }
                      else if (operation === 'delete') {
                          const requesterGroupId = this.getNodeParameter('requesterGroupId', i);
                          const endpoint = `/requester_groups/${requesterGroupId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'DELETE', endpoint);
                      }
                      else if (operation === 'get') {
                          const requesterGroupId = this.getNodeParameter('requesterGroupId', i);
                          const endpoint = `/requester_groups/${requesterGroupId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', endpoint);
                      }
                      else if (operation === 'getAll') {
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/requester_groups');
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          GenericFunctions_1.validateUpdateFields.call(this, updateFields, resource);
                          Object.assign(body, updateFields);
                          const requesterGroupId = this.getNodeParameter('requesterGroupId', i);
                          const endpoint = `/requester_groups/${requesterGroupId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'PUT', endpoint, body);
                      }
                  }
                  else if (resource === 'software') {
                      if (operation === 'create') {
                          const body = {
                              application: {
                                  application_type: this.getNodeParameter('applicationType', i),
                                  name: this.getNodeParameter('name', i),
                              },
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              Object.assign(body.application, additionalFields);
                          }
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'POST', '/applications', body);
                      }
                      else if (operation === 'delete') {
                          const softwareId = this.getNodeParameter('softwareId', i);
                          const endpoint = `/applications/${softwareId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'DELETE', endpoint);
                      }
                      else if (operation === 'get') {
                          const softwareId = this.getNodeParameter('softwareId', i);
                          const endpoint = `/applications/${softwareId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', endpoint);
                      }
                      else if (operation === 'getAll') {
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/applications');
                      }
                      else if (operation === 'update') {
                          const body = { application: {} };
                          const updateFields = this.getNodeParameter('updateFields', i);
                          GenericFunctions_1.validateUpdateFields.call(this, updateFields, resource);
                          Object.assign(body.application, updateFields);
                          const softwareId = this.getNodeParameter('softwareId', i);
                          const endpoint = `/applications/${softwareId}`;
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'PUT', endpoint, body);
                      }
                  }
                  else if (resource === 'ticket') {
                      if (operation === 'create') {
                          const body = {
                              email: this.getNodeParameter('email', i),
                              subject: this.getNodeParameter('subject', i),
                              description: this.getNodeParameter('description', i),
                              priority: this.getNodeParameter('priority', i),
                              status: this.getNodeParameter('status', i),
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              const { cc_emails, ...rest } = additionalFields;
                              Object.assign(body, {
                                  ...(cc_emails && { cc_emails: (0, GenericFunctions_1.toArray)(cc_emails) }),
                                  ...rest,
                              });
                          }
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'POST', '/tickets', body);
                      }
                      else if (operation === 'delete') {
                          const ticketId = this.getNodeParameter('ticketId', i);
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'DELETE', `/tickets/${ticketId}`);
                      }
                      else if (operation === 'get') {
                          const ticketId = this.getNodeParameter('ticketId', i);
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'GET', `/tickets/${ticketId}`);
                      }
                      else if (operation === 'getAll') {
                          const qs = {};
                          const filters = this.getNodeParameter('filters', i);
                          let endpoint = '';
                          if (Object.keys(filters).length) {
                              Object.assign(qs, (0, GenericFunctions_1.formatFilters)(filters));
                              endpoint = '/tickets/filter';
                          }
                          else {
                              endpoint = '/tickets';
                          }
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', endpoint, {}, qs);
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          GenericFunctions_1.validateUpdateFields.call(this, updateFields, resource);
                          Object.assign(body, updateFields);
                          const ticketId = this.getNodeParameter('ticketId', i);
                          responseData = await GenericFunctions_1.freshserviceApiRequest.call(this, 'PUT', `/tickets/${ticketId}`, body);
                      }
                  }
                  if (operation === 'delete' && !responseData) {
                      responseData = { success: true };
                  }
                  else if (operation !== 'getAll') {
                      const special = {
                          agentGroup: 'group',
                          agentRole: 'role',
                          assetType: 'asset_type',
                          requesterGroup: 'requester_group',
                          software: 'application',
                      };
                      responseData = (_a = responseData[special[resource]]) !== null && _a !== void 0 ? _a : responseData[resource];
                  }
              }
              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.Freshservice = Freshservice;
  //# sourceMappingURL=Freshservice.node.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Freshservice credentials
  description: Documentation for Freshservice credentials. Use these credentials to authenticate Freshservice in n8n, a workflow automation platform.
  contentType: [integration, reference]
  ---

  # Freshservice credentials

  You can use these credentials to authenticate the following nodes:

  - [Freshservice](/integrations/builtin/app-nodes/n8n-nodes-base.freshservice.md)

  ## Prerequisites

  Create a [Freshservice](https://freshservice.com/){:target=_blank .external-link} account.

  ## Supported authentication methods

  - API key

  ## Related resources

  Refer to [Freshservice's API documentation](https://api.freshservice.com/v2/){:target=_blank .external-link} for more information about the service.

  ## Using API key

  To configure this credential, you'll need:

  - An **API Key**: Refer to the [Freshservice API authenticaton documentation](https://api.freshservice.com/v2/#authentication){:target=_blank .external-link} for detailed instructions on getting your API key.
  - Your Freshservice **Domain**: Use the subdomain of your Freshservice account. This is part of the URL, for example `https://<subdomain>.freshservice.com`. So if you access Freshservice through `https://n8n.freshservice.com`, enter `n8n` as your **Domain**.

example_workflow:
  {"nodes":[{"parameters":{},"type":"n8n-nodes-base.node","typeVersion":1,"position":[220,120],"id":"fefb1593-4a70-407b-ad25-f0df363be0ba","name":"Node"}],"connections":{"Node":{"main":[[]]}},"pinData":{},"meta":{"templateCredsSetupCompleted":true,"instanceId":"2c81a75ba8ba0d8f5fc34ff8f4a1a659a7d85e41e7c590987117dd770c83fa84"}}


node_type: n8n-nodes-base.FreshworksCrm
name: FreshworksCrm
display_name: Freshworks CRM
description: Consume the Freshworks CRM API
category: Other
code_hash: 28020dd98482da8bc65443cb9e65f8e0220e24752f7c39100edb1a6b69a0ea47
documentation_url: https://docs.n8n.io/integrations/builtin/credentials/freshworkscrm
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-08 08:05:21
updated_at: 2025-06-08 08:05:21
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.FreshworksCrm = void 0;
  const GenericFunctions_1 = require("./GenericFunctions");
  const descriptions_1 = require("./descriptions");
  const moment_timezone_1 = require("moment-timezone");
  class FreshworksCrm {
      constructor() {
          this.description = {
              displayName: 'Freshworks CRM',
              name: 'freshworksCrm',
              icon: 'file:freshworksCrm.svg',
              group: ['transform'],
              version: 1,
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Consume the Freshworks CRM API',
              defaults: {
                  name: 'Freshworks CRM',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'freshworksCrmApi',
                      required: true,
                  },
              ],
              properties: [
                  {
                      displayName: 'Resource',
                      name: 'resource',
                      type: 'options',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Account',
                              value: 'account',
                          },
                          {
                              name: 'Appointment',
                              value: 'appointment',
                          },
                          {
                              name: 'Contact',
                              value: 'contact',
                          },
                          {
                              name: 'Deal',
                              value: 'deal',
                          },
                          {
                              name: 'Note',
                              value: 'note',
                          },
                          {
                              name: 'Sales Activity',
                              value: 'salesActivity',
                          },
                          {
                              name: 'Search',
                              value: 'search',
                          },
                          {
                              name: 'Task',
                              value: 'task',
                          },
                      ],
                      default: 'account',
                  },
                  ...descriptions_1.accountOperations,
                  ...descriptions_1.accountFields,
                  ...descriptions_1.appointmentOperations,
                  ...descriptions_1.appointmentFields,
                  ...descriptions_1.contactOperations,
                  ...descriptions_1.contactFields,
                  ...descriptions_1.dealOperations,
                  ...descriptions_1.dealFields,
                  ...descriptions_1.noteOperations,
                  ...descriptions_1.noteFields,
                  ...descriptions_1.salesActivityOperations,
                  ...descriptions_1.salesActivityFields,
                  ...descriptions_1.searchOperations,
                  ...descriptions_1.searchFields,
                  ...descriptions_1.taskOperations,
                  ...descriptions_1.taskFields,
              ],
          };
          this.methods = {
              loadOptions: {
                  async getAccounts() {
                      const viewId = await GenericFunctions_1.getAllItemsViewId.call(this, { fromLoadOptions: true });
                      const responseData = await GenericFunctions_1.handleListing.call(this, 'GET', `/sales_accounts/view/${viewId}`);
                      return responseData.map(({ name, id }) => ({ name, value: id }));
                  },
                  async getAccountViews() {
                      const responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/sales_accounts/filters');
                      return responseData.map(({ name, id }) => ({ name, value: id }));
                  },
                  async getBusinessTypes() {
                      return GenericFunctions_1.loadResource.call(this, 'business_types');
                  },
                  async getCampaigns() {
                      return GenericFunctions_1.loadResource.call(this, 'campaigns');
                  },
                  async getContactStatuses() {
                      return GenericFunctions_1.loadResource.call(this, 'contact_statuses');
                  },
                  async getContactViews() {
                      const responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/contacts/filters');
                      return responseData.map(({ name, id }) => ({ name, value: id }));
                  },
                  async getCurrencies() {
                      const response = (await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'GET', '/selector/currencies'));
                      const key = Object.keys(response)[0];
                      return response[key].map(({ currency_code, id }) => ({ name: currency_code, value: id }));
                  },
                  async getDealPaymentStatuses() {
                      return GenericFunctions_1.loadResource.call(this, 'deal_payment_statuses');
                  },
                  async getDealPipelines() {
                      return GenericFunctions_1.loadResource.call(this, 'deal_pipelines');
                  },
                  async getDealProducts() {
                      return GenericFunctions_1.loadResource.call(this, 'deal_products');
                  },
                  async getDealReasons() {
                      return GenericFunctions_1.loadResource.call(this, 'deal_reasons');
                  },
                  async getDealStages() {
                      return GenericFunctions_1.loadResource.call(this, 'deal_stages');
                  },
                  async getDealTypes() {
                      return GenericFunctions_1.loadResource.call(this, 'deal_types');
                  },
                  async getDealViews() {
                      const responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/deals/filters');
                      return responseData.map(({ name, id }) => ({ name, value: id }));
                  },
                  async getIndustryTypes() {
                      return GenericFunctions_1.loadResource.call(this, 'industry_types');
                  },
                  async getLifecycleStages() {
                      return GenericFunctions_1.loadResource.call(this, 'lifecycle_stages');
                  },
                  async getOutcomes() {
                      return GenericFunctions_1.loadResource.call(this, 'sales_activity_outcomes');
                  },
                  async getSalesActivityTypes() {
                      return GenericFunctions_1.loadResource.call(this, 'sales_activity_types');
                  },
                  async getTerritories() {
                      return GenericFunctions_1.loadResource.call(this, 'territories');
                  },
                  async getUsers() {
                      const response = (await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'GET', '/selector/owners'));
                      const key = Object.keys(response)[0];
                      return response[key].map(({ display_name, id }) => ({ name: display_name, value: id }));
                  },
              },
          };
      }
      async execute() {
          var _a, _b;
          const items = this.getInputData();
          const returnData = [];
          const resource = this.getNodeParameter('resource', 0);
          const operation = this.getNodeParameter('operation', 0);
          const defaultTimezone = this.getTimezone();
          let responseData;
          for (let i = 0; i < items.length; i++) {
              try {
                  if (resource === 'account') {
                      if (operation === 'create') {
                          const body = {
                              name: this.getNodeParameter('name', i),
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              Object.assign(body, additionalFields);
                          }
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'POST', '/sales_accounts', body);
                          responseData = responseData.sales_account;
                      }
                      else if (operation === 'delete') {
                          const accountId = this.getNodeParameter('accountId', i);
                          const endpoint = `/sales_accounts/${accountId}`;
                          await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'DELETE', endpoint);
                          responseData = { success: true };
                      }
                      else if (operation === 'get') {
                          const accountId = this.getNodeParameter('accountId', i);
                          const endpoint = `/sales_accounts/${accountId}`;
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'GET', endpoint);
                          responseData = responseData.sales_account;
                      }
                      else if (operation === 'getAll') {
                          const view = this.getNodeParameter('view', i);
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', `/sales_accounts/view/${view}`);
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          if (Object.keys(updateFields).length) {
                              Object.assign(body, updateFields);
                          }
                          else {
                              GenericFunctions_1.throwOnEmptyUpdate.call(this, resource);
                          }
                          const accountId = this.getNodeParameter('accountId', i);
                          const endpoint = `/sales_accounts/${accountId}`;
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'PUT', endpoint, body);
                          responseData = responseData.sales_account;
                      }
                  }
                  else if (resource === 'appointment') {
                      if (operation === 'create') {
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          const startDate = this.getNodeParameter('fromDate', i);
                          const endDate = this.getNodeParameter('endDate', i);
                          const attendees = this.getNodeParameter('attendees.attendee', i, []);
                          const timezone = (_a = additionalFields.time_zone) !== null && _a !== void 0 ? _a : defaultTimezone;
                          let allDay = false;
                          if (additionalFields.is_allday) {
                              allDay = additionalFields.is_allday;
                          }
                          const start = (0, moment_timezone_1.tz)(startDate, timezone);
                          const end = (0, moment_timezone_1.tz)(endDate, timezone);
                          const body = {
                              title: this.getNodeParameter('title', i),
                              from_date: start.format(),
                              end_date: allDay ? start.format() : end.format(),
                          };
                          Object.assign(body, additionalFields);
                          if (attendees.length) {
                              body.appointment_attendees_attributes = (0, GenericFunctions_1.adjustAttendees)(attendees);
                          }
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'POST', '/appointments', body);
                          responseData = responseData.appointment;
                      }
                      else if (operation === 'delete') {
                          const appointmentId = this.getNodeParameter('appointmentId', i);
                          const endpoint = `/appointments/${appointmentId}`;
                          await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'DELETE', endpoint);
                          responseData = { success: true };
                      }
                      else if (operation === 'get') {
                          const appointmentId = this.getNodeParameter('appointmentId', i);
                          const endpoint = `/appointments/${appointmentId}`;
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'GET', endpoint);
                          responseData = responseData.appointment;
                      }
                      else if (operation === 'getAll') {
                          const { filter, include } = this.getNodeParameter('filters', i);
                          const qs = {};
                          if (filter) {
                              qs.filter = filter;
                          }
                          if (include) {
                              qs.include = include;
                          }
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/appointments', {}, qs);
                      }
                      else if (operation === 'update') {
                          const updateFields = this.getNodeParameter('updateFields', i);
                          const attendees = this.getNodeParameter('updateFields.attendees.attendee', i, []);
                          if (!Object.keys(updateFields).length) {
                              GenericFunctions_1.throwOnEmptyUpdate.call(this, resource);
                          }
                          const body = {};
                          const { from_date, end_date, ...rest } = updateFields;
                          const timezone = (_b = rest.time_zone) !== null && _b !== void 0 ? _b : defaultTimezone;
                          if (from_date) {
                              body.from_date = (0, moment_timezone_1.tz)(from_date, timezone).format();
                          }
                          if (end_date) {
                              body.end_date = (0, moment_timezone_1.tz)(end_date, timezone).format();
                          }
                          Object.assign(body, rest);
                          if (attendees.length) {
                              body.appointment_attendees_attributes = (0, GenericFunctions_1.adjustAttendees)(attendees);
                              delete body.attendees;
                          }
                          const appointmentId = this.getNodeParameter('appointmentId', i);
                          const endpoint = `/appointments/${appointmentId}`;
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'PUT', endpoint, body);
                          responseData = responseData.appointment;
                      }
                  }
                  else if (resource === 'contact') {
                      if (operation === 'create') {
                          const body = {
                              first_name: this.getNodeParameter('firstName', i),
                              last_name: this.getNodeParameter('lastName', i),
                              emails: this.getNodeParameter('emails', i),
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              Object.assign(body, (0, GenericFunctions_1.adjustAccounts)(additionalFields));
                          }
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'POST', '/contacts', body);
                          responseData = responseData.contact;
                      }
                      else if (operation === 'delete') {
                          const contactId = this.getNodeParameter('contactId', i);
                          const endpoint = `/contacts/${contactId}`;
                          await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'DELETE', endpoint);
                          responseData = { success: true };
                      }
                      else if (operation === 'get') {
                          const contactId = this.getNodeParameter('contactId', i);
                          const endpoint = `/contacts/${contactId}`;
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'GET', endpoint);
                          responseData = responseData.contact;
                      }
                      else if (operation === 'getAll') {
                          const view = this.getNodeParameter('view', i);
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', `/contacts/view/${view}`);
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          if (Object.keys(updateFields).length) {
                              Object.assign(body, (0, GenericFunctions_1.adjustAccounts)(updateFields));
                          }
                          else {
                              GenericFunctions_1.throwOnEmptyUpdate.call(this, resource);
                          }
                          const contactId = this.getNodeParameter('contactId', i);
                          const endpoint = `/contacts/${contactId}`;
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'PUT', endpoint, body);
                          responseData = responseData.contact;
                      }
                  }
                  else if (resource === 'deal') {
                      if (operation === 'create') {
                          const body = {
                              name: this.getNodeParameter('name', i),
                              amount: this.getNodeParameter('amount', i),
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              Object.assign(body, (0, GenericFunctions_1.adjustAccounts)(additionalFields));
                          }
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'POST', '/deals', body);
                          responseData = responseData.deal;
                      }
                      else if (operation === 'delete') {
                          const dealId = this.getNodeParameter('dealId', i);
                          await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'DELETE', `/deals/${dealId}`);
                          responseData = { success: true };
                      }
                      else if (operation === 'get') {
                          const dealId = this.getNodeParameter('dealId', i);
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'GET', `/deals/${dealId}`);
                          responseData = responseData.deal;
                      }
                      else if (operation === 'getAll') {
                          const view = this.getNodeParameter('view', i);
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', `/deals/view/${view}`);
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          if (Object.keys(updateFields).length) {
                              Object.assign(body, (0, GenericFunctions_1.adjustAccounts)(updateFields));
                          }
                          else {
                              GenericFunctions_1.throwOnEmptyUpdate.call(this, resource);
                          }
                          const dealId = this.getNodeParameter('dealId', i);
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'PUT', `/deals/${dealId}`, body);
                          responseData = responseData.deal;
                      }
                  }
                  else if (resource === 'note') {
                      if (operation === 'create') {
                          const body = {
                              description: this.getNodeParameter('description', i),
                              targetable_id: this.getNodeParameter('targetable_id', i),
                              targetable_type: this.getNodeParameter('targetableType', i),
                          };
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'POST', '/notes', body);
                          responseData = responseData.note;
                      }
                      else if (operation === 'delete') {
                          const noteId = this.getNodeParameter('noteId', i);
                          await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'DELETE', `/notes/${noteId}`);
                          responseData = { success: true };
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          if (Object.keys(updateFields).length) {
                              Object.assign(body, updateFields);
                          }
                          else {
                              GenericFunctions_1.throwOnEmptyUpdate.call(this, resource);
                          }
                          const noteId = this.getNodeParameter('noteId', i);
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'PUT', `/notes/${noteId}`, body);
                          responseData = responseData.note;
                      }
                  }
                  else if (resource === 'salesActivity') {
                      if (operation === 'create') {
                          const startDate = this.getNodeParameter('from_date', i);
                          const endDate = this.getNodeParameter('end_date', i);
                          const body = {
                              sales_activity_type_id: this.getNodeParameter('sales_activity_type_id', i),
                              title: this.getNodeParameter('title', i),
                              owner_id: this.getNodeParameter('ownerId', i),
                              start_date: (0, moment_timezone_1.tz)(startDate, defaultTimezone).format(),
                              end_date: (0, moment_timezone_1.tz)(endDate, defaultTimezone).format(),
                              targetable_type: this.getNodeParameter('targetableType', i),
                              targetable_id: this.getNodeParameter('targetable_id', i),
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              Object.assign(body, additionalFields);
                          }
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'POST', '/sales_activities', {
                              sales_activity: body,
                          });
                          responseData = responseData.sales_activity;
                      }
                      else if (operation === 'delete') {
                          const salesActivityId = this.getNodeParameter('salesActivityId', i);
                          const endpoint = `/sales_activities/${salesActivityId}`;
                          await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'DELETE', endpoint);
                          responseData = { success: true };
                      }
                      else if (operation === 'get') {
                          const salesActivityId = this.getNodeParameter('salesActivityId', i);
                          const endpoint = `/sales_activities/${salesActivityId}`;
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'GET', endpoint);
                          responseData = responseData.sales_activity;
                      }
                      else if (operation === 'getAll') {
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/sales_activities');
                      }
                      else if (operation === 'update') {
                          const updateFields = this.getNodeParameter('updateFields', i);
                          if (!Object.keys(updateFields).length) {
                              GenericFunctions_1.throwOnEmptyUpdate.call(this, resource);
                          }
                          const body = {};
                          const { from_date, end_date, ...rest } = updateFields;
                          if (from_date) {
                              body.from_date = (0, moment_timezone_1.tz)(from_date, defaultTimezone).format();
                          }
                          if (end_date) {
                              body.end_date = (0, moment_timezone_1.tz)(end_date, defaultTimezone).format();
                          }
                          if (Object.keys(rest).length) {
                              Object.assign(body, rest);
                          }
                          const salesActivityId = this.getNodeParameter('salesActivityId', i);
                          const endpoint = `/sales_activities/${salesActivityId}`;
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'PUT', endpoint, body);
                          responseData = responseData.sales_activity;
                      }
                  }
                  else if (resource === 'search') {
                      if (operation === 'query') {
                          const query = this.getNodeParameter('query', i);
                          let entities = this.getNodeParameter('entities', i);
                          const returnAll = this.getNodeParameter('returnAll', 0, false);
                          if (Array.isArray(entities)) {
                              entities = entities.join(',');
                          }
                          const qs = {
                              q: query,
                              include: entities,
                              per_page: 100,
                          };
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'GET', '/search', {}, qs);
                          if (!returnAll) {
                              const limit = this.getNodeParameter('limit', 0);
                              responseData = responseData.slice(0, limit);
                          }
                      }
                      if (operation === 'lookup') {
                          let searchField = this.getNodeParameter('searchField', i);
                          let fieldValue = this.getNodeParameter('fieldValue', i, '');
                          let entities = this.getNodeParameter('options.entities', i);
                          if (Array.isArray(entities)) {
                              entities = entities.join(',');
                          }
                          if (searchField === 'customField') {
                              searchField = this.getNodeParameter('customFieldName', i);
                              fieldValue = this.getNodeParameter('customFieldValue', i);
                          }
                          const qs = {
                              q: fieldValue,
                              f: searchField,
                              entities,
                          };
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'GET', '/lookup', {}, qs);
                      }
                  }
                  else if (resource === 'task') {
                      if (operation === 'create') {
                          const dueDate = this.getNodeParameter('dueDate', i);
                          const body = {
                              title: this.getNodeParameter('title', i),
                              owner_id: this.getNodeParameter('ownerId', i),
                              due_date: (0, moment_timezone_1.tz)(dueDate, defaultTimezone).format(),
                              targetable_type: this.getNodeParameter('targetableType', i),
                              targetable_id: this.getNodeParameter('targetable_id', i),
                          };
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          if (Object.keys(additionalFields).length) {
                              Object.assign(body, additionalFields);
                          }
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'POST', '/tasks', body);
                          responseData = responseData.task;
                      }
                      else if (operation === 'delete') {
                          const taskId = this.getNodeParameter('taskId', i);
                          await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'DELETE', `/tasks/${taskId}`);
                          responseData = { success: true };
                      }
                      else if (operation === 'get') {
                          const taskId = this.getNodeParameter('taskId', i);
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'GET', `/tasks/${taskId}`);
                          responseData = responseData.task;
                      }
                      else if (operation === 'getAll') {
                          const { filter, include } = this.getNodeParameter('filters', i);
                          const qs = {
                              filter: 'open',
                          };
                          if (filter) {
                              qs.filter = filter;
                          }
                          if (include) {
                              qs.include = include;
                          }
                          responseData = await GenericFunctions_1.handleListing.call(this, 'GET', '/tasks', {}, qs);
                      }
                      else if (operation === 'update') {
                          const body = {};
                          const updateFields = this.getNodeParameter('updateFields', i);
                          if (!Object.keys(updateFields).length) {
                              GenericFunctions_1.throwOnEmptyUpdate.call(this, resource);
                          }
                          const { dueDate, ...rest } = updateFields;
                          if (dueDate) {
                              body.due_date = (0, moment_timezone_1.tz)(dueDate, defaultTimezone).format();
                          }
                          if (Object.keys(rest).length) {
                              Object.assign(body, rest);
                          }
                          const taskId = this.getNodeParameter('taskId', i);
                          responseData = await GenericFunctions_1.freshworksCrmApiRequest.call(this, 'PUT', `/tasks/${taskId}`, body);
                          responseData = responseData.task;
                      }
                  }
              }
              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.FreshworksCrm = FreshworksCrm;
  //# sourceMappingURL=FreshworksCrm.node.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Freshworks CRM credentials
  description: Documentation for Freshworks CRM credentials. Use these credentials to authenticate Freshworks CRM in n8n, a workflow automation platform.
  contentType: [integration, reference]
  ---

  # Freshworks CRM credentials

  You can use these credentials to authenticate the following nodes:

  - [Freshworks CRM](/integrations/builtin/app-nodes/n8n-nodes-base.freshworkscrm.md)

  ## Prerequisites

  Create a [Freshworks CRM](https://www.freshworks.com/freshsales-crm/){:target=_blank .external-link} account.

  ## Supported authentication methods

  - API key

  ## Related resources

  Refer to [Freshworks CRM's API documentation](https://developers.freshworks.com/crm/api/){:target=_blank .external-link} for more information about the service.

  ## Using API key

  To configure this credential, you'll need:

  - An **API Key**: Refer to the [Freshworks CRM API authenticaton documentation](https://developers.freshworks.com/crm/api/#authentication){:target=_blank .external-link} for detailed instructions on getting your API key.
  - Your Freshworks CRM **Domain**: Use the subdomain of your Freshworks CRM account. This is part of the URL, for example `https://<subdomain>.myfreshworks.com`. So if you access Freshworks CRM through `https://n8n.myfreshworks.com`, enter `n8n` as your **Domain**.

example_workflow:
  {"nodes":[{"parameters":{},"type":"n8n-nodes-base.node","typeVersion":1,"position":[220,120],"id":"f1c8d282-b7e6-4081-89f1-3abaf351a73a","name":"Node"}],"connections":{"Node":{"main":[[]]}},"pinData":{},"meta":{"templateCredsSetupCompleted":true,"instanceId":"0fb9bd192f04f28f47c9c60ea88d46e97d5a107a6a37465ed8b04b2977eab7d6"}}


node_type: n8n-nodes-base.Ftp
name: Ftp
display_name: FTP
description: Transfers files via FTP or SFTP
category: Other
code_hash: 48e8e0ee75c7e8ba39f526f5a690b1bcc679c5852a93609ddd264fd68ced6e92
documentation_url: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.ftp
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-08 08:05:21
updated_at: 2025-06-08 08:05:21
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.Ftp = void 0;
  const n8n_workflow_1 = require("n8n-workflow");
  const utilities_1 = require("../../utils/utilities");
  const fs_1 = require("fs");
  const path_1 = require("path");
  const stream_1 = require("stream");
  const util_1 = require("util");
  const tmp_promise_1 = require("tmp-promise");
  const promise_ftp_1 = __importDefault(require("promise-ftp"));
  const ssh2_sftp_client_1 = __importDefault(require("ssh2-sftp-client"));
  const streamPipeline = (0, util_1.promisify)(stream_1.pipeline);
  async function callRecursiveList(path, client, normalizeFunction) {
      const pathArray = [path];
      let currentPath = path;
      const directoryItems = [];
      let index = 0;
      const prepareAndNormalize = (item) => {
          if (pathArray[index].endsWith('/')) {
              currentPath = `${pathArray[index]}${item.name}`;
          }
          else {
              currentPath = `${pathArray[index]}/${item.name}`;
          }
          if (item.type === 'd') {
              if (item.name === '.' || item.name === '..') {
                  return;
              }
              pathArray.push(currentPath);
          }
          normalizeFunction(item, currentPath, true);
          directoryItems.push(item);
      };
      do {
          const returnData = await client.list(pathArray[index]);
          returnData.map(prepareAndNormalize);
          index++;
      } while (index <= pathArray.length - 1);
      return directoryItems;
  }
  async function recursivelyCreateSftpDirs(sftp, path) {
      const dirPath = (0, path_1.dirname)(path);
      const dirExists = await sftp.exists(dirPath);
      if (!dirExists) {
          await sftp.mkdir(dirPath, true);
      }
  }
  function normalizeSFtpItem(input, path, recursive = false) {
      const item = input;
      item.accessTime = new Date(input.accessTime);
      item.modifyTime = new Date(input.modifyTime);
      item.path = !recursive ? `${path}${path.endsWith('/') ? '' : '/'}${item.name}` : path;
  }
  function normalizeFtpItem(input, path, recursive = false) {
      const item = input;
      item.modifyTime = input.date;
      item.path = !recursive ? `${path}${path.endsWith('/') ? '' : '/'}${item.name}` : path;
      item.date = undefined;
  }
  class Ftp {
      constructor() {
          this.description = {
              displayName: 'FTP',
              name: 'ftp',
              icon: 'fa:server',
              group: ['input'],
              version: 1,
              subtitle: '={{$parameter["protocol"] + ": " + $parameter["operation"]}}',
              description: 'Transfers files via FTP or SFTP',
              defaults: {
                  name: 'FTP',
                  color: '#303050',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'ftp',
                      required: true,
                      displayOptions: {
                          show: {
                              protocol: ['ftp'],
                          },
                      },
                      testedBy: 'ftpConnectionTest',
                  },
                  {
                      name: 'sftp',
                      required: true,
                      displayOptions: {
                          show: {
                              protocol: ['sftp'],
                          },
                      },
                      testedBy: 'sftpConnectionTest',
                  },
              ],
              properties: [
                  {
                      displayName: 'Protocol',
                      name: 'protocol',
                      type: 'options',
                      options: [
                          {
                              name: 'FTP',
                              value: 'ftp',
                          },
                          {
                              name: 'SFTP',
                              value: 'sftp',
                          },
                      ],
                      default: 'ftp',
                      description: 'File transfer protocol',
                  },
                  {
                      displayName: 'Operation',
                      name: 'operation',
                      type: 'options',
                      options: [
                          {
                              name: 'Delete',
                              value: 'delete',
                              description: 'Delete a file/folder',
                              action: 'Delete a file or folder',
                          },
                          {
                              name: 'Download',
                              value: 'download',
                              description: 'Download a file',
                              action: 'Download a file',
                          },
                          {
                              name: 'List',
                              value: 'list',
                              description: 'List folder content',
                              action: 'List folder content',
                          },
                          {
                              name: 'Rename',
                              value: 'rename',
                              description: 'Rename/move oldPath to newPath',
                              action: 'Rename / move a file or folder',
                          },
                          {
                              name: 'Upload',
                              value: 'upload',
                              description: 'Upload a file',
                              action: 'Upload a file',
                          },
                      ],
                      default: 'download',
                      noDataExpression: true,
                  },
                  {
                      displayName: 'Path',
                      displayOptions: {
                          show: {
                              operation: ['delete'],
                          },
                      },
                      name: 'path',
                      type: 'string',
                      default: '',
                      description: 'The file path of the file to delete. Has to contain the full path.',
                      required: true,
                  },
                  {
                      displayName: 'Options',
                      name: 'options',
                      type: 'collection',
                      placeholder: 'Add Option',
                      displayOptions: {
                          show: {
                              operation: ['delete'],
                          },
                      },
                      default: {},
                      options: [
                          {
                              displayName: 'Folder',
                              name: 'folder',
                              type: 'boolean',
                              default: false,
                              description: 'Whether folders can be deleted',
                          },
                          {
                              displayName: 'Recursive',
                              displayOptions: {
                                  show: {
                                      folder: [true],
                                  },
                              },
                              name: 'recursive',
                              type: 'boolean',
                              default: false,
                              description: 'Whether to remove all files and directories in target directory',
                          },
                      ],
                  },
                  {
                      displayName: 'Path',
                      displayOptions: {
                          show: {
                              operation: ['download'],
                          },
                      },
                      name: 'path',
                      type: 'string',
                      default: '',
                      placeholder: '/documents/invoice.txt',
                      description: 'The file path of the file to download. Has to contain the full path.',
                      required: true,
                  },
                  {
                      displayName: 'Binary Property',
                      displayOptions: {
                          show: {
                              operation: ['download'],
                          },
                      },
                      name: 'binaryPropertyName',
                      type: 'string',
                      default: 'data',
                      description: 'Object property name which holds binary data',
                      required: true,
                  },
                  {
                      displayName: 'Old Path',
                      displayOptions: {
                          show: {
                              operation: ['rename'],
                          },
                      },
                      name: 'oldPath',
                      type: 'string',
                      default: '',
                      required: true,
                  },
                  {
                      displayName: 'New Path',
                      displayOptions: {
                          show: {
                              operation: ['rename'],
                          },
                      },
                      name: 'newPath',
                      type: 'string',
                      default: '',
                      required: true,
                  },
                  {
                      displayName: 'Options',
                      name: 'options',
                      type: 'collection',
                      placeholder: 'Add Field',
                      default: {},
                      displayOptions: {
                          show: {
                              operation: ['rename'],
                          },
                      },
                      options: [
                          {
                              displayName: 'Create Directories',
                              name: 'createDirectories',
                              type: 'boolean',
                              default: false,
                              description: 'Whether to recursively create destination directory when renaming an existing file or folder',
                          },
                      ],
                  },
                  {
                      displayName: 'Path',
                      displayOptions: {
                          show: {
                              operation: ['upload'],
                          },
                      },
                      name: 'path',
                      type: 'string',
                      default: '',
                      description: 'The file path of the file to upload. Has to contain the full path.',
                      required: true,
                  },
                  {
                      displayName: 'Binary Data',
                      displayOptions: {
                          show: {
                              operation: ['upload'],
                          },
                      },
                      name: 'binaryData',
                      type: 'boolean',
                      default: true,
                      description: 'The text content of the file to upload',
                  },
                  {
                      displayName: 'Binary Property',
                      displayOptions: {
                          show: {
                              operation: ['upload'],
                              binaryData: [true],
                          },
                      },
                      name: 'binaryPropertyName',
                      type: 'string',
                      default: 'data',
                      description: 'Object property name which holds binary data',
                      required: true,
                  },
                  {
                      displayName: 'File Content',
                      displayOptions: {
                          show: {
                              operation: ['upload'],
                              binaryData: [false],
                          },
                      },
                      name: 'fileContent',
                      type: 'string',
                      default: '',
                      description: 'The text content of the file to upload',
                  },
                  {
                      displayName: 'Path',
                      displayOptions: {
                          show: {
                              operation: ['list'],
                          },
                      },
                      name: 'path',
                      type: 'string',
                      default: '/',
                      description: 'Path of directory to list contents of',
                      required: true,
                  },
                  {
                      displayName: 'Recursive',
                      displayOptions: {
                          show: {
                              operation: ['list'],
                          },
                      },
                      name: 'recursive',
                      type: 'boolean',
                      default: false,
                      description: 'Whether to return object representing all directories / objects recursively found within SFTP server',
                      required: true,
                  },
              ],
          };
          this.methods = {
              credentialTest: {
                  async ftpConnectionTest(credential) {
                      const credentials = credential.data;
                      try {
                          const ftp = new promise_ftp_1.default();
                          await ftp.connect({
                              host: credentials.host,
                              port: credentials.port,
                              user: credentials.username,
                              password: credentials.password,
                          });
                      }
                      catch (error) {
                          return {
                              status: 'Error',
                              message: error.message,
                          };
                      }
                      return {
                          status: 'OK',
                          message: 'Connection successful!',
                      };
                  },
                  async sftpConnectionTest(credential) {
                      const credentials = credential.data;
                      try {
                          const sftp = new ssh2_sftp_client_1.default();
                          if (credentials.privateKey) {
                              await sftp.connect({
                                  host: credentials.host,
                                  port: credentials.port,
                                  username: credentials.username,
                                  privateKey: (0, utilities_1.formatPrivateKey)(credentials.privateKey),
                                  passphrase: credentials.passphrase,
                              });
                          }
                          else {
                              await sftp.connect({
                                  host: credentials.host,
                                  port: credentials.port,
                                  username: credentials.username,
                                  password: credentials.password,
                              });
                          }
                      }
                      catch (error) {
                          return {
                              status: 'Error',
                              message: error.message,
                          };
                      }
                      return {
                          status: 'OK',
                          message: 'Connection successful!',
                      };
                  },
              },
          };
      }
      async execute() {
          const items = this.getInputData();
          const returnItems = [];
          let responseData;
          const operation = this.getNodeParameter('operation', 0);
          let credentials = undefined;
          const protocol = this.getNodeParameter('protocol', 0);
          if (protocol === 'sftp') {
              credentials = await this.getCredentials('sftp');
          }
          else {
              credentials = await this.getCredentials('ftp');
          }
          try {
              let ftp;
              let sftp;
              if (protocol === 'sftp') {
                  sftp = new ssh2_sftp_client_1.default();
                  if (credentials.privateKey) {
                      await sftp.connect({
                          host: credentials.host,
                          port: credentials.port,
                          username: credentials.username,
                          privateKey: (0, utilities_1.formatPrivateKey)(credentials.privateKey),
                          passphrase: credentials.passphrase,
                      });
                  }
                  else {
                      await sftp.connect({
                          host: credentials.host,
                          port: credentials.port,
                          username: credentials.username,
                          password: credentials.password,
                      });
                  }
              }
              else {
                  ftp = new promise_ftp_1.default();
                  await ftp.connect({
                      host: credentials.host,
                      port: credentials.port,
                      user: credentials.username,
                      password: credentials.password,
                  });
              }
              for (let i = 0; i < items.length; i++) {
                  const newItem = {
                      json: items[i].json,
                      binary: {},
                  };
                  if (items[i].binary !== undefined && newItem.binary) {
                      Object.assign(newItem.binary, items[i].binary);
                  }
                  items[i] = newItem;
                  if (protocol === 'sftp') {
                      if (operation === 'list') {
                          const path = this.getNodeParameter('path', i);
                          const recursive = this.getNodeParameter('recursive', i);
                          if (recursive) {
                              responseData = await callRecursiveList(path, sftp, normalizeSFtpItem);
                              const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                              returnItems.push.apply(returnItems, executionData);
                          }
                          else {
                              responseData = await sftp.list(path);
                              responseData.forEach((item) => normalizeSFtpItem(item, path));
                              const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                              returnItems.push.apply(returnItems, executionData);
                          }
                      }
                      if (operation === 'delete') {
                          const path = this.getNodeParameter('path', i);
                          const options = this.getNodeParameter('options', i);
                          if (options.folder === true) {
                              responseData = await sftp.rmdir(path, !!options.recursive);
                          }
                          else {
                              responseData = await sftp.delete(path);
                          }
                          const executionData = this.helpers.constructExecutionMetaData([{ json: { success: true } }], { itemData: { item: i } });
                          returnItems.push(...executionData);
                      }
                      if (operation === 'rename') {
                          const oldPath = this.getNodeParameter('oldPath', i);
                          const { createDirectories = false } = this.getNodeParameter('options', i);
                          const newPath = this.getNodeParameter('newPath', i);
                          if (createDirectories) {
                              await recursivelyCreateSftpDirs(sftp, newPath);
                          }
                          responseData = await sftp.rename(oldPath, newPath);
                          const executionData = this.helpers.constructExecutionMetaData([{ json: { success: true } }], { itemData: { item: i } });
                          returnItems.push(...executionData);
                      }
                      if (operation === 'download') {
                          const path = this.getNodeParameter('path', i);
                          const binaryFile = await (0, tmp_promise_1.file)({ prefix: 'n8n-sftp-' });
                          try {
                              await sftp.get(path, (0, fs_1.createWriteStream)(binaryFile.path));
                              const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i);
                              const remoteFilePath = this.getNodeParameter('path', i);
                              items[i].binary[dataPropertyNameDownload] = await this.nodeHelpers.copyBinaryFile(binaryFile.path, (0, path_1.basename)(remoteFilePath));
                              const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(items[i]), { itemData: { item: i } });
                              returnItems.push(...executionData);
                          }
                          finally {
                              await binaryFile.cleanup();
                          }
                      }
                      if (operation === 'upload') {
                          const remotePath = this.getNodeParameter('path', i);
                          await recursivelyCreateSftpDirs(sftp, remotePath);
                          if (this.getNodeParameter('binaryData', i)) {
                              const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 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);
                              }
                              await sftp.put(uploadData, remotePath);
                          }
                          else {
                              const buffer = Buffer.from(this.getNodeParameter('fileContent', i), 'utf8');
                              await sftp.put(buffer, remotePath);
                          }
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(items[i]), { itemData: { item: i } });
                          returnItems.push(...executionData);
                      }
                  }
                  if (protocol === 'ftp') {
                      if (operation === 'list') {
                          const path = this.getNodeParameter('path', i);
                          const recursive = this.getNodeParameter('recursive', i);
                          if (recursive) {
                              responseData = await callRecursiveList(path, ftp, normalizeFtpItem);
                              const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                              returnItems.push.apply(returnItems, executionData);
                          }
                          else {
                              responseData = await ftp.list(path);
                              responseData.forEach((item) => normalizeFtpItem(item, path));
                              const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                              returnItems.push.apply(returnItems, executionData);
                          }
                      }
                      if (operation === 'delete') {
                          const path = this.getNodeParameter('path', i);
                          const options = this.getNodeParameter('options', i);
                          if (options.folder === true) {
                              responseData = await ftp.rmdir(path, !!options.recursive);
                          }
                          else {
                              responseData = await ftp.delete(path);
                          }
                          const executionData = this.helpers.constructExecutionMetaData([{ json: { success: true } }], { itemData: { item: i } });
                          returnItems.push(...executionData);
                      }
                      if (operation === 'download') {
                          const path = this.getNodeParameter('path', i);
                          const binaryFile = await (0, tmp_promise_1.file)({ prefix: 'n8n-sftp-' });
                          try {
                              const stream = await ftp.get(path);
                              await streamPipeline(stream, (0, fs_1.createWriteStream)(binaryFile.path));
                              const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i);
                              const remoteFilePath = this.getNodeParameter('path', i);
                              items[i].binary[dataPropertyNameDownload] = await this.nodeHelpers.copyBinaryFile(binaryFile.path, (0, path_1.basename)(remoteFilePath));
                              const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(items[i]), { itemData: { item: i } });
                              returnItems.push(...executionData);
                          }
                          finally {
                              await binaryFile.cleanup();
                          }
                      }
                      if (operation === 'rename') {
                          const oldPath = this.getNodeParameter('oldPath', i);
                          const newPath = this.getNodeParameter('newPath', i);
                          responseData = await ftp.rename(oldPath, newPath);
                          const executionData = this.helpers.constructExecutionMetaData([{ json: { success: true } }], { itemData: { item: i } });
                          returnItems.push(...executionData);
                      }
                      if (operation === 'upload') {
                          const remotePath = this.getNodeParameter('path', i);
                          const fileName = (0, path_1.basename)(remotePath);
                          const dirPath = remotePath.replace(fileName, '');
                          if (this.getNodeParameter('binaryData', i)) {
                              const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 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);
                              }
                              try {
                                  await ftp.put(uploadData, remotePath);
                              }
                              catch (error) {
                                  if (error.code === 553) {
                                      await ftp.mkdir(dirPath, true);
                                      await ftp.put(uploadData, remotePath);
                                  }
                                  else {
                                      throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
                                  }
                              }
                          }
                          else {
                              const buffer = Buffer.from(this.getNodeParameter('fileContent', i), 'utf8');
                              try {
                                  await ftp.put(buffer, remotePath);
                              }
                              catch (error) {
                                  if (error.code === 553) {
                                      await ftp.mkdir(dirPath, true);
                                      await ftp.put(buffer, remotePath);
                                  }
                                  else {
                                      throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
                                  }
                              }
                          }
                          const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(items[i]), { itemData: { item: i } });
                          returnItems.push(...executionData);
                      }
                  }
              }
              if (protocol === 'sftp') {
                  await sftp.end();
              }
              else {
                  await ftp.end();
              }
          }
          catch (error) {
              if (this.continueOnFail()) {
                  return [[{ json: { error: error.message } }]];
              }
              throw error;
          }
          return [returnItems];
      }
  }
  exports.Ftp = Ftp;
  //# sourceMappingURL=Ftp.node.js.map

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

  # FTP

  The FTP node is useful to access and upload files to an FTP or SFTP server.

  /// note | Credentials
  You can find authentication information for this node [here](/integrations/builtin/credentials/ftp.md).
  ///

  To connect to an SFTP server, use an SFTP credential. Refer to [FTP credentials](/integrations/builtin/credentials/ftp.md) for more information.

  ## Operations

  - [**Delete**](#delete) a file or folder
  - [**Download**](#download) a file
  - [**List**](#list) folder content
  - [**Rename**](#rename) or move a file or folder
  - [**Upload**](#upload) a file

  /// note | Uploading files
  To attach a file for upload, you'll need to use an extra node such as the [Read/Write Files from Disk](/integrations/builtin/core-nodes/n8n-nodes-base.readwritefile.md) node or the [HTTP Request](/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/index.md) node to pass the file as a data property.
  ///

  ## Delete

  This operation includes one parameter: **Path**. Enter the remote path that you would like to connect to.

  ### Delete options

  The delete operation adds one new option: **Folder**. If you turn this option on, the node can delete both folders and files. This configuration also displays one more option:

  - **Recursive**: If you turn this option on and you delete a folder or directory, the node will delete all files and directories within the target directory.

  ## Download

  Configure this operation with these parameters:

  * **Path**: Enter the remote path that you would like to connect to.
  * **Put Output File in Field**: Enter the name of the output binary field to put the file in.

  ## List

  Configure this operation with these parameters:

  * **Path**: Enter the remote path that you would like to connect to.
  * **Recursive**: Select whether to return an object representing all directories / objects recursively found within the FTP/SFTP server (turned on) or not (turned off).

  ## Rename

  Configure this operation with these parameters:

  - **Old Path**: Enter the existing path of the file you'd like to rename in this field.
  - **New Path**: Enter the new path for the renamed file in this field.

  ### Rename options

  This operation adds one new option: **Create Directories**. If you turn this option on, the node will recursively create the destination directory when renaming an existing file or folder.

  ## Upload

  Configure this operation with these parameters:

  * **Path**: Enter the remote path that you would like to connect to.
  * **Binary File**: Select whether you'll upload a binary file (turned on) or enter text content to be uploaded (turned off). Other parameters depend on your selection in this field.
      * **Input Binary Field**: Displayed if you turn on **Binary File**. Enter the name of the input binary field that contains the file you'll upload in this field.
      * **File Content**: Displayed if you turn off **Binary File** Enter the text content of the file you'll upload in this field.

  /// note | Uploading files
  To attach a file for upload, you'll need to use an extra node such as the [Read/Write Files from Disk](/integrations/builtin/core-nodes/n8n-nodes-base.readwritefile.md) node or the [HTTP Request](/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/index.md) node to pass the file as a data property.
  ///

  ## Templates and examples

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

example_workflow:
  {"nodes":[{"parameters":{},"type":"n8n-nodes-base.node","typeVersion":1,"position":[220,120],"id":"6c730ac3-206f-49f0-b5f9-44d824d76cf6","name":"Node"}],"connections":{"Node":{"main":[[]]}},"pinData":{},"meta":{"templateCredsSetupCompleted":true,"instanceId":"79fc2e297c45808ce1368f8331c173c2b335a9aff226f5ed8b09dd55b5391a29"}}


node_type: n8n-nodes-base.Function
name: Function
display_name: Function
category: Other
code_hash: d68f1ab94b190161e2ec2c56ec6631f6c3992826557c100ec578efff5de96a70
documentation_url: https://docs.n8n.io/advanced-ai/examples/using-the-fromai-function
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-08 08:05:21
updated_at: 2025-06-08 08:05:21
description:
  Run custom function code which gets executed once and allows you to add, remove, change and replace items

source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Function = void 0;
  const vm2_1 = require("@n8n/vm2");
  const n8n_workflow_1 = require("n8n-workflow");
  const JavaScriptSandbox_1 = require("../Code/JavaScriptSandbox");
  class Function {
      constructor() {
          this.description = {
              displayName: 'Function',
              name: 'function',
              hidden: true,
              icon: 'fa:code',
              group: ['transform'],
              version: 1,
              description: 'Run custom function code which gets executed once and allows you to add, remove, change and replace items',
              defaults: {
                  name: 'Function',
                  color: '#FF9922',
              },
              inputs: ['main'],
              outputs: ['main'],
              properties: [
                  {
                      displayName: 'A newer version of this node type is available, called the ‘Code’ node',
                      name: 'notice',
                      type: 'notice',
                      default: '',
                  },
                  {
                      displayName: 'JavaScript Code',
                      name: 'functionCode',
                      typeOptions: {
                          alwaysOpenEditWindow: true,
                          codeAutocomplete: 'function',
                          editor: 'code',
                          rows: 10,
                      },
                      type: 'string',
                      default: `// Code here will run only once, no matter how many input items there are.
  // More info and help:https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.function/
  // Tip: You can use luxon for dates and $jmespath for querying JSON structures

  // Loop over inputs and add a new field called 'myNewField' to the JSON of each one
  for (item of items) {
    item.json.myNewField = 1;
  }

  // You can write logs to the browser console
  console.log('Done!');

  return items;`,
                      description: 'The JavaScript code to execute',
                      noDataExpression: true,
                  },
              ],
          };
      }
      async execute() {
          let items = this.getInputData();
          items = (0, n8n_workflow_1.deepCopy)(items);
          for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
              items[itemIndex].index = itemIndex;
          }
          const cleanupData = (inputData) => {
              Object.keys(inputData).map((key) => {
                  if (inputData[key] !== null && typeof inputData[key] === 'object') {
                      if (inputData[key].constructor.name === 'Object') {
                          inputData[key] = cleanupData(inputData[key]);
                      }
                      else {
                          inputData[key] = (0, n8n_workflow_1.deepCopy)(inputData[key]);
                      }
                  }
              });
              return inputData;
          };
          const sandbox = {
              getNodeParameter: this.getNodeParameter,
              getWorkflowStaticData: this.getWorkflowStaticData,
              helpers: this.helpers,
              items,
              $item: (index) => this.getWorkflowDataProxy(index),
              getBinaryDataAsync: async (item) => {
                  var _a;
                  if ((item === null || item === void 0 ? void 0 : item.binary) && (item === null || item === void 0 ? void 0 : item.index) !== undefined && (item === null || item === void 0 ? void 0 : item.index) !== null) {
                      for (const binaryPropertyName of Object.keys(item.binary)) {
                          item.binary[binaryPropertyName].data = (_a = (await this.helpers.getBinaryDataBuffer(item.index, binaryPropertyName))) === null || _a === void 0 ? void 0 : _a.toString('base64');
                      }
                  }
                  return item.binary;
              },
              setBinaryDataAsync: async (item, data) => {
                  if (!item) {
                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No item was provided to setBinaryDataAsync (item: INodeExecutionData, data: IBinaryKeyData).');
                  }
                  if (!data) {
                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No data was provided to setBinaryDataAsync (item: INodeExecutionData, data: IBinaryKeyData).');
                  }
                  for (const binaryPropertyName of Object.keys(data)) {
                      const binaryItem = data[binaryPropertyName];
                      data[binaryPropertyName] = await this.helpers.setBinaryDataBuffer(binaryItem, Buffer.from(binaryItem.data, 'base64'));
                  }
                  item.binary = data;
              },
          };
          Object.assign(sandbox, sandbox.$item(0));
          const mode = this.getMode();
          const options = {
              console: mode === 'manual' ? 'redirect' : 'inherit',
              sandbox,
              require: JavaScriptSandbox_1.vmResolver,
          };
          const vm = new vm2_1.NodeVM(options);
          if (mode === 'manual') {
              vm.on('console.log', this.sendMessageToUI);
          }
          const functionCode = this.getNodeParameter('functionCode', 0);
          try {
              items = await vm.run(`module.exports = async function() {${functionCode}\n}()`, __dirname);
              items = this.helpers.normalizeItems(items);
              if (items === undefined) {
                  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No data got returned. Always return an Array of items!');
              }
              if (!Array.isArray(items)) {
                  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Always an Array of items has to be returned!');
              }
              for (const item of items) {
                  if (item.json === undefined) {
                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'All returned items have to contain a property named "json"!');
                  }
                  if (typeof item.json !== 'object') {
                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'The json-property has to be an object!');
                  }
                  item.json = cleanupData(item.json);
                  if (item.binary !== undefined) {
                      if (Array.isArray(item.binary) || typeof item.binary !== 'object') {
                          throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'The binary-property has to be an object!');
                      }
                  }
              }
          }
          catch (error) {
              if (this.continueOnFail()) {
                  items = [{ json: { error: error.message } }];
              }
              else {
                  const stackLines = error.stack.split('\n');
                  if (stackLines.length > 0) {
                      stackLines.shift();
                      const lineParts = stackLines.find((line) => line.includes('Function')).split(':');
                      if (lineParts.length > 2) {
                          const lineNumber = lineParts.splice(-2, 1);
                          if (!isNaN(lineNumber)) {
                              error.message = `${error.message} [Line ${lineNumber}]`;
                          }
                      }
                  }
                  throw error;
              }
          }
          return [items];
      }
  }
  exports.Function = Function;
  //# sourceMappingURL=Function.node.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Let AI specify tool parameters
  description: Understand how n8n's `$fromAI()` function works and how to use it to dynamically populate parameters for AI app tools, or use the built-in automation to complete them instead.
  contentType: explanation
  tags:
    - $fromAI
    - $fromAI()
    - fromAI
    - fromAI()
  hide:
    - tags
  ---

  # Let AI specify the tool parameters

  When configuring [app node](/integrations/builtin/app-nodes/index.md) [tools](/glossary.md#ai-tool) connected to the Tools Agent, many parameters can be filled in by the AI model itself. The AI model will use the context from the task and information from other connected tools to fill in the appropriate details.

  There are two ways to do this, and you can switch between them.

  ## Let the model fill in the parameter

  Each appropriate parameter field in the tool's editing dialog has an extra button at the end:

  ![image showing stars icon to the right of parameter field](/_images/advanced-ai/ai-stars.png)

  On activating this button, the [AI Agent](/glossary.md#ai-agent) will fill in the expression for you, with no need for any further user input.
  The field itself is filled in with a message indicating that the parameter has been defined automatically by the model.

  If you want to define the parameter yourself, click on the 'X' in this box to revert to user-defined values. Note that the 'expression' field will now contain the expression generated by this feature, though you can now edit it further to add extra details as described in the following section.

  /// warning 
  Activating this feature will overwrite any manual definition you may have already added.
  ///

  ## Use the `$fromAI()` function 

  The `$fromAI()` function uses AI to dynamically fill in parameters for tools connected to the [Tools AI agent](/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.agent/tools-agent.md).  You can use the `$fromAI()` function in expressions within [app nodes](/integrations/builtin/app-nodes/index.md) (like [Gmail](/integrations/builtin/app-nodes/n8n-nodes-base.gmail/index.md), [Notion](/integrations/builtin/app-nodes/n8n-nodes-base.notion/index.md), or [Slack](/integrations/builtin/app-nodes/n8n-nodes-base.slack.md)) which are connected to the **AI Agent** as tools.

  /// note | Only for the Node Tools
  The `$fromAI()` function is only available for [app node](/integrations/builtin/app-nodes/index.md) tools connected to the Tools Agent. It isn't possible to use the `$fromAI()` function with the [Call n8n Workflow](/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolworkflow.md), [Code](/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolcode.md), [HTTP Request](/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolhttprequest.md), or [other cluster sub-nodes](/integrations/builtin/cluster-nodes/sub-nodes/index.md).
  ///

  To use the `$fromAI()` function, call it with the required `key` parameter:

  ```javascript
  {{ $fromAI('email') }}
  ```

  The `key` parameter and other arguments to the `$fromAI()` function aren't references to existing values. Instead, think of these arguments as hints that the AI model will use to populate the right data.

  For instance, if you choose a key called `email`, the AI Model will look for an email address in its context, other tools, and input data. In chat workflows, it may ask the user for an email address if it can't find one elsewhere. You can optionally pass other parameters like `description` to give extra context to the AI model.

  ### Parameters

  The `$fromAI()` function accepts the following parameters:

  <!-- vale off -->

  | Parameter | Type | Required? | Description |
  | --------- | ---- | --------- | ----------- |
  | `key` | string | :white_check_mark: | A string representing the key or name of the argument. This must be between 1 and 64 characters in length and can only contain lowercase letters, uppercase letters, numbers, underscores, and hyphens. |
  | `description` | string | :x: | A string describing the argument. |
  | `type` | string | :x: | A string specifying the data type. Can be string, number, boolean, or json (defaults to string). |
  | `defaultValue` | any | :x: | The default value to use for the argument. |

  <!-- vale on -->

  ### Examples

  As an example, you could use the following `$fromAI()` expression to dynamically populate a field with a name:

  ```javascript
  $fromAI("name", "The commenter's name", "string", "Jane Doe")
  ```

  If you don't need the optional parameters, you could simplify this as:

  ```javascript
  $fromAI("name")
  ```

  To dynamically populate the number of items you have in stock, you could use a `$fromAI()` expression like this:

  ```javascript
  $fromAI("numItemsInStock", "Number of items in stock", "number", 5)
  ```

  If you only want to fill in parts of a field with a dynamic value from the model, you can use it in a normal expression as well. For example, if you want the model to fill out the `subject` parameter for an e-mail, but always pre-fix the generated value with the string 'Generated by AI:', you could use the following expression:

  ```javascript
  Generated by AI: {{ $fromAI("subject") }}
  ```

  ### Templates

  You can see the `$fromAI()` function in action in the following [templates](/glossary.md#template-n8n):

  * [Angie, Personal AI Assistant with Telegram Voice and Text](https://n8n.io/workflows/2462-angie-personal-ai-assistant-with-telegram-voice-and-text/)
  * [Automate Customer Support Issue Resolution using AI Text Classifier](https://n8n.io/workflows/2468-automate-customer-support-issue-resolution-using-ai-text-classifier/)
  * [Scale Deal Flow with a Pitch Deck AI Vision, Chatbot and QDrant Vector Store](https://n8n.io/workflows/2464-scale-deal-flow-with-a-pitch-deck-ai-vision-chatbot-and-qdrant-vector-store/)

example_workflow:
  {"nodes":[{"parameters":{},"type":"n8n-nodes-base.node","typeVersion":1,"position":[220,120],"id":"6827b708-ad50-42e4-b80d-87ce25941fb3","name":"Node"}],"connections":{"Node":{"main":[[]]}},"pinData":{},"meta":{"templateCredsSetupCompleted":true,"instanceId":"e4de9c14ffc58f0df946cb3758f8d2a7a56b97b4542ec18ae6dec99cb13c0cf3"}}


node_type: n8n-nodes-base.GetResponse
name: GetResponse
display_name: GetResponse
description: Consume GetResponse API
category: Other
code_hash: 656f8c68066e4eb9ba77ed1ed799dde425402f50b1f72c60e09520faa5448977
documentation_url: https://docs.n8n.io/integrations/builtin/credentials/getresponse
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-08 08:05:21
updated_at: 2025-06-08 08:05:21
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.GetResponse = void 0;
  const GenericFunctions_1 = require("./GenericFunctions");
  const ContactDescription_1 = require("./ContactDescription");
  const moment_timezone_1 = __importDefault(require("moment-timezone"));
  class GetResponse {
      constructor() {
          this.description = {
              displayName: 'GetResponse',
              name: 'getResponse',
              icon: 'file:getResponse.png',
              group: ['input'],
              version: 1,
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Consume GetResponse API',
              defaults: {
                  name: 'GetResponse',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'getResponseApi',
                      required: true,
                      displayOptions: {
                          show: {
                              authentication: ['apiKey'],
                          },
                      },
                  },
                  {
                      name: 'getResponseOAuth2Api',
                      required: true,
                      displayOptions: {
                          show: {
                              authentication: ['oAuth2'],
                          },
                      },
                  },
              ],
              properties: [
                  {
                      displayName: 'Authentication',
                      name: 'authentication',
                      type: 'options',
                      options: [
                          {
                              name: 'API Key',
                              value: 'apiKey',
                          },
                          {
                              name: 'OAuth2',
                              value: 'oAuth2',
                          },
                      ],
                      default: 'apiKey',
                  },
                  {
                      displayName: 'Resource',
                      name: 'resource',
                      type: 'options',
                      noDataExpression: true,
                      options: [
                          {
                              name: 'Contact',
                              value: 'contact',
                          },
                      ],
                      default: 'contact',
                  },
                  ...ContactDescription_1.contactOperations,
                  ...ContactDescription_1.contactFields,
              ],
          };
          this.methods = {
              loadOptions: {
                  async getCampaigns() {
                      const returnData = [];
                      const campaigns = await GenericFunctions_1.getresponseApiRequest.call(this, 'GET', '/campaigns');
                      for (const campaign of campaigns) {
                          returnData.push({
                              name: campaign.name,
                              value: campaign.campaignId,
                          });
                      }
                      return returnData;
                  },
                  async getTags() {
                      const returnData = [];
                      const tags = await GenericFunctions_1.getresponseApiRequest.call(this, 'GET', '/tags');
                      for (const tag of tags) {
                          returnData.push({
                              name: tag.name,
                              value: tag.tagId,
                          });
                      }
                      return returnData;
                  },
                  async getCustomFields() {
                      const returnData = [];
                      const customFields = await GenericFunctions_1.getresponseApiRequest.call(this, 'GET', '/custom-fields');
                      for (const customField of customFields) {
                          returnData.push({
                              name: customField.name,
                              value: customField.customFieldId,
                          });
                      }
                      return returnData;
                  },
              },
          };
      }
      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++) {
              try {
                  if (resource === 'contact') {
                      if (operation === 'create') {
                          const email = this.getNodeParameter('email', i);
                          const campaignId = this.getNodeParameter('campaignId', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          const body = {
                              email,
                              campaign: {
                                  campaignId,
                              },
                          };
                          Object.assign(body, additionalFields);
                          if (additionalFields.customFieldsUi) {
                              const customFieldValues = additionalFields.customFieldsUi
                                  .customFieldValues;
                              if (customFieldValues) {
                                  body.customFieldValues = customFieldValues;
                                  for (let index = 0; index < customFieldValues.length; index++) {
                                      if (!Array.isArray(customFieldValues[index].value)) {
                                          customFieldValues[index].value = [customFieldValues[index].value];
                                      }
                                  }
                                  delete body.customFieldsUi;
                              }
                          }
                          responseData = await GenericFunctions_1.getresponseApiRequest.call(this, 'POST', '/contacts', body);
                          responseData = { success: true };
                      }
                      if (operation === 'delete') {
                          const contactId = this.getNodeParameter('contactId', i);
                          const options = this.getNodeParameter('options', i);
                          Object.assign(qs, options);
                          responseData = await GenericFunctions_1.getresponseApiRequest.call(this, 'DELETE', `/contacts/${contactId}`, {}, qs);
                          responseData = { success: true };
                      }
                      if (operation === 'get') {
                          const contactId = this.getNodeParameter('contactId', i);
                          const options = this.getNodeParameter('options', i);
                          Object.assign(qs, options);
                          responseData = await GenericFunctions_1.getresponseApiRequest.call(this, 'GET', `/contacts/${contactId}`, {}, qs);
                      }
                      if (operation === 'getAll') {
                          const returnAll = this.getNodeParameter('returnAll', i);
                          const options = this.getNodeParameter('options', i);
                          const timezone = this.getTimezone();
                          Object.assign(qs, options);
                          const isNotQuery = ['sortBy', 'sortOrder', 'additionalFlags', 'fields', 'exactMatch'];
                          const isDate = ['createdOnFrom', 'createdOnTo', 'changeOnFrom', 'changeOnTo'];
                          const dateMapToKey = {
                              createdOnFrom: '[createdOn][from]',
                              createdOnTo: '[createdOn][to]',
                              changeOnFrom: '[changeOn][from]',
                              changeOnTo: '[changeOn][to]',
                          };
                          for (const key of Object.keys(qs)) {
                              if (!isNotQuery.includes(key)) {
                                  if (isDate.includes(key)) {
                                      qs[`query${dateMapToKey[key]}`] = moment_timezone_1.default
                                          .tz(qs[key], timezone)
                                          .format('YYYY-MM-DDTHH:mm:ssZZ');
                                  }
                                  else {
                                      qs[`query[${key}]`] = qs[key];
                                  }
                                  delete qs[key];
                              }
                          }
                          if (qs.sortBy) {
                              qs[`sort[${qs.sortBy}]`] = qs.sortOrder || 'ASC';
                          }
                          if (qs.exactMatch === true) {
                              qs.additionalFlags = 'exactMatch';
                              delete qs.exactMatch;
                          }
                          if (returnAll) {
                              responseData = await GenericFunctions_1.getResponseApiRequestAllItems.call(this, 'GET', '/contacts', {}, qs);
                          }
                          else {
                              qs.perPage = this.getNodeParameter('limit', i);
                              responseData = await GenericFunctions_1.getresponseApiRequest.call(this, 'GET', '/contacts', {}, qs);
                          }
                      }
                      if (operation === 'update') {
                          const contactId = this.getNodeParameter('contactId', i);
                          const updateFields = this.getNodeParameter('updateFields', i);
                          const body = {};
                          Object.assign(body, updateFields);
                          if (updateFields.customFieldsUi) {
                              const customFieldValues = updateFields.customFieldsUi
                                  .customFieldValues;
                              if (customFieldValues) {
                                  body.customFieldValues = customFieldValues;
                                  delete body.customFieldsUi;
                              }
                          }
                          responseData = await GenericFunctions_1.getresponseApiRequest.call(this, 'POST', `/contacts/${contactId}`, body);
                      }
                  }
                  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.GetResponse = GetResponse;
  //# sourceMappingURL=GetResponse.node.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: GetResponse credentials
  description: Documentation for GetResponse credentials. Use these credentials to authenticate GetResponse in n8n, a workflow automation platform.
  contentType: [integration, reference]
  ---

  # GetResponse credentials

  You can use these credentials to authenticate the following nodes:

  - [GetResponse](/integrations/builtin/app-nodes/n8n-nodes-base.getresponse.md)
  - [GetResponse Trigger](/integrations/builtin/trigger-nodes/n8n-nodes-base.getresponsetrigger.md)

  ## Prerequisites

  Create a [GetResponse](https://www.getresponse.com/){:target=_blank .external-link} account.

  ## Supported authentication methods

  - API key
  - OAuth2

  ## Related resources

  Refer to [GetResponse's API documentation](https://apidocs.getresponse.com/v3){:target=_blank .external-link} for more information about the service.

  ## Using API key

  To configure this credential, you'll need:

  - An **API Key**: To view or generate an API key, go to **Integrations and API > API**. Refer to the [GetResponse Help Center](https://www.getresponse.com/help/where-do-i-find-the-api-key.html){:target=_blank .external-link} for more detailed instructions.

  ## Using OAuth2

  To configure this credential, you'll need:

  - A **Client ID**: Generated when you [register your application](https://apidocs.getresponse.com/v3/authentication/oauth2){:target=_blank .external-link}.
  - A **Client Secret**: Generated when you [register your application](https://apidocs.getresponse.com/v3/authentication/oauth2){:target=_blank .external-link} as the **Client Secret Key**.

  When you register your application, copy the **OAuth Redirect URL** from n8n and add it as the **Redirect URL** in GetResponse.

  /// note | Redirect URL with localhost
  The Redirect URL should be a URL in your domain, for example: `https://mytemplatemaker.example.com/gr_callback`. GetResponse doesn't accept a localhost callback URL. Refer to the [FAQs](#configure-oauth2-credentials-for-a-local-environment) to configure the credentials for the local environment.
  ///

  ## Configure OAuth2 credentials for a local environment

  GetResponse doesn't accept the localhost callback URL. Follow the steps below to configure the OAuth credentials for a local environment:
  1. Use [ngrok](https://ngrok.com/){:target=_blank .external-link} to expose the local server running on port `5678` to the internet. In your terminal, run the following command:
  ```sh
  ngrok http 5678
  ```
  2. Run the following command in a new terminal. Replace `<YOUR-NGROK-URL>` with the URL that you got from the previous step.
  ```sh
  export WEBHOOK_URL=<YOUR-NGROK-URL>
  ```
  3. Follow the [Using OAuth2](#using-oauth2) instructions to configure your credentials, using this URL as your **Redirect URL**.

example_workflow:
  {"nodes":[{"parameters":{},"type":"n8n-nodes-base.node","typeVersion":1,"position":[220,120],"id":"b12517d4-b5b5-41d5-bdef-dd90739eacfe","name":"Node"}],"connections":{"Node":{"main":[[]]}},"pinData":{},"meta":{"templateCredsSetupCompleted":true,"instanceId":"c882a72a78f253d0b8e31ad0005532ed3670c2381b5679a5393788cb205ffd2a"}}


node_type: n8n-nodes-base.Ghost
name: Ghost
display_name: Ghost
description: Consume Ghost API
category: Other
code_hash: d71663706631c3fa7968cf9519d85bac19bdfb4b37d8043b0ed29130df735818
documentation_url: https://docs.n8n.io/integrations/builtin/credentials/ghost
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-08 08:05:22
updated_at: 2025-06-08 08:05:22
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.Ghost = void 0;
  const n8n_workflow_1 = require("n8n-workflow");
  const GenericFunctions_1 = require("./GenericFunctions");
  const PostDescription_1 = require("./PostDescription");
  const moment_timezone_1 = __importDefault(require("moment-timezone"));
  class Ghost {
      constructor() {
          this.description = {
              displayName: 'Ghost',
              name: 'ghost',
              icon: 'file:ghost.svg',
              group: ['input'],
              version: 1,
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Consume Ghost API',
              defaults: {
                  name: 'Ghost',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'ghostAdminApi',
                      required: true,
                      displayOptions: {
                          show: {
                              source: ['adminApi'],
                          },
                      },
                  },
                  {
                      name: 'ghostContentApi',
                      required: true,
                      displayOptions: {
                          show: {
                              source: ['contentApi'],
                          },
                      },
                  },
              ],
              properties: [
                  {
                      displayName: 'Source',
                      name: 'source',
                      type: 'options',
                      description: 'Pick where your data comes from, Content or Admin API',
                      options: [
                          {
                              name: 'Admin API',
                              value: 'adminApi',
                          },
                          {
                              name: 'Content API',
                              value: 'contentApi',
                          },
                      ],
                      default: 'contentApi',
                  },
                  {
                      displayName: 'Resource',
                      name: 'resource',
                      type: 'options',
                      options: [
                          {
                              name: 'Post',
                              value: 'post',
                          },
                      ],
                      noDataExpression: true,
                      default: 'post',
                  },
                  ...PostDescription_1.postOperations,
                  ...PostDescription_1.postFields,
              ],
          };
          this.methods = {
              loadOptions: {
                  async getAuthors() {
                      const returnData = [];
                      const users = await GenericFunctions_1.ghostApiRequestAllItems.call(this, 'users', 'GET', '/admin/users');
                      for (const user of users) {
                          returnData.push({
                              name: user.name,
                              value: user.id,
                          });
                      }
                      return returnData;
                  },
                  async getTags() {
                      const returnData = [];
                      const tags = await GenericFunctions_1.ghostApiRequestAllItems.call(this, 'tags', 'GET', '/admin/tags');
                      for (const tag of tags) {
                          returnData.push({
                              name: tag.name,
                              value: tag.name,
                          });
                      }
                      return returnData;
                  },
              },
          };
      }
      async execute() {
          const items = this.getInputData();
          const returnData = [];
          const length = items.length;
          const timezone = this.getTimezone();
          const qs = {};
          let responseData;
          const resource = this.getNodeParameter('resource', 0);
          const operation = this.getNodeParameter('operation', 0);
          const source = this.getNodeParameter('source', 0);
          for (let i = 0; i < length; i++) {
              try {
                  if (source === 'contentApi') {
                      if (resource === 'post') {
                          if (operation === 'get') {
                              const by = this.getNodeParameter('by', i);
                              const identifier = this.getNodeParameter('identifier', i);
                              const options = this.getNodeParameter('options', i);
                              Object.assign(qs, options);
                              let endpoint;
                              if (by === 'slug') {
                                  endpoint = `/content/posts/slug/${identifier}`;
                              }
                              else {
                                  endpoint = `/content/posts/${identifier}`;
                              }
                              responseData = await GenericFunctions_1.ghostApiRequest.call(this, 'GET', endpoint, {}, qs);
                              responseData = responseData.posts;
                          }
                          if (operation === 'getAll') {
                              const returnAll = this.getNodeParameter('returnAll', 0);
                              const options = this.getNodeParameter('options', i);
                              Object.assign(qs, options);
                              if (returnAll) {
                                  responseData = await GenericFunctions_1.ghostApiRequestAllItems.call(this, 'posts', 'GET', '/content/posts', {}, qs);
                              }
                              else {
                                  qs.limit = this.getNodeParameter('limit', 0);
                                  responseData = await GenericFunctions_1.ghostApiRequest.call(this, 'GET', '/content/posts', {}, qs);
                                  responseData = responseData.posts;
                              }
                          }
                      }
                  }
                  if (source === 'adminApi') {
                      if (resource === 'post') {
                          if (operation === 'create') {
                              const title = this.getNodeParameter('title', i);
                              const contentFormat = this.getNodeParameter('contentFormat', i);
                              const content = this.getNodeParameter('content', i);
                              const additionalFields = this.getNodeParameter('additionalFields', i);
                              const post = {
                                  title,
                              };
                              if (contentFormat === 'html') {
                                  post.html = content;
                                  qs.source = 'html';
                              }
                              else if (contentFormat === 'lexical') {
                                  const lexical = (0, GenericFunctions_1.validateJSON)(content);
                                  if (lexical === undefined) {
                                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Content must be a valid JSON', {
                                          itemIndex: i,
                                      });
                                  }
                                  post.lexical = content;
                              }
                              else {
                                  const mobileDoc = (0, GenericFunctions_1.validateJSON)(content);
                                  if (mobileDoc === undefined) {
                                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Content must be a valid JSON', {
                                          itemIndex: i,
                                      });
                                  }
                                  post.mobiledoc = content;
                              }
                              delete post.content;
                              Object.assign(post, additionalFields);
                              if (post.published_at) {
                                  post.published_at = moment_timezone_1.default.tz(post.published_at, timezone).utc().format();
                              }
                              if (post.status === 'scheduled' && post.published_at === undefined) {
                                  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Published at must be define when status is scheduled', { itemIndex: i });
                              }
                              responseData = await GenericFunctions_1.ghostApiRequest.call(this, 'POST', '/admin/posts', { posts: [post] }, qs);
                              responseData = responseData.posts;
                          }
                          if (operation === 'delete') {
                              const postId = this.getNodeParameter('postId', i);
                              responseData = await GenericFunctions_1.ghostApiRequest.call(this, 'DELETE', `/admin/posts/${postId}`);
                          }
                          if (operation === 'get') {
                              const by = this.getNodeParameter('by', i);
                              const identifier = this.getNodeParameter('identifier', i);
                              const options = this.getNodeParameter('options', i);
                              Object.assign(qs, options);
                              let endpoint;
                              if (by === 'slug') {
                                  endpoint = `/admin/posts/slug/${identifier}`;
                              }
                              else {
                                  endpoint = `/admin/posts/${identifier}`;
                              }
                              responseData = await GenericFunctions_1.ghostApiRequest.call(this, 'GET', endpoint, {}, qs);
                              responseData = responseData.posts;
                          }
                          if (operation === 'getAll') {
                              const returnAll = this.getNodeParameter('returnAll', 0);
                              const options = this.getNodeParameter('options', i);
                              Object.assign(qs, options);
                              if (returnAll) {
                                  responseData = await GenericFunctions_1.ghostApiRequestAllItems.call(this, 'posts', 'GET', '/admin/posts', {}, qs);
                              }
                              else {
                                  qs.limit = this.getNodeParameter('limit', 0);
                                  responseData = await GenericFunctions_1.ghostApiRequest.call(this, 'GET', '/admin/posts', {}, qs);
                                  responseData = responseData.posts;
                              }
                          }
                          if (operation === 'update') {
                              const postId = this.getNodeParameter('postId', i);
                              const contentFormat = this.getNodeParameter('contentFormat', i);
                              const updateFields = this.getNodeParameter('updateFields', i);
                              const post = {};
                              if (contentFormat === 'html') {
                                  post.html = updateFields.content || '';
                                  qs.source = 'html';
                                  delete updateFields.content;
                              }
                              else if (contentFormat === 'lexical') {
                                  const lexical = (0, GenericFunctions_1.validateJSON)(updateFields.contentJson || undefined);
                                  if (lexical === undefined) {
                                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Content must be a valid JSON', {
                                          itemIndex: i,
                                      });
                                  }
                                  post.lexical = updateFields.contentJson;
                                  delete updateFields.contentJson;
                              }
                              else {
                                  const mobileDoc = (0, GenericFunctions_1.validateJSON)(updateFields.contentJson || undefined);
                                  if (mobileDoc === undefined) {
                                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Content must be a valid JSON', {
                                          itemIndex: i,
                                      });
                                  }
                                  post.mobiledoc = updateFields.contentJson;
                                  delete updateFields.contentJson;
                              }
                              Object.assign(post, updateFields);
                              const { posts } = await GenericFunctions_1.ghostApiRequest.call(this, 'GET', `/admin/posts/${postId}`, {}, { fields: 'id, updated_at' });
                              if (post.published_at) {
                                  post.published_at = moment_timezone_1.default.tz(post.published_at, timezone).utc().format();
                              }
                              if (post.status === 'scheduled' && post.published_at === undefined) {
                                  throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Published at must be define when status is scheduled', { itemIndex: i });
                              }
                              post.updated_at = posts[0].updated_at;
                              responseData = await GenericFunctions_1.ghostApiRequest.call(this, 'PUT', `/admin/posts/${postId}`, { posts: [post] }, qs);
                              responseData = responseData.posts;
                          }
                      }
                  }
                  responseData = this.helpers.returnJsonArray(responseData);
                  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.Ghost = Ghost;
  //# sourceMappingURL=Ghost.node.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: Ghost credentials
  description: Documentation for Ghost credentials. Use these credentials to authenticate Ghost in n8n, a workflow automation platform.
  contentType: [integration, reference]
  ---

  # Ghost credentials

  You can use these credentials to authenticate the following nodes:

  - [Ghost](/integrations/builtin/app-nodes/n8n-nodes-base.ghost.md)

  ## Prerequisites

  Create a [Ghost](https://ghost.org/){:target=_blank .external-link} account.

  ## Supported authentication methods

  - Admin API key
  - Content API key

  The keys are generated following the same steps, but the authorization flows and key format are different, so n8n stores the credentials separately. The Content API uses an API key; the Admin API uses an API key to generate a token for authentication.

  ## Related resources

  Refer to Ghost's [Admin API documentation](https://ghost.org/docs/admin-api/){:target=_blank .external-link} for more information about the Admin API service. Refer to Ghost's [Content API documentation](https://ghost.org/docs/content-api/){:target=_blank .external-link} for more information about the Content API service.

  ## Using Admin API key

  To configure this credential, you'll need:

  - The **URL** of your Ghost admin domain. Your [admin domain](https://ghost.org/docs/admin-api/#base-url){:target=_blank .external-link} can be different to your main domain and may include a subdirectory. All Ghost(Pro) blogs have a `*.ghost.io` domain as their admin domain and require https.
  - An **API Key**: To generate a new API key, create a new Custom Integration. Refer to the [Ghost Admin API Token Authentication Key documentation](https://ghost.org/docs/admin-api/#token-authentication){:target=_blank .external-link} for more detailed instructions. Copy the **Admin API Key** and use this as the **API Key** in the Ghost Admin n8n credential.

  ## Using Content API key

  To configure this credential, you'll need:

  - The **URL** of your Ghost admin domain. Your [admin domain](https://ghost.org/docs/content-api/#url){:target=_blank .external-link} can be different to your main domain and may include a subdirectory. All Ghost(Pro) blogs have a `*.ghost.io` domain as their admin domain and require https.
  - An **API Key**: To generate a new API key, create a new Custom Integration. Refer to the [Ghost Content API Key documentation](https://ghost.org/docs/content-api/#key){:target=_blank .external-link} for more detailed instructions. Copy the **Content API Key** and use this as the **API Key** in the Ghost Content n8n credential.

example_workflow:
  {"nodes":[{"parameters":{},"type":"n8n-nodes-base.node","typeVersion":1,"position":[220,120],"id":"c9f9abf9-be9d-4bd2-afda-82d160a8d1b1","name":"Node"}],"connections":{"Node":{"main":[[]]}},"pinData":{},"meta":{"templateCredsSetupCompleted":true,"instanceId":"0b9fb52309c388d3691b466aa33e95e96a83c9bd72f57005c6e4776ba76304b1"}}


node_type: n8n-nodes-base.Git
name: Git
display_name: Git
description: Control git.
category: Other
code_hash: 50ecff111cb4e7515e3a857d6d6c64da67db9cdb8bed00c31a04f424748b70ba
documentation_url: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.git
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-08 08:05:22
updated_at: 2025-06-08 08:05:22
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.Git = void 0;
  const descriptions_1 = require("./descriptions");
  const simple_git_1 = __importDefault(require("simple-git"));
  const promises_1 = require("fs/promises");
  const url_1 = require("url");
  class Git {
      constructor() {
          this.description = {
              displayName: 'Git',
              name: 'git',
              icon: 'file:git.svg',
              group: ['transform'],
              version: 1,
              description: 'Control git.',
              defaults: {
                  name: 'Git',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'gitPassword',
                      required: true,
                      displayOptions: {
                          show: {
                              authentication: ['gitPassword'],
                          },
                      },
                  },
              ],
              properties: [
                  {
                      displayName: 'Authentication',
                      name: 'authentication',
                      type: 'options',
                      options: [
                          {
                              name: 'Authenticate',
                              value: 'gitPassword',
                          },
                          {
                              name: 'None',
                              value: 'none',
                          },
                      ],
                      displayOptions: {
                          show: {
                              operation: ['clone', 'push'],
                          },
                      },
                      default: 'none',
                      description: 'The way to authenticate',
                  },
                  {
                      displayName: 'Operation',
                      name: 'operation',
                      type: 'options',
                      noDataExpression: true,
                      default: 'log',
                      options: [
                          {
                              name: 'Add',
                              value: 'add',
                              description: 'Add a file or folder to commit',
                              action: 'Add a file or folder to commit',
                          },
                          {
                              name: 'Add Config',
                              value: 'addConfig',
                              description: 'Add configuration property',
                              action: 'Add configuration property',
                          },
                          {
                              name: 'Clone',
                              value: 'clone',
                              description: 'Clone a repository',
                              action: 'Clone a repository',
                          },
                          {
                              name: 'Commit',
                              value: 'commit',
                              description: 'Commit files or folders to git',
                              action: 'Commit files or folders to git',
                          },
                          {
                              name: 'Fetch',
                              value: 'fetch',
                              description: 'Fetch from remote repository',
                              action: 'Fetch from remote repository',
                          },
                          {
                              name: 'List Config',
                              value: 'listConfig',
                              description: 'Return current configuration',
                              action: 'Return current configuration',
                          },
                          {
                              name: 'Log',
                              value: 'log',
                              description: 'Return git commit history',
                              action: 'Return git commit history',
                          },
                          {
                              name: 'Pull',
                              value: 'pull',
                              description: 'Pull from remote repository',
                              action: 'Pull from remote repository',
                          },
                          {
                              name: 'Push',
                              value: 'push',
                              description: 'Push to remote repository',
                              action: 'Push to remote repository',
                          },
                          {
                              name: 'Push Tags',
                              value: 'pushTags',
                              description: 'Push Tags to remote repository',
                              action: 'Push tags to remote repository',
                          },
                          {
                              name: 'Status',
                              value: 'status',
                              description: 'Return status of current repository',
                              action: 'Return status of current repository',
                          },
                          {
                              name: 'Tag',
                              value: 'tag',
                              description: 'Create a new tag',
                              action: 'Create a new tag',
                          },
                          {
                              name: 'User Setup',
                              value: 'userSetup',
                              description: 'Set the user',
                              action: 'Set up a user',
                          },
                      ],
                  },
                  {
                      displayName: 'Repository Path',
                      name: 'repositoryPath',
                      type: 'string',
                      displayOptions: {
                          hide: {
                              operation: ['clone'],
                          },
                      },
                      default: '',
                      placeholder: '/tmp/repository',
                      required: true,
                      description: 'Local path of the git repository to operate on',
                  },
                  {
                      displayName: 'New Repository Path',
                      name: 'repositoryPath',
                      type: 'string',
                      displayOptions: {
                          show: {
                              operation: ['clone'],
                          },
                      },
                      default: '',
                      placeholder: '/tmp/repository',
                      required: true,
                      description: 'Local path to which the git repository should be cloned into',
                  },
                  ...descriptions_1.addFields,
                  ...descriptions_1.addConfigFields,
                  ...descriptions_1.cloneFields,
                  ...descriptions_1.commitFields,
                  ...descriptions_1.logFields,
                  ...descriptions_1.pushFields,
                  ...descriptions_1.tagFields,
              ],
          };
      }
      async execute() {
          const items = this.getInputData();
          const prepareRepository = async (repositoryPath) => {
              const authentication = this.getNodeParameter('authentication', 0);
              if (authentication === 'gitPassword') {
                  const gitCredentials = await this.getCredentials('gitPassword');
                  const url = new url_1.URL(repositoryPath);
                  url.username = gitCredentials.username;
                  url.password = gitCredentials.password;
                  return url.toString();
              }
              return repositoryPath;
          };
          const operation = this.getNodeParameter('operation', 0);
          const returnItems = [];
          for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
              try {
                  const repositoryPath = this.getNodeParameter('repositoryPath', itemIndex, '');
                  const options = this.getNodeParameter('options', itemIndex, {});
                  if (operation === 'clone') {
                      try {
                          await (0, promises_1.access)(repositoryPath);
                      }
                      catch (error) {
                          await (0, promises_1.mkdir)(repositoryPath);
                      }
                  }
                  const gitOptions = {
                      baseDir: repositoryPath,
                  };
                  const git = (0, simple_git_1.default)(gitOptions)
                      .env('GIT_TERMINAL_PROMPT', '0');
                  if (operation === 'add') {
                      const pathsToAdd = this.getNodeParameter('pathsToAdd', itemIndex, '');
                      await git.add(pathsToAdd.split(','));
                      returnItems.push({
                          json: {
                              success: true,
                          },
                          pairedItem: {
                              item: itemIndex,
                          },
                      });
                  }
                  else if (operation === 'addConfig') {
                      const key = this.getNodeParameter('key', itemIndex, '');
                      const value = this.getNodeParameter('value', itemIndex, '');
                      let append = false;
                      if (options.mode === 'append') {
                          append = true;
                      }
                      await git.addConfig(key, value, append);
                      returnItems.push({
                          json: {
                              success: true,
                          },
                          pairedItem: {
                              item: itemIndex,
                          },
                      });
                  }
                  else if (operation === 'clone') {
                      let sourceRepository = this.getNodeParameter('sourceRepository', itemIndex, '');
                      sourceRepository = await prepareRepository(sourceRepository);
                      await git.clone(sourceRepository, '.');
                      returnItems.push({
                          json: {
                              success: true,
                          },
                          pairedItem: {
                              item: itemIndex,
                          },
                      });
                  }
                  else if (operation === 'commit') {
                      const message = this.getNodeParameter('message', itemIndex, '');
                      let pathsToAdd = undefined;
                      if (options.files !== undefined) {
                          pathsToAdd = options.pathsToAdd.split(',');
                      }
                      await git.commit(message, pathsToAdd);
                      returnItems.push({
                          json: {
                              success: true,
                          },
                          pairedItem: {
                              item: itemIndex,
                          },
                      });
                  }
                  else if (operation === 'fetch') {
                      await git.fetch();
                      returnItems.push({
                          json: {
                              success: true,
                          },
                          pairedItem: {
                              item: itemIndex,
                          },
                      });
                  }
                  else if (operation === 'log') {
                      const logOptions = {};
                      const returnAll = this.getNodeParameter('returnAll', itemIndex, false);
                      if (!returnAll) {
                          logOptions.maxCount = this.getNodeParameter('limit', itemIndex, 100);
                      }
                      if (options.file) {
                          logOptions.file = options.file;
                      }
                      const log = await git.log(logOptions);
                      returnItems.push(...this.helpers.returnJsonArray(log.all).map((item) => {
                          return {
                              ...item,
                              pairedItem: { item: itemIndex },
                          };
                      }));
                  }
                  else if (operation === 'pull') {
                      await git.pull();
                      returnItems.push({
                          json: {
                              success: true,
                          },
                          pairedItem: {
                              item: itemIndex,
                          },
                      });
                  }
                  else if (operation === 'push') {
                      if (options.repository) {
                          const targetRepository = await prepareRepository(options.targetRepository);
                          await git.push(targetRepository);
                      }
                      else {
                          const authentication = this.getNodeParameter('authentication', 0);
                          if (authentication === 'gitPassword') {
                              const config = await git.listConfig();
                              let targetRepository;
                              for (const fileName of Object.keys(config.values)) {
                                  if (config.values[fileName]['remote.origin.url']) {
                                      targetRepository = config.values[fileName]['remote.origin.url'];
                                      break;
                                  }
                              }
                              targetRepository = await prepareRepository(targetRepository);
                              await git.push(targetRepository);
                          }
                          else {
                              await git.push();
                          }
                      }
                      returnItems.push({
                          json: {
                              success: true,
                          },
                          pairedItem: {
                              item: itemIndex,
                          },
                      });
                  }
                  else if (operation === 'pushTags') {
                      await git.pushTags();
                      returnItems.push({
                          json: {
                              success: true,
                          },
                          pairedItem: {
                              item: itemIndex,
                          },
                      });
                  }
                  else if (operation === 'listConfig') {
                      const config = await git.listConfig();
                      const data = [];
                      for (const fileName of Object.keys(config.values)) {
                          data.push({
                              _file: fileName,
                              ...config.values[fileName],
                          });
                      }
                      returnItems.push(...this.helpers.returnJsonArray(data).map((item) => {
                          return {
                              ...item,
                              pairedItem: { item: itemIndex },
                          };
                      }));
                  }
                  else if (operation === 'status') {
                      const status = await git.status();
                      returnItems.push(...this.helpers.returnJsonArray([status]).map((item) => {
                          return {
                              ...item,
                              pairedItem: { item: itemIndex },
                          };
                      }));
                  }
                  else if (operation === 'tag') {
                      const name = this.getNodeParameter('name', itemIndex, '');
                      await git.addTag(name);
                      returnItems.push({
                          json: {
                              success: true,
                          },
                          pairedItem: {
                              item: itemIndex,
                          },
                      });
                  }
              }
              catch (error) {
                  if (this.continueOnFail()) {
                      returnItems.push({
                          json: {
                              error: error.toString(),
                          },
                          pairedItem: {
                              item: itemIndex,
                          },
                      });
                      continue;
                  }
                  throw error;
              }
          }
          return [returnItems];
      }
  }
  exports.Git = Git;
  //# sourceMappingURL=Git.node.js.map

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

  # Git

  [Git](https://git-scm.com/) is a free and open-source distributed version control system designed to handle everything from small to large projects with speed and efficiency.

  /// note | Credentials
  You can find authentication information for this node [here](/integrations/builtin/credentials/git.md).
  ///

  ## Operations

  * [**Add**](#add) a file or folder to commit. Performs a [git add](https://git-scm.com/docs/git-add){:target=_blank .external-link}.
  * [**Add Config**](#add-config): Add configuration property. Performs a [git config](https://git-scm.com/docs/git-config){:target=_blank .external-link} set or add.
  * [**Clone**](#clone) a repository: Performs a [git clone](https://git-scm.com/docs/git-clone){:target=_blank .external-link}.
  * [**Commit**](#commit) files or folders to git. Performs a [git commit](https://git-scm.com/docs/git-commit){:target=_blank .external-link}.
  * [**Fetch**](#fetch) from remote repository. Performs a [git fetch](https://git-scm.com/docs/git-fetch){:target=_blank .external-link}.
  * [**List Config**](#list-config): Return current configuration. Performs a [git config](https://git-scm.com/docs/git-config){:target=_blank .external-link} query.
  * [**Log**](#log): Return git commit history. Performs a [git log](https://git-scm.com/docs/git-log){:target=_blank .external-link}.
  * [**Pull**](#pull) from remote repository: Performs a [git pull](https://git-scm.com/docs/git-pull){:target=_blank .external-link}.
  * [**Push**](#push) to remote repository: Performs a [git push](https://git-scm.com/docs/git-push){:target=_blank .external-link}.
  * [**Push Tags**](#push-tags) to remote repository: Performs a [git push --tags](https://git-scm.com/docs/git-push#Documentation/git-push.txt---tags){:target=_blank .external-link}.
  * Return [**Status**](#status) of current repository: Performs a [git status](https://git-scm.com/docs/git-status){:target=_blank .external-link}.
  * Create a new [**Tag**](#tag): Performs a [git tag](https://git-scm.com/docs/git-tag){:target=_blank .external-link}.
  * [**User Setup**](#user-setup): Set the user.

  Refer to the sections below for more details on the parameters and options for each operation.

  ## Add

  Configure this operation with these parameters:

  * **Repository Path**: Enter the local path of the git repository.
  * **Paths to Add**: Enter a comma-separated list of paths of files or folders to add in this field. You can use absolute paths or relative paths from the **Repository Path**.

  <!--Vale doesn't like "Config"-->
  <!-- vale off -->
  ## Add Config

  Configure this operation with these parameters:

  * **Repository Path**: Enter the local path of the git repository.
  * **Key**: Enter the name of the key to set.
  * **Value**: Enter the value of the key to set.

  ### Add Config options

  The add config operation adds the **Mode** option. Choose whether to **Set** or **Append** the setting in the local config.
  <!-- vale on -->

  ## Clone

  Configure this operation with these parameters:

  * **Repository Path**: Enter the local path of the git repository.
  * **Authentication**: Select **Authenticate** to pass credentials in. Select **None** to not use authentication.
      * **Credential for Git**: If you select **Authenticate**, you must select or create credentials for the node to use. Refer to [Git credential](/integrations/builtin/credentials/git.md) for more information.
  * **New Repository Path**: Enter the local path where you'd like to locate the cloned repository.
  * **Source Repository**: Enter the URL or path of the repository you want to clone.

  ## Commit

  Configure this operation with these parameters:

  * **Repository Path**: Enter the local path of the git repository.
  * **Message**: Enter the commit message to use in this field.

  ### Commit options

  The commit operation adds the **Paths to Add** option. To commit all "added" files and folders, leave this field blank. To commit specific "added" files and folders, enter a comma-separated list of paths of files or folders in this field.

  You can use absolute paths or relative paths from the **Repository Path**.

  ## Fetch

  This operation only prompts you to enter the local path of the git repository in the **Repository Path** parameter.

  <!--Vale doesn't like "Config"-->
  <!-- vale off -->
  ## List Config

  This operation only prompts you to enter the local path of the git repository in the **Repository Path** parameter.
  <!-- vale on -->

  ## Log

  Configure this operation with these parameters:

  * **Repository Path**: Enter the local path of the git repository.
  * **Return All**: When turned on, the node will return all results. When turned off, the node will return results up to the set **Limit**.
  * **Limit**: Only available when you turn off **Return All**. Enter the maximum number of results to return.

  ### Log options

  The log operation adds the **File** option. Enter the path of a file or folder to get the history of in this field.

  You can use absolute paths or relative paths from the **Repository Path**.

  ## Pull

  This operation only prompts you to enter the local path of the git repository in the **Repository Path** parameter.

  ## Push

  Configure this operation with these parameters:

  * **Repository Path**: Enter the local path of the git repository.
  * **Authentication**: Select **Authenticate** to pass credentials in or **None** to not use authentication.
      * If you select **Authenticate**, you must select or create **Credential for Git** for the node to use. Refer to [Git credential](/integrations/builtin/credentials/git.md) for more information.

  ### Push options

  The push operation adds the **Target Repository** option. Enter the URL or path of the repository to push to in this field.

  ## Push Tags

  This operation only prompts you to enter the local path of the git repository in the **Repository Path** parameter.

  ## Status

  This operation only prompts you to enter the local path of the git repository in the **Repository Path** parameter.

  ## Tag

  Configure this operation with these parameters:

  * **Repository Path**: Enter the local path of the git repository.
  * **Name**: Enter the name of the tag to create in this field.

  ## User Setup

  This operation only prompts you to enter the local path of the git repository in the **Repository Path** parameter.

  ## Templates and examples

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

example_workflow:
  {"nodes":[{"parameters":{},"type":"n8n-nodes-base.node","typeVersion":1,"position":[220,120],"id":"fa4f418f-42bb-4d6a-9a90-ab9175dced5e","name":"Node"}],"connections":{"Node":{"main":[[]]}},"pinData":{},"meta":{"templateCredsSetupCompleted":true,"instanceId":"2b19adaf4dfc5fad9beb57886b35da3667de47ad5511d5db6bec808a51428525"}}


node_type: n8n-nodes-base.Github
name: Github
display_name: GitHub
description: Consume GitHub API
category: Other
code_hash: 749f403fea31f46ff0b72d3f102f45d2b3b252be9caad1c740dbf910d757f364
documentation_url: https://docs.n8n.io/integrations/builtin/credentials/github
example_parameters: {}
properties_schema: []
package_name: n8n-nodes-base
extracted_at: 2025-06-08 08:05:22
updated_at: 2025-06-08 08:05:22
source_code:
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.Github = void 0;
  const n8n_workflow_1 = require("n8n-workflow");
  const GenericFunctions_1 = require("./GenericFunctions");
  const change_case_1 = require("change-case");
  const SearchFunctions_1 = require("./SearchFunctions");
  class Github {
      constructor() {
          this.description = {
              displayName: 'GitHub',
              name: 'github',
              icon: 'file:github.svg',
              group: ['input'],
              version: 1,
              subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
              description: 'Consume GitHub API',
              defaults: {
                  name: 'GitHub',
              },
              inputs: ['main'],
              outputs: ['main'],
              credentials: [
                  {
                      name: 'githubApi',
                      required: true,
                      displayOptions: {
                          show: {
                              authentication: ['accessToken'],
                          },
                      },
                  },
                  {
                      name: 'githubOAuth2Api',
                      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: 'File',
                              value: 'file',
                          },
                          {
                              name: 'Issue',
                              value: 'issue',
                          },
                          {
                              name: 'Organization',
                              value: 'organization',
                          },
                          {
                              name: 'Release',
                              value: 'release',
                          },
                          {
                              name: 'Repository',
                              value: 'repository',
                          },
                          {
                              name: 'Review',
                              value: 'review',
                          },
                          {
                              name: 'User',
                              value: 'user',
                          },
                      ],
                      default: 'issue',
                  },
                  {
                      displayName: 'Operation',
                      name: 'operation',
                      type: 'options',
                      noDataExpression: true,
                      displayOptions: {
                          show: {
                              resource: ['organization'],
                          },
                      },
                      options: [
                          {
                              name: 'Get Repositories',
                              value: 'getRepositories',
                              description: 'Returns all repositories of an organization',
                              action: 'Get repositories for an organization',
                          },
                      ],
                      default: 'getRepositories',
                  },
                  {
                      displayName: 'Operation',
                      name: 'operation',
                      type: 'options',
                      noDataExpression: true,
                      displayOptions: {
                          show: {
                              resource: ['issue'],
                          },
                      },
                      options: [
                          {
                              name: 'Create',
                              value: 'create',
                              description: 'Create a new issue',
                              action: 'Create an issue',
                          },
                          {
                              name: 'Create Comment',
                              value: 'createComment',
                              description: 'Create a new comment on an issue',
                              action: 'Create a comment on an issue',
                          },
                          {
                              name: 'Edit',
                              value: 'edit',
                              description: 'Edit an issue',
                              action: 'Edit an issue',
                          },
                          {
                              name: 'Get',
                              value: 'get',
                              description: 'Get the data of a single issue',
                              action: 'Get an issue',
                          },
                          {
                              name: 'Lock',
                              value: 'lock',
                              description: 'Lock an issue',
                              action: 'Lock an issue',
                          },
                      ],
                      default: 'create',
                  },
                  {
                      displayName: 'Operation',
                      name: 'operation',
                      type: 'options',
                      noDataExpression: true,
                      displayOptions: {
                          show: {
                              resource: ['file'],
                          },
                      },
                      options: [
                          {
                              name: 'Create',
                              value: 'create',
                              description: 'Create a new file in repository',
                              action: 'Create a file',
                          },
                          {
                              name: 'Delete',
                              value: 'delete',
                              description: 'Delete a file in repository',
                              action: 'Delete a file',
                          },
                          {
                              name: 'Edit',
                              value: 'edit',
                              description: 'Edit a file in repository',
                              action: 'Edit a file',
                          },
                          {
                              name: 'Get',
                              value: 'get',
                              description: 'Get the data of a single file',
                              action: 'Get a file',
                          },
                          {
                              name: 'List',
                              value: 'list',
                              description: 'List contents of a folder',
                              action: 'List a file',
                          },
                      ],
                      default: 'create',
                  },
                  {
                      displayName: 'Operation',
                      name: 'operation',
                      type: 'options',
                      noDataExpression: true,
                      displayOptions: {
                          show: {
                              resource: ['repository'],
                          },
                      },
                      options: [
                          {
                              name: 'Get',
                              value: 'get',
                              description: 'Get the data of a single repository',
                              action: 'Get a repository',
                          },
                          {
                              name: 'Get Issues',
                              value: 'getIssues',
                              description: 'Returns issues of a repository',
                              action: 'Get issues of a repository',
                          },
                          {
                              name: 'Get License',
                              value: 'getLicense',
                              description: "Returns the contents of the repository's license file, if one is detected",
                              action: 'Get the license of a repository',
                          },
                          {
                              name: 'Get Profile',
                              value: 'getProfile',
                              description: 'Get the community profile of a repository with metrics, health score, description, license, etc',
                              action: 'Get the profile of a repository',
                          },
                          {
                              name: 'List Popular Paths',
                              value: 'listPopularPaths',
                              description: 'Get the top 10 popular content paths over the last 14 days',
                              action: 'List popular paths in a repository',
                          },
                          {
                              name: 'List Referrers',
                              value: 'listReferrers',
                              description: 'Get the top 10 referrering domains over the last 14 days',
                              action: 'List the top referrers of a repository',
                          },
                      ],
                      default: 'getIssues',
                  },
                  {
                      displayName: 'Operation',
                      name: 'operation',
                      type: 'options',
                      noDataExpression: true,
                      displayOptions: {
                          show: {
                              resource: ['user'],
                          },
                      },
                      options: [
                          {
                              name: 'Get Repositories',
                              value: 'getRepositories',
                              description: 'Returns the repositories of a user',
                              action: "Get a user's repositories",
                          },
                          {
                              name: 'Invite',
                              value: 'invite',
                              description: 'Invites a user to an organization',
                              action: 'Invite a user',
                          },
                      ],
                      default: 'getRepositories',
                  },
                  {
                      displayName: 'Operation',
                      name: 'operation',
                      type: 'options',
                      noDataExpression: true,
                      displayOptions: {
                          show: {
                              resource: ['release'],
                          },
                      },
                      options: [
                          {
                              name: 'Create',
                              value: 'create',
                              description: 'Creates a new release',
                              action: 'Create a release',
                          },
                          {
                              name: 'Delete',
                              value: 'delete',
                              description: 'Delete a release',
                              action: 'Delete a release',
                          },
                          {
                              name: 'Get',
                              value: 'get',
                              description: 'Get a release',
                              action: 'Get a release',
                          },
                          {
                              name: 'Get Many',
                              value: 'getAll',
                              description: 'Get many repository releases',
                              action: 'Get many releases',
                          },
                          {
                              name: 'Update',
                              value: 'update',
                              description: 'Update a release',
                              action: 'Update a release',
                          },
                      ],
                      default: 'create',
                  },
                  {
                      displayName: 'Operation',
                      name: 'operation',
                      type: 'options',
                      noDataExpression: true,
                      displayOptions: {
                          show: {
                              resource: ['review'],
                          },
                      },
                      options: [
                          {
                              name: 'Create',
                              value: 'create',
                              description: 'Creates a new review',
                              action: 'Create a review',
                          },
                          {
                              name: 'Get',
                              value: 'get',
                              description: 'Get a review for a pull request',
                              action: 'Get a review',
                          },
                          {
                              name: 'Get Many',
                              value: 'getAll',
                              description: 'Get many reviews for a pull request',
                              action: 'Get many reviews',
                          },
                          {
                              name: 'Update',
                              value: 'update',
                              description: 'Update a review',
                              action: 'Update a review',
                          },
                      ],
                      default: 'create',
                  },
                  {
                      displayName: 'Repository Owner',
                      name: 'owner',
                      type: 'resourceLocator',
                      default: { mode: 'list', value: '' },
                      required: true,
                      modes: [
                          {
                              displayName: 'Repository Owner',
                              name: 'list',
                              type: 'list',
                              placeholder: 'Select an owner...',
                              typeOptions: {
                                  searchListMethod: 'getUsers',
                                  searchable: true,
                                  searchFilterRequired: true,
                              },
                          },
                          {
                              displayName: 'Link',
                              name: 'url',
                              type: 'string',
                              placeholder: 'e.g. https://github.com/n8n-io',
                              extractValue: {
                                  type: 'regex',
                                  regex: 'https:\\/\\/github.com\\/([-_0-9a-zA-Z]+)',
                              },
                              validation: [
                                  {
                                      type: 'regex',
                                      properties: {
                                          regex: 'https:\\/\\/github.com\\/([-_0-9a-zA-Z]+)(?:.*)',
                                          errorMessage: 'Not a valid Github URL',
                                      },
                                  },
                              ],
                          },
                          {
                              displayName: 'By Name',
                              name: 'name',
                              type: 'string',
                              placeholder: 'e.g. n8n-io',
                              validation: [
                                  {
                                      type: 'regex',
                                      properties: {
                                          regex: '[-_a-zA-Z0-9]+',
                                          errorMessage: 'Not a valid Github Owner Name',
                                      },
                                  },
                              ],
                              url: '=https://github.com/{{$value}}',
                          },
                      ],
                      displayOptions: {
                          hide: {
                              operation: ['invite'],
                          },
                      },
                  },
                  {
                      displayName: 'Repository Name',
                      name: 'repository',
                      type: 'resourceLocator',
                      default: { mode: 'list', value: '' },
                      required: true,
                      modes: [
                          {
                              displayName: 'Repository Name',
                              name: 'list',
                              type: 'list',
                              placeholder: 'Select an Repository...',
                              typeOptions: {
                                  searchListMethod: 'getRepositories',
                                  searchable: true,
                              },
                          },
                          {
                              displayName: 'Link',
                              name: 'url',
                              type: 'string',
                              placeholder: 'e.g. https://github.com/n8n-io/n8n',
                              extractValue: {
                                  type: 'regex',
                                  regex: 'https:\\/\\/github.com\\/(?:[-_0-9a-zA-Z]+)\\/([-_.0-9a-zA-Z]+)',
                              },
                              validation: [
                                  {
                                      type: 'regex',
                                      properties: {
                                          regex: 'https:\\/\\/github.com\\/(?:[-_0-9a-zA-Z]+)\\/([-_.0-9a-zA-Z]+)(?:.*)',
                                          errorMessage: 'Not a valid Github Repository URL',
                                      },
                                  },
                              ],
                          },
                          {
                              displayName: 'By Name',
                              name: 'name',
                              type: 'string',
                              placeholder: 'e.g. n8n',
                              validation: [
                                  {
                                      type: 'regex',
                                      properties: {
                                          regex: '[-_.0-9a-zA-Z]+',
                                          errorMessage: 'Not a valid Github Repository Name',
                                      },
                                  },
                              ],
                              url: '=https://github.com/{{$parameter["owner"]}}/{{$value}}',
                          },
                      ],
                      displayOptions: {
                          hide: {
                              resource: ['user', 'organization'],
                              operation: ['getRepositories'],
                          },
                      },
                  },
                  {
                      displayName: 'File Path',
                      name: 'filePath',
                      type: 'string',
                      default: '',
                      required: true,
                      displayOptions: {
                          show: {
                              resource: ['file'],
                          },
                          hide: {
                              operation: ['list'],
                          },
                      },
                      placeholder: 'docs/README.md',
                      description: 'The file path of the file. Has to contain the full path.',
                  },
                  {
                      displayName: 'Path',
                      name: 'filePath',
                      type: 'string',
                      default: '',
                      displayOptions: {
                          show: {
                              resource: ['file'],
                              operation: ['list'],
                          },
                      },
                      placeholder: 'docs/',
                      description: 'The path of the folder to list',
                  },
                  {
                      displayName: 'Binary Data',
                      name: 'binaryData',
                      type: 'boolean',
                      default: false,
                      required: true,
                      displayOptions: {
                          show: {
                              operation: ['create', 'edit'],
                              resource: ['file'],
                          },
                      },
                      description: 'Whether the data to upload should be taken from binary field',
                  },
                  {
                      displayName: 'File Content',
                      name: 'fileContent',
                      type: 'string',
                      default: '',
                      required: true,
                      displayOptions: {
                          show: {
                              binaryData: [false],
                              operation: ['create', 'edit'],
                              resource: ['file'],
                          },
                      },
                      placeholder: '',
                      description: 'The text content of the file',
                  },
                  {
                      displayName: 'Binary Property',
                      name: 'binaryPropertyName',
                      type: 'string',
                      default: 'data',
                      required: true,
                      displayOptions: {
                          show: {
                              binaryData: [true],
                              operation: ['create', 'edit'],
                              resource: ['file'],
                          },
                      },
                      placeholder: '',
                      description: 'Name of the binary property which contains the data for the file',
                  },
                  {
                      displayName: 'Commit Message',
                      name: 'commitMessage',
                      type: 'string',
                      default: '',
                      required: true,
                      displayOptions: {
                          show: {
                              operation: ['create', 'delete', 'edit'],
                              resource: ['file'],
                          },
                      },
                  },
                  {
                      displayName: 'Additional Parameters',
                      name: 'additionalParameters',
                      placeholder: 'Add Parameter',
                      description: 'Additional fields to add',
                      type: 'fixedCollection',
                      default: {},
                      displayOptions: {
                          show: {
                              operation: ['create', 'delete', 'edit'],
                              resource: ['file'],
                          },
                      },
                      options: [
                          {
                              name: 'author',
                              displayName: 'Author',
                              values: [
                                  {
                                      displayName: 'Name',
                                      name: 'name',
                                      type: 'string',
                                      default: '',
                                      description: 'The name of the author of the commit',
                                  },
                                  {
                                      displayName: 'Email',
                                      name: 'email',
                                      type: 'string',
                                      placeholder: 'name@email.com',
                                      default: '',
                                      description: 'The email of the author of the commit',
                                  },
                              ],
                          },
                          {
                              name: 'branch',
                              displayName: 'Branch',
                              values: [
                                  {
                                      displayName: 'Branch',
                                      name: 'branch',
                                      type: 'string',
                                      default: '',
                                      description: 'The branch to commit to. If not set the repository’s default branch (usually master) is used.',
                                  },
                              ],
                          },
                          {
                              name: 'committer',
                              displayName: 'Committer',
                              values: [
                                  {
                                      displayName: 'Name',
                                      name: 'name',
                                      type: 'string',
                                      default: '',
                                      description: 'The name of the committer of the commit',
                                  },
                                  {
                                      displayName: 'Email',
                                      name: 'email',
                                      type: 'string',
                                      placeholder: 'name@email.com',
                                      default: '',
                                      description: 'The email of the committer of the commit',
                                  },
                              ],
                          },
                      ],
                  },
                  {
                      displayName: 'As Binary Property',
                      name: 'asBinaryProperty',
                      type: 'boolean',
                      default: true,
                      displayOptions: {
                          show: {
                              operation: ['get'],
                              resource: ['file'],
                          },
                      },
                      description: 'Whether to set the data of the file as binary property instead of returning the raw API response',
                  },
                  {
                      displayName: 'Binary Property',
                      name: 'binaryPropertyName',
                      type: 'string',
                      default: 'data',
                      required: true,
                      displayOptions: {
                          show: {
                              asBinaryProperty: [true],
                              operation: ['get'],
                              resource: ['file'],
                          },
                      },
                      placeholder: '',
                      description: 'Name of the binary property in which to save the binary data of the received file',
                  },
                  {
                      displayName: 'Additional Parameters',
                      name: 'additionalParameters',
                      placeholder: 'Add Parameter',
                      description: 'Additional fields to add',
                      type: 'collection',
                      default: {},
                      displayOptions: {
                          show: {
                              operation: ['get'],
                              resource: ['file'],
                          },
                      },
                      options: [
                          {
                              displayName: 'Reference',
                              name: 'reference',
                              type: 'string',
                              default: '',
                              placeholder: 'master',
                              description: 'The name of the commit/branch/tag. Default: the repository’s default branch (usually master).',
                          },
                      ],
                  },
                  {
                      displayName: 'Title',
                      name: 'title',
                      type: 'string',
                      default: '',
                      required: true,
                      displayOptions: {
                          show: {
                              operation: ['create'],
                              resource: ['issue'],
                          },
                      },
                      description: 'The title of the issue',
                  },
                  {
                      displayName: 'Body',
                      name: 'body',
                      type: 'string',
                      typeOptions: {
                          rows: 5,
                      },
                      default: '',
                      displayOptions: {
                          show: {
                              operation: ['create'],
                              resource: ['issue'],
                          },
                      },
                      description: 'The body of the issue',
                  },
                  {
                      displayName: 'Labels',
                      name: 'labels',
                      type: 'collection',
                      typeOptions: {
                          multipleValues: true,
                          multipleValueButtonText: 'Add Label',
                      },
                      displayOptions: {
                          show: {
                              operation: ['create'],
                              resource: ['issue'],
                          },
                      },
                      default: { label: '' },
                      options: [
                          {
                              displayName: 'Label',
                              name: 'label',
                              type: 'string',
                              default: '',
                              description: 'Label to add to issue',
                          },
                      ],
                  },
                  {
                      displayName: 'Assignees',
                      name: 'assignees',
                      type: 'collection',
                      typeOptions: {
                          multipleValues: true,
                          multipleValueButtonText: 'Add Assignee',
                      },
                      displayOptions: {
                          show: {
                              operation: ['create'],
                              resource: ['issue'],
                          },
                      },
                      default: { assignee: '' },
                      options: [
                          {
                              displayName: 'Assignee',
                              name: 'assignee',
                              type: 'string',
                              default: '',
                              description: 'User to assign issue too',
                          },
                      ],
                  },
                  {
                      displayName: 'Issue Number',
                      name: 'issueNumber',
                      type: 'number',
                      default: 0,
                      required: true,
                      displayOptions: {
                          show: {
                              operation: ['createComment'],
                              resource: ['issue'],
                          },
                      },
                      description: 'The number of the issue on which to create the comment on',
                  },
                  {
                      displayName: 'Body',
                      name: 'body',
                      type: 'string',
                      typeOptions: {
                          rows: 5,
                      },
                      displayOptions: {
                          show: {
                              operation: ['createComment'],
                              resource: ['issue'],
                          },
                      },
                      default: '',
                      description: 'The body of the comment',
                  },
                  {
                      displayName: 'Issue Number',
                      name: 'issueNumber',
                      type: 'number',
                      default: 0,
                      required: true,
                      displayOptions: {
                          show: {
                              operation: ['edit'],
                              resource: ['issue'],
                          },
                      },
                      description: 'The number of the issue edit',
                  },
                  {
                      displayName: 'Edit Fields',
                      name: 'editFields',
                      type: 'collection',
                      typeOptions: {
                          multipleValueButtonText: 'Add Field',
                      },
                      displayOptions: {
                          show: {
                              operation: ['edit'],
                              resource: ['issue'],
                          },
                      },
                      default: {},
                      options: [
                          {
                              displayName: 'Title',
                              name: 'title',
                              type: 'string',
                              default: '',
                              description: 'The title of the issue',
                          },
                          {
                              displayName: 'Body',
                              name: 'body',
                              type: 'string',
                              typeOptions: {
                                  rows: 5,
                              },
                              default: '',
                              description: 'The body of the issue',
                          },
                          {
                              displayName: 'State',
                              name: 'state',
                              type: 'options',
                              options: [
                                  {
                                      name: 'Closed',
                                      value: 'closed',
                                      description: 'Set the state to "closed"',
                                  },
                                  {
                                      name: 'Open',
                                      value: 'open',
                                      description: 'Set the state to "open"',
                                  },
                              ],
                              default: 'open',
                              description: 'The state to set',
                          },
                          {
                              displayName: 'Labels',
                              name: 'labels',
                              type: 'collection',
                              typeOptions: {
                                  multipleValues: true,
                                  multipleValueButtonText: 'Add Label',
                              },
                              default: { label: '' },
                              options: [
                                  {
                                      displayName: 'Label',
                                      name: 'label',
                                      type: 'string',
                                      default: '',
                                      description: 'Label to add to issue',
                                  },
                              ],
                          },
                          {
                              displayName: 'Assignees',
                              name: 'assignees',
                              type: 'collection',
                              typeOptions: {
                                  multipleValues: true,
                                  multipleValueButtonText: 'Add Assignee',
                              },
                              default: { assignee: '' },
                              options: [
                                  {
                                      displayName: 'Assignees',
                                      name: 'assignee',
                                      type: 'string',
                                      default: '',
                                      description: 'User to assign issue to',
                                  },
                              ],
                          },
                      ],
                  },
                  {
                      displayName: 'Issue Number',
                      name: 'issueNumber',
                      type: 'number',
                      default: 0,
                      required: true,
                      displayOptions: {
                          show: {
                              operation: ['get'],
                              resource: ['issue'],
                          },
                      },
                      description: 'The number of the issue get data of',
                  },
                  {
                      displayName: 'Issue Number',
                      name: 'issueNumber',
                      type: 'number',
                      default: 0,
                      required: true,
                      displayOptions: {
                          show: {
                              operation: ['lock'],
                              resource: ['issue'],
                          },
                      },
                      description: 'The number of the issue to lock',
                  },
                  {
                      displayName: 'Lock Reason',
                      name: 'lockReason',
                      type: 'options',
                      displayOptions: {
                          show: {
                              operation: ['lock'],
                              resource: ['issue'],
                          },
                      },
                      options: [
                          {
                              name: 'Off-Topic',
                              value: 'off-topic',
                              description: 'The issue is Off-Topic',
                          },
                          {
                              name: 'Too Heated',
                              value: 'too heated',
                              description: 'The discussion is too heated',
                          },
                          {
                              name: 'Resolved',
                              value: 'resolved',
                              description: 'The issue got resolved',
                          },
                          {
                              name: 'Spam',
                              value: 'spam',
                              description: 'The issue is spam',
                          },
                      ],
                      default: 'resolved',
                      description: 'The reason to lock the issue',
                  },
                  {
                      displayName: 'Tag',
                      name: 'releaseTag',
                      type: 'string',
                      default: '',
                      required: true,
                      displayOptions: {
                          show: {
                              operation: ['create'],
                              resource: ['release'],
                          },
                      },
                      description: 'The tag of the release',
                  },
                  {
                      displayName: 'Additional Fields',
                      name: 'additionalFields',
                      type: 'collection',
                      typeOptions: {
                          multipleValueButtonText: 'Add Field',
                      },
                      displayOptions: {
                          show: {
                              operation: ['create'],
                              resource: ['release'],
                          },
                      },
                      default: {},
                      options: [
                          {
                              displayName: 'Name',
                              name: 'name',
                              type: 'string',
                              default: '',
                              description: 'The name of the issue',
                          },
                          {
                              displayName: 'Body',
                              name: 'body',
                              type: 'string',
                              typeOptions: {
                                  rows: 5,
                              },
                              default: '',
                              description: 'The body of the release',
                          },
                          {
                              displayName: 'Draft',
                              name: 'draft',
                              type: 'boolean',
                              default: false,
                              description: 'Whether to create a draft (unpublished) release, "false" to create a published one',
                          },
                          {
                              displayName: 'Prerelease',
                              name: 'prerelease',
                              type: 'boolean',
                              default: false,
                              description: 'Whether to point out that the release is non-production ready',
                          },
                          {
                              displayName: 'Target Commitish',
                              name: 'target_commitish',
                              type: 'string',
                              default: '',
                              description: "Specifies the commitish value that determines where the Git tag is created from. Can be any branch or commit SHA. Unused if the Git tag already exists. Default: the repository's default branch(usually master).",
                          },
                      ],
                  },
                  {
                      displayName: 'Release ID',
                      name: 'release_id',
                      type: 'string',
                      default: '',
                      required: true,
                      displayOptions: {
                          show: {
                              resource: ['release'],
                              operation: ['get', 'delete', 'update'],
                          },
                      },
                  },
                  {
                      displayName: 'Additional Fields',
                      name: 'additionalFields',
                      type: 'collection',
                      typeOptions: {
                          multipleValueButtonText: 'Add Field',
                      },
                      displayOptions: {
                          show: {
                              operation: ['update'],
                              resource: ['release'],
                          },
                      },
                      default: {},
                      options: [
                          {
                              displayName: 'Body',
                              name: 'body',
                              type: 'string',
                              typeOptions: {
                                  rows: 5,
                              },
                              default: '',
                              description: 'The body of the release',
                          },
                          {
                              displayName: 'Draft',
                              name: 'draft',
                              type: 'boolean',
                              default: false,
                              description: 'Whether to create a draft (unpublished) release, "false" to create a published one',
                          },
                          {
                              displayName: 'Name',
                              name: 'name',
                              type: 'string',
                              default: '',
                              description: 'The name of the release',
                          },
                          {
                              displayName: 'Prerelease',
                              name: 'prerelease',
                              type: 'boolean',
                              default: false,
                              description: 'Whether to point out that the release is non-production ready',
                          },
                          {
                              displayName: 'Tag Name',
                              name: 'tag_name',
                              type: 'string',
                              default: '',
                              description: 'The name of the tag',
                          },
                          {
                              displayName: 'Target Commitish',
                              name: 'target_commitish',
                              type: 'string',
                              default: '',
                              description: "Specifies the commitish value that determines where the Git tag is created from. Can be any branch or commit SHA. Unused if the Git tag already exists. Default: the repository's default branch(usually master).",
                          },
                      ],
                  },
                  {
                      displayName: 'Return All',
                      name: 'returnAll',
                      type: 'boolean',
                      displayOptions: {
                          show: {
                              resource: ['release'],
                              operation: ['getAll'],
                          },
                      },
                      default: false,
                      description: 'Whether to return all results or only up to a given limit',
                  },
                  {
                      displayName: 'Limit',
                      name: 'limit',
                      type: 'number',
                      displayOptions: {
                          show: {
                              resource: ['release'],
                              operation: ['getAll'],
                              returnAll: [false],
                          },
                      },
                      typeOptions: {
                          minValue: 1,
                          maxValue: 100,
                      },
                      default: 50,
                      description: 'Max number of results to return',
                  },
                  {
                      displayName: 'Return All',
                      name: 'returnAll',
                      type: 'boolean',
                      displayOptions: {
                          show: {
                              resource: ['repository'],
                              operation: ['getIssues'],
                          },
                      },
                      default: false,
                      description: 'Whether to return all results or only up to a given limit',
                  },
                  {
                      displayName: 'Limit',
                      name: 'limit',
                      type: 'number',
                      displayOptions: {
                          show: {
                              resource: ['repository'],
                              operation: ['getIssues'],
                              returnAll: [false],
                          },
                      },
                      typeOptions: {
                          minValue: 1,
                          maxValue: 100,
                      },
                      default: 50,
                      description: 'Max number of results to return',
                  },
                  {
                      displayName: 'Filters',
                      name: 'getRepositoryIssuesFilters',
                      type: 'collection',
                      typeOptions: {
                          multipleValueButtonText: 'Add Filter',
                      },
                      displayOptions: {
                          show: {
                              operation: ['getIssues'],
                              resource: ['repository'],
                          },
                      },
                      default: {},
                      options: [
                          {
                              displayName: 'Assignee',
                              name: 'assignee',
                              type: 'string',
                              default: '',
                              description: 'Return only issues which are assigned to a specific user',
                          },
                          {
                              displayName: 'Creator',
                              name: 'creator',
                              type: 'string',
                              default: '',
                              description: 'Return only issues which were created by a specific user',
                          },
                          {
                              displayName: 'Mentioned',
                              name: 'mentioned',
                              type: 'string',
                              default: '',
                              description: 'Return only issues in which a specific user was mentioned',
                          },
                          {
                              displayName: 'Labels',
                              name: 'labels',
                              type: 'string',
                              default: '',
                              description: 'Return only issues with the given labels. Multiple lables can be separated by comma.',
                          },
                          {
                              displayName: 'Updated Since',
                              name: 'since',
                              type: 'dateTime',
                              default: '',
                              description: 'Return only issues updated at or after this time',
                          },
                          {
                              displayName: 'State',
                              name: 'state',
                              type: 'options',
                              options: [
                                  {
                                      name: 'All',
                                      value: 'all',
                                      description: 'Returns issues with any state',
                                  },
                                  {
                                      name: 'Closed',
                                      value: 'closed',
                                      description: 'Return issues with "closed" state',
                                  },
                                  {
                                      name: 'Open',
                                      value: 'open',
                                      description: 'Return issues with "open" state',
                                  },
                              ],
                              default: 'open',
                              description: 'The state to set',
                          },
                          {
                              displayName: 'Sort',
                              name: 'sort',
                              type: 'options',
                              options: [
                                  {
                                      name: 'Created',
                                      value: 'created',
                                      description: 'Sort by created date',
                                  },
                                  {
                                      name: 'Updated',
                                      value: 'updated',
                                      description: 'Sort by updated date',
                                  },
                                  {
                                      name: 'Comments',
                                      value: 'comments',
                                      description: 'Sort by comments',
                                  },
                              ],
                              default: 'created',
                              description: 'The order the issues should be returned in',
                          },
                          {
                              displayName: 'Direction',
                              name: 'direction',
                              type: 'options',
                              options: [
                                  {
                                      name: 'Ascending',
                                      value: 'asc',
                                      description: 'Sort in ascending order',
                                  },
                                  {
                                      name: 'Descending',
                                      value: 'desc',
                                      description: 'Sort in descending order',
                                  },
                              ],
                              default: 'desc',
                              description: 'The sort order',
                          },
                      ],
                  },
                  {
                      displayName: 'PR Number',
                      name: 'pullRequestNumber',
                      type: 'number',
                      default: 0,
                      required: true,
                      displayOptions: {
                          show: {
                              operation: ['get', 'update'],
                              resource: ['review'],
                          },
                      },
                      description: 'The number of the pull request',
                  },
                  {
                      displayName: 'Review ID',
                      name: 'reviewId',
                      type: 'string',
                      default: '',
                      required: true,
                      displayOptions: {
                          show: {
                              operation: ['get', 'update'],
                              resource: ['review'],
                          },
                      },
                      description: 'ID of the review',
                  },
                  {
                      displayName: 'PR Number',
                      name: 'pullRequestNumber',
                      type: 'number',
                      default: 0,
                      required: true,
                      displayOptions: {
                          show: {
                              operation: ['getAll'],
                              resource: ['review'],
                          },
                      },
                      description: 'The number of the pull request',
                  },
                  {
                      displayName: 'Return All',
                      name: 'returnAll',
                      type: 'boolean',
                      displayOptions: {
                          show: {
                              resource: ['review'],
                              operation: ['getAll'],
                          },
                      },
                      default: false,
                      description: 'Whether to return all results or only up to a given limit',
                  },
                  {
                      displayName: 'Limit',
                      name: 'limit',
                      type: 'number',
                      displayOptions: {
                          show: {
                              resource: ['review'],
                              operation: ['getAll'],
                              returnAll: [false],
                          },
                      },
                      typeOptions: {
                          minValue: 1,
                          maxValue: 100,
                      },
                      default: 50,
                      description: 'Max number of results to return',
                  },
                  {
                      displayName: 'PR Number',
                      name: 'pullRequestNumber',
                      type: 'number',
                      default: 0,
                      required: true,
                      displayOptions: {
                          show: {
                              operation: ['create'],
                              resource: ['review'],
                          },
                      },
                      description: 'The number of the pull request to review',
                  },
                  {
                      displayName: 'Event',
                      name: 'event',
                      type: 'options',
                      displayOptions: {
                          show: {
                              operation: ['create'],
                              resource: ['review'],
                          },
                      },
                      options: [
                          {
                              name: 'Approve',
                              value: 'approve',
                              description: 'Approve the pull request',
                          },
                          {
                              name: 'Request Change',
                              value: 'requestChanges',
                              description: 'Request code changes',
                          },
                          {
                              name: 'Comment',
                              value: 'comment',
                              description: 'Add a comment without approval or change requests',
                          },
                          {
                              name: 'Pending',
                              value: 'pending',
                              description: 'You will need to submit the pull request review when you are ready',
                          },
                      ],
                      default: 'approve',
                      description: 'The review action you want to perform',
                  },
                  {
                      displayName: 'Body',
                      name: 'body',
                      type: 'string',
                      displayOptions: {
                          show: {
                              operation: ['create'],
                              resource: ['review'],
                              event: ['requestChanges', 'comment'],
                          },
                      },
                      default: '',
                      description: 'The body of the review (required for events Request Changes or Comment)',
                  },
                  {
                      displayName: 'Additional Fields',
                      name: 'additionalFields',
                      placeholder: 'Add Field',
                      type: 'collection',
                      default: {},
                      displayOptions: {
                          show: {
                              operation: ['create'],
                              resource: ['review'],
                          },
                      },
                      options: [
                          {
                              displayName: 'Commit ID',
                              name: 'commitId',
                              type: 'string',
                              default: '',
                              description: 'The SHA of the commit that needs a review, if different from the latest',
                          },
                      ],
                  },
                  {
                      displayName: 'Body',
                      name: 'body',
                      type: 'string',
                      displayOptions: {
                          show: {
                              operation: ['update'],
                              resource: ['review'],
                          },
                      },
                      default: '',
                      description: 'The body of the review',
                  },
                  {
                      displayName: 'Return All',
                      name: 'returnAll',
                      type: 'boolean',
                      displayOptions: {
                          show: {
                              resource: ['user'],
                              operation: ['getRepositories'],
                          },
                      },
                      default: false,
                      description: 'Whether to return all results or only up to a given limit',
                  },
                  {
                      displayName: 'Limit',
                      name: 'limit',
                      type: 'number',
                      displayOptions: {
                          show: {
                              resource: ['user'],
                              operation: ['getRepositories'],
                              returnAll: [false],
                          },
                      },
                      typeOptions: {
                          minValue: 1,
                          maxValue: 100,
                      },
                      default: 50,
                      description: 'Max number of results to return',
                  },
                  {
                      displayName: 'Organization',
                      name: 'organization',
                      type: 'string',
                      default: '',
                      required: true,
                      displayOptions: {
                          show: {
                              operation: ['invite'],
                              resource: ['user'],
                          },
                      },
                      description: 'The GitHub organization that the user is being invited to',
                  },
                  {
                      displayName: 'Email',
                      name: 'email',
                      type: 'string',
                      placeholder: 'name@email.com',
                      default: '',
                      required: true,
                      displayOptions: {
                          show: {
                              operation: ['invite'],
                              resource: ['user'],
                          },
                      },
                      description: 'The email address of the invited user',
                  },
                  {
                      displayName: 'Return All',
                      name: 'returnAll',
                      type: 'boolean',
                      displayOptions: {
                          show: {
                              resource: ['organization'],
                              operation: ['getRepositories'],
                          },
                      },
                      default: false,
                      description: 'Whether to return all results or only up to a given limit',
                  },
                  {
                      displayName: 'Limit',
                      name: 'limit',
                      type: 'number',
                      displayOptions: {
                          show: {
                              resource: ['organization'],
                              operation: ['getRepositories'],
                              returnAll: [false],
                          },
                      },
                      typeOptions: {
                          minValue: 1,
                          maxValue: 100,
                      },
                      default: 50,
                      description: 'Max number of results to return',
                  },
              ],
          };
          this.methods = {
              listSearch: {
                  getUsers: SearchFunctions_1.getUsers,
                  getRepositories: SearchFunctions_1.getRepositories,
              },
          };
      }
      async execute() {
          const items = this.getInputData();
          const returnData = [];
          let returnAll = false;
          let responseData;
          const overwriteDataOperations = [
              'file:create',
              'file:delete',
              'file:edit',
              'file:get',
              'issue:create',
              'issue:createComment',
              'issue:edit',
              'issue:get',
              'release:create',
              'release:delete',
              'release:get',
              'release:update',
              'repository:get',
              'repository:getLicense',
              'repository:getProfile',
              'review:create',
              'review:get',
              'review:update',
              'user:invite',
          ];
          const overwriteDataOperationsArray = [
              'file:list',
              'repository:getIssues',
              'repository:listPopularPaths',
              'repository:listReferrers',
              'user:getRepositories',
              'release:getAll',
              'review:getAll',
              'organization:getRepositories',
          ];
          let body;
          let qs;
          let requestMethod;
          let endpoint;
          const operation = this.getNodeParameter('operation', 0);
          const resource = this.getNodeParameter('resource', 0);
          const fullOperation = `${resource}:${operation}`;
          for (let i = 0; i < items.length; i++) {
              try {
                  requestMethod = 'GET';
                  endpoint = '';
                  body = {};
                  qs = {};
                  let owner = '';
                  if (fullOperation !== 'user:invite') {
                      owner = this.getNodeParameter('owner', i, '', { extractValue: true });
                  }
                  let repository = '';
                  if (fullOperation !== 'user:getRepositories' &&
                      fullOperation !== 'user:invite' &&
                      fullOperation !== 'organization:getRepositories') {
                      repository = this.getNodeParameter('repository', i, '', { extractValue: true });
                  }
                  if (resource === 'file') {
                      if (['create', 'edit'].includes(operation)) {
                          requestMethod = 'PUT';
                          const filePath = this.getNodeParameter('filePath', i);
                          const additionalParameters = this.getNodeParameter('additionalParameters', i, {});
                          if (additionalParameters.author) {
                              body.author = additionalParameters.author;
                          }
                          if (additionalParameters.committer) {
                              body.committer = additionalParameters.committer;
                          }
                          if (additionalParameters.branch &&
                              additionalParameters.branch.branch) {
                              body.branch = additionalParameters.branch.branch;
                          }
                          if (operation === 'edit') {
                              body.sha = await GenericFunctions_1.getFileSha.call(this, owner, repository, filePath, body.branch);
                          }
                          body.message = this.getNodeParameter('commitMessage', i);
                          if (this.getNodeParameter('binaryData', i)) {
                              const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
                              const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName);
                              body.content = binaryData.data;
                          }
                          else {
                              body.content = Buffer.from(this.getNodeParameter('fileContent', i)).toString('base64');
                          }
                          endpoint = `/repos/${owner}/${repository}/contents/${encodeURI(filePath)}`;
                      }
                      else if (operation === 'delete') {
                          requestMethod = 'DELETE';
                          const additionalParameters = this.getNodeParameter('additionalParameters', i, {});
                          if (additionalParameters.author) {
                              body.author = additionalParameters.author;
                          }
                          if (additionalParameters.committer) {
                              body.committer = additionalParameters.committer;
                          }
                          if (additionalParameters.branch &&
                              additionalParameters.branch.branch) {
                              body.branch = additionalParameters.branch.branch;
                          }
                          const filePath = this.getNodeParameter('filePath', i);
                          body.message = this.getNodeParameter('commitMessage', i);
                          body.sha = await GenericFunctions_1.getFileSha.call(this, owner, repository, filePath, body.branch);
                          endpoint = `/repos/${owner}/${repository}/contents/${encodeURI(filePath)}`;
                      }
                      else if (operation === 'get') {
                          requestMethod = 'GET';
                          const filePath = this.getNodeParameter('filePath', i);
                          const additionalParameters = this.getNodeParameter('additionalParameters', i);
                          if (additionalParameters.reference) {
                              qs.ref = additionalParameters.reference;
                          }
                          endpoint = `/repos/${owner}/${repository}/contents/${encodeURI(filePath)}`;
                      }
                      else if (operation === 'list') {
                          requestMethod = 'GET';
                          const filePath = this.getNodeParameter('filePath', i);
                          endpoint = `/repos/${owner}/${repository}/contents/${encodeURI(filePath)}`;
                      }
                  }
                  else if (resource === 'issue') {
                      if (operation === 'create') {
                          requestMethod = 'POST';
                          body.title = this.getNodeParameter('title', i);
                          body.body = this.getNodeParameter('body', i);
                          const labels = this.getNodeParameter('labels', i);
                          const assignees = this.getNodeParameter('assignees', i);
                          body.labels = labels.map((data) => data.label);
                          body.assignees = assignees.map((data) => data.assignee);
                          endpoint = `/repos/${owner}/${repository}/issues`;
                      }
                      else if (operation === 'createComment') {
                          requestMethod = 'POST';
                          const issueNumber = this.getNodeParameter('issueNumber', i);
                          body.body = this.getNodeParameter('body', i);
                          endpoint = `/repos/${owner}/${repository}/issues/${issueNumber}/comments`;
                      }
                      else if (operation === 'edit') {
                          requestMethod = 'PATCH';
                          const issueNumber = this.getNodeParameter('issueNumber', i);
                          body = this.getNodeParameter('editFields', i, {});
                          if (body.labels !== undefined) {
                              body.labels = body.labels.map((data) => data.label);
                          }
                          if (body.assignees !== undefined) {
                              body.assignees = body.assignees.map((data) => data.assignee);
                          }
                          endpoint = `/repos/${owner}/${repository}/issues/${issueNumber}`;
                      }
                      else if (operation === 'get') {
                          requestMethod = 'GET';
                          const issueNumber = this.getNodeParameter('issueNumber', i);
                          endpoint = `/repos/${owner}/${repository}/issues/${issueNumber}`;
                      }
                      else if (operation === 'lock') {
                          requestMethod = 'PUT';
                          const issueNumber = this.getNodeParameter('issueNumber', i);
                          qs.lock_reason = this.getNodeParameter('lockReason', i);
                          endpoint = `/repos/${owner}/${repository}/issues/${issueNumber}/lock`;
                      }
                  }
                  else if (resource === 'release') {
                      if (operation === 'create') {
                          requestMethod = 'POST';
                          body = this.getNodeParameter('additionalFields', i, {});
                          body.tag_name = this.getNodeParameter('releaseTag', i);
                          endpoint = `/repos/${owner}/${repository}/releases`;
                      }
                      if (operation === 'delete') {
                          requestMethod = 'DELETE';
                          const releaseId = this.getNodeParameter('release_id', i);
                          endpoint = `/repos/${owner}/${repository}/releases/${releaseId}`;
                      }
                      if (operation === 'get') {
                          requestMethod = 'GET';
                          const releaseId = this.getNodeParameter('release_id', i);
                          endpoint = `/repos/${owner}/${repository}/releases/${releaseId}`;
                      }
                      if (operation === 'getAll') {
                          requestMethod = 'GET';
                          endpoint = `/repos/${owner}/${repository}/releases`;
                          returnAll = this.getNodeParameter('returnAll', 0);
                          if (!returnAll) {
                              qs.per_page = this.getNodeParameter('limit', 0);
                          }
                      }
                      if (operation === 'update') {
                          requestMethod = 'PATCH';
                          const releaseId = this.getNodeParameter('release_id', i);
                          body = this.getNodeParameter('additionalFields', i, {});
                          endpoint = `/repos/${owner}/${repository}/releases/${releaseId}`;
                      }
                  }
                  else if (resource === 'repository') {
                      if (operation === 'listPopularPaths') {
                          requestMethod = 'GET';
                          endpoint = `/repos/${owner}/${repository}/traffic/popular/paths`;
                      }
                      else if (operation === 'listReferrers') {
                          requestMethod = 'GET';
                          endpoint = `/repos/${owner}/${repository}/traffic/popular/referrers`;
                      }
                      else if (operation === 'get') {
                          requestMethod = 'GET';
                          endpoint = `/repos/${owner}/${repository}`;
                      }
                      else if (operation === 'getLicense') {
                          requestMethod = 'GET';
                          endpoint = `/repos/${owner}/${repository}/license`;
                      }
                      else if (operation === 'getIssues') {
                          requestMethod = 'GET';
                          qs = this.getNodeParameter('getRepositoryIssuesFilters', i);
                          endpoint = `/repos/${owner}/${repository}/issues`;
                          returnAll = this.getNodeParameter('returnAll', 0);
                          if (!returnAll) {
                              qs.per_page = this.getNodeParameter('limit', 0);
                          }
                      }
                  }
                  else if (resource === 'review') {
                      if (operation === 'get') {
                          requestMethod = 'GET';
                          const reviewId = this.getNodeParameter('reviewId', i);
                          const pullRequestNumber = this.getNodeParameter('pullRequestNumber', i);
                          endpoint = `/repos/${owner}/${repository}/pulls/${pullRequestNumber}/reviews/${reviewId}`;
                      }
                      else if (operation === 'getAll') {
                          requestMethod = 'GET';
                          returnAll = this.getNodeParameter('returnAll', 0);
                          const pullRequestNumber = this.getNodeParameter('pullRequestNumber', i);
                          if (!returnAll) {
                              qs.per_page = this.getNodeParameter('limit', 0);
                          }
                          endpoint = `/repos/${owner}/${repository}/pulls/${pullRequestNumber}/reviews`;
                      }
                      else if (operation === 'create') {
                          requestMethod = 'POST';
                          const pullRequestNumber = this.getNodeParameter('pullRequestNumber', i);
                          const additionalFields = this.getNodeParameter('additionalFields', i);
                          Object.assign(body, additionalFields);
                          body.event = (0, change_case_1.snakeCase)(this.getNodeParameter('event', i)).toUpperCase();
                          if (body.event === 'REQUEST_CHANGES' || body.event === 'COMMENT') {
                              body.body = this.getNodeParameter('body', i);
                          }
                          endpoint = `/repos/${owner}/${repository}/pulls/${pullRequestNumber}/reviews`;
                      }
                      else if (operation === 'update') {
                          requestMethod = 'PUT';
                          const pullRequestNumber = this.getNodeParameter('pullRequestNumber', i);
                          const reviewId = this.getNodeParameter('reviewId', i);
                          body.body = this.getNodeParameter('body', i);
                          endpoint = `/repos/${owner}/${repository}/pulls/${pullRequestNumber}/reviews/${reviewId}`;
                      }
                  }
                  else if (resource === 'user') {
                      if (operation === 'getRepositories') {
                          requestMethod = 'GET';
                          endpoint = `/users/${owner}/repos`;
                          returnAll = this.getNodeParameter('returnAll', 0);
                          if (!returnAll) {
                              qs.per_page = this.getNodeParameter('limit', 0);
                          }
                      }
                      else if (operation === 'invite') {
                          requestMethod = 'POST';
                          const org = this.getNodeParameter('organization', i);
                          endpoint = `/orgs/${org}/invitations`;
                          body.email = this.getNodeParameter('email', i);
                      }
                  }
                  else if (resource === 'organization') {
                      if (operation === 'getRepositories') {
                          requestMethod = 'GET';
                          endpoint = `/orgs/${owner}/repos`;
                          returnAll = this.getNodeParameter('returnAll', 0);
                          if (!returnAll) {
                              qs.per_page = this.getNodeParameter('limit', 0);
                          }
                      }
                  }
                  else {
                      throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`, {
                          itemIndex: i,
                      });
                  }
                  const asBinaryProperty = this.getNodeParameter('asBinaryProperty', i, false);
                  if (returnAll) {
                      responseData = await GenericFunctions_1.githubApiRequestAllItems.call(this, requestMethod, endpoint, body, qs);
                  }
                  else {
                      responseData = await GenericFunctions_1.githubApiRequest.call(this, requestMethod, endpoint, body, qs);
                  }
                  if (fullOperation === 'file:get') {
                      if (asBinaryProperty) {
                          if (Array.isArray(responseData) && responseData.length > 1) {
                              throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'File Path is a folder, not a file.', {
                                  itemIndex: i,
                              });
                          }
                          const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
                          const newItem = {
                              json: items[i].json,
                              binary: {},
                          };
                          if (items[i].binary !== undefined) {
                              Object.assign(newItem.binary, items[i].binary);
                          }
                          const { content, path } = responseData;
                          newItem.binary[binaryPropertyName] = await this.helpers.prepareBinaryData(Buffer.from(content, 'base64'), path);
                          items[i] = newItem;
                          return [items];
                      }
                  }
                  if (fullOperation === 'release:delete') {
                      responseData = { success: true };
                  }
                  if (overwriteDataOperations.includes(fullOperation) ||
                      overwriteDataOperationsArray.includes(fullOperation)) {
                      const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
                      returnData.push(...executionData);
                  }
              }
              catch (error) {
                  if (this.continueOnFail()) {
                      if (overwriteDataOperations.includes(fullOperation) ||
                          overwriteDataOperationsArray.includes(fullOperation)) {
                          const executionErrorData = this.helpers.constructExecutionMetaData([
                              {
                                  json: {
                                      error: error.message,
                                  },
                              },
                          ], { itemData: { item: i } });
                          returnData.push(...executionErrorData);
                      }
                      else {
                          items[i].json = { error: error.message };
                      }
                      continue;
                  }
                  throw error;
              }
          }
          if (overwriteDataOperations.includes(fullOperation) ||
              overwriteDataOperationsArray.includes(fullOperation)) {
              return [returnData];
          }
          else {
              return [items];
          }
      }
  }
  exports.Github = Github;
  //# sourceMappingURL=Github.node.js.map

documentation_markdown:
  ---
  #https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
  title: GitHub credentials
  description: Documentation for GitHub credentials. Use these credentials to authenticate GitHub in n8n, a workflow automation platform.
  contentType: [integration, reference]
  priority: medium
  ---

  # GitHub credentials

  You can use these credentials to authenticate the following nodes:

  - [GitHub](/integrations/builtin/app-nodes/n8n-nodes-base.github.md)
  - [GitHub Trigger](/integrations/builtin/trigger-nodes/n8n-nodes-base.githubtrigger.md)
  - [GitHub Document Loader](/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.documentgithubloader.md): this node doesn't support OAuth.

  ## Prerequisites

  Create a [GitHub](https://github.com/){:target=_blank .external-link} account.

  ## Supported authentication methods

  - API access token: Use this method with any GitHub nodes.
  - OAuth2: Use this method with [GitHub](/integrations/builtin/app-nodes/n8n-nodes-base.github.md) and [GitHub Trigger](/integrations/builtin/trigger-nodes/n8n-nodes-base.githubtrigger.md) nodes only; don't use with [GitHub Document Loader](/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.documentgithubloader.md).

  ## Related resources

  Refer to [GitHub's API documentation](https://docs.github.com/en/rest){:target=_blank .external-link} for more information about the service.

  ## Using API access token

  To configure this credential, you'll need a [GitHub](https://github.com/){:target=_blank .external-link} account.

  There are two steps to setting up this credential:

  1. [Generate a GitHub personal access token](#generate-personal-access-token).
  2. [Set up the credential](#set-up-the-credential).

  Refer to the sections below for detailed instructions.

  ### Generate personal access token

  /// note | Recommended access token type
  n8n recommends using a personal access token (classic). GitHub's fine-grained personal access tokens are still in beta and can't access all endpoints.
  ///

  To generate your personal access token:

  1. If you haven't done so already, verify your email address with GitHub. Refer to [Verifying your email address](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-email-preferences/verifying-your-email-address){:target=_blank .external-link} for more information.
  2. Open your GitHub profile [Settings](https://github.com/settings/profile){:target=_blank .external-link}.
  3. In the left navigation, select [**Developer settings**](https://github.com/settings/apps){:target=_blank .external-link}.
  4. In the left navigation, under **Personal access tokens**, select **Tokens (classic)**.
  5. Select **Generate new token > Generate new token (classic)**.
  6. Enter a descriptive name for your token in the **Note** field, like `n8n integration`.
  7. Select the **Expiration** you'd like for the token, or select **No expiration**.
  8. Select **Scopes** for your token. For most of the n8n GitHub nodes, add the `repo` scope.
      - A token without assigned scopes can only access public information.
      - Refer to 
  9. Select **Generate token**.
  10. Copy the token.

  Refer to [Creating a personal access token (classic)](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic){:target=_blank .external-link} for more information. Refer to [Scopes for OAuth apps](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps#available-scopes){:target=_blank .external-link} for more information on GitHub scopes.

  ### Set up the credential

  Then, in your n8n credential:

  1. If you aren't using GitHub Enterprise Server, don't change the **GitHub server** URL.
      - If you're using [GitHub Enterprise Server](https://docs.github.com/en/enterprise-server@3.9/admin/overview/about-github-enterprise-server){:target=_blank .external-link}, update **GitHub server** to match the URL for your server.
  2. Enter your **User** name as it appears in your GitHub profile.
  3. Enter the **Access Token** you generated above.

  ## Using OAuth2

  --8<-- "_snippets/integrations/builtin/credentials/cloud-oauth-button.md"

  If you're [self-hosting n8n](/hosting/index.md), create a new GitHub [OAuth app](https://docs.github.com/en/apps/oauth-apps){:target=_blank .external-link}:

  1. Open your GitHub profile [Settings](https://github.com/settings/profile){:target=_blank .external-link}.
  2. In the left navigation, select [**Developer settings**](https://github.com/settings/apps){:target=_blank .external-link}.
  3. In the left navigation, select **OAuth apps**.
  4. Select **New OAuth App**.
      - If you haven't created an app before, you may see **Register a new application** instead. Select it.
  5. Enter an **Application name**, like `n8n integration`.
  6. Enter the **Homepage URL** for your app's website.
  7. If you'd like, add the optional **Application description**, which GitHub displays to end-users.
  8. From n8n, copy the **OAuth Redirect URL** and paste it into the GitHub **Authorization callback URL**.
  9. Select **Register application**.
  10. Copy the **Client ID** and **Client Secret** this generates and add them to your n8n credential.

  Refer to the [GitHub Authorizing OAuth apps documentation](https://docs.github.com/en/apps/oauth-apps/using-oauth-apps/authorizing-oauth-apps){:target=_blank .external-link} for more information on the authorization process.

example_workflow:
  {"nodes":[{"parameters":{},"type":"n8n-nodes-base.node","typeVersion":1,"position":[220,120],"id":"ecf87377-40cb-4489-a1f5-ab803f4ff522","name":"Node"}],"connections":{"Node":{"main":[[]]}},"pinData":{},"meta":{"templateCredsSetupCompleted":true,"instanceId":"c21a9e1f0def80609945f6ae2545f79b7090214fd399ad12fc1a200e736dae4e"}}


