761 lines
31 KiB
PHP
761 lines
31 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\Lib\V18\GoogleAdsServerStreamDecorator;
|
||
use Google\Ads\GoogleAds\Util\FieldMasks;
|
||
use Google\Ads\GoogleAds\Util\V18\ResourceNames;
|
||
use Google\Ads\GoogleAds\V18\Common\ManualCpc;
|
||
use Google\Ads\GoogleAds\V18\Enums\AdvertisingChannelTypeEnum\AdvertisingChannelType;
|
||
use Google\Ads\GoogleAds\V18\Enums\BudgetDeliveryMethodEnum\BudgetDeliveryMethod;
|
||
use Google\Ads\GoogleAds\V18\Enums\CampaignStatusEnum\CampaignStatus;
|
||
use Google\Ads\GoogleAds\V18\Errors\GoogleAdsError;
|
||
use Google\Ads\GoogleAds\V18\Resources\Campaign;
|
||
use Google\Ads\GoogleAds\V18\Resources\Campaign\NetworkSettings;
|
||
use Google\Ads\GoogleAds\V18\Resources\CampaignBudget;
|
||
use Google\Ads\GoogleAds\V18\Services\CampaignBudgetOperation;
|
||
use Google\Ads\GoogleAds\V18\Services\CampaignOperation;
|
||
use Google\Ads\GoogleAds\V18\Services\GoogleAdsRow;
|
||
use Google\Ads\GoogleAds\V18\Services\MutateCampaignsRequest;
|
||
use Google\Ads\GoogleAds\V18\Services\MutateCampaignBudgetsRequest;
|
||
use Google\Ads\GoogleAds\V18\Services\SearchGoogleAdsStreamRequest;
|
||
use Google\Ads\GoogleAds\V18\Services\SearchGoogleAdsRequest;
|
||
use Google\Ads\GoogleAds\V18\Services\SearchGoogleAdsResponse;
|
||
use app\model\Campaign as CampaignModel;
|
||
use app\model\DayData as DayDataModel;
|
||
use Monolog\Handler\NewRelicHandler;
|
||
use think\facade\Db as ThinkDb;
|
||
|
||
use Google\ApiCore\ApiException;
|
||
|
||
class GoogleAdsCampaignService extends BaseService
|
||
{
|
||
private $googleAdsClient;
|
||
private $customerId;
|
||
private const NUMBER_OF_CAMPAIGNS_TO_ADD = 1;
|
||
|
||
public function __construct($customerId = null, GoogleAdsClientService $googleAdsClientService = null)
|
||
{
|
||
// 使用 GoogleAdsClientService 来初始化 googleAdsClient
|
||
// $googleAdsClient = new GoogleAdsClientService($customerId);
|
||
// $this->googleAdsClient = $googleAdsClient->getGoogleAdsClient();
|
||
}
|
||
|
||
// 从数据库动态获取 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', '未找到该广告主或关联的用户');
|
||
// }
|
||
// }
|
||
|
||
|
||
/**
|
||
* Runs the example.
|
||
*
|
||
* @param int $customerId the customer ID
|
||
* @param $options
|
||
* @return mixed
|
||
* @throws ApiException
|
||
*/
|
||
public function runAddCampaign(int $customerId, $options): mixed
|
||
{
|
||
$googleAdsClient = new GoogleAdsClientService($options['refresh_token']);
|
||
|
||
// Creates a single shared budget to be used by the campaigns added below.
|
||
$budgetResourceName = self::addCampaignBudget($googleAdsClient->getGoogleAdsClient(), $customerId, $options);
|
||
|
||
// Configures the campaign network options.
|
||
$networkSettings = new NetworkSettings([
|
||
'target_google_search' => true,
|
||
'target_search_network' => true,
|
||
// Enables Display Expansion on Search campaigns. See
|
||
// https://support.google.com/google-ads/answer/7193800 to learn more.
|
||
'target_content_network' => true,
|
||
'target_partner_search_network' => false
|
||
]);
|
||
|
||
$campaignOperations = [];
|
||
for ($i = 0; $i < self::NUMBER_OF_CAMPAIGNS_TO_ADD; $i++) {
|
||
// Creates a campaign.
|
||
// [START add_campaigns_1]
|
||
$campaign = new Campaign([
|
||
// 'name' => 'Interplanetary Cruise #' . Helper::getPrintableDatetime(),
|
||
'name' => $options['campaign_name'] . rand(10, 99) . ' #' . Helper::getPrintableDatetime(),
|
||
'advertising_channel_type' => AdvertisingChannelType::SEARCH,
|
||
// Recommendation: Set the campaign to PAUSED when creating it to prevent
|
||
// the ads from immediately serving. Set to ENABLED once you've added
|
||
// targeting and the ads are ready to serve.
|
||
'status' => CampaignStatus::PAUSED,
|
||
// Sets the bidding strategy and budget.
|
||
'manual_cpc' => new ManualCpc(),
|
||
'campaign_budget' => $budgetResourceName,
|
||
// Adds the network settings configured above.
|
||
'network_settings' => $networkSettings,
|
||
// Optional: Sets the start and end dates.
|
||
'start_date' => date('Ymd', strtotime('+1 day')),
|
||
'end_date' => date('Ymd', strtotime('+1 month'))
|
||
]);
|
||
// [END add_campaigns_1]
|
||
|
||
// Creates a campaign operation.
|
||
$campaignOperation = new CampaignOperation();
|
||
$campaignOperation->setCreate($campaign);
|
||
$campaignOperations[] = $campaignOperation;
|
||
}
|
||
|
||
// Issues a mutate request to add campaigns.
|
||
$campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
|
||
$response = $campaignServiceClient->mutateCampaigns(
|
||
MutateCampaignsRequest::build($customerId, $campaignOperations)
|
||
);
|
||
// printf("Added %d campaigns:%s", $response->getResults()->count(), PHP_EOL);
|
||
//
|
||
foreach ($response->getResults() as $addedCampaign) {
|
||
/** @var Campaign $addedCampaign */
|
||
// print "{$addedCampaign->getResourceName()}" . PHP_EOL;
|
||
$resourceNames[] = $addedCampaign->getResourceName();
|
||
}
|
||
return $resourceNames;
|
||
}
|
||
|
||
/**
|
||
* Runs the example.
|
||
*
|
||
* @param int $customerId the customer ID
|
||
* @param $options
|
||
* @return mixed
|
||
* @throws ApiException
|
||
*/
|
||
public function runAddCampaignBudget(int $customerId, $options): mixed
|
||
{
|
||
// if(!$customerId){
|
||
// $customerId = $this->customerId;
|
||
// }
|
||
// $googleAdsClient = $this->googleAdsClient;
|
||
$googleAdsClient = new GoogleAdsClientService($customerId);
|
||
// Creates a single shared budget to be used by the campaigns added below.
|
||
$budgetResourceName = self::addCampaignBudget($googleAdsClient->getGoogleAdsClient(), $customerId, $options);
|
||
|
||
return $budgetResourceName;
|
||
}
|
||
|
||
/**
|
||
* Creates a new campaign budget in the specified client account.
|
||
*
|
||
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
|
||
* @param int $customerId the customer ID
|
||
* @return string the resource name of the newly created budget
|
||
* @throws ApiException
|
||
*/
|
||
// [START add_campaigns]
|
||
private static function addCampaignBudget(GoogleAdsClient $googleAdsClient, int $customerId, $options)
|
||
{
|
||
|
||
// Creates a campaign budget.
|
||
$budget = new CampaignBudget([
|
||
// 'name' => 'Interplanetary Cruise Budget #' . Helper::getPrintableDatetime(),
|
||
'name' => $options['name'] . rand(10, 99) . ' #' . Helper::getPrintableDatetime(),
|
||
// 'delivery_method' => BudgetDeliveryMethod::STANDARD,
|
||
'amount_micros' => $options['amount'] * 1000000
|
||
]);
|
||
|
||
// Creates a campaign budget operation.
|
||
$campaignBudgetOperation = new CampaignBudgetOperation();
|
||
$campaignBudgetOperation->setCreate($budget);
|
||
|
||
// Issues a mutate request.
|
||
$campaignBudgetServiceClient = $googleAdsClient->getCampaignBudgetServiceClient();
|
||
$response = $campaignBudgetServiceClient->mutateCampaignBudgets(
|
||
MutateCampaignBudgetsRequest::build($customerId, [$campaignBudgetOperation])
|
||
);
|
||
|
||
/** @var CampaignBudget $addedBudget */
|
||
$addedBudget = $response->getResults()[0];
|
||
// printf("Added budget named '%s'%s", $addedBudget->getResourceName(), PHP_EOL);
|
||
|
||
return $addedBudget->getResourceName();
|
||
}
|
||
|
||
// [END add_campaigns]
|
||
|
||
/* @param int $customerId the customer ID
|
||
* @param $options
|
||
* @return mixed
|
||
* @throws ApiException
|
||
*/
|
||
public function runListCampaigns(int $customerId, $options): mixed
|
||
{
|
||
|
||
$googleAdsClient = new GoogleAdsClientService($options['refresh_token'], $options['login_customer_id']);
|
||
$campaignsResourceName = self::getCampaigns($googleAdsClient->getGoogleAdsClientWithloginCustomerId(), $customerId);
|
||
// dump(json_encode($campaignsResourceName));
|
||
if (is_array($campaignsResourceName)) {
|
||
self::saveCampaigns($campaignsResourceName);
|
||
}
|
||
|
||
return $campaignsResourceName;
|
||
}
|
||
|
||
/* @param int $customerId the customer ID
|
||
* @param $options
|
||
* @return mixed
|
||
* @throws ApiException
|
||
*/
|
||
public function runListDateDatas(int $customerId, $date): mixed
|
||
{
|
||
|
||
// $googleAdsClient = $this->googleAdsClient;
|
||
$googleAdsClient = new GoogleAdsClientService($customerId);
|
||
// Creates a single shared budget to be used by the campaigns added below.
|
||
$dayResourceName = self::getDateDatas($googleAdsClient->getGoogleAdsClient(), $customerId, $date);
|
||
// dump(json_encode($dayResourceName));
|
||
if (is_array($dayResourceName)) {
|
||
self::saveDateDatas($dayResourceName);
|
||
}
|
||
|
||
return $dayResourceName;
|
||
}
|
||
|
||
|
||
/**
|
||
* Runs the example.
|
||
*
|
||
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
|
||
* @param int $customerId the customer ID
|
||
*/
|
||
// [START get_campaigns]
|
||
|
||
public static function getCampaigns(GoogleAdsClient $googleAdsClient, int $customerId)
|
||
{
|
||
$googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
|
||
// Creates a query that retrieves all campaigns.
|
||
// $query = 'SELECT campaign.id,campaign.name,campaign.status,campaign.campaign_budget,campaign_budget.id,campaign_budget.name,campaign_budget.amount_micros FROM campaign ORDER BY campaign.id';
|
||
$query = "SELECT
|
||
campaign.id,
|
||
campaign.name,
|
||
campaign.status,
|
||
campaign.advertising_channel_type,
|
||
campaign.start_date,
|
||
campaign.end_date,
|
||
campaign_budget.amount_micros,
|
||
customer.id
|
||
FROM campaign
|
||
WHERE
|
||
campaign.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['campaign_id'] = $googleAdsRow->getCampaign()->getId();
|
||
$resourceName['campaign_name'] = $googleAdsRow->getCampaign()->getName();
|
||
$resourceName['advertising_channel_type'] = $googleAdsRow->getCampaign()->getAdvertisingChannelType();
|
||
$resourceName['status'] = $googleAdsRow->getCampaign()->getStatus();
|
||
$resourceName['start_date'] = $googleAdsRow->getCampaign()->getStartDate();
|
||
$resourceName['end_date'] = $googleAdsRow->getCampaign()->getEndDate();
|
||
$resourceName['budget_amount_micros'] = $googleAdsRow->getCampaignBudget()->getAmountMicros();
|
||
$resourceName['customer_id'] = $googleAdsRow->getCustomer()->getId();
|
||
$resourceNames[] = $resourceName;
|
||
}
|
||
return $resourceNames;
|
||
}
|
||
|
||
|
||
/**
|
||
* Runs the example.
|
||
*
|
||
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
|
||
* @param int $customerId the customer ID
|
||
*/
|
||
// [START get_campaigns]
|
||
|
||
public static function getDateDatas(GoogleAdsClient $googleAdsClient, int $customerId, $date = '2024-12-19')
|
||
{
|
||
// 调用私有方法提取 year, month, season
|
||
$dateDetails = self::extractDateDetails($date);
|
||
|
||
$year = $dateDetails['year'];
|
||
$month = $dateDetails['month'];
|
||
$season = $dateDetails['season'];
|
||
|
||
|
||
$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";
|
||
// dump($query);return;
|
||
// 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 */
|
||
$resourceName['ad_id'] = $googleAdsRow->getAdGroupAd()->getAd()->getId();
|
||
$resourceName['customer_id'] = $googleAdsRow->getCustomer()->getId();
|
||
$resourceName['ad_name'] = $googleAdsRow->getAdGroupAd()->getAd()->getName();
|
||
$resourceName['ad_resource_name'] = $googleAdsRow->getAdGroupAd()->getAd()->getResourceName();
|
||
$resourceName['ad_group_id'] = $googleAdsRow->getAdGroup()->getId();
|
||
$resourceName['campaign_id'] = $googleAdsRow->getCampaign()->getId();
|
||
$resourceName['clicks'] = $googleAdsRow->getMetrics()->getClicks();
|
||
$resourceName['cost_micros'] = $googleAdsRow->getMetrics()->getCostMicros();
|
||
$resourceName['conversions'] = $googleAdsRow->getMetrics()->getConversions();
|
||
$resourceName['conversions_value'] = $googleAdsRow->getMetrics()->getConversionsValue();
|
||
$resourceName['impressions'] = $googleAdsRow->getMetrics()->getImpressions();
|
||
$resourceName['date'] = $date;
|
||
$resourceName['month'] = $month;
|
||
$resourceName['season'] = $season;
|
||
$resourceName['year'] = $year;
|
||
|
||
|
||
// $resourceName['budget_id'] = $googleAdsRow->getCampaignBudget()->getId();
|
||
$resourceNames[] = $resourceName;
|
||
}
|
||
return $resourceNames;
|
||
}
|
||
|
||
|
||
/**
|
||
* 从日期字符串中提取年、月、季节信息,并返回这些信息
|
||
*
|
||
* @param string $date 日期,格式为 'Y-m-d'
|
||
* @return array 包含 year, month 和 season 的数组
|
||
*/
|
||
private static function extractDateDetails($date)
|
||
{
|
||
$dateObj = new DateTime($date); // 将日期字符串转换为 DateTime 对象
|
||
|
||
// 提取年和月
|
||
$year = (int)$dateObj->format('Y');
|
||
$month = (int)$dateObj->format('m');
|
||
|
||
// 计算季度
|
||
if ($month >= 1 && $month <= 3) {
|
||
$season = (int)$dateObj->format('Ym') . '01'; // Q1
|
||
} elseif ($month >= 4 && $month <= 6) {
|
||
$season = (int)$dateObj->format('Ym') . '02'; // Q2
|
||
} elseif ($month >= 7 && $month <= 9) {
|
||
$season = (int)$dateObj->format('Ym') . '03'; // Q3
|
||
} else {
|
||
$season = (int)$dateObj->format('Ym') . '04'; // Q4
|
||
}
|
||
|
||
return [
|
||
'year' => $year,
|
||
'month' => $month,
|
||
'season' => $season
|
||
];
|
||
}
|
||
|
||
/**
|
||
* Runs the example.
|
||
*
|
||
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
|
||
* @param int $customerId the customer ID
|
||
*/
|
||
// [START get_campaigns]
|
||
|
||
/**
|
||
* 在数据库中保存广告系列信息
|
||
* @param $campaignsResourceName
|
||
* @return void
|
||
*/
|
||
public static function saveCampaigns($campaignsResourceName)
|
||
{
|
||
$tableName = 'bps_google_ads_campaign';
|
||
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'public' . $tableName;
|
||
// foreach ($campaignsResourceName as $data) {
|
||
// $sql = "INSERT INTO {$tableName}
|
||
// (campaign_id, customer_id, campaign_name, status, advertising_channel_type, start_date, end_date, budget_amount_micros)
|
||
// VALUES (:campaign_id, :customer_id, :campaign_name, :status, :advertising_channel_type, :start_date, :end_date, :budget_amount_micros)";
|
||
// ThinkDb::execute($sql, $data);
|
||
// }
|
||
foreach ($campaignsResourceName as $data) {
|
||
$sql = "INSERT INTO {$tableName}
|
||
(campaign_id, customer_id, campaign_name, status, advertising_channel_type, start_date, end_date, budget_amount_micros)
|
||
VALUES (:campaign_id, :customer_id, :campaign_name, :status, :advertising_channel_type, :start_date, :end_date, :budget_amount_micros)
|
||
ON CONFLICT (campaign_id)
|
||
DO UPDATE SET
|
||
customer_id = EXCLUDED.customer_id,
|
||
campaign_name = EXCLUDED.campaign_name,
|
||
status = EXCLUDED.status,
|
||
advertising_channel_type = EXCLUDED.advertising_channel_type,
|
||
start_date = EXCLUDED.start_date,
|
||
end_date = EXCLUDED.end_date,
|
||
budget_amount_micros = EXCLUDED.budget_amount_micros,
|
||
update_at = EXCLUDED.update_at"; // 你可以根据实际情况决定是否需要更新时间戳
|
||
|
||
ThinkDb::execute($sql, $data);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 在数据库中保存广告系列信息
|
||
* @param $campaignsResourceName
|
||
* @return void
|
||
*/
|
||
public static function saveDateDatas($dayResourceName)
|
||
{
|
||
// dump($campaignsResourceName);
|
||
|
||
foreach ($dayResourceName as $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)
|
||
// VALUES (:ad_id, :customer_id, :ad_name, :ad_resource_name, :ad_group_id, :campaign_id, :clicks, :cost_micros, :conversions, :conversions_value, :impressions, :date)";
|
||
// 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)
|
||
ON CONFLICT (ad_id, date) -- 假设 (ad_id, date) 为唯一约束
|
||
DO UPDATE SET
|
||
customer_id = EXCLUDED.customer_id,
|
||
ad_name = EXCLUDED.ad_name,
|
||
ad_resource_name = EXCLUDED.ad_resource_name,
|
||
ad_group_id = EXCLUDED.ad_group_id,
|
||
campaign_id = EXCLUDED.campaign_id,
|
||
clicks = EXCLUDED.clicks,
|
||
cost_micros = EXCLUDED.cost_micros,
|
||
conversions = EXCLUDED.conversions,
|
||
conversions_value = EXCLUDED.conversions_value,
|
||
impressions = EXCLUDED.impressions,
|
||
month = EXCLUDED.month,
|
||
season = EXCLUDED.season,
|
||
year = EXCLUDED.year,
|
||
update_at = EXCLUDED.update_at"; // 更新其他字段和更新时间戳
|
||
|
||
ThinkDb::execute($sql, $data);
|
||
|
||
}
|
||
}
|
||
|
||
/* @param int $customerId the customer ID
|
||
* @param $options
|
||
* @return mixed
|
||
* @throws ApiException
|
||
*/
|
||
public function runListCampaignsNext($options): mixed
|
||
{
|
||
// $googleAdsClient = $this->googleAdsClient;
|
||
$googleAdsClient = new GoogleAdsClientService($options['customer_id']);
|
||
// Creates a single shared budget to be used by the campaigns added below.
|
||
$campaigns = self::getCampaignsNext($googleAdsClient->getGoogleAdsClient(), $options['customer_id'], $options['page_token']);
|
||
|
||
return $campaigns;
|
||
}
|
||
|
||
/**
|
||
* 获取广告系列列表,支持分页
|
||
*
|
||
* @param GoogleAdsClient $googleAdsClient
|
||
* @param string $customerId 客户 ID
|
||
* @param null $pageToken 下一页的令牌
|
||
* @return array 广告系列列表及下一页令牌
|
||
*/
|
||
public function getCampaignsNext(GoogleAdsClient $googleAdsClient, $customerId, $pageToken = null)
|
||
{
|
||
$googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
|
||
|
||
// 创建查询,获取广告系列信息
|
||
$query = "SELECT campaign.id, campaign.name FROM campaign ORDER BY campaign.id";
|
||
|
||
// 初始化分页参数
|
||
$pageToken = null;
|
||
// $pageSize = 1000; // 每页1000条记录
|
||
$allCampaigns = [];
|
||
$totalResultsCount = 0;
|
||
$queryResourceConsumption = 0;
|
||
|
||
// 创建请求对象
|
||
$request = new SearchGoogleAdsRequest([
|
||
'customer_id' => $customerId,
|
||
'query' => $query,
|
||
'page_token' => $pageToken, // 分页令牌
|
||
// 'page_size' => $pageSize, // 设置每页的大小
|
||
]);
|
||
// 调用 search 方法进行数据获取
|
||
try {
|
||
// 发起查询请求,返回 PagedListResponse
|
||
$response = $googleAdsServiceClient->search($request);
|
||
|
||
// 获取总结果数
|
||
$totalResultsCount = $response->getTotalResultsCount();
|
||
|
||
// 获取查询消耗的资源
|
||
$queryResourceConsumption = $response->getQueryResourceConsumption();
|
||
|
||
// 获取返回结果(PagedListResponse 类型)
|
||
$this->processSearchGoogleAdsResponse($response, $allCampaigns);
|
||
|
||
// 获取下一页的分页令牌
|
||
$pageToken = $response->getNextPageToken();
|
||
|
||
} catch (ApiException $e) {
|
||
// 处理异常
|
||
printf("API request failed with message: %s\n", $e->getMessage());
|
||
}
|
||
|
||
return [
|
||
'campaigns' => $allCampaigns,
|
||
'totalResultsCount' => $totalResultsCount,
|
||
'queryResourceConsumption' => $queryResourceConsumption
|
||
];
|
||
}
|
||
|
||
/**
|
||
* 处理 SearchGoogleAdsResponse 数据并提取广告系列信息
|
||
*
|
||
* @param SearchGoogleAdsResponse $response 查询响应
|
||
* @param array $allCampaigns 用于存储广告系列的数组
|
||
*/
|
||
private function processSearchGoogleAdsResponse(SearchGoogleAdsResponse $response, array &$allCampaigns)
|
||
{
|
||
// 获取查询结果
|
||
foreach ($response->getResults() as $googleAdsRow) {
|
||
/** @var \Google\Ads\GoogleAds\V18\Resources\Campaign $campaign */
|
||
$campaign = $googleAdsRow->getCampaign();
|
||
$allCampaigns[] = [
|
||
'id' => $campaign->getId(),
|
||
'name' => $campaign->getName(),
|
||
];
|
||
}
|
||
|
||
// 输出分页的总结果数
|
||
printf("Total Results Count: %d\n", $response->getTotalResultsCount());
|
||
|
||
// 输出查询资源消耗
|
||
printf("Query Resource Consumption: %d\n", $response->getQueryResourceConsumption());
|
||
|
||
// 输出汇总数据(如果存在)
|
||
if ($summaryRow = $response->getSummaryRow()) {
|
||
// 处理汇总行(根据需要)
|
||
printf("Summary Row Metrics: %s\n", $summaryRow);
|
||
}
|
||
|
||
// 获取下一页的分页令牌
|
||
$nextPageToken = $response->getNextPageToken();
|
||
if ($nextPageToken) {
|
||
printf("Next Page Token: %s\n", $nextPageToken);
|
||
}
|
||
}
|
||
|
||
|
||
/* @param int $customerId the customer ID
|
||
* @param $options
|
||
* @return mixed
|
||
* @throws ApiException
|
||
*/
|
||
public function runRemoveCampaign($options): mixed
|
||
{
|
||
// $googleAdsClient = $this->googleAdsClient;
|
||
$googleAdsClient = new GoogleAdsClientService($options['customer_id']);
|
||
|
||
// Creates a single shared budget to be used by the campaigns added below.
|
||
$resourceName = self::removeCampaign($googleAdsClient->getGoogleAdsClient(), $options['customer_id'], $options['campaign_id']);
|
||
|
||
return $resourceName;
|
||
}
|
||
|
||
/**
|
||
* Runs the example.
|
||
*
|
||
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
|
||
* @param int $customerId the customer ID
|
||
* @param int $campaignId the ID of the campaign to remove
|
||
*/
|
||
public static function removeCampaign(
|
||
GoogleAdsClient $googleAdsClient,
|
||
int $customerId,
|
||
int $campaignId
|
||
)
|
||
{
|
||
// Creates the resource name of a campaign to remove.
|
||
$campaignResourceName = ResourceNames::forCampaign($customerId, $campaignId);
|
||
|
||
// Creates a campaign operation.
|
||
$campaignOperation = new CampaignOperation();
|
||
$campaignOperation->setRemove($campaignResourceName);
|
||
|
||
// Issues a mutate request to remove the campaign.
|
||
$campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
|
||
$response = $campaignServiceClient->mutateCampaigns(
|
||
MutateCampaignsRequest::build($customerId, [$campaignOperation])
|
||
);
|
||
|
||
/** @var Campaign $removedCampaign */
|
||
$removedCampaign = $response->getResults()[0];
|
||
printf(
|
||
"Removed campaign with resource name '%s'%s",
|
||
$removedCampaign->getResourceName(),
|
||
PHP_EOL
|
||
);
|
||
return $removedCampaign->getResourceName();
|
||
}
|
||
|
||
/**
|
||
* 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 runUpdateCampaign($options): mixed
|
||
{
|
||
|
||
$googleAdsClient = new GoogleAdsClientService($options['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']);
|
||
|
||
return $resourceName;
|
||
}
|
||
|
||
/**
|
||
* Runs the updateCampaign example.
|
||
*
|
||
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
|
||
* @param int $customerId the customer ID
|
||
* @param int $campaignId the ID of campaign to update
|
||
*/
|
||
public static function updateCampaign(
|
||
GoogleAdsClient $googleAdsClient,
|
||
int $customerId,
|
||
int $campaignId,
|
||
int $status
|
||
)
|
||
{
|
||
|
||
// Creates a campaign object with the specified resource name and other changes.
|
||
$campaign = new Campaign([
|
||
// 'resource_name' => ResourceNames::forCampaign($customerId, $campaignId),
|
||
// 'status' => CampaignStatus::PAUSED
|
||
'resource_name' => ResourceNames::forCampaign($customerId, $campaignId),
|
||
'status' => $status,
|
||
]);
|
||
|
||
// Constructs an operation that will update the campaign 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 campaign you want to change.
|
||
$campaignOperation = new CampaignOperation();
|
||
$campaignOperation->setUpdate($campaign);
|
||
$campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign));
|
||
|
||
// Issues a mutate request to update the campaign.
|
||
$campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
|
||
$response = $campaignServiceClient->mutateCampaigns(MutateCampaignsRequest::build(
|
||
$customerId,
|
||
[$campaignOperation]
|
||
));
|
||
|
||
// Prints the resource name of the updated campaign.
|
||
/** @var Campaign $updatedCampaign */
|
||
$updatedCampaign = $response->getResults()[0];
|
||
printf(
|
||
"Updated campaign with resource name: '%s'%s",
|
||
$updatedCampaign->getResourceName(),
|
||
PHP_EOL
|
||
);
|
||
return $updatedCampaign->getResourceName();
|
||
}
|
||
|
||
|
||
/**
|
||
* 更新广告系列状态
|
||
*/
|
||
public function updateCampaignStatus(int $customerId, int $campaignId, int $status)
|
||
{
|
||
// 从数据库获取 Campaign 对象
|
||
$campaign = CampaignModel::find($campaignId);
|
||
// dump($campaign);return;
|
||
if (!$campaign) {
|
||
// throw new ValidateException('Campaign not found');
|
||
return false;
|
||
}
|
||
// 更新本地数据库的状态
|
||
if ($this->modifyDbCampaignStatus($campaignId, $status)) {
|
||
// 更新 Google Ads 上的状态
|
||
// $googleAdsClient = $this->googleAdsClient;
|
||
$googleAdsClient = new GoogleAdsClientService($customerId);
|
||
$resourceName = self::updateCampaign($googleAdsClient->getGoogleAdsClient(), $customerId, $campaignId, $status);
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 获取广告活动状态
|
||
*/
|
||
// public function getCampaignStatus(int $campaignId)
|
||
// {
|
||
// // 从本地数据库获取状态
|
||
// $campaign = CampaignModel::find($campaignId);
|
||
// if (!$campaign) {
|
||
// throw new ValidateException('Campaign not found');
|
||
// }
|
||
//
|
||
// // 获取 Google Ads 状态
|
||
// $googleAdsStatus = $this->googleAdsClient->getCampaignStatus($campaignId);
|
||
//
|
||
// // 返回 Google Ads 的状态
|
||
// return $googleAdsStatus;
|
||
// }
|
||
|
||
|
||
/**
|
||
* 获取 Google Ads Campaign 状态
|
||
*/
|
||
// public function getCampaignStatus(int $campaignId)
|
||
// {
|
||
// try {
|
||
// // 获取 Google Ads 客户端
|
||
// $campaignServiceClient = $this->client->getCampaignServiceClient();
|
||
//
|
||
// // 获取 Campaign 资源
|
||
// $resourceName = "customers/{customer_id}/campaigns/{$campaignId}";
|
||
// $campaign = $campaignServiceClient->getCampaign($resourceName);
|
||
//
|
||
// return $campaign->getStatus();
|
||
// } catch (ApiException $e) {
|
||
// throw new \Exception("Google Ads API error: " . $e->getMessage());
|
||
// }
|
||
// }
|
||
|
||
}
|