| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 |
- <?php
- namespace App\Jobs;
- use App\Game\GlobalUserInfo;
- use App\Game\WebChannelConfig;
- use App\Services\ApkService;
- use GuzzleHttp\Client;
- use Illuminate\Bus\Queueable;
- use Illuminate\Queue\SerializesModels;
- use Illuminate\Queue\InteractsWithQueue;
- use Illuminate\Contracts\Queue\ShouldQueue;
- use Illuminate\Foundation\Bus\Dispatchable;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- class AfEvent implements ShouldQueue
- {
- use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
- protected $data;
- protected $user;
- /**
- * Create a new job instance.
- *
- * @return void
- */
- public function __construct($data = [])
- {
- $this->data = $data;
- }
- /**
- * Execute the job.
- *
- * @return void
- */
- public function handle()
- {
- Log::channel('adjustEvent')->info('enter:'.json_encode($this->data));
- if (empty($this->data)) return;
- [$UserID, $payAmt, $AdId, $eventType, $channel, $pfType, $params] = $this->normalizePayload($this->data);
- if (!$UserID) {
- return;
- }
- if (empty($eventType)) $eventType = 2;
- Log::channel('adjustEvent')->info('接收数据' . \GuzzleHttp\json_encode($this->data));
- if ($this->isFacebookPlatform($pfType)) {
- $this->reportFacebookEvents($channel, $UserID, $payAmt, $AdId, $params);
- return;
- }
- if ($payAmt && !empty($AdId)) {
- // 执行AF事件
- $dao = new \App\dao\af\AfEvent();
- $dao->pay($AdId, $UserID, $eventType);
- $dao->paySum($AdId, $UserID, $payAmt, $eventType);
- $dao->payCount($AdId, $UserID, $eventType);
- }
- // $dao->recordKwaiRecharge($UserID, $payAmt);
- // $dao->recordGoogleRecharge($UserID, $payAmt);
- }
- protected function normalizePayload($data)
- {
- if (isset($data['UserID'])) {
- $user = GlobalUserInfo::getGameUserInfo('UserID', $data['UserID']);
- $this->user = $user;
- $params = is_array($data['params'] ?? null) ? $data['params'] : [];
- $orderSn = $params['order_sn'] ?? '';
- $orderInfo = $orderSn === '' ? null : DB::connection('write')->table('agent.dbo.order')
- ->where('order_sn', $orderSn)
- ->select('AdId', 'eventType','Channel')
- ->first();
- $channel = $data['channel']
- ?? ($orderInfo->Channel ?? null)
- ?? ($user->Channel ?? null)
- ?? $this->extractChannelFromCookie($data['UserID'])
- ?? 100;
- $channelConfig = $channel ? WebChannelConfig::getByChannel($channel) : null;
- $params['config'] = $channelConfig;
- $params['event_name'] = $data['event_name'] ?? ($params['event_name'] ?? '');
- $params['custom_data'] = is_array($data['custom_data'] ?? null) ? $data['custom_data'] : ($params['custom_data'] ?? []);
- Log::channel('adjustEvent')->info('normalizePayload:' . json_encode([
- 'user_id' => $data['UserID'] ?? 0,
- 'event_name' => $params['event_name'],
- 'order_sn' => $orderSn,
- 'order_channel' => $orderInfo->Channel ?? null,
- 'global_channel' => $user->Channel ?? null,
- 'final_channel' => $channel,
- 'platform_name' => $channelConfig->PlatformName ?? null,
- ], JSON_UNESCAPED_UNICODE));
- return [
- $data['UserID'] ?? 0,
- $params['golds'] ?? 0,
- $orderInfo->AdId ?? '',
- $orderInfo->eventType ?? 2,
- $channel,
- $channelConfig->PlatformName ?? '',
- $params,
- ];
- }
- return [
- $data[0] ?? 0,
- $data[1] ?? 0,
- $data[2] ?? '',
- $data[3] ?? 2,
- $data[4] ?? 0,
- $data[5] ?? '',
- $data[6] ?? [],
- ];
- }
- protected function isFacebookPlatform($pfType)
- {
- return is_string($pfType) && stripos($pfType, 'fb') !== false;
- }
- protected function reportFacebookEvents($channel, $userID, $payAmt, $adId, array $params = [])
- {
- try {
- $config = $params['config'] ?? null;
- if (!$config || !$this->isFacebookPlatform($config->PlatformName ?? '')) {
- Log::channel('adjustEvent')->info('facebook s2s skipped: invalid config', [
- 'channel' => $channel,
- 'user_id' => $userID,
- 'platform_name' => $config->PlatformName ?? null,
- ]);
- return;
- }
- $pixelId = trim((string)($config->PlatformID ?? ''));
- $accessToken = trim((string)($config->PlatformToken ?? ''));
- if ($pixelId === '' || $accessToken === '') {
- Log::channel('adjustEvent')->info('facebook s2s skipped: missing pixel config', [
- 'channel' => $channel,
- 'user_id' => $userID,
- 'pixel_id' => $pixelId,
- ]);
- return;
- }
- $events = $this->buildFacebookEvents($userID, $payAmt, $adId, $params);
- if (empty($events)) {
- return;
- }
- $url = "https://graph.facebook.com/v21.0/{$pixelId}/events";
- $payload = [
- 'data' => $events,
- 'access_token' => $accessToken,
- ];
- Log::channel('adjustEvent')->info('facebook s2s request ' . json_encode([
- 'channel' => $channel,
- 'user_id' => $userID,
- 'pixel_id' => $pixelId,
- 'event_count' => count($events),
- 'payload' => $payload,
- ], JSON_UNESCAPED_UNICODE));
- $client = new Client([
- 'timeout' => 10,
- 'http_errors' => false,
- ]);
- $response = $client->post($url, ['json' => $payload]);
- Log::channel('adjustEvent')->info('facebook s2s response ' . json_encode([
- 'channel' => $channel,
- 'user_id' => $userID,
- 'status' => $response->getStatusCode(),
- 'body' => (string)$response->getBody(),
- ], JSON_UNESCAPED_UNICODE));
- } catch (\Throwable $e) {
- Log::channel('adjustEvent')->info('facebook s2s failed ' . json_encode([
- 'channel' => $channel,
- 'user_id' => $userID,
- 'message' => $e->getMessage(),
- ], JSON_UNESCAPED_UNICODE));
- }
- }
- protected function buildFacebookEvents($userID, $payAmt, $adId, array $params = [])
- {
- $cookieInfo = $this->getFacebookCookieInfo($userID);
- if (!empty($params['event_name'])) {
- return $this->buildSingleFacebookEvent($userID, $adId, $params, $cookieInfo);
- }
- $orderSn = $params['order_sn'] ?? '';
- $first = !empty($params['first']);
- $isD0 = !empty($params['isd0']);
- $currency = env('CONFIG_24680_CURRENCY', 'BRL');
- $userData = $this->buildFacebookUserData($userID, $adId, $params, $cookieInfo);
- $customData = array_filter([
- 'value' => (float)$payAmt,
- 'currency' => $currency,
- ], function ($value) {
- return $value !== '' && $value !== null;
- });
- $origin = $cookieInfo['Origin'] ?? '';
- $events = [];
- if ($first) {
- if ($isD0) {
- $events[] = $this->makeFacebookEvent('firstpayD0', 'd0_' . $orderSn, $userData, $customData, $origin);
- $events[] = $this->makeFacebookEvent('AddToWishlist', 'aw_' . $orderSn, $userData, $customData, $origin);
- } else {
- $events[] = $this->makeFacebookEvent('firstpayD1', 'd1_' . $orderSn, $userData, $customData, $origin);
- $events[] = $this->makeFacebookEvent('AddToCart', 'ac_' . $orderSn, $userData, $customData, $origin);
- }
- } else if (!$isD0) {
- $events[] = $this->makeFacebookEvent('payagain', 'pa_' . $orderSn, $userData, $customData, $origin);
- $events[] = $this->makeFacebookEvent('InitiateCheckout', 'ic_' . $orderSn, $userData, $customData, $origin);
- }
- $events[] = $this->makeFacebookEvent('Purchase', 'pay_' . $orderSn, $userData, $customData, $origin);
- return $events;
- }
- protected function buildSingleFacebookEvent($userID, $adId, array $params = [], array $cookieInfo = [])
- {
- $user = $this->user;
- $eventName = trim((string)($params['event_name'] ?? ''));
- if ($eventName === '') {
- return [];
- }
- $eventId = $eventName . '_' . ($user->FPID ?? '');
- $customData = is_array($params['custom_data'] ?? null) ? $params['custom_data'] : [];
- $customData = array_filter($customData, function ($value) {
- return $value !== '' && $value !== null;
- });
- return [
- $this->makeFacebookEvent(
- $eventName,
- $eventId,
- $this->buildFacebookUserData($userID, $adId, $params, $cookieInfo),
- $customData,
- $cookieInfo['Origin'] ?? ''
- )
- ];
- }
- protected function buildFacebookUserData($userID, $adId, array $params = [], array $cookieInfo = [])
- {
- $user = $this->user;
- if (empty($cookieInfo)) {
- $cookieInfo = $this->getFacebookCookieInfo($userID);
- }
- $cookieValues = $this->parseCookieValues($cookieInfo['Cookie'] ?? '');
- $browserIds = $this->resolveFacebookBrowserIds($userID, $params, $cookieInfo, $cookieValues);
- $externalId = $params['udid'] ?? ($user ? md5($user->UserID) : md5($userID));
- $userData = [
- 'external_id' => (string)$externalId,
- 'fbp' => $browserIds['fbp'],
- 'fbc' => $browserIds['fbc'],
- 'client_ip_address' => $cookieInfo['IP'] ?? '',
- 'client_user_agent' => $cookieInfo['ClickUA'] ?? $cookieInfo['GameUA'] ?? '',
- ];
- return array_filter($userData, function ($value) {
- return $value !== '' && $value !== null;
- });
- }
- protected function getFacebookCookieInfo($userID)
- {
- $user = $this->user;
- return ApkService::loadCookie($userID, $user->FPID ?? '', $user->FF ?? '') ?: [];
- }
- protected function parseCookieValues($cookieString)
- {
- $cookies = [];
- if (!is_string($cookieString) || $cookieString === '') {
- return $cookies;
- }
- foreach (explode(';', $cookieString) as $part) {
- $part = trim($part);
- if ($part === '' || strpos($part, '=') === false) {
- continue;
- }
- [$name, $value] = explode('=', $part, 2);
- $cookies[trim($name)] = trim($value);
- }
- return $cookies;
- }
- protected function resolveFacebookBrowserIds($userID, array $params, array $cookieInfo, array $cookieValues)
- {
- $fbp = trim((string)($cookieValues['_fbp'] ?? ''));
- $fbc = trim((string)($cookieValues['_fbc'] ?? ''));
- $cookieParamsFbclid = '';
- if (!empty($cookieInfo['Params'])) {
- $cookieParams = json_decode($cookieInfo['Params'], true);
- if (is_array($cookieParams)) {
- $cookieParamsFbclid = trim((string)($cookieParams['fbclid'] ?? ''));
- }
- }
- if ($cookieParamsFbclid === '') {
- return compact('fbp', 'fbc');
- }
- $timestamp = $this->resolveFacebookCookieTimestamp($cookieInfo);
- $currentFbclid = ApkService::extractFbclid($fbc);
- if ($fbc === '' || $currentFbclid === '' || $currentFbclid !== $cookieParamsFbclid) {
- $fbc = 'fb.1.' . $timestamp . '.' . $cookieParamsFbclid;
- }
- if ($fbp === '') {
- $seed = implode('|', [
- $userID,
- $cookieInfo['FPID'] ?? '',
- $cookieInfo['FF'] ?? '',
- $cookieInfo['IP'] ?? '',
- $cookieInfo['CreateTime'] ?? '',
- ]);
- $fbp = 'fb.1.' . $timestamp . '.' . substr(md5($seed), 0, 16);
- }
- return compact('fbp', 'fbc');
- }
- protected function resolveFacebookCookieTimestamp(array $cookieInfo)
- {
- $rawTime = $cookieInfo['CreateTime'] ?? '';
- if (!empty($rawTime)) {
- $timestamp = strtotime((string)$rawTime);
- if ($timestamp !== false) {
- return (string)($timestamp * 1000);
- }
- }
- return (string)round(microtime(true) * 1000);
- }
- protected function extractChannelFromCookie($userID)
- {
- $cookieInfo = $this->getFacebookCookieInfo($userID);
- if (!$cookieInfo || empty($cookieInfo['Params'])) {
- return null;
- }
- $params = json_decode($cookieInfo['Params'], true);
- if (!is_array($params)) {
- return null;
- }
- return $params['c'] ?? null;
- }
- protected function makeFacebookEvent($eventName, $eventId, array $userData, array $customData, $eventSourceUrl = '')
- {
- $event = [
- 'event_name' => $eventName,
- 'event_time' => time(),
- 'event_id' => $eventId,
- 'action_source' => 'website',
- 'user_data' => $userData,
- ];
- if (!empty($customData)) {
- $event['custom_data'] = (object)$customData;
- }
- if (!empty($eventSourceUrl)) {
- $event['event_source_url'] = $eventSourceUrl;
- }
- return $event;
- }
- }
|