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/src/routes/api/ActiveCampaign.ts
import type { IRecord, IRequest } from '$type/form';
import WLogger from './WLogger';
import Sanitizing from './Sanitizing';
import { env } from '$env/dynamic/private';
import type { IRequestField } from '$type/form';

const ACTIVE_CAMPAIGN_FIELDS = {
  LANDING_URL: '6',
  UTM_SOURCE: '7',
  UTM_MEDIUM: '8',
  UTM_CAMPAIGN: '9',
  UTM_CONTENT: '10',
  UTM_TERMS: '11',
};

const customFields: { key: IRequestField; keyNew: string }[] = [
  { key: 'landing_url', keyNew: ACTIVE_CAMPAIGN_FIELDS.LANDING_URL },
  { key: 'utm_source', keyNew: ACTIVE_CAMPAIGN_FIELDS.UTM_SOURCE },
  { key: 'utm_medium', keyNew: ACTIVE_CAMPAIGN_FIELDS.UTM_MEDIUM },
  { key: 'utm_campaign', keyNew: ACTIVE_CAMPAIGN_FIELDS.UTM_CAMPAIGN },
  { key: 'utm_content', keyNew: ACTIVE_CAMPAIGN_FIELDS.UTM_CONTENT },
  { key: 'utm_term', keyNew: ACTIVE_CAMPAIGN_FIELDS.UTM_TERMS },
];

const convertLead = (additional: IRequest) => {
  const data: Record<string, string | IRecord[] | IRecord> = {
    email: additional.email,
  };

  if (additional?.first_name) {
    data['firstName'] = additional.first_name;
  }

  if (additional?.name && !additional?.first_name) {
    data['firstName'] = additional?.name;
  }

  if (additional?.last_name) {
    data['lastName'] = additional.last_name;
  }

  if (additional?.phone) {
    data['phone'] = additional.phone;
  }

  const customData: IRecord[] = [];

  customFields.forEach((item) => {
    if (item.key in additional) {
      customData.push({
        field: item.keyNew,
        value: additional[item.key],
      });
    }
  });

  data['fieldValues'] = customData;

  return {
    contact: data,
  };
};

const searchContact = async (email: string) => {
  return fetch(`${env.PRIVATE_ACTIVE_CAMPAIGN_HOST}/api/3/contacts?filters[email]=${email}`, {
    method: 'GET',
    headers: {
      'Api-Token': env.PRIVATE_ACTIVE_CAMPAIGN_TOKEN,
    },
  });
};

const createContact = async (additional: IRequest) => {
  const data = convertLead(additional);

  return fetch(`${env.PRIVATE_ACTIVE_CAMPAIGN_HOST}/api/3/contacts`, {
    method: 'POST',
    headers: {
      'Api-Token': env.PRIVATE_ACTIVE_CAMPAIGN_TOKEN,
    },
    body: JSON.stringify(data),
  });
};

const updateListStatus = async (contactId: number, type?: boolean) => {
  const data = {
    contactList: {
      list: type ? env.PRIVATE_ACTIVE_CAMPAIGN_LIST_BLOG_ID : env.PRIVATE_ACTIVE_CAMPAIGN_LIST_ID,
      contact: contactId,
      status: 1,
    },
  };

  return fetch(`${env.PRIVATE_ACTIVE_CAMPAIGN_HOST}/api/3/contactLists`, {
    method: 'POST',
    headers: {
      'Api-Token': env.PRIVATE_ACTIVE_CAMPAIGN_TOKEN,
    },
    body: JSON.stringify(data),
  });
};

const sendActiveCampaign = async (values: IRequest) => {
  const additional = { ...values };
  WLogger.log('info', '[ACTIVE_CAMPAIGN]: START', Sanitizing(additional));

  if (
    !env?.PRIVATE_ACTIVE_CAMPAIGN_HOST ||
    !env?.PRIVATE_ACTIVE_CAMPAIGN_LIST_ID ||
    !env?.PRIVATE_ACTIVE_CAMPAIGN_TOKEN ||
    !env?.PRIVATE_ACTIVE_CAMPAIGN_LIST_BLOG_ID
  ) {
    WLogger.log('error', '[ACTIVE_CAMPAIGN]: END', {
      error: `PRIVATE_ACTIVE_CAMPAIGN_TOKEN or PRIVATE_ACTIVE_CAMPAIGN_LIST_BLOG_ID or PRIVATE_ACTIVE_CAMPAIGN_LIST_ID or PRIVATE_ACTIVE_CAMPAIGN_HOST: undefined`,
    });

    return;
  }

  WLogger.log('info', '[ACTIVE_CAMPAIGN]: SEARCH CONTACT START', Sanitizing(additional));
  const response = await searchContact(additional.email);

  if (!response.ok) {
    WLogger.log('error', '[ACTIVE_CAMPAIGN]: SEARCH CONTACT END');
    return;
  }

  const responseData = await response.json();
  WLogger.log('info', '[ACTIVE_CAMPAIGN]: SEARCH CONTACT END');

  let contact = responseData['contacts'][0] ?? null;

  if (!contact) {
    WLogger.log('info', '[ACTIVE_CAMPAIGN]: CREATE CONTACT START', Sanitizing(additional));
    const response = await createContact(additional);

    if (!response.ok) {
      WLogger.log('error', '[ACTIVE_CAMPAIGN]: CREATE CONTACT END');
      return;
    }

    const responseData = await response.json();
    WLogger.log('info', '[ACTIVE_CAMPAIGN]: CREATE CONTACT END');

    contact = responseData['contact'] ?? null;
  }

  if (!contact) {
    WLogger.log('error', '[ACTIVE_CAMPAIGN]: CONTACT NULL', Sanitizing(contact));
    return;
  }

  WLogger.log('info', '[ACTIVE_CAMPAIGN]: UPDATE LIST STATUS START', Sanitizing(contact));
  const responseList = await updateListStatus(contact.id, additional?.isPost || false);

  if (!responseList.ok) {
    WLogger.log('error', '[ACTIVE_CAMPAIGN]: UPDATE LIST STATUS END');
    return;
  }

  WLogger.log('info', '[ACTIVE_CAMPAIGN]: UPDATE LIST STATUS END');
};

export default sendActiveCampaign;