From 96837526eb2d06c438eea3033e3b1a500ddbfae6 Mon Sep 17 00:00:00 2001 From: hgc Date: Tue, 17 Dec 2024 15:19:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B9=BF=E5=91=8A=20=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E3=80=81=E6=9B=B4=E6=96=B0=E6=93=8D=E4=BD=9C=EF=BC=9Bresponsiv?= =?UTF-8?q?e=20search=E5=B9=BF=E5=91=8A=20=E5=88=97=E8=A1=A8=E3=80=81?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/GoogleAdsController.php | 73 ++++++ app/service/GoogleAdsAdService.php | 316 +++++++++++++++++++++++++ config/route.php | 8 + 3 files changed, 397 insertions(+) create mode 100644 app/service/GoogleAdsAdService.php diff --git a/app/controller/GoogleAdsController.php b/app/controller/GoogleAdsController.php index 3dc8e65..2e01fd4 100644 --- a/app/controller/GoogleAdsController.php +++ b/app/controller/GoogleAdsController.php @@ -6,6 +6,7 @@ use Google\ApiCore\ApiException; use support\Request; use app\service\GoogleAdsCampaignService; use app\service\GoogleAdsGroupService; +use app\service\GoogleAdsAdService; use app\service\GoogleAdsAccountService; use support\Response; use DI\Annotation\Inject; @@ -25,6 +26,12 @@ class GoogleAdsController */ private $googleAdsGroupService; + /** + * @Inject + * @var GoogleAdsAdService + */ + private $googleAdsAdService; + /** * @Inject * @var GoogleAdsAccountService @@ -94,6 +101,32 @@ class GoogleAdsController return $this->modifyGroup($options); } + public function updateAd(Request $request) + { + $options = $request->all(); + + // 继续处理 Google Ads API 操作 + return $this->modifyAd($options); + } + + public function updateResponsiveSearchAd(Request $request) + { + $options = $request->all(); + + // 继续处理 Google Ads API 操作 + return $this->modifyResponsiveSearchAd($options); + } + + + + public function listResponsiveSearchAds(Request $request) + { + $options = $request->all(); + + // 继续处理 Google Ads API 操作 + return $this->getResponsiveSearchAds($options); + } + public function createLinkManagerToClient(Request $request) { $options = $request->all(); @@ -212,6 +245,46 @@ class GoogleAdsController $resourceName = $this->googleAdsGroupService->runUpdateGroup($options); return $this->successResponse(['group_updated' => $resourceName]); } + /** + * 更新广告 + * @throws ApiException + */ + public function modifyAd($options): Response + { + $adGroupStatus = [ + 0, // UNSPECIFIED + 1, // UNKNOWN + 2, // ENABLED + 3, // PAUSED + 4 // REMOVED + ]; + if (!in_array($options['status'], $adGroupStatus)) { + return $this->errorResponse(101, 'status参数错误'); + } + $resourceName = $this->googleAdsAdService->runUpdateAd($options); + return $this->successResponse(['ad_updated' => $resourceName]); + } + + + /** + * get campaigns + * @throws ApiException + */ + public function getResponsiveSearchAds($options): Response + { + $resourceName = $this->googleAdsAdService->runGetResponsiveSearchAds($options); + return $this->successResponse(['ads_list' => $resourceName]); + } + /** + * get campaigns + * @throws ApiException + */ + public function modifyResponsiveSearchAd($options): Response + { + $resourceName = $this->googleAdsAdService->runUpdateResponsiveSearchAd($options); + return $this->successResponse(['ad_updated' => $resourceName]); + } + // 可以加入一些公共方法 protected function successResponse($data): Response diff --git a/app/service/GoogleAdsAdService.php b/app/service/GoogleAdsAdService.php new file mode 100644 index 0000000..5edd57f --- /dev/null +++ b/app/service/GoogleAdsAdService.php @@ -0,0 +1,316 @@ +customerId = getenv('GOOGLE_ADS_CUSTOMER_ID'); + + // OAuth2 Token Authentication + $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build(); + + // Google Ads Client initialization + $this->googleAdsClient = (new GoogleAdsClientBuilder()) + ->fromFile() + ->withOAuth2Credential($oAuth2Credential) + ->build(); + } + /** + * This example updates the CPC bid and status for a given ad group. To get ad groups, run + * GetAdGroups.php. + */ + /* @param int $customerId the customer ID + * @param $options + * @return mixed + * @throws ApiException + */ + public function runUpdateAd($options): mixed + { + $googleAdsClient = $this->googleAdsClient; + // Creates a single shared budget to be used by the campaigns added below. + + $resourceNames = self::updateAd($googleAdsClient, $options['customer_id'], $options['group_id'], $options['ad_id'], $options['status']); + + return $resourceNames; + } + + + /** + * Runs the updateAd example. + * + * @param GoogleAdsClient $googleAdsClient the Google Ads API client + * @param int $customerId the customer ID + * @param int $adGroupId the ad group ID that the ad group ad belongs to + * @param int $adId the ID of the ad to pause + */ + public static function updateAd( + GoogleAdsClient $googleAdsClient, + int $customerId, + int $adGroupId, + int $adId, + int $status + ) + { + // Creates ad group ad resource name. + $adGroupAdResourceName = ResourceNames::forAdGroupAd($customerId, $adGroupId, $adId); + + // Creates an ad and sets its status to PAUSED. + $adGroupAd = new AdGroupAd(); + $adGroupAd->setResourceName($adGroupAdResourceName); +// $adGroupAd->setStatus(AdGroupAdStatus::PAUSED); + $adGroupAd->setStatus($status); + + // Constructs an operation that will pause the ad with the specified resource name, + // using the FieldMasks utility to derive the update mask. This mask tells the Google Ads + // API which attributes of the ad group you want to change. + $adGroupAdOperation = new AdGroupAdOperation(); + $adGroupAdOperation->setUpdate($adGroupAd); + $adGroupAdOperation->setUpdateMask(FieldMasks::allSetFieldsOf($adGroupAd)); + + // Issues a mutate request to pause the ad group ad. + $adGroupAdServiceClient = $googleAdsClient->getAdGroupAdServiceClient(); + $response = $adGroupAdServiceClient->mutateAdGroupAds(MutateAdGroupAdsRequest::build( + $customerId, + [$adGroupAdOperation] + )); + + // Prints the resource name of the paused ad group ad. + /** @var AdGroupAd $pausedAdGroupAd */ + $pausedAdGroupAd = $response->getResults()[0]; + printf( + "Ad group ad with resource name: '%s' is paused.%s", + $pausedAdGroupAd->getResourceName(), + PHP_EOL + ); + return $pausedAdGroupAd->getResourceName(); + } + + /** + * This example updates the CPC bid and status for a given ad group. To get ad groups, run + * GetAdGroups.php. + */ + /* @param int $customerId the customer ID + * @param $options + * @return mixed + * @throws ApiException + */ + public function runGetResponsiveSearchAds($options): mixed + { + $googleAdsClient = $this->googleAdsClient; + // Creates a single shared budget to be used by the campaigns added below. + if (!isset($options['group_id'])) { + $options['group_id'] = null; + } + $resourceNames = self::getResponsiveSearchAds($googleAdsClient, $options['customer_id'], $options['group_id']); + + return $resourceNames; + } + + /** + * 获取指定广告组中未移除的自适应搜索广告。 + * + * @param GoogleAdsClient $googleAdsClient the Google Ads API client + * @param int $customerId the customer ID + * @param int|null $adGroupId the ad group ID for which responsive search ads will be retrieved. + * If `null`, returns from all ad groups + */ + public static function getResponsiveSearchAds( + GoogleAdsClient $googleAdsClient, + int $customerId, + ?int $adGroupId + ) + { + $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient(); + + // Creates a query that retrieves responsive search ads. + $query = + 'SELECT ad_group.id, ' + . 'ad_group_ad.ad.id, ' + . 'ad_group_ad.ad.responsive_search_ad.headlines, ' + . 'ad_group_ad.ad.responsive_search_ad.descriptions, ' + . 'ad_group_ad.status ' + . 'FROM ad_group_ad ' + . 'WHERE ad_group_ad.ad.type = RESPONSIVE_SEARCH_AD ' + . 'AND ad_group_ad.status != "REMOVED"'; + if (!is_null($adGroupId)) { + $query .= " AND ad_group.id = $adGroupId"; + } + + // Issues a search request. + $response = + $googleAdsServiceClient->search(SearchGoogleAdsRequest::build($customerId, $query)); + + // Iterates over all rows in all pages and prints the requested field values for + // the responsive search ad in each row. + $isEmptyResult = true; + $resources = []; + foreach ($response->iterateAllElements() as $googleAdsRow) { + /** @var GoogleAdsRow $googleAdsRow */ + $isEmptyResult = false; + $ad = $googleAdsRow->getAdGroupAd()->getAd(); + $resource = []; +// printf( +// "Responsive search ad with resource name '%s' and status '%s' was found.%s", +// $ad->getResourceName(), +// AdGroupAdStatus::name($googleAdsRow->getAdGroupAd()->getStatus()), +// PHP_EOL +// ); + $resource['resource_name'] = $ad->getResourceName(); + $resource['status'] = AdGroupAdStatus::name($googleAdsRow->getAdGroupAd()->getStatus()); + $responsiveSearchAdInfo = $ad->getResponsiveSearchAd(); +// printf( +// 'Headlines:%1$s%2$sDescriptions:%1$s%3$s%1$s', +// PHP_EOL, +// self::convertAdTextAssetsToString($responsiveSearchAdInfo->getHeadlines()), +// self::convertAdTextAssetsToString($responsiveSearchAdInfo->getDescriptions()) +// ) + $resource['content'] = sprintf( + 'Headlines:%1$s%2$sDescriptions:%1$s%3$s%1$s', + PHP_EOL, + self::convertAdTextAssetsToString($responsiveSearchAdInfo->getHeadlines()), + self::convertAdTextAssetsToString($responsiveSearchAdInfo->getDescriptions()) + ); + $resources[] = $resource; + } + return $resources; +// if ($isEmptyResult) { +// print 'No responsive search ads were found.' . PHP_EOL; +// } + } + + /** + * Converts the list of AdTextAsset objects into a string representation. + * + * @param RepeatedField $assets the list of AdTextAsset objects + * @return string the string representation of the provided list of AdTextAsset objects + */ + private static function convertAdTextAssetsToString(RepeatedField $assets): string + { + $result = ''; + foreach ($assets as $asset) { + /** @var AdTextAsset $asset */ + $result .= sprintf( + "\t%s pinned to %s.%s", + $asset->getText(), + ServedAssetFieldType::name($asset->getPinnedField()), + PHP_EOL + ); + } + return $result; + } + + /** + * This example updates the CPC bid and status for a given ad group. To get ad groups, run + * GetAdGroups.php. + */ + /* @param int $customerId the customer ID + * @param $options + * @return mixed + * @throws ApiException + */ + public function runUpdateResponsiveSearchAd($options): mixed + { + $googleAdsClient = $this->googleAdsClient; + // Creates a single shared budget to be used by the campaigns added below. + $resourceName = self::updateResponsiveSearchAd($googleAdsClient, $options['customer_id'], $options['ad_id']); + + return $resourceName; + } + + /** + * updateResponsiveSearchAd. + * + * @param GoogleAdsClient $googleAdsClient the Google Ads API client + * @param int $customerId the customer ID + * @param int $adId the ad ID to update + */ + // [START update_responsive_search_ad] + public static function updateResponsiveSearchAd( + GoogleAdsClient $googleAdsClient, + int $customerId, + int $adId + ) + { + // Creates an ad with the specified resource name and other changes. + $ad = new Ad([ + 'resource_name' => ResourceNames::forAd($customerId, $adId), + 'responsive_search_ad' => new ResponsiveSearchAdInfo([ + // Update some properties of the responsive search ad. + 'headlines' => [ + new AdTextAsset([ + 'text' => 'Cruise to Pluto #' . Helper::getShortPrintableDatetime(), + 'pinned_field' => ServedAssetFieldType::HEADLINE_1 + ]), + new AdTextAsset(['text' => 'Tickets on sale now','pinned_field' => ServedAssetFieldType::HEADLINE_2]), + new AdTextAsset(['text' => 'Buy your ticket now']) + ], + 'descriptions' => [ + new AdTextAsset(['text' => 'Best space cruise ever.']), + new AdTextAsset([ + 'text' => 'The most wonderful space experience you will ever have.']) + ] + ]), + 'final_urls' => ['http://www.baidu.com'], + 'final_mobile_urls' => ['http://www.baidu.com/mobile'] + ]); + + // Constructs an operation that will update the ad, using the FieldMasks to derive the + // update mask. This mask tells the Google Ads API which attributes of the ad you want to + // change. + $adOperation = new AdOperation(); + $adOperation->setUpdate($ad); + $adOperation->setUpdateMask(FieldMasks::allSetFieldsOf($ad)); + + // Issues a mutate request to update the ad. + $adServiceClient = $googleAdsClient->getAdServiceClient(); + $response = + $adServiceClient->mutateAds(MutateAdsRequest::build($customerId, [$adOperation])); + + // Prints the resource name of the updated ad. + /** @var Ad $updatedAd */ + $updatedAd = $response->getResults()[0]; + printf( + "Updated ad with resource name: '%s'.%s", + $updatedAd->getResourceName(), + PHP_EOL + ); + return $updatedAd->getResourceName(); + } + // [END update_responsive_search_ad] + + +} diff --git a/config/route.php b/config/route.php index 7cdf79e..330b711 100644 --- a/config/route.php +++ b/config/route.php @@ -48,6 +48,14 @@ Route::group('/googleads', function () { Route::group('/group', function () { Route::post('/update', [GoogleAdsController::class, 'updateGroup']); }); + Route::group('/ad', function () { + Route::post('/update', [GoogleAdsController::class, 'updateAd']); + Route::group('/responsive_search', function () { + Route::post('/list', [GoogleAdsController::class, 'listResponsiveSearchAds']); + Route::post('/update', [GoogleAdsController::class, 'updateResponsiveSearchAd']); + }); + }); + Route::group('/account_link', function () { Route::post('/create', [GoogleAdsController::class, 'createLinkManagerToClient']); });