File: /var/www/quadcode-site/app/Helpers/BitrixHelper.php
<?php
namespace App\Helpers;
use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class BitrixHelper
{
private string $host;
private int $userId;
private string $token;
const LOG_CHANNEL = 'bitrix';
const STATUS_JUNK = 'JUNK';
const DEAL_STAGE_APOLOGY = 'APOLOGY';
const DEAL_STAGE_NOT_ANSWERED = 'LOSE';
const CUSTOM_FIELD_LANDING_URL = 'UF_CRM_1708364992';
const CUSTOM_FIELD_GCLID = 'UF_CRM_1708366868784';
const CUSTOM_FIELD_LANG = 'UF_CRM_1708365178';
const CUSTOM_FIELD_BUSINESS_IDENTIFICATION = 'UF_CRM_1709012311521';
const CUSTOM_FIELD_INITIAL_INVESTMENT = 'UF_CRM_1708365367';
const CUSTOM_FIELD_REGION = 'UF_CRM_1708366122';
const CUSTOM_FIELD_COUNTRY_CODE = 'UF_CRM_1708366441792';
const CUSTOM_FIELD_UTM_CONTENT = 'UF_CRM_1712249375';
const CUSTOM_FIELD_UTM_TERMS = 'UF_CRM_1712249249';
const CUSTOM_FIELD_UTM_MEDIUM = 'UF_CRM_1712248114';
const CUSTOM_FIELD_UTM_CAMPAIGN = 'UF_CRM_1712248092';
const CUSTOM_FIELD_UTM_SOURCE = 'UF_CRM_1712248129';
private static array $businessIdentifications = [
'Brokerage business' => '79',
'Introducing broker' => '81',
'Affiliate' => '83',
'Trader' => '85',
'Entrepreneur' => '87',
'Other' => '89',
];
private static array $initialInvestments = [
'$0' => '45',
'$1000' => '47',
'$5000' => '49',
'$10000' => '51',
'$25000' => '53',
'$50000' => '55',
'More then $50000' => '57',
];
private static array $regions = [
'Europe' => '69',
'North America' => '71',
'South America' => '73',
'Asia-Pacific' => '75',
'Africa' => '77',
];
private static array $customFields = [
'landing_url' => self::CUSTOM_FIELD_LANDING_URL,
'gclid' => self::CUSTOM_FIELD_GCLID,
'lang' => self::CUSTOM_FIELD_LANG,
'business_identification' => self::CUSTOM_FIELD_BUSINESS_IDENTIFICATION,
'initial_investment' => self::CUSTOM_FIELD_INITIAL_INVESTMENT,
'region' => self::CUSTOM_FIELD_REGION,
'country_code' => self::CUSTOM_FIELD_COUNTRY_CODE,
'utm_content' => self::CUSTOM_FIELD_UTM_CONTENT,
'utm_term' => self::CUSTOM_FIELD_UTM_TERMS,
'utm_medium' => self::CUSTOM_FIELD_UTM_MEDIUM,
'utm_campaign' => self::CUSTOM_FIELD_UTM_CAMPAIGN,
'utm_source' => self::CUSTOM_FIELD_UTM_SOURCE,
];
public function __construct()
{
$this->host = getenv('BITRIX24_HOST');
$this->userId = getenv('BITRIX24_USER_ID');
$this->token = getenv('BITRIX24_TOKEN');
}
public function check(): bool
{
return !empty($this->host) && !empty($this->userId) && !empty($this->token);
}
public function convertLead(array $additional = []): array
{
$title = 'New lead from ' . $additional['landing_url'] . ' from ' . $additional['email'];
$data = [
'fields' => [
'TITLE' => $title,
'NAME' => $additional['first_name'],
'LAST_NAME' => $additional['last_name'] ?? null,
'COMMENTS' => $additional['message'] ?? null,
'PHONE' => [
[
'VALUE' => $additional['phone'],
'VALUE_TYPE' => 'WORK',
],
],
'EMAIL' => [
[
'VALUE' => $additional['email'],
'VALUE_TYPE' => 'WORK',
],
],
'UTM_CONTENT' => $additional['utm_content'] ?? null,
'UTM_TERM' => $additional['utm_term'] ?? null,
'UTM_MEDIUM' => $additional['utm_medium'] ?? null,
'UTM_CAMPAIGN' => $additional['utm_campaign'] ?? null,
'UTM_SOURCE' => $additional['utm_source'] ?? null,
],
];
$data['fields'] = array_filter($data['fields']);
$toUnset = ['first_name', 'last_name', 'message', 'phone', 'email'];
foreach ($toUnset as $field) {
unset($additional[$field]);
}
foreach (self::$customFields as $field => $externalKey) {
if (!empty($additional[$field]) || 'calendly_scheduled' === $field) {
switch ($field) {
case 'business_identification':
$data['fields'][$externalKey] = self::$businessIdentifications[$additional[$field]];
break;
case 'initial_investment':
$data['fields'][$externalKey] = self::$initialInvestments[$additional[$field]];
break;
case 'region':
$data['fields'][$externalKey] = [self::$regions[$additional[$field]]];
break;
default:
$data['fields'][$externalKey] = $additional[$field];
break;
}
unset($additional[$field]);
}
}
if (!empty($additional)) {
$data['fields']['SOURCE_DESCRIPTION'] = json_encode($additional);
}
return $data;
}
private function get(string $apiMethod, $data): Response
{
return Http::get($this->host . '/rest/' . $this->userId . '/' . $this->token . $apiMethod, $data);
}
public function getStatusList(array $filter): array
{
$data = ['filter' => $filter];
Log::channel(self::LOG_CHANNEL)->info('Get status list request', compact('data'));
$response = $this->get('/crm.status.list', $data)->json();
Log::channel(self::LOG_CHANNEL)->info('Get status list response', $response);
return $response;
}
public function addLead(array $data = []): array
{
$data = $this->convertLead($data);
Log::channel(self::LOG_CHANNEL)->info('Add lead request', compact('data'));
$response = $this->get('/crm.lead.add.json', $data)->json();
Log::channel(self::LOG_CHANNEL)->info('Add lead response', $response);
return $response;
}
public function leadList(array $filter, array $select = []): array
{
$data = [
'filter' => $filter,
'start' => 1,
];
if (!empty($select)) {
$data['select'] = $select;
}
Log::channel(self::LOG_CHANNEL)->info('Get lead list request', compact('data'));
$data['start'] = 1;
$response = $this->get('/crm.lead.list', $data)->json();
$index = 1;
Log::channel(self::LOG_CHANNEL)->info('Get lead list response #' . $index++, $response);
$leads = $response['result'];
while (isset($response['next'])) {
$data['start'] = $response['next'];
$response = $this->get('/crm.lead.list', $data)->json();
Log::channel(self::LOG_CHANNEL)->info('Get lead list response #' . $index++, $response);
$leads = array_merge($leads, $response['result']);
}
return $leads;
}
public function updateLeadStatus(string $leadId, array $fields): array
{
$data = ['id' => $leadId, 'fields' => $fields];
Log::channel(self::LOG_CHANNEL)->info('Update lead status request', compact('data'));
$response = $this->get('/crm.lead.update', $data)->json();
Log::channel(self::LOG_CHANNEL)->info('Update lead status response', $response);
return $response;
}
public function dealList(array $filter, array $select = []): array
{
$data = [
'filter' => $filter,
'start' => 1,
];
if (!empty($select)) {
$data['select'] = $select;
}
Log::channel(self::LOG_CHANNEL)->info('Get deal list request', compact('data'));
$response = $this->get('/crm.deal.list', $data)->json();
$index = 1;
Log::channel(self::LOG_CHANNEL)->info('Get deal list response #' . $index++, $response);
$leads = $response['result'];
while (isset($response['next'])) {
$data['start'] = $response['next'];
$response = $this->get('/crm.deal.list', $data)->json();
Log::channel(self::LOG_CHANNEL)->info('Get deal list response #' . $index++, $response);
$leads = array_merge($leads, $response['result']);
}
return $leads;
}
public function contactsList(array $filter = [], array $select = []): array
{
$data = ['start' => 1];
if (!empty($filter)) {
$data['filter'] = $filter;
}
if (!empty($select)) {
$data['select'] = $select;
}
Log::channel(self::LOG_CHANNEL)->info('Get contact list request', compact('data'));
$response = $this->get('/crm.contact.list', $data)->json();
$index = 1;
Log::channel(self::LOG_CHANNEL)->info('Get contact list response #' . $index++, $response);
$leads = $response['result'];
while (isset($response['next'])) {
$data['start'] = $response['next'];
$response = $this->get('/crm.contact.list', $data)->json();
Log::channel(self::LOG_CHANNEL)->info('Get contact list response #' . $index++, $response);
$leads = array_merge($leads, $response['result']);
}
return $leads;
}
public function getContact(string|int $id): array
{
$data = ['id' => $id];
Log::channel(self::LOG_CHANNEL)->info('Get contact request', compact('data'));
$response = $this->get('/crm.contact.get', $data)->json();
Log::channel(self::LOG_CHANNEL)->info('Get contact response', $response);
return $response['result'];
}
}