@tuanltntu/n8n-nodes-bitrix24
Version:
Comprehensive n8n community node for Bitrix24 API integration with CRM, Tasks, Chat, Telephony, and more
323 lines • 12.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getEntityFields = exports.returnFullBitrix24Response = exports.testAuth = exports.validateBinaryDataExists = exports.bitrix24DownloadFile = exports.bitrix24ApiRequestAllItems = exports.bitrix24Request = exports.bitrix24WebhookRequest = exports.bitrix24OAuth2Request = void 0;
/**
* Make an API request to Bitrix24 using OAuth2
*/
async function bitrix24OAuth2Request(endpoint, body = {}, qs = {}, uri, option = {}) {
var _a, _b, _c, _d;
try {
// Use OAuth2 authentication
const credentials = await this.getCredentials("bitrix24OAuth");
const portalUrl = credentials.portalUrl;
// Ensure portal URL doesn't have trailing slash
const baseUrl = portalUrl.replace(/\/$/, "");
// Remove leading slash if it exists
endpoint = endpoint.startsWith("/") ? endpoint.substring(1) : endpoint;
// Form request URL
const url = uri || `${baseUrl}/rest/${endpoint}`;
const options = {
method: "POST",
url,
qs,
body,
json: true,
};
// Handle form data if provided
if (option.formData) {
options.formData = option.formData;
}
return await this.helpers.requestOAuth2.call(this, "bitrix24OAuth", options);
}
catch (error) {
if (error.statusCode === 401) {
throw new Error("Bitrix24 OAuth credentials are not valid!");
}
let errorMessage;
if ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.error_description) {
errorMessage = error.response.body.error_description;
}
else if ((_d = (_c = error.response) === null || _c === void 0 ? void 0 : _c.body) === null || _d === void 0 ? void 0 : _d.error) {
errorMessage = error.response.body.error;
}
else {
errorMessage = error.message;
}
throw new Error(`Bitrix24 OAuth2 request error: ${errorMessage}`);
}
}
exports.bitrix24OAuth2Request = bitrix24OAuth2Request;
/**
* Make an API request using webhook URL
*/
async function bitrix24WebhookRequest(endpoint, body = {}, qs = {}, option = {}) {
var _a, _b, _c, _d;
try {
// Get webhook credentials
const credentials = await this.getCredentials("bitrix24Webhook");
// Get webhook URL from credentials
const webhookUrl = credentials.webhookUrl;
if (!webhookUrl) {
throw new Error("Invalid webhook URL: The webhook URL is empty");
}
// Make sure webhook URL ends with /
const baseUrl = webhookUrl.endsWith("/") ? webhookUrl : `${webhookUrl}/`;
// Remove leading slash if it exists in endpoint
endpoint = endpoint.startsWith("/") ? endpoint.substring(1) : endpoint;
// Construct full URL
const url = `${baseUrl}${endpoint}`;
// Make request
const options = {
headers: {
Accept: "application/json",
},
method: "POST",
uri: url,
qs,
body,
json: true,
};
// Handle form data if provided
if (option.formData) {
options.formData = option.formData;
}
// Execute the HTTP request
return await this.helpers.request(options);
}
catch (error) {
if (error.statusCode === 401) {
throw new Error("Bitrix24 webhook credentials are not valid!");
}
let errorMessage;
if ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.error_description) {
errorMessage = `${error.response.body.error_description}`;
}
else if ((_d = (_c = error.response) === null || _c === void 0 ? void 0 : _c.body) === null || _d === void 0 ? void 0 : _d.error) {
errorMessage = `${error.response.body.error}`;
}
else {
errorMessage = error.message;
}
throw new Error(`Bitrix24 webhook request error: ${errorMessage}`);
}
}
exports.bitrix24WebhookRequest = bitrix24WebhookRequest;
/**
* Make an API request to Bitrix24 - tries OAuth2 first, then webhook if OAuth2 fails
*/
async function bitrix24Request(endpoint, body = {}, qs = {}, uri, option = {}) {
try {
// First try OAuth2
try {
return await bitrix24OAuth2Request.call(this, endpoint, body, qs, uri, option);
}
catch (oauthError) {
// Fall back to webhook
try {
return await bitrix24WebhookRequest.call(this, endpoint, body, qs, option);
}
catch (webhookError) {
throw new Error(`Bitrix24 API request failed: All credential types failed - ${webhookError.message}`);
}
}
}
catch (error) {
throw new Error(`Bitrix24 API request failed: ${error.message}`);
}
}
exports.bitrix24Request = bitrix24Request;
/**
* Make an API request to load all items from paginated Bitrix24 API
*/
async function bitrix24ApiRequestAllItems(propertyName, endpoint, body = {}, query = {}, uri) {
var _a;
const returnData = [];
let responseData;
query.start = query.start || 0;
do {
try {
// Use the unified request method
responseData = await bitrix24Request.call(this, endpoint, body, query, uri);
// If the response has result but the property name doesn't exist, return full result
if (!responseData || responseData[propertyName] === undefined) {
if (responseData && responseData.result) {
return responseData.result;
}
break;
}
// If the property is not an array
if (!Array.isArray(responseData[propertyName])) {
if (responseData[propertyName]) {
returnData.push(responseData[propertyName]);
}
break;
}
// Add the items to our return data
returnData.push.apply(returnData, responseData[propertyName]);
// Increment the start position for the next page
query.start = query.start + 50; // Default Bitrix24 page size
}
catch (error) {
break;
}
} while (((_a = responseData[propertyName]) === null || _a === void 0 ? void 0 : _a.length) > 0);
return returnData;
}
exports.bitrix24ApiRequestAllItems = bitrix24ApiRequestAllItems;
/**
* Download a file from a URL
*/
async function bitrix24DownloadFile(downloadUrl) {
try {
const options = {
method: "POST",
uri: downloadUrl,
encoding: null,
};
return await this.helpers.request(options);
}
catch (error) {
throw new Error(`Failed to download file: ${error.message}`);
}
}
exports.bitrix24DownloadFile = bitrix24DownloadFile;
/**
* Validate that the binary data field exists in the input
*/
function validateBinaryDataExists(helpers, item, binaryPropertyName) {
if (item.binary === undefined) {
throw new Error("No binary data exists on item!");
}
if (item.binary[binaryPropertyName] === undefined) {
throw new Error(`No binary data property "${binaryPropertyName}" exists on item!`);
}
}
exports.validateBinaryDataExists = validateBinaryDataExists;
/**
* Test if credentials are valid
*/
async function testAuth(credential) {
// Test the credentials based on which type is being used
if (credential.hasOwnProperty("webhookUrl")) {
// Test webhook-based API
const webhookUrl = credential.webhookUrl;
try {
const options = {
method: "POST",
uri: `${webhookUrl}user.current`,
json: true,
};
await this.helpers.request(options);
return true;
}
catch (error) {
return false;
}
}
else {
// Test OAuth2-based API
try {
const portalUrl = credential.portalUrl;
const baseUrl = portalUrl.replace(/\/$/, "");
const options = {
method: "POST",
url: `${baseUrl}/rest/user.current`,
json: true,
};
await this.helpers.requestOAuth2.call(this, "bitrix24OAuth", options);
return true;
}
catch (error) {
return false;
}
}
}
exports.testAuth = testAuth;
/**
* Process and return full Bitrix24 API response
* Unified handler for all response types
*/
function returnFullBitrix24Response(responseData, helpers, itemIndex) {
// Ensure we're working with an object
if (typeof responseData !== "object" || responseData === null) {
responseData = { response: responseData };
}
// Return the full response with all data
return helpers.constructExecutionMetaData(helpers.returnJsonArray(responseData), { itemData: { item: itemIndex } });
}
exports.returnFullBitrix24Response = returnFullBitrix24Response;
/**
* Load resource options for use in dropdown selectors
*/
function getEntityFields(entityType) {
return new Promise(async (resolve, reject) => {
try {
// Get entity fields
const endpoint = `crm.${entityType}.fields`;
// Use the unified request method
const response = await bitrix24Request.call(this, endpoint);
if (!response || !response.result) {
return resolve([]);
}
// Process response to format n8n expects
const options = [];
for (const key in response.result) {
const field = response.result[key];
// Custom fields (UF_*) handling
if (key.startsWith("UF_")) {
// Try to find the best label for custom fields
let fieldName = "";
// Check various possible label properties in order of preference
if (field.formLabel) {
fieldName = field.formLabel;
}
else if (field.listLabel) {
fieldName = field.listLabel;
}
else if (field.editFormLabel) {
fieldName = field.editFormLabel;
}
else if (field.title) {
fieldName = field.title;
}
else if (field.NAME) {
fieldName = field.NAME;
}
else if (field.name) {
fieldName = field.name;
}
else if (field.FIELD_NAME) {
fieldName = field.FIELD_NAME;
}
else {
// If no label found, use the field ID but mark it as custom
fieldName = `Custom Field: ${key}`;
}
options.push({
name: fieldName,
value: key,
description: `Custom field (${key})`,
});
}
else {
// Standard fields
options.push({
name: field.title ||
field.formLabel ||
field.listLabel ||
field.NAME ||
field.name ||
key,
value: key,
});
}
}
return resolve(options);
}
catch (error) {
reject(error);
}
});
}
exports.getEntityFields = getEntityFields;
//# sourceMappingURL=SimplifiedFunctions.js.map