471 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			471 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | ||
| 
 | ||
| namespace app\service;
 | ||
| 
 | ||
| use app\service\GoogleAdsClientService;
 | ||
| use app\model\ThirdUserAdvertiser;
 | ||
| use app\util\Helper;
 | ||
| use app\util\ArgumentNames;
 | ||
| use app\util\ArgumentParser;
 | ||
| 
 | ||
| use Google\Ads\GoogleAds\Lib\V18\GoogleAdsClient;
 | ||
| 
 | ||
| use Google\Ads\GoogleAds\Util\FieldMasks;
 | ||
| use Google\Ads\GoogleAds\Util\V18\ResourceNames;
 | ||
| use Google\Ads\GoogleAds\V18\Enums\AdGroupStatusEnum\AdGroupStatus;
 | ||
| use Google\Ads\GoogleAds\V18\Enums\AdGroupTypeEnum\AdGroupType;
 | ||
| use Google\Ads\GoogleAds\V18\Errors\GoogleAdsError;
 | ||
| use Google\Ads\GoogleAds\V18\Resources\AdGroup;
 | ||
| use Google\Ads\GoogleAds\V18\Services\AdGroupOperation;
 | ||
| use Google\Ads\GoogleAds\V18\Services\MutateAdGroupsRequest;
 | ||
| use Google\Ads\GoogleAds\V18\Services\SearchGoogleAdsStreamRequest;
 | ||
| use Google\ApiCore\ApiException;
 | ||
| use think\facade\Db as ThinkDb;
 | ||
| use app\model\AdGroup as AdGroupModel;
 | ||
| 
 | ||
| 
 | ||
| class GoogleAdsGroupService extends BaseService
 | ||
