diff --git a/app/service/GoogleAdsAdService.php b/app/service/GoogleAdsAdService.php index 1cc317f..5a3b0d5 100644 --- a/app/service/GoogleAdsAdService.php +++ b/app/service/GoogleAdsAdService.php @@ -88,7 +88,6 @@ class GoogleAdsAdService extends BaseService return $groupAdsResourceName; } - /** * 在数据库中保存广告信息 * @param $groupadsResourceName @@ -101,20 +100,20 @@ class GoogleAdsAdService extends BaseService foreach ($groupadsResourceName as $data) { // 构建 SQL 语句,添加 ad_type 和 metadata $sql = "INSERT INTO {$tableName} - (ad_id, ad_set_id, campaign_id, account_id, name, status, metadata,platform_type, last_sync_time, update_at) - VALUES - (:ad_id, :ad_group_id, :campaign_id, :customer_id, :ad_name, :status, :metadata, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) - ON CONFLICT (platform_type,ad_id) - DO UPDATE SET - ad_set_id = EXCLUDED.ad_set_id, - campaign_id = EXCLUDED.campaign_id, - account_id = EXCLUDED.account_id, - name = EXCLUDED.name, - status = EXCLUDED.status, - metadata = EXCLUDED.metadata, - last_sync_time = CURRENT_TIMESTAMP, -- 使用当前时间戳 - update_at = CURRENT_TIMESTAMP -- 使用当前时间戳 - WHERE {$tableName}.platform_type = 2"; + (ad_id, ad_set_id, campaign_id, account_id, name, status, metadata, platform_type, last_sync_time, update_at) + VALUES + (:ad_id, :ad_group_id, :campaign_id, :customer_id, :ad_name, :status, :metadata, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) + ON CONFLICT (platform_type, ad_id) + DO UPDATE SET + ad_set_id = EXCLUDED.ad_set_id, + campaign_id = EXCLUDED.campaign_id, + account_id = EXCLUDED.account_id, + name = EXCLUDED.name, + status = EXCLUDED.status, + metadata = EXCLUDED.metadata, + last_sync_time = CURRENT_TIMESTAMP, -- 使用当前时间戳 + update_at = CURRENT_TIMESTAMP -- 使用当前时间戳 + WHERE {$tableName}.platform_type = 2"; // 绑定数据 $bindData = [ @@ -125,14 +124,67 @@ class GoogleAdsAdService extends BaseService 'ad_name' => $data['ad_name'], 'status' => $data['status'], 'metadata' => $data['metadata'], +// 'display_url' => $data['display_url'] ?? '', // 新增字段,默认值为空字符串 +// 'final_app_urls' => self::toPgArray($data['final_app_urls']), // 新增字段,默认值为空数组 +// 'final_mobile_urls' => self::toPgArray($data['final_mobile_urls']), // 新增字段,默认值为空数组 +// 'final_url_suffix' => $data['final_url_suffix'] ?? '', // 新增字段,默认值为空字符串 +// 'final_urls' => self::toPgArray($data['final_urls']), // 新增字段,默认值为空数组 ]; // 执行 SQL 插入语句 ThinkDb::execute($sql, $bindData); + // 处理 final_app_urls、final_mobile_urls 和 final_urls + self::saveLandingUrls($data['ad_id'], $data['customer_id'], $data['final_app_urls'] ?? [], 'app'); + self::saveLandingUrls($data['ad_id'], $data['customer_id'], $data['final_mobile_urls'] ?? [], 'mobile'); + self::saveLandingUrls($data['ad_id'], $data['customer_id'], $data['final_urls'] ?? [], 'web'); } } + /** + * 将 URL 数组存储到 bps_ads_landing_url 表中 + * + * @param string $adId 广告 ID + * @param string $accountId 账户 ID + * @param array $urls URL 数组 + * @param string $landingAccess 落地类型(如 'app', 'mobile', 'web') + */ + private static function saveLandingUrls($adId, $accountId, $urls, $landingAccess) + { + if (empty($urls)) { + return; + } + $tableName = 'bps.bps_ads_landing_url'; + $platformType = 2; // Google Ads 平台类型 + + foreach ($urls as $url) { + // 构建 SQL 语句,插入或更新 URL 数据 + $sql = "INSERT INTO {$tableName} + (landing_url, landing_access, ad_id, account_id, last_sync_time, platform_type, create_at, update_at) + VALUES + (:landing_url, :landing_access, :ad_id, :account_id, CURRENT_TIMESTAMP, :platform_type, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) + ON CONFLICT (platform_type, landing_url) + DO UPDATE SET + landing_access = EXCLUDED.landing_access, + ad_id = EXCLUDED.ad_id, + account_id = EXCLUDED.account_id, + last_sync_time = CURRENT_TIMESTAMP, + update_at = CURRENT_TIMESTAMP"; + + // 绑定数据 + $bindData = [ + 'landing_url' => $url, + 'landing_access' => $landingAccess, + 'ad_id' => $adId, + 'account_id' => $accountId, + 'platform_type' => $platformType, + ]; + + // 执行 SQL 插入或更新 URL 数据 + ThinkDb::execute($sql, $bindData); + } + } + /** * 在数据库中保存广告信息 * @param $groupadsResourceName @@ -285,21 +337,26 @@ class GoogleAdsAdService extends BaseService // $response = $googleAdsServiceClient->search($customerId, $query); $query = "SELECT - ad_group_ad.ad.id, + ad_group_ad.ad.id, ad_group.id, campaign.id, customer.id, - ad_group_ad.ad.name, - ad_group_ad.status, + ad_group_ad.ad.name, + ad_group_ad.status, ad_group_ad.ad.resource_name, ad_group_ad.ad.type, ad_group_ad.ad.responsive_display_ad.logo_images, ad_group_ad.ad.responsive_display_ad.square_logo_images, ad_group_ad.ad.responsive_display_ad.marketing_images, ad_group_ad.ad.responsive_display_ad.square_marketing_images, - ad_group_ad.ad.responsive_display_ad.youtube_videos - FROM ad_group_ad - WHERE + ad_group_ad.ad.responsive_display_ad.youtube_videos, + ad_group_ad.ad.display_url, -- 新增字段 + ad_group_ad.ad.final_app_urls, -- 新增字段 + ad_group_ad.ad.final_mobile_urls, -- 新增字段 + ad_group_ad.ad.final_url_suffix, -- 新增字段 + ad_group_ad.ad.final_urls -- 新增字段 + FROM ad_group_ad + WHERE ad_group_ad.status != 'REMOVED' "; // Issues a search stream request. /** @var GoogleAdsServerStreamDecorator $stream */ @@ -315,16 +372,27 @@ class GoogleAdsAdService extends BaseService // $finalUrlsList = $googleAdsRow->getAdGroupAd()->getAd()->getFinalUrls(); // 将最终的 URL 列表转换为 PHP 数组 // $finalUrlsArray = iterator_to_array($finalUrlsList); + $finalAppUrls = iterator_to_array($googleAdsRow->getAdGroupAd()->getAd()->getFinalAppUrls()); + $finalMobileUrls = iterator_to_array($googleAdsRow->getAdGroupAd()->getAd()->getFinalMobileUrls()); + $finalUrls = iterator_to_array($googleAdsRow->getAdGroupAd()->getAd()->getFinalUrls()); + $resourceName = []; $resourceName['ad_id'] = $googleAdsRow->getAdGroupAd()->getAd()->getId(); $resourceName['ad_name'] = $googleAdsRow->getAdGroupAd()->getAd()->getName(); $resourceName['ad_group_id'] = $googleAdsRow->getAdGroup()->getId(); $resourceName['campaign_id'] = $googleAdsRow->getCampaign()->getId(); $resourceName['customer_id'] = $googleAdsRow->getCustomer()->getId(); + // 新增字段 + + $resourceName['display_url'] = $googleAdsRow->getAdGroupAd()->getAd()->getDisplayUrl(); + $resourceName['final_app_urls'] = $finalAppUrls; + $resourceName['final_mobile_urls'] = $finalMobileUrls; + $resourceName['final_url_suffix'] = $googleAdsRow->getAdGroupAd()->getAd()->getFinalUrlSuffix(); + $resourceName['final_urls'] = $finalUrls; // $resourceName['final_urls'] = $finalUrlsArray; - $resourceName['status'] = $googleAdsRow->getAdGroupAd()->getStatus(); + $resourceName['status'] = $googleAdsRow->getAdGroupAd()->getStatus(); // $resourceName['resource_name'] = $googleAdsRow->getAdGroupAd()->getAd()->getResourceName(); - $adType = $googleAdsRow->getAdGroupAd()->getAd()->getType(); + $adType = $googleAdsRow->getAdGroupAd()->getAd()->getType(); //ad_type 19=> RESPONSIVE_DISPLAY_AD 自适应展示广告 详细看model定义 if ($adType === 19) { // 获取 squareMarketingImages 中的每个 asset diff --git a/app/service/GoogleAdsCampaignService.php b/app/service/GoogleAdsCampaignService.php index f677a1e..06f1ff9 100644 --- a/app/service/GoogleAdsCampaignService.php +++ b/app/service/GoogleAdsCampaignService.php @@ -203,7 +203,7 @@ class GoogleAdsCampaignService extends BaseService public function runListCampaigns(int $customerId, $options): mixed { - $googleAdsClient = new GoogleAdsClientService($options['refresh_token'], $options['login_customer_id']); + $googleAdsClient = new GoogleAdsClientService($options['refresh_token'], $options['login_customer_id']); // $campaignsResourceName = self::getCampaigns($googleAdsClient->getGoogleAdsClientWithloginCustomerId(), $customerId); $campaignsResourceName = self::getCampaignsNew($googleAdsClient->getGoogleAdsClientWithloginCustomerId(), $customerId); // dump(json_encode($campaignsResourceName)); @@ -220,7 +220,7 @@ class GoogleAdsCampaignService extends BaseService * @return mixed * @throws ApiException */ - public function runListDateDatas($customerId,$options, $date): mixed + public function runListDateDatas($customerId, $options, $date): mixed { // $googleAdsClient = $this->googleAdsClient; @@ -281,11 +281,11 @@ class GoogleAdsCampaignService extends BaseService // $googleAdsRow->getCampaignBudget()->getName(), // PHP_EOL // ); - $resourceName['campaign_id'] = $googleAdsRow->getCampaign()->getId(); - $resourceName['campaign_name'] = $googleAdsRow->getCampaign()->getName(); - $resourceName['status'] = $googleAdsRow->getCampaign()->getStatus(); - $resourceName['customer_id'] = $googleAdsRow->getCustomer()->getId(); - $resourceNames[] = $resourceName; + $resourceName['campaign_id'] = $googleAdsRow->getCampaign()->getId(); + $resourceName['campaign_name'] = $googleAdsRow->getCampaign()->getName(); + $resourceName['status'] = $googleAdsRow->getCampaign()->getStatus(); + $resourceName['customer_id'] = $googleAdsRow->getCustomer()->getId(); + $resourceNames[] = $resourceName; } return $resourceNames; } @@ -370,8 +370,44 @@ class GoogleAdsCampaignService extends BaseService $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient(); // Creates a query that retrieves all campaigns. - $query = "SELECT ad_group_ad.ad.id, ad_group_ad.ad.name, ad_group_ad.ad.resource_name, ad_group.id, campaign.id, customer.id, metrics.clicks, metrics.cost_micros, metrics.conversions, metrics.conversions_value, metrics.impressions FROM ad_group_ad WHERE segments.date = '{$date}' ORDER BY ad_group.id ASC LIMIT 10000"; +// $query = "SELECT ad_group_ad.ad.id, ad_group_ad.ad.name, ad_group_ad.ad.resource_name, ad_group.id, campaign.id, customer.id, metrics.clicks, metrics.cost_micros, metrics.conversions, metrics.conversions_value, metrics.impressions FROM ad_group_ad WHERE segments.date = '{$date}' ORDER BY ad_group.id ASC LIMIT 10000"; + $query = "SELECT + ad_group_ad.ad.id, + ad_group_ad.ad.name, + ad_group_ad.ad.resource_name, + ad_group.id, + campaign.id, + customer.id, + metrics.clicks, + metrics.cost_micros, + metrics.conversions, + metrics.conversions_value, + metrics.impressions, + metrics.interactions,-- 新增字段 + metrics.orders,-- 新增字段 + metrics.revenue_micros,-- 新增字段 + metrics.value_per_all_conversions,-- 新增字段 + metrics.value_per_all_conversions_by_conversion_date,-- 新增字段 + metrics.value_per_conversion,-- 新增字段 + metrics.value_per_conversions_by_conversion_date,-- 新增字段 + metrics.video_quartile_p25_rate,-- 新增字段 + metrics.video_quartile_p50_rate,-- 新增字段 + metrics.video_quartile_p75_rate,-- 新增字段 + metrics.video_quartile_p100_rate,-- 新增字段 + metrics.video_view_rate,-- 新增字段 + metrics.video_views,-- 新增字段 + metrics.view_through_conversions -- 新增字段 + FROM + ad_group_ad + WHERE + segments.date = '{$date}' + ORDER BY + ad_group.id ASC + LIMIT 10000 + "; + // dump($query);return; + // Issues a search stream request. /** @var GoogleAdsServerStreamDecorator $stream */ $stream = $googleAdsServiceClient->searchStream( @@ -397,7 +433,21 @@ class GoogleAdsCampaignService extends BaseService $resourceName['month'] = $month; $resourceName['season'] = $season; $resourceName['year'] = $year; - + // 新增字段 + $resourceName['interactions'] = $googleAdsRow->getMetrics()->getInteractions(); + $resourceName['orders'] = $googleAdsRow->getMetrics()->getOrders(); + $resourceName['revenue_micros'] = $googleAdsRow->getMetrics()->getRevenueMicros(); + $resourceName['value_per_all_conversions'] = $googleAdsRow->getMetrics()->getValuePerAllConversions(); + $resourceName['value_per_all_conversions_by_conversion_date'] = $googleAdsRow->getMetrics()->getValuePerAllConversionsByConversionDate(); + $resourceName['value_per_conversion'] = $googleAdsRow->getMetrics()->getValuePerConversion(); + $resourceName['value_per_conversions_by_conversion_date'] = $googleAdsRow->getMetrics()->getValuePerConversionsByConversionDate(); + $resourceName['video_quartile_p25_rate'] = $googleAdsRow->getMetrics()->getVideoQuartileP25Rate(); + $resourceName['video_quartile_p50_rate'] = $googleAdsRow->getMetrics()->getVideoQuartileP50Rate(); + $resourceName['video_quartile_p75_rate'] = $googleAdsRow->getMetrics()->getVideoQuartileP75Rate(); + $resourceName['video_quartile_p100_rate'] = $googleAdsRow->getMetrics()->getVideoQuartileP100Rate(); + $resourceName['video_view_rate'] = $googleAdsRow->getMetrics()->getVideoViewRate(); + $resourceName['video_views'] = $googleAdsRow->getMetrics()->getVideoViews(); + $resourceName['view_through_conversions'] = $googleAdsRow->getMetrics()->getViewThroughConversions(); // $resourceName['budget_id'] = $googleAdsRow->getCampaignBudget()->getId(); $resourceNames[] = $resourceName; @@ -479,6 +529,7 @@ class GoogleAdsCampaignService extends BaseService ThinkDb::execute($sql, $data); } } + /** * 在数据库中保存广告系列信息 * @param $campaignsResourceName @@ -525,8 +576,16 @@ class GoogleAdsCampaignService extends BaseService // ThinkDb::execute($sql, $data); $sql = "INSERT INTO bps.bps_google_ad_day_data - (ad_id, customer_id, ad_name, ad_resource_name, ad_group_id, campaign_id, clicks, cost_micros, conversions, conversions_value, impressions, date, month, season, year) - VALUES (:ad_id, :customer_id, :ad_name, :ad_resource_name, :ad_group_id, :campaign_id, :clicks, :cost_micros, :conversions, :conversions_value, :impressions, :date, :month, :season, :year) + (ad_id, customer_id, ad_name, ad_resource_name, ad_group_id, campaign_id, clicks, cost_micros, conversions, conversions_value, impressions, date, month, season, year,interactions, orders, revenue_micros, value_per_all_conversions, + value_per_all_conversions_by_conversion_date, value_per_conversion, + value_per_conversions_by_conversion_date, video_quartile_p25_rate, + video_quartile_p50_rate, video_quartile_p75_rate, video_quartile_p100_rate, + video_view_rate, video_views, view_through_conversions) + VALUES (:ad_id, :customer_id, :ad_name, :ad_resource_name, :ad_group_id, :campaign_id, :clicks, :cost_micros, :conversions, :conversions_value, :impressions, :date, :month, :season, :year,:interactions, :orders, :revenue_micros, :value_per_all_conversions, + :value_per_all_conversions_by_conversion_date, :value_per_conversion, + :value_per_conversions_by_conversion_date, :video_quartile_p25_rate, + :video_quartile_p50_rate, :video_quartile_p75_rate, :video_quartile_p100_rate, + :video_view_rate, :video_views, :view_through_conversions) ON CONFLICT (ad_id, date) DO UPDATE SET customer_id = EXCLUDED.customer_id, @@ -542,6 +601,20 @@ class GoogleAdsCampaignService extends BaseService month = EXCLUDED.month, season = EXCLUDED.season, year = EXCLUDED.year, + interactions = EXCLUDED.interactions, + orders = EXCLUDED.orders, + revenue_micros = EXCLUDED.revenue_micros, + value_per_all_conversions = EXCLUDED.value_per_all_conversions, + value_per_all_conversions_by_conversion_date = EXCLUDED.value_per_all_conversions_by_conversion_date, + value_per_conversion = EXCLUDED.value_per_conversion, + value_per_conversions_by_conversion_date = EXCLUDED.value_per_conversions_by_conversion_date, + video_quartile_p25_rate = EXCLUDED.video_quartile_p25_rate, + video_quartile_p50_rate = EXCLUDED.video_quartile_p50_rate, + video_quartile_p75_rate = EXCLUDED.video_quartile_p75_rate, + video_quartile_p100_rate = EXCLUDED.video_quartile_p100_rate, + video_view_rate = EXCLUDED.video_view_rate, + video_views = EXCLUDED.video_views, + view_through_conversions = EXCLUDED.view_through_conversions, update_at = EXCLUDED.update_at"; // 更新其他字段和更新时间戳 // dump($sql, $data); ThinkDb::execute($sql, $data); @@ -724,7 +797,7 @@ class GoogleAdsCampaignService extends BaseService public function runUpdateCampaign($options): mixed { - $googleAdsClient = new GoogleAdsClientService($options['refresh_token'],$options['login_customer_id']); + $googleAdsClient = new GoogleAdsClientService($options['refresh_token'], $options['login_customer_id']); // Creates a single shared budget to be used by the campaigns added below. $resourceName = self::updateCampaign($googleAdsClient->getGoogleAdsClient(), $options['customer_id'], $options['campaign_id'], $options['status']);