@tuanltntu/n8n-nodes-bitrix24
Version:
Comprehensive n8n community node for Bitrix24 API integration with CRM, Tasks, Chat, Telephony, and more
240 lines • 10.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DirectApiResourceHandler = void 0;
const n8n_workflow_1 = require("n8n-workflow");
const ResourceHandlerBase_1 = require("./ResourceHandlerBase");
/**
* Handler for Direct API
* Allows direct calls to any Bitrix24 API endpoint
*/
class DirectApiResourceHandler extends ResourceHandlerBase_1.ResourceHandlerBase {
constructor(executeFunctions, returnData, options = {}) {
super(executeFunctions, returnData, options);
}
/**
* Handle pagination for Direct API list operations
*/
async handleDirectApiPagination(endpoint, baseBody, itemIndex, maxPages) {
let allResults = [];
let pageCount = 0;
let start = 0;
while (pageCount < maxPages) {
const body = { ...baseBody };
body.start = start;
body.limit = 50;
try {
const response = await this.makeApiCall(endpoint, body, {}, itemIndex);
if (response && response.result) {
// Extract data from response - if result has nested property, use it; otherwise use result directly
let results;
if (typeof response.result === "object" &&
!Array.isArray(response.result)) {
// Find first array property in result
const resultKeys = Object.keys(response.result);
const arrayProperty = resultKeys.find((key) => Array.isArray(response.result[key]));
results = arrayProperty ? response.result[arrayProperty] : [];
}
else if (Array.isArray(response.result)) {
results = response.result;
}
else {
results = [response.result];
}
allResults = allResults.concat(results);
pageCount++;
// Check if there's more data - if no "next" property, stop
if (!response.next) {
break;
}
start = response.next;
}
else {
break;
}
}
catch (error) {
console.error(`DirectAPI pagination error:`, error);
break;
}
}
return {
result: allResults,
total: allResults.length,
};
}
/**
* Process the direct API call
*/
async process() {
// Process each item
const items = this.executeFunctions.getInputData();
const returnItems = [];
// Process each item
for (let i = 0; i < items.length; i++) {
try {
// Get operation first
const operation = this.executeFunctions.getNodeParameter("operation", i);
if (operation !== "call") {
throw new n8n_workflow_1.NodeOperationError(this.executeFunctions.getNode(), `Unsupported operation: ${operation}`, { itemIndex: i });
}
// Get endpoint
const endpoint = this.executeFunctions.getNodeParameter("endpoint", i);
if (!endpoint || endpoint.trim() === "") {
throw new n8n_workflow_1.NodeOperationError(this.executeFunctions.getNode(), "Endpoint cannot be empty", { itemIndex: i });
}
// Get additional options
const options = this.executeFunctions.getNodeParameter("directApiOptions", i, {});
// Store request info for debug
const requestInfo = {
endpoint,
timestamp: new Date().toISOString(),
};
// Try to get body as JSON
let body = {};
let bodyError = null;
try {
const bodyJson = this.executeFunctions.getNodeParameter("body", i, "{}");
// Store raw body for debug purposes
requestInfo.rawBody = bodyJson;
// Check if the input is already an object (happens when using expression)
if (typeof bodyJson === "object") {
body = bodyJson;
requestInfo.body = body;
}
else {
// Try to parse the string as JSON
try {
body = JSON.parse(bodyJson);
requestInfo.body = body;
}
catch (parseError) {
bodyError = parseError;
requestInfo.parseError = parseError.message;
}
}
}
catch (e) {
bodyError = e;
requestInfo.parseError = e.message;
}
// If there was a JSON parsing error and debug mode is on, return detailed error
if (bodyError && options.debug === true) {
const errorItem = {
json: {
error: "Invalid JSON in Request Body",
_debug: {
request: requestInfo,
error: {
message: bodyError.message,
stack: bodyError.stack,
timestamp: new Date().toISOString(),
},
},
},
pairedItem: { item: i },
};
returnItems.push(errorItem);
continue; // Skip to next item
}
// If there was a JSON parsing error and we're still here, throw the error
if (bodyError) {
throw new n8n_workflow_1.NodeOperationError(this.executeFunctions.getNode(), "Invalid JSON in Request Body", { itemIndex: i });
}
// Check for pagination options
const returnAll = this.executeFunctions.getNodeParameter("returnAll", i, false);
const maxPages = this.executeFunctions.getNodeParameter("maxPages", i, 5);
let responseData;
// Check if this is a .list operation that supports pagination
if (endpoint.includes(".list")) {
if (returnAll) {
// Return All: Load all pages until no more data
responseData = await this.handleDirectApiPagination(endpoint, body, i, 999 // Large number to load all pages
);
}
else {
// Use limited pagination
responseData = await this.handleDirectApiPagination(endpoint, body, i, maxPages);
}
}
else {
// Single API call for non-list operations
responseData = await this.makeApiCall(endpoint, body, {}, i);
}
// Create return item
const newItem = {
json: responseData,
pairedItem: { item: i },
};
// Add debug information if debug mode is enabled
if (options.debug === true) {
newItem.json = {
...newItem.json,
_debug: {
request: requestInfo,
response: {
statusCode: 200,
timestamp: new Date().toISOString(),
},
},
};
}
// Add to return data
returnItems.push(newItem);
}
catch (error) {
if (this.continueOnFail()) {
const errorItem = {
json: {
error: error.message,
},
pairedItem: { item: i },
};
// Add debug information if debug mode is enabled
try {
const options = this.executeFunctions.getNodeParameter("directApiOptions", i, {});
if (options.debug === true) {
// Try to get the endpoint and body for debug info
let endpoint = "";
let body = {};
try {
endpoint = this.executeFunctions.getNodeParameter("endpoint", i);
}
catch (e) {
// Ignore if we can't get the endpoint
}
try {
const bodyJson = this.executeFunctions.getNodeParameter("body", i, "{}");
body = JSON.parse(bodyJson);
}
catch (e) {
// Ignore if we can't parse the body
}
errorItem.json._debug = {
request: {
endpoint,
body,
timestamp: new Date().toISOString(),
},
error: {
message: error.message,
stack: error.stack,
timestamp: new Date().toISOString(),
},
};
}
}
catch (debugError) {
// Ignore errors in debug info generation
}
returnItems.push(errorItem);
}
else {
throw error;
}
}
}
return returnItems;
}
}
exports.DirectApiResourceHandler = DirectApiResourceHandler;
//# sourceMappingURL=DirectApiResourceHandler.js.map