>, tiktok: array>} $config */ public static function dispatch(array $config, string $clientIp, string $userAgent, string $eventSourceUrl = ''): void { foreach (SplitPixelConfigService::getEnabledSorted($config, SplitPixelConfigService::PLATFORM_FACEBOOK) as $row) { if ((int) ($row['server_postback'] ?? 0) !== 1) { continue; } $token = trim((string) ($row['access_token'] ?? '')); if ($token === '') { continue; } self::sendFacebook($row, $token, $clientIp, $userAgent, $eventSourceUrl); } foreach (SplitPixelConfigService::getEnabledSorted($config, SplitPixelConfigService::PLATFORM_TIKTOK) as $row) { if ((int) ($row['server_postback'] ?? 0) !== 1) { continue; } $token = trim((string) ($row['access_token'] ?? '')); if ($token === '') { continue; } self::sendTikTok($row, $token, $clientIp, $userAgent, $eventSourceUrl); } } /** * @param array $row */ private static function sendFacebook(array $row, string $accessToken, string $clientIp, string $userAgent, string $eventSourceUrl): void { $pixelId = trim((string) ($row['pixel_id'] ?? '')); if ($pixelId === '') { return; } $eventName = (string) ($row['event'] ?? 'PageView'); $testCode = trim((string) ($row['test_code'] ?? '')); $payload = [ 'data' => [[ 'event_name' => $eventName, 'event_time' => time(), 'action_source' => 'website', 'user_data' => array_filter([ 'client_ip_address' => $clientIp !== '' ? $clientIp : null, 'client_user_agent' => $userAgent !== '' ? $userAgent : null, ]), ]], ]; if ($eventSourceUrl !== '') { $payload['data'][0]['event_source_url'] = $eventSourceUrl; } if ($testCode !== '') { $payload['test_event_code'] = $testCode; } $url = 'https://graph.facebook.com/v19.0/' . rawurlencode($pixelId) . '/events?access_token=' . rawurlencode($accessToken); self::postJson($url, $payload, [], 'facebook', $pixelId); } /** * @param array $row */ private static function sendTikTok(array $row, string $accessToken, string $clientIp, string $userAgent, string $eventSourceUrl): void { $pixelId = trim((string) ($row['pixel_id'] ?? '')); if ($pixelId === '') { return; } $event = self::mapTikTokServerEvent((string) ($row['event'] ?? 'PageView')); $testCode = trim((string) ($row['test_code'] ?? '')); $payload = [ 'pixel_code' => $pixelId, 'event' => $event, 'event_id' => uniqid('split_', true), 'timestamp' => gmdate('c'), 'context' => array_filter([ 'ip' => $clientIp !== '' ? $clientIp : null, 'user_agent' => $userAgent !== '' ? $userAgent : null, 'page' => $eventSourceUrl !== '' ? ['url' => $eventSourceUrl] : null, ]), ]; if ($testCode !== '') { $payload['test_event_code'] = $testCode; } $url = 'https://business-api.tiktok.com/open_api/v1.3/event/track/'; self::postJson($url, $payload, [ 'Access-Token: ' . $accessToken, 'Content-Type: application/json', ], 'tiktok', $pixelId); } private static function mapTikTokServerEvent(string $event): string { $map = [ 'PageView' => 'Pageview', 'Lead' => 'SubmitForm', 'Contact' => 'Contact', 'AddToCart' => 'AddToCart', 'Purchase' => 'CompletePayment', 'Subscribe' => 'Subscribe', ]; return $map[$event] ?? 'Pageview'; } /** * @param array $payload * @param array $headers */ private static function postJson(string $url, array $payload, array $headers, string $platform, string $pixelId): void { $json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); if ($json === false) { return; } $ch = curl_init($url); if ($ch === false) { return; } $defaultHeaders = ['Content-Type: application/json']; curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => $json, CURLOPT_HTTPHEADER => array_merge($defaultHeaders, $headers), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 3, CURLOPT_CONNECTTIMEOUT => 2, ]); $response = curl_exec($ch); $errno = curl_errno($ch); $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($errno !== 0 || ($httpCode >= 400 && $httpCode !== 0)) { Log::error(sprintf( 'Split pixel postback failed platform=%s pixel=%s http=%d curl=%d', $platform, $pixelId, $httpCode, $errno )); } elseif (is_string($response) && strpos($response, '"error"') !== false) { Log::error(sprintf('Split pixel postback api error platform=%s pixel=%s', $platform, $pixelId)); } } }