File: /var/www/fintechfuel/src/routes/api/Bitrix24.ts
import WLogger from './WLogger';
import { env } from '$env/dynamic/private';
import type { IRequest, IRequestField } from '../../type/form';
import Sanitizing from './Sanitizing';
import escapeRegExp from '../../utils/escapeRegExp';
const BITRIX24_FIELDS = {
LANDING_URL: 'UF_CRM_1708364992',
GCLID: 'UF_CRM_1708366868784',
LANG: 'UF_CRM_1708365178',
LANG_BY_BROWSER: 'UF_CRM_1728917539511',
BUSINESS_IDENTIFICATION: 'UF_CRM_1709012311521',
INITIAL_INVESTMENT: 'UF_CRM_1708365367',
REGION: 'UF_CRM_1708366122',
COUNTRY_CODE: 'UF_CRM_1708366441792',
UTM_CONTENT: 'UF_CRM_1712249375',
UTM_TERMS: 'UF_CRM_1712249249',
UTM_MEDIUM: 'UF_CRM_1712248114',
UTM_CAMPAIGN: 'UF_CRM_1712248092',
UTM_SOURCE: 'UF_CRM_1712248129',
ROISTAT_ID: 'UF_CRM_1744804235',
COMPANY_NAME: 'UF_CRM_COMPANY_TITLE',
SHORT_BIO: 'UF_CRM_1761209155062',
TG_CHANNEL: 'UF_CRM_1763371894',
INSTAGRAM: 'UF_CRM_1763371831',
YOUTUBE: 'UF_CRM_1763371853',
TIKTOK: 'UF_CRM_1763371879',
FTD_SUM: 'UF_CRM_1763371917',
HAS_NETWORK: 'UF_CRM_1763371959',
LAUNCH_REASON: 'UF_CRM_1761209155062',
};
const businessIdentifications = [79, 81, 83, 85, 87, 89];
const initialInvestments = [47, 49, 51, 53, 55, 57];
const regions = [69, 71, 73, 75, 77];
const regionMapping: { [key: string]: number } = {
'latam': 69,
'asia': 71,
'middle-east': 73,
'africa': 75,
};
const customFields: { key: IRequestField; keyNew: string }[] = [
{ key: 'landing_url', keyNew: BITRIX24_FIELDS.LANDING_URL },
{ key: 'gclid', keyNew: BITRIX24_FIELDS.GCLID },
{ key: 'language', keyNew: BITRIX24_FIELDS.LANG },
{ key: 'lang_by_browser', keyNew: BITRIX24_FIELDS.LANG_BY_BROWSER },
{ key: 'business_identification', keyNew: BITRIX24_FIELDS.BUSINESS_IDENTIFICATION },
{ key: 'price', keyNew: BITRIX24_FIELDS.INITIAL_INVESTMENT },
{ key: 'region', keyNew: BITRIX24_FIELDS.REGION },
{ key: 'country_code', keyNew: BITRIX24_FIELDS.COUNTRY_CODE },
{ key: 'utm_content', keyNew: BITRIX24_FIELDS.UTM_CONTENT },
{ key: 'utm_term', keyNew: BITRIX24_FIELDS.UTM_TERMS },
{ key: 'utm_medium', keyNew: BITRIX24_FIELDS.UTM_MEDIUM },
{ key: 'utm_campaign', keyNew: BITRIX24_FIELDS.UTM_CAMPAIGN },
{ key: 'utm_source', keyNew: BITRIX24_FIELDS.UTM_SOURCE },
{ key: 'roistatId', keyNew: BITRIX24_FIELDS.ROISTAT_ID },
{ key: 'company_name', keyNew: BITRIX24_FIELDS.COMPANY_NAME },
{ key: 'short_bio', keyNew: BITRIX24_FIELDS.SHORT_BIO },
{ key: 'tg_channel', keyNew: BITRIX24_FIELDS.TG_CHANNEL },
{ key: 'instagram', keyNew: BITRIX24_FIELDS.INSTAGRAM },
{ key: 'youtube', keyNew: BITRIX24_FIELDS.YOUTUBE },
{ key: 'tiktok', keyNew: BITRIX24_FIELDS.TIKTOK },
{ key: 'ftd_sum', keyNew: BITRIX24_FIELDS.FTD_SUM },
{ key: 'has_network', keyNew: BITRIX24_FIELDS.HAS_NETWORK },
{ key: 'launch_reason', keyNew: BITRIX24_FIELDS.LAUNCH_REASON },
];
const convertLead = (additional: IRequest) => {
const title = `New lead from ${additional?.landing_url} from ${additional.email}`;
const data: { [name: string]: any } = {
TITLE: title,
NAME: escapeRegExp(additional.name),
COMMENTS: escapeRegExp(additional?.message) ?? null,
PHONE: {
VALUE: additional.phone,
VALUE_TYPE: 'WORK',
},
EMAIL: {
VALUE: additional.email,
VALUE_TYPE: 'WORK',
},
UTM_CONTENT: additional?.utm_content ? escapeRegExp(additional.utm_content) : null,
UTM_TERM: additional?.utm_term ? escapeRegExp(additional.utm_term) : null,
UTM_MEDIUM: additional?.utm_medium ? escapeRegExp(additional.utm_medium) : null,
UTM_CAMPAIGN: additional?.utm_campaign ? escapeRegExp(additional.utm_campaign) : null,
UTM_SOURCE: additional?.utm_source ? escapeRegExp(additional.utm_source) : null,
};
const toUnset: IRequestField[] = ['first_name', 'name', 'last_name', 'message', 'phone', 'email'];
toUnset.forEach((item) => {
delete additional[item];
});
customFields.forEach((item) => {
if (item.key in additional) {
const value = additional[item.key as keyof typeof additional];
switch (item.key) {
case 'business_identification':
data[item.keyNew] = businessIdentifications[Number(value)];
break;
case 'price':
data[item.keyNew] = initialInvestments[Number(value)];
break;
case 'region':
data[item.keyNew] = regions[Number(value)];
break;
case 'regions':
if (Array.isArray(value) && value.length > 0) {
const firstRegion = value[0];
if (typeof firstRegion === 'string') {
data[item.keyNew] = regionMapping[firstRegion] || 69;
}
}
break;
default:
data[item.keyNew] = value;
break;
}
delete additional[item.key as keyof typeof additional];
}
});
if (Object.keys(additional).length) {
data['SOURCE_DESCRIPTION'] = JSON.stringify(additional);
}
return data;
};
const addLeadBitrix24 = (values: IRequest) => {
const additional = { ...values };
WLogger.log('info', '[BITRIX24]: START', Sanitizing(additional));
if (!env?.PRIVATE_BITRIX24_HOST || !env?.PRIVATE_BITRIX24_USER_ID || !env?.PRIVATE_BITRIX24_TOKEN) {
WLogger.log('error', '[BITRIX24]: END', {
error: `PRIVATE_BITRIX24_TOKEN or PRIVATE_BITRIX24_USER_ID or PRIVATE_BITRIX24_HOST: undefined`,
});
return;
}
const data = convertLead(additional);
const myUrlWithParams = new URL(
`${env?.PRIVATE_BITRIX24_HOST}/rest/${env?.PRIVATE_BITRIX24_USER_ID}/${env?.PRIVATE_BITRIX24_TOKEN}/crm.lead.add.json`
);
Object.keys(data).forEach(function (key) {
if (data[key]?.['VALUE']) {
myUrlWithParams.searchParams.append(`fields[${key}][0][VALUE]`, data[key]?.['VALUE']);
} else if (data[key]?.['VALUE_TYPE']) {
myUrlWithParams.searchParams.append(`fields[${key}][0][VALUE_TYPE]`, data[key]?.['VALUE_TYPE']);
} else {
myUrlWithParams.searchParams.append(`fields[${key}]`, data[key]);
}
});
return fetch(myUrlWithParams.href, {
method: 'GET',
})
.then((res) => res.json())
.then((res) => {
if ('error' in res) {
WLogger.log('error', '[BITRIX24]: ADD LEAD END', { error: res });
} else {
WLogger.log('info', '[BITRIX24]: ADD LEAD END', { res: res });
}
return res;
})
.catch((error) => {
WLogger.log('error', '[BITRIX24]: ADD LEAD END', { ...error });
return error;
});
};
export default addLeadBitrix24;