HEX
Server: nginx/1.18.0
System: Linux test-ipsremont 5.4.0-214-generic #234-Ubuntu SMP Fri Mar 14 23:50:27 UTC 2025 x86_64
User: ips (1000)
PHP: 8.0.30
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/quadcode.com/builds/-DFbjr9L/0/foach/quadcode.com/src/routes/api/Bitrix24.ts
import WLogger from './WLogger';
import { env } from '$env/dynamic/public';
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',
  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',
};

const businessIdentifications = [79, 81, 83, 85, 87, 89];

const initialInvestments = [47, 49, 51, 53, 55, 57];

const regions = [69, 71, 73, 75, 77];

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: '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 },
];

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?.text) ?? null,
    PHONE: {
      VALUE: additional.phone,
      VALUE_TYPE: 'WORK',
    },
    EMAIL: {
      VALUE: additional.email,
      VALUE_TYPE: 'WORK',
    },
    UTM_CONTENT: escapeRegExp(additional?.utm_content || '') ?? null,
    UTM_TERM: escapeRegExp(additional?.utm_term || '') ?? null,
    UTM_MEDIUM: escapeRegExp(additional?.utm_medium || '') ?? null,
    UTM_CAMPAIGN: escapeRegExp(additional?.utm_campaign || '') ?? null,
    UTM_SOURCE: escapeRegExp(additional?.utm_source || '') ?? null,
  };

  const toUnset: IRequestField[] = ['first_name', 'name', 'last_name', 'text', 'phone', 'email'];

  toUnset.forEach((item) => {
    delete additional[item];
  });

  customFields.forEach((item) => {
    if (item.key in additional) {
      switch (item.key) {
        case 'business_identification':
          data[item.keyNew] = businessIdentifications[Number(additional[item.key])];
          break;
        case 'price':
          data[item.keyNew] = initialInvestments[Number(additional[item.key])];
          break;
        case 'region':
          data[item.keyNew] = regions[Number(additional[item.key])];
          break;
        default:
          data[item.keyNew] = additional[item.key];
          break;
      }
      delete additional[item.key];
    }
  });

  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?.PUBLIC_BITRIX24_HOST || !env?.PUBLIC_BITRIX24_USER_ID || !env?.PUBLIC_BITRIX24_TOKEN) {
    WLogger.log('error', '[BITRIX24]: END', {
      error: `PUBLIC_BITRIX24_TOKEN or PUBLIC_BITRIX24_USER_ID or PUBLIC_BITRIX24_HOST: undefined`,
    });

    return;
  }

  const data = convertLead(additional);

  const myUrlWithParams = new URL(
    `${env.PUBLIC_BITRIX24_HOST}/rest/${env.PUBLIC_BITRIX24_USER_ID}/${env.PUBLIC_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;