| {
 | ||
|     private $googleAdsClient;
 | ||
|     private $customerId;
 | ||
| 
 | ||
|     public function __construct($customerId = null)
 | ||
|     {
 | ||
| 
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     // 从数据库动态获取 google RefreshToken
 | ||
| //    private function getRefreshTokenFromDatabase($advertiserId)
 | ||
| //    {
 | ||
| //        // 通过 advertiser_id 查询 ThirdUserAdvertiser,联表查询 ThirdUser 数据
 | ||
| //        $userAdvertiser = ThirdUserAdvertiser::with('googleUser')  // 联表查询 user 关联
 | ||
| //        ->where('advertiser_id', $advertiserId)  // 根据 advertiser_id 查询
 | ||
| //        ->find();  // 获取第一个结果
 | ||
| //
 | ||
| //// 如果找到广告主数据
 | ||
| //        if ($userAdvertiser && $userAdvertiser->googleUser) {
 | ||
| //            // 获取关联用户的 access_token
 | ||
| //            return $userAdvertiser->googleUser ? $userAdvertiser->googleUser->access_token : null;
 | ||
| //        } else {
 | ||
| ////            return $this->errorResponse('101', '未找到该广告主或关联的用户');
 | ||
| //        }
 | ||
| //    }
 | ||
| 
 | ||
| 
 | ||
|     /* @param int $customerId the customer ID
 | ||
|      * @param $options
 | ||
|      * @return mixed
 | ||
|      * @throws ApiException
 | ||
|      */
 | ||
|     public function runListGroups(int $customerId, $options): mixed
 | ||
|     {
 | ||
| 
 | ||
| //        $googleAdsClient = $this->googleAdsClient;
 | ||
| //        dump($customerId,$options['refresh_token']);
 | ||
|         $googleAdsClient = new GoogleAdsClientService($options['refresh_token'],$options['login_customer_id']);
 | ||
|         // Creates a single shared budget to be used by the campaigns added below.
 | ||
| //        $groupsResourceName = self::getGroups($googleAdsClient->getGoogleAdsClientWithloginCustomerId(), $customerId);
 | ||
|         $groupsResourceName = self::getGroupsNew($googleAdsClient->getGoogleAdsClientWithloginCustomerId(), $customerId);
 | ||
| //        dump(json_encode($groupsResourceName));
 | ||
|         if (is_array($groupsResourceName)) {
 | ||
| //            self::saveGroups($groupsResourceName);
 | ||
|             self::saveGroupsNew($groupsResourceName);
 | ||
|         }
 | ||
| 
 | ||
|         return $groupsResourceName;
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      *  在数据库中保存广告系列信息
 | ||
|      * @param $groupsResourceName
 | ||
|      * @return void
 | ||
|      */
 | ||
|     public static function saveGroups($groupsResourceName)
 | ||
|     {
 | ||
|         $tableName = 'bps_google_ads_ad_group';
 | ||
|         $tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'public' . $tableName;
 | ||
|         foreach ($groupsResourceName as $data) {
 | ||
|             $sql = "INSERT INTO  {$tableName}
 | ||
|         (ad_group_id, campaign_id, customer_id, ad_group_name, status, cpc_bid_micros)
 | ||
|             VALUES (:ad_group_id, :campaign_id, :customer_id, :ad_group_name, :status, :cpc_bid_micros)
 | ||
|             ON CONFLICT (ad_group_id) 
 | ||
|             DO UPDATE SET
 | ||
|                 campaign_id = EXCLUDED.campaign_id,
 | ||
|                 customer_id = EXCLUDED.customer_id,
 | ||
|                 ad_group_name = EXCLUDED.ad_group_name,
 | ||
|                 status = EXCLUDED.status,
 | ||
|                 cpc_bid_micros = EXCLUDED.cpc_bid_micros,
 | ||
|                 update_at = EXCLUDED.update_at";
 | ||
| 
 | ||
|             ThinkDb::execute($sql, $data);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      *  在数据库中保存广告系列信息
 | ||
|      * @param $groupsResourceName
 | ||
|      * @return void
 | ||
|      */
 | ||
|     public static function saveGroupsNew($groupsResourceName)
 | ||
|     {
 | ||
|         $tableName = 'bps_ads_set';
 | ||
|         $tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'public' . $tableName;
 | ||
|         foreach ($groupsResourceName as $data) {
 | ||
|             $sql = "INSERT INTO  {$tableName}
 | ||
|         (ad_set_id, campaign_id, account_id, name, status,platform_type, last_sync_time, update_at)
 | ||
|             VALUES (:ad_group_id, :campaign_id, :customer_id, :ad_group_name, :status,2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
 | ||
|             ON CONFLICT (platform_type,ad_set_id)
 | ||
|             DO UPDATE SET
 | ||
|                 campaign_id = EXCLUDED.campaign_id,
 | ||
|                 account_id = EXCLUDED.account_id,
 | ||
|                 name = EXCLUDED.name,
 | ||
|                 status = EXCLUDED.status,
 | ||
|                 last_sync_time = CURRENT_TIMESTAMP,  -- 使用当前时间戳
 | ||
|                 update_at = CURRENT_TIMESTAMP
 | ||
|             WHERE {$tableName}.platform_type = 2";
 | ||
|             ThinkDb::execute($sql, $data);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      * Runs the example.
 | ||
|      *
 | ||
|      * @param GoogleAdsClient $googleAdsClient the Google Ads API client
 | ||
|      * @param int $customerId the customer ID
 | ||
|      */
 | ||
|     // [START get_campaigns]
 | ||
| 
 | ||
|     public static function getGroupsNew(GoogleAdsClient $googleAdsClient, int $customerId)
 | ||
|     {
 | ||
|         $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
 | ||
|         // Creates a query that retrieves all groups.
 | ||
| 
 | ||
| //            $response = $googleAdsServiceClient->search($customerId, $query);
 | ||
|         $query = "SELECT 
 | ||
|                               ad_group.id, 
 | ||
|                               ad_group.name, 
 | ||
|                               campaign.id, 
 | ||
|                               customer.id, 
 | ||
|                               ad_group.status, 
 | ||
|                               ad_group.cpc_bid_micros 
 | ||
|                             FROM ad_group 
 | ||
|                             WHERE 
 | ||
|                               ad_group.status != 'REMOVED'  ";
 | ||
|         // Issues a search stream request.
 | ||
|         /** @var GoogleAdsServerStreamDecorator $stream */
 | ||
|         $stream        = $googleAdsServiceClient->searchStream(
 | ||
|             SearchGoogleAdsStreamRequest::build($customerId, $query)
 | ||
|         );
 | ||
|         $resourceNames = [];
 | ||
|         // Iterates over all rows in all messages and prints the requested field values for
 | ||
|         // the campaign in each row.
 | ||
|         foreach ($stream->iterateAllElements() as $googleAdsRow) {
 | ||
|             /** @var GoogleAdsRow $googleAdsRow */
 | ||
| //            printf(
 | ||
| //                "Campaign with ID %d and name '%s' was found.BudgetID %s: %d %s",
 | ||
| //                $googleAdsRow->getCampaign()->getId(),
 | ||
| //                $googleAdsRow->getCampaign()->getName(),
 | ||
| //                $googleAdsRow->getCampaignBudget()->getName(),
 | ||
| //                $googleAdsRow->getCampaignBudget()->getAmountMicros(),
 | ||
| //
 | ||
| //                $googleAdsRow->getCampaignBudget()->getName(),
 | ||
| //                PHP_EOL
 | ||
| //            );
 | ||
|             $resourceName['ad_group_id']    = $googleAdsRow->getAdGroup()->getId();
 | ||
|             $resourceName['ad_group_name']  = $googleAdsRow->getAdGroup()->getName();
 | ||
|             $resourceName['status']         = $googleAdsRow->getAdGroup()->getStatus();
 | ||
|             $resourceName['campaign_id']    = $googleAdsRow->getCampaign()->getId();
 | ||
|             $resourceName['customer_id']    = $googleAdsRow->getCustomer()->getId();
 | ||
|             $resourceNames[]                = $resourceName;
 | ||
|         }
 | ||
|         return $resourceNames;
 | ||
|     }
 | ||
|     public static function getGroups(GoogleAdsClient $googleAdsClient, int $customerId)
 | ||
|     {
 | ||
|         $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
 | ||
|         // Creates a query that retrieves all groups.
 | ||
| 
 | ||
| //            $response = $googleAdsServiceClient->search($customerId, $query);
 | ||
|         $query = "SELECT 
 | ||
|                               ad_group.id, 
 | ||
|                               ad_group.name, 
 | ||
|                               campaign.id, 
 | ||
|                               customer.id, 
 | ||
|                               ad_group.status, 
 | ||
|                               ad_group.cpc_bid_micros 
 | ||
|                             FROM ad_group 
 | ||
|                             WHERE 
 | ||
|                               ad_group.status != 'REMOVED'  ";
 | ||
|         // Issues a search stream request.
 | ||
|         /** @var GoogleAdsServerStreamDecorator $stream */
 | ||
|         $stream        = $googleAdsServiceClient->searchStream(
 | ||
|             SearchGoogleAdsStreamRequest::build($customerId, $query)
 | ||
|         );
 | ||
|         $resourceNames = [];
 | ||
|         // Iterates over all rows in all messages and prints the requested field values for
 | ||
|         // the campaign in each row.
 | ||
|         foreach ($stream->iterateAllElements() as $googleAdsRow) {
 | ||
|             /** @var GoogleAdsRow $googleAdsRow */
 | ||
| //            printf(
 | ||
| //                "Campaign with ID %d and name '%s' was found.BudgetID %s: %d %s",
 | ||
| //                $googleAdsRow->getCampaign()->getId(),
 | ||
| //                $googleAdsRow->getCampaign()->getName(),
 | ||
| //                $googleAdsRow->getCampaignBudget()->getName(),
 | ||
| //                $googleAdsRow->getCampaignBudget()->getAmountMicros(),
 | ||
| //
 | ||
| //                $googleAdsRow->getCampaignBudget()->getName(),
 | ||
| //                PHP_EOL
 | ||
| //            );
 | ||
|             $resourceName['ad_group_id']    = $googleAdsRow->getAdGroup()->getId();
 | ||
|             $resourceName['ad_group_name']  = $googleAdsRow->getAdGroup()->getName();
 | ||
|             $resourceName['cpc_bid_micros'] = $googleAdsRow->getAdGroup()->getCpcBidMicros();
 | ||
|             $resourceName['status']         = $googleAdsRow->getAdGroup()->getStatus();
 | ||
|             $resourceName['campaign_id']    = $googleAdsRow->getCampaign()->getId();
 | ||
|             $resourceName['customer_id']    = $googleAdsRow->getCustomer()->getId();
 | ||
|             $resourceNames[]                = $resourceName;
 | ||
|         }
 | ||
|         return $resourceNames;
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      * This example updates a campaign by setting the status to `PAUSED`. To get campaigns, run
 | ||
|      * GetCampaigns.php.
 | ||
|      */
 | ||
|     /* @param int $customerId the customer ID
 | ||
|      * @param $options
 | ||
|      * @return mixed
 | ||
|      * @throws ApiException
 | ||
|      */
 | ||
|     public function runAddGroup($options): mixed
 | ||
|     {
 | ||
| //        $googleAdsClient = $this->googleAdsClient;
 | ||
|         $googleAdsClient = new GoogleAdsClientService($options['refresh_token']);
 | ||
|         // Creates a single shared budget to be used by the campaigns added below.
 | ||
|         $resourceNames = self::addGroup($googleAdsClient->getGoogleAdsClient(), $options['customer_id'], $options['campaign_id']);
 | ||
| 
 | ||
|         return $resourceNames;
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      * Runs the addGroup example.
 | ||
|      *
 | ||
|      * @param GoogleAdsClient $googleAdsClient the Google Ads API client
 | ||
|      * @param int $customerId the customer ID
 | ||
|      * @param int $campaignId the campaign ID to add ad groups to
 | ||
|      */
 | ||
|     public static function addGroup(
 | ||
|         GoogleAdsClient $googleAdsClient,
 | ||
|         int             $customerId,
 | ||
|         int             $campaignId
 | ||
|     )
 | ||
|     {
 | ||
|         $campaignResourceName = ResourceNames::forCampaign($customerId, $campaignId);
 | ||
| 
 | ||
|         $operations = [];
 | ||
| 
 | ||
|         // Constructs an ad group and sets an optional CPC value.
 | ||
|         $adGroup1 = new AdGroup([
 | ||
|             'name' => 'Earth to Mars Cruises #' . Helper::getPrintableDatetime(),
 | ||
|             'campaign' => $campaignResourceName,
 | ||
|             'status' => AdGroupStatus::ENABLED,
 | ||
|             'type' => AdGroupType::SEARCH_STANDARD,
 | ||
|             'cpc_bid_micros' => 10000000
 | ||
|         ]);
 | ||
| 
 | ||
|         $adGroupOperation1 = new AdGroupOperation();
 | ||
|         $adGroupOperation1->setCreate($adGroup1);
 | ||
|         $operations[] = $adGroupOperation1;
 | ||
| 
 | ||
|         // Constructs another ad group.
 | ||
|         $adGroup2 = new AdGroup([
 | ||
|             'name' => 'Earth to Venus Cruises #' . Helper::getPrintableDatetime(),
 | ||
|             'campaign' => $campaignResourceName,
 | ||
|             'status' => AdGroupStatus::ENABLED,
 | ||
|             'type' => AdGroupType::SEARCH_STANDARD,
 | ||
|             'cpc_bid_micros' => 20000000
 | ||
|         ]);
 | ||
| 
 | ||
|         $adGroupOperation2 = new AdGroupOperation();
 | ||
|         $adGroupOperation2->setCreate($adGroup2);
 | ||
|         $operations[] = $adGroupOperation2;
 | ||
| 
 | ||
|         // Issues a mutate request to add the ad groups.
 | ||
|         $adGroupServiceClient = $googleAdsClient->getAdGroupServiceClient();
 | ||
|         $response             = $adGroupServiceClient->mutateAdGroups(MutateAdGroupsRequest::build(
 | ||
|             $customerId,
 | ||
|             $operations
 | ||
|         ));
 | ||
|         $resourceNames        = [];
 | ||
| 
 | ||
|         printf("Added %d ad groups:%s", $response->getResults()->count(), PHP_EOL);
 | ||
| 
 | ||
|         foreach ($response->getResults() as $addedAdGroup) {
 | ||
|             /** @var AdGroup $addedAdGroup */
 | ||
|             print $addedAdGroup->getResourceName() . PHP_EOL;
 | ||
|             $resourceNames[] = $addedAdGroup->getResourceName();
 | ||
|         }
 | ||
|         return $resourceNames;
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      * This example updates the CPC bid and status for a given ad group. To get ad groups, run
 | ||
|      * GetAdGroups.php.
 | ||
|      * @param $options
 | ||
|      * @return mixed
 | ||
|      * @throws ApiException
 | ||
|      */
 | ||
|     public function runUpdateGroup($options): mixed
 | ||
|     {
 | ||
| //        $googleAdsClient = $this->googleAdsClient;
 | ||
|         $googleAdsClient = new GoogleAdsClientService($options['refresh_token'],$options['login_customer_id']);
 | ||
|         // Creates a single shared budget to be used by the campaigns added below.
 | ||
| 
 | ||
| //        $resourceNames = self::updateGroup($googleAdsClient, $options['customer_id'], $options['group_id'],  $options['status'], $options['bid_micro_amount'],);
 | ||
|         $resourceNames = self::updateGroup($googleAdsClient->getGoogleAdsClient(), $options['customer_id'], $options['group_id'], $options['status']);
 | ||
| 
 | ||
|         return $resourceNames;
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * Runs the updateAdGroup example.
 | ||
|      *
 | ||
|      * @param GoogleAdsClient $googleAdsClient the Google Ads API client
 | ||
|      * @param int $customerId the customer ID
 | ||
|      * @param int $adGroupId the ID of ad group to update
 | ||
|      * @param int $bidMicroAmount the bid amount in micros to use for the ad group bid
 | ||
|      */
 | ||
|     // [START update_ad_group]
 | ||
|     public static function updateGroup(
 | ||
|         GoogleAdsClient $googleAdsClient,
 | ||
|         int             $customerId,
 | ||
|         int             $adGroupId,
 | ||
|         int             $status,
 | ||
|         //                        $bidMicroAmount
 | ||
|     )
 | ||
|     {
 | ||
| 
 | ||
|         // Creates an ad group object with the specified resource name and other changes.
 | ||
|         $adGroup = new AdGroup([
 | ||
|             'resource_name' => ResourceNames::forAdGroup($customerId, $adGroupId),
 | ||
| //            'cpc_bid_micros' => $bidMicroAmount,
 | ||
| //            'status' => AdGroupStatus::PAUSED
 | ||
|             'status' => $status
 | ||
|         ]);
 | ||
| 
 | ||
|         // Constructs an operation that will update the ad group 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.
 | ||
|         $adGroupOperation = new AdGroupOperation();
 | ||
|         $adGroupOperation->setUpdate($adGroup);
 | ||
|         $adGroupOperation->setUpdateMask(FieldMasks::allSetFieldsOf($adGroup));
 | ||
| 
 | ||
|         // Issues a mutate request to update the ad group.
 | ||
|         $adGroupServiceClient = $googleAdsClient->getAdGroupServiceClient();
 | ||
|         $response             = $adGroupServiceClient->mutateAdGroups(MutateAdGroupsRequest::build(
 | ||
|             $customerId,
 | ||
|             [$adGroupOperation]
 | ||
|         ));
 | ||
| 
 | ||
|         // Prints the resource name of the updated ad group.
 | ||
|         /** @var AdGroup $updatedAdGroup */
 | ||
|         $updatedAdGroup = $response->getResults()[0];
 | ||
|         printf(
 | ||
|             "Updated ad group with resource name: '%s'%s",
 | ||
|             $updatedAdGroup->getResourceName(),
 | ||
|             PHP_EOL
 | ||
|         );
 | ||
|         return $updatedAdGroup->getResourceName();
 | ||
|     }
 | ||
|     // [END update_ad_group]
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      * 更新广告组状态
 | ||
|      */
 | ||
|     public function updateGroupStatus($options)
 | ||
|     {
 | ||
|         // 从数据库获取 AdGroup
 | ||
|         $adGroup = AdGroupModel::find($options['group_id']);
 | ||
|         if (!$adGroup) {
 | ||
|             return false;
 | ||
| //            throw new ValidateException('AdGroup not found');
 | ||
|         }
 | ||
| 
 | ||
|         // 更新数据库中的状态
 | ||
| //        $adGroup->updateStatus($status);
 | ||
|         if ($this->modifyDbGroupStatus($options['group_id'], $options['status'])) {
 | ||
|             // 更新 Google Ads 上的状态
 | ||
| //            $googleAdsClient = $this->googleAdsClient;
 | ||
|              $googleAdsClient = new GoogleAdsClientService($options['refresh_token'], $options['login_customer_id']);
 | ||
| 
 | ||
|             $resourceName    = self::updateGroup($googleAdsClient->getGoogleAdsClientWithloginCustomerId(), $options['customer_id'], $options['group_id'], $options['status']);
 | ||
|             return true;
 | ||
|         }
 | ||
| 
 | ||
|         return false;
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 获取广告组状态
 | ||
|      */
 | ||
| //    public function getAdGroupStatus(int $adGroupId)
 | ||
| //    {
 | ||
| //        // 从数据库获取 AdGroup
 | ||
| //        $adGroup = AdGroupModel::find($adGroupId);
 | ||
| //        if (!$adGroup) {
 | ||
| //            throw new ValidateException('AdGroup not found');
 | ||
| //        }
 | ||
| //
 | ||
| //        // 返回广告组状态
 | ||
| //        return $adGroup->getStatusTextAttr(null, $adGroup->toArray());
 | ||
| //    }
 | ||
| 
 | ||
|     /**
 | ||
|      * 判断广告组是否启用
 | ||
|      */
 | ||
| //    public function isAdGroupEnabled(int $adGroupId)
 | ||
| //    {
 | ||
| //        $adGroup = AdGroup::find($adGroupId);
 | ||
| //        if (!$adGroup) {
 | ||
| //            throw new ValidateException('AdGroup not found');
 | ||
| //        }
 | ||
| //
 | ||
| //        return $adGroup->isEnabled();
 | ||
| //    }
 | ||
| 
 | ||
|     /**
 | ||
|      * 判断广告组是否暂停
 | ||
|      */
 | ||
| //    public function isAdGroupPaused(int $adGroupId)
 | ||
| //    {
 | ||
| //        $adGroup = AdGroup::find($adGroupId);
 | ||
| //        if (!$adGroup) {
 | ||
| //            throw new ValidateException('AdGroup not found');
 | ||
| //        }
 | ||
| //
 | ||
| //        return $adGroup->isPaused();
 | ||
| //    }
 | ||
| 
 | ||
|     /**
 | ||
|      * 判断广告组是否停止
 | ||
|      */
 | ||
| //    public function isAdGroupStopped(int $adGroupId)
 | ||
| //    {
 | ||
| //        $adGroup = AdGroup::find($adGroupId);
 | ||
| //        if (!$adGroup) {
 | ||
| //            throw new ValidateException('AdGroup not found');
 | ||
| //        }
 | ||
| //
 | ||
| //        return $adGroup->isStopped();
 | ||
| //    }
 | ||
| 
 | ||
| 
 | ||
| }
 | 
