820 lines
29 KiB
PHP
820 lines
29 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Google\Ads\GoogleAds\Lib\V22\GoogleAdsClientBuilder;
|
|
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
|
|
use Google\Ads\GoogleAds\V22\Services\SearchGoogleAdsRequest;
|
|
use Google\Ads\GoogleAds\V22\Enums\CustomerStatusEnum\CustomerStatus;
|
|
use Google\Ads\GoogleAds\V22\Enums\CampaignStatusEnum\CampaignStatus;
|
|
use Google\Ads\GoogleAds\V22\Enums\AdvertisingChannelTypeEnum\AdvertisingChannelType;
|
|
use Google\Ads\GoogleAds\V22\Enums\AdvertisingChannelSubTypeEnum\AdvertisingChannelSubType;
|
|
use Google\Ads\GoogleAds\V22\Enums\AdGroupStatusEnum\AdGroupStatus;
|
|
use Google\Ads\GoogleAds\V22\Enums\AdGroupTypeEnum\AdGroupType;
|
|
use Google\Ads\GoogleAds\V22\Enums\PolicyApprovalStatusEnum\PolicyApprovalStatus;
|
|
use Google\Ads\GoogleAds\V22\Enums\AdGroupAdStatusEnum\AdGroupAdStatus;
|
|
use Google\Ads\GoogleAds\V22\Enums\AdTypeEnum\AdType;
|
|
use Google\Ads\GoogleAds\V22\Enums\KeywordMatchTypeEnum\KeywordMatchType;
|
|
use Google\Ads\GoogleAds\V22\Enums\AdGroupCriterionStatusEnum\AdGroupCriterionStatus;
|
|
use Google\Ads\GoogleAds\V22\Enums\AssetSourceEnum\AssetSource;
|
|
use Google\Ads\GoogleAds\V22\Enums\AssetTypeEnum\AssetType;
|
|
use Google\Ads\GoogleAds\V22\Enums\AssetFieldTypeEnum\AssetFieldType;
|
|
use Google\Ads\GoogleAds\V22\Enums\PolicyReviewStatusEnum\PolicyReviewStatus;
|
|
use Google\Ads\GoogleAds\V22\Enums\AssetLinkStatusEnum\AssetLinkStatus;
|
|
use GPBMetadata\Google\Api\Log;
|
|
use Illuminate\Support\Facades\Log as FacadesLog;
|
|
|
|
class GoogleAdsService
|
|
{
|
|
protected $oAuth2Credential;
|
|
protected $developerToken;
|
|
protected $loginCustomerId;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->oAuth2Credential = (new OAuth2TokenBuilder())
|
|
->withClientId(env('GOOGLE_ADS_CLIENT_ID'))
|
|
->withClientSecret(env('GOOGLE_ADS_CLIENT_SECRET'))
|
|
->withRefreshToken(env('GOOGLE_ADS_REFRESH_TOKEN'))
|
|
->build();
|
|
|
|
$this->developerToken = env('GOOGLE_ADS_DEVELOPER_TOKEN');
|
|
$this->loginCustomerId = env('GOOGLE_ADS_LOGIN_CUSTOMER_ID'); // MCC ID
|
|
}
|
|
|
|
/**
|
|
* Build a GoogleAdsClient scoped to a specific customer ID
|
|
*/
|
|
protected function buildClient(string $customerId)
|
|
{
|
|
return (new GoogleAdsClientBuilder())
|
|
->withDeveloperToken($this->developerToken)
|
|
->withOAuth2Credential($this->oAuth2Credential)
|
|
->withLoginCustomerId($customerId)
|
|
->withTransport('rest')
|
|
->build();
|
|
}
|
|
|
|
/**
|
|
* List all accounts under MCC
|
|
*/
|
|
public function listAccounts(): array
|
|
{
|
|
$client = $this->buildClient($this->loginCustomerId);
|
|
$service = $client->getGoogleAdsServiceClient();
|
|
|
|
$query = <<<QUERY
|
|
SELECT
|
|
customer_client.id,
|
|
customer_client.client_customer,
|
|
customer_client.level,
|
|
customer_client.manager,
|
|
customer_client.descriptive_name,
|
|
customer_client.status,
|
|
customer_client.applied_labels,
|
|
customer_client.resource_name,
|
|
customer_client.time_zone
|
|
FROM
|
|
customer_client
|
|
QUERY;
|
|
|
|
$request = new SearchGoogleAdsRequest([
|
|
'customer_id' => $this->loginCustomerId,
|
|
'query' => $query,
|
|
]);
|
|
|
|
$response = $service->search($request);
|
|
|
|
$accounts = [];
|
|
foreach ($response->iterateAllElements() as $row) {
|
|
$clientData = $row->getCustomerClient();
|
|
$accounts[] = [
|
|
'customer_id' => (string) $clientData->getId(),
|
|
'id' => $clientData->getId(),
|
|
'name' => $clientData->getDescriptiveName(),
|
|
'level' => $clientData->getLevel(),
|
|
'status' => CustomerStatus::name($clientData->getStatus()),
|
|
'resource_name' => $clientData->getResourceName(),
|
|
'time_zone' => $clientData->getTimeZone(),
|
|
'applied_labels' => $clientData->getAppliedLabels(),
|
|
'manager' => $clientData->getManager(),
|
|
];
|
|
}
|
|
|
|
return $accounts;
|
|
}
|
|
|
|
public function listCampaigns(string $clientCustomerId): array
|
|
{
|
|
$client = $this->buildClient($this->loginCustomerId);
|
|
$service = $client->getGoogleAdsServiceClient();
|
|
$customerId = str_replace('-', '', $clientCustomerId);
|
|
|
|
$query = <<<QUERY
|
|
SELECT
|
|
campaign.id,
|
|
campaign.name,
|
|
campaign.status,
|
|
campaign.advertising_channel_type,
|
|
campaign.advertising_channel_sub_type,
|
|
campaign.start_date,
|
|
campaign.end_date,
|
|
campaign.resource_name,
|
|
campaign.serving_status,
|
|
campaign.bidding_strategy_type,
|
|
campaign.campaign_budget,
|
|
campaign.primary_status,
|
|
campaign.primary_status_reasons,
|
|
campaign.payment_mode
|
|
FROM campaign
|
|
QUERY;
|
|
|
|
$request = new SearchGoogleAdsRequest([
|
|
'customer_id' => $customerId,
|
|
'query' => $query,
|
|
]);
|
|
|
|
$response = $service->search($request);
|
|
|
|
$campaigns = [];
|
|
foreach ($response->iterateAllElements() as $row) {
|
|
$c = $row->getCampaign();
|
|
$campaigns[] = [
|
|
'id' => $c->getId(),
|
|
'name' => $c->getName(),
|
|
'status' => CampaignStatus::name($c->getStatus()),
|
|
'channel' => AdvertisingChannelType::name($c->getAdvertisingChannelType()),
|
|
'sub_channel' => AdvertisingChannelSubType::name($c->getAdvertisingChannelSubType()),
|
|
'start_date' => $c->getStartDate(),
|
|
'end_date' => $c->getEndDate(),
|
|
'resource_name' => $c->getResourceName(),
|
|
];
|
|
}
|
|
|
|
return $campaigns;
|
|
}
|
|
|
|
public function listCampaignsMetrics(string $clientCustomerId, string $campaignId, string $startDate, string $endDate): array
|
|
{
|
|
$client = $this->buildClient($this->loginCustomerId);
|
|
$service = $client->getGoogleAdsServiceClient();
|
|
|
|
$customerId = str_replace('-', '', $clientCustomerId);
|
|
|
|
$query = <<<QUERY
|
|
SELECT
|
|
campaign.id,
|
|
campaign.name,
|
|
segments.date,
|
|
campaign_budget.amount_micros,
|
|
metrics.impressions,
|
|
metrics.clicks,
|
|
metrics.ctr,
|
|
metrics.average_cpc,
|
|
metrics.conversions,
|
|
metrics.conversions_value,
|
|
metrics.cost_per_conversion,
|
|
metrics.all_conversions_from_interactions_rate,
|
|
metrics.interactions,
|
|
metrics.interaction_rate,
|
|
metrics.all_conversions,
|
|
metrics.view_through_conversions,
|
|
metrics.cost_micros
|
|
FROM campaign
|
|
WHERE segments.date BETWEEN '$startDate' AND '$endDate'
|
|
AND campaign.id = '$campaignId'
|
|
ORDER BY segments.date ASC
|
|
QUERY;
|
|
|
|
$request = new SearchGoogleAdsRequest([
|
|
'customer_id' => $customerId,
|
|
'query' => $query,
|
|
]);
|
|
$response = $service->search($request);
|
|
FacadesLog::info('Google Ads Query', [
|
|
'query' => $query,
|
|
'customer_id' => $customerId,
|
|
]);
|
|
$metrics = [];
|
|
|
|
foreach ($response->iterateAllElements() as $row) {
|
|
$c = $row->getCampaign();
|
|
$metrics[] = [
|
|
'id' => $c->getId(),
|
|
'name' => $c->getName(),
|
|
'date' => $row->getSegments()->getDate(),
|
|
'impressions' => $row->getMetrics()->getImpressions(),
|
|
'clicks' => $row->getMetrics()->getClicks(),
|
|
// 'ctr' => round($row->getMetrics()->getCtr() * 100, 2),
|
|
'daily_budget' => $row->getCampaignBudget()->getAmountMicros() / 1000000,
|
|
'actual_spend' => number_format($row->getMetrics()->getCostMicros() / 1000000, 2, '.', ''),
|
|
// 'average_cpc' => round($row->getMetrics()->getAverageCpc() / 1000000, 2),
|
|
'conversions' => $row->getMetrics()->getConversions(),
|
|
'conversions_value' => $row->getMetrics()->getConversionsValue(),
|
|
'cost_per_conversion' =>number_format(( $row->getMetrics()->getCostPerConversion() / 1000000), 2, '.', ''),
|
|
// 'conversions_from_interactions_rate' => round($row->getMetrics()->getConversionsFromInteractionsRate() * 100, 2),
|
|
'interactions' => $row->getMetrics()->getInteractions(),
|
|
'interaction_rate' => number_format($row->getMetrics()->getInteractionRate() * 100, 2, '.', ''),
|
|
// 'all_conversions' => $row->getMetrics()->getAllConversions(),
|
|
// 'view_through_conversions' => $row->getMetrics()->getViewThroughConversions()
|
|
];
|
|
}
|
|
return $metrics;
|
|
}
|
|
|
|
public function listCampaignsMetricsById(string $clientCustomerId, string $campaignId, string $startDate = '', string $endDate = ''): array
|
|
{
|
|
$client = $this->buildClient($this->loginCustomerId);
|
|
$service = $client->getGoogleAdsServiceClient();
|
|
$customerId = str_replace('-', '', $clientCustomerId);
|
|
|
|
if (empty($startDate)) {
|
|
$startDate = date('Y-m-d');
|
|
}
|
|
|
|
if (empty($endDate)) {
|
|
$endDate = date('Y-m-d');
|
|
}
|
|
|
|
$query = <<<QUERY
|
|
SELECT
|
|
campaign.id,
|
|
campaign.name,
|
|
campaign.start_date,
|
|
segments.date,
|
|
campaign_budget.amount_micros,
|
|
metrics.impressions,
|
|
metrics.clicks,
|
|
metrics.cost_micros,
|
|
metrics.conversions,
|
|
metrics.conversions_value,
|
|
metrics.interactions,
|
|
metrics.interaction_rate
|
|
FROM campaign
|
|
WHERE campaign.id = $campaignId
|
|
AND segments.date BETWEEN '$startDate' AND '$endDate'
|
|
ORDER BY segments.date ASC
|
|
QUERY;
|
|
|
|
$request = new SearchGoogleAdsRequest([
|
|
'customer_id' => $customerId,
|
|
'query' => $query,
|
|
]);
|
|
|
|
$response = $service->search($request);
|
|
$metrics = [];
|
|
|
|
foreach ($response->iterateAllElements() as $row) {
|
|
$c = $row->getCampaign();
|
|
$metrics[] = [
|
|
'id' => $c->getId(),
|
|
'name' => $c->getName(),
|
|
'start_date' => $c->getStartDate(), // Actual launch date
|
|
'date' => $row->getSegments()->getDate(),
|
|
'impressions' => $row->getMetrics()->getImpressions(),
|
|
'clicks' => $row->getMetrics()->getClicks(),
|
|
'daily_budget' => round($row->getCampaignBudget()->getAmountMicros() / 1000000, 2),
|
|
'actual_spend' => round($row->getMetrics()->getCostMicros() / 1000000, 2),
|
|
'conversions' => $row->getMetrics()->getConversions(),
|
|
'conversions_value' => $row->getMetrics()->getConversionsValue(),
|
|
'interactions' => $row->getMetrics()->getInteractions(),
|
|
'interaction_rate' => round($row->getMetrics()->getInteractionRate() * 100, 2),
|
|
];
|
|
}
|
|
return $metrics;
|
|
}
|
|
|
|
public function listAdGroupsByCampaignId(string $clientCustomerId, string $campaignId): array
|
|
{
|
|
$customerId = str_replace('-', '', $clientCustomerId);
|
|
|
|
$client = $this->buildClient($this->loginCustomerId);
|
|
$service = $client->getGoogleAdsServiceClient();
|
|
|
|
$query = <<<QUERY
|
|
SELECT
|
|
ad_group.id,
|
|
ad_group.name,
|
|
ad_group.status,
|
|
ad_group.type,
|
|
ad_group.cpc_bid_micros,
|
|
campaign.id,
|
|
campaign.name
|
|
FROM ad_group
|
|
WHERE campaign.id = $campaignId
|
|
AND ad_group.status IN ('ENABLED', 'PAUSED', 'REMOVED')
|
|
QUERY;
|
|
|
|
$request = new SearchGoogleAdsRequest([
|
|
'customer_id' => $customerId,
|
|
'query' => $query,
|
|
]);
|
|
|
|
$response = $service->search($request);
|
|
$adGroups = [];
|
|
|
|
foreach ($response->iterateAllElements() as $row) {
|
|
$ag = $row->getAdGroup();
|
|
$campaign = $row->getCampaign();
|
|
|
|
$adGroups[] = [
|
|
'ad_group_id' => $ag->getId(),
|
|
'ad_group_name' => $ag->getName(),
|
|
'status' => AdGroupStatus::name($ag->getStatus()),
|
|
'type' => AdGroupType::name($ag->getType()),
|
|
'cpc_bid_micros' => round($ag->getCpcBidMicros() / 1000000, 2),
|
|
'parent_campaign_id' => $campaign->getId(),
|
|
'parent_campaign_name' => $campaign->getName(),
|
|
];
|
|
}
|
|
|
|
return $adGroups;
|
|
}
|
|
|
|
public function listAdsByAdGroupId(string $clientCustomerId, string $adGroupId): array
|
|
{
|
|
$customerId = str_replace('-', '', $clientCustomerId);
|
|
$client = $this->buildClient($this->loginCustomerId);
|
|
$service = $client->getGoogleAdsServiceClient();
|
|
|
|
// Query the ad_group_ad resource
|
|
$query = <<<QUERY
|
|
SELECT
|
|
ad_group_ad.ad.id,
|
|
ad_group_ad.status,
|
|
ad_group_ad.ad.type,
|
|
ad_group_ad.ad.final_urls,
|
|
ad_group_ad.policy_summary.approval_status,
|
|
ad_group.id,
|
|
ad_group.name
|
|
FROM ad_group_ad
|
|
WHERE ad_group.id = $adGroupId
|
|
AND ad_group_ad.status IN ('ENABLED', 'PAUSED', 'REMOVED')
|
|
QUERY;
|
|
|
|
$request = new SearchGoogleAdsRequest([
|
|
'customer_id' => $customerId,
|
|
'query' => $query,
|
|
]);
|
|
|
|
$response = $service->search($request);
|
|
$ads = [];
|
|
|
|
foreach ($response->iterateAllElements() as $row) {
|
|
$adGroupAd = $row->getAdGroupAd();
|
|
$ad = $adGroupAd->getAd();
|
|
|
|
$ads[] = [
|
|
'ad_id' => $ad->getId(),
|
|
'type' => AdType::name($ad->getType()),
|
|
'status' => AdGroupAdStatus::name($adGroupAd->getStatus()),
|
|
'approval_status' => PolicyApprovalStatus::name($adGroupAd->getPolicySummary()->getApprovalStatus()),
|
|
'final_urls' => iterator_to_array($ad->getFinalUrls()),
|
|
'ad_group_id' => $row->getAdGroup()->getId()
|
|
];
|
|
}
|
|
|
|
return $ads;
|
|
}
|
|
|
|
public function listAssetsByCampaignId(string $clientCustomerId, string $campaignId): array
|
|
{
|
|
$customerId = str_replace('-', '', $clientCustomerId);
|
|
$client = $this->buildClient($this->loginCustomerId);
|
|
$service = $client->getGoogleAdsServiceClient();
|
|
|
|
$query = <<<QUERY
|
|
SELECT
|
|
asset.id,
|
|
asset.name,
|
|
asset.source,
|
|
asset.type,
|
|
asset.policy_summary.approval_status,
|
|
asset.policy_summary.review_status,
|
|
campaign_asset.field_type,
|
|
campaign_asset.status,
|
|
campaign.id
|
|
FROM campaign_asset
|
|
WHERE campaign.id = $campaignId
|
|
QUERY;
|
|
|
|
$request = new SearchGoogleAdsRequest([
|
|
'customer_id' => $customerId,
|
|
'query' => $query,
|
|
]);
|
|
|
|
$response = $service->search($request);
|
|
$assets = [];
|
|
|
|
|
|
foreach ($response->iterateAllElements() as $row) {
|
|
$asset = $row->getAsset();
|
|
$ca = $row->getCampaignAsset();
|
|
$policy = $asset->getPolicySummary();
|
|
|
|
// 1. Safe access for policy_summary
|
|
$policy = $asset->getPolicySummary();
|
|
|
|
// Check if policy exists before calling methods
|
|
$approvalStatus = 'NOT_APPLICABLE';
|
|
$reviewStatus = 'NOT_APPLICABLE';
|
|
|
|
if (! is_null($policy)) {
|
|
$approvalStatus = PolicyApprovalStatus::name($policy->getApprovalStatus());
|
|
$reviewStatus = PolicyReviewStatus::name($policy->getReviewStatus());
|
|
}
|
|
$assets[] = [
|
|
'id' => $asset->getId(),
|
|
'name' => $asset->getName(),
|
|
'added_by' => AssetSource::name($asset->getSource()),
|
|
'type' => AssetType::name($asset->getType()),
|
|
'use_case' => AssetFieldType::name($ca->getFieldType()),
|
|
'approval_status' => $approvalStatus,
|
|
'review_status' => $reviewStatus,
|
|
'status' => AssetLinkStatus::name($ca->getStatus()),
|
|
];
|
|
}
|
|
|
|
return $assets;
|
|
}
|
|
|
|
|
|
public function listKeywordsByAdGroupId(string $clientCustomerId, string $adGroupId): array
|
|
{
|
|
$customerId = str_replace('-', '', $clientCustomerId);
|
|
$client = $this->buildClient($this->loginCustomerId);
|
|
$service = $client->getGoogleAdsServiceClient();
|
|
|
|
$query = <<<QUERY
|
|
SELECT
|
|
ad_group_criterion.criterion_id,
|
|
ad_group_criterion.keyword.text,
|
|
ad_group_criterion.keyword.match_type,
|
|
ad_group_criterion.status,
|
|
ad_group_criterion.cpc_bid_micros,
|
|
ad_group.id
|
|
FROM ad_group_criterion
|
|
WHERE ad_group.id = $adGroupId
|
|
AND ad_group_criterion.type = 'KEYWORD'
|
|
AND ad_group_criterion.status IN ('ENABLED', 'PAUSED', 'REMOVED')
|
|
QUERY;
|
|
|
|
$request = new SearchGoogleAdsRequest([
|
|
'customer_id' => $customerId,
|
|
'query' => $query,
|
|
]);
|
|
|
|
$response = $service->search($request);
|
|
$keywords = [];
|
|
|
|
foreach ($response->iterateAllElements() as $row) {
|
|
$criterion = $row->getAdGroupCriterion();
|
|
$keywordInfo = $criterion->getKeyword();
|
|
|
|
$keywords[] = [
|
|
'keyword_id' => $criterion->getCriterionId(),
|
|
'text' => $keywordInfo->getText(),
|
|
'match_type' => KeywordMatchType::name($keywordInfo->getMatchType()),
|
|
'status' => AdGroupCriterionStatus::name($criterion->getStatus()),
|
|
'cpc_bid' => round($criterion->getCpcBidMicros() / 1000000, 2),
|
|
'ad_group_id' => $row->getAdGroup()->getId()
|
|
];
|
|
}
|
|
|
|
return $keywords;
|
|
}
|
|
|
|
|
|
public function listAdGroupMetrics(string $dateFrom, string $dateTo): array
|
|
{
|
|
$client = $this->buildClient($this->loginCustomerId);
|
|
$service = $client->getGoogleAdsServiceClient();
|
|
|
|
$query = <<<QUERY
|
|
SELECT
|
|
ad_group.resource_name,
|
|
segments.date,
|
|
metrics.impressions,
|
|
metrics.clicks,
|
|
metrics.cost_micros,
|
|
metrics.conversions,
|
|
metrics.ctr,
|
|
metrics.average_cpc
|
|
FROM ad_group
|
|
WHERE segments.date BETWEEN '$dateFrom' AND '$dateTo'
|
|
QUERY;
|
|
|
|
$request = new SearchGoogleAdsRequest([
|
|
'customer_id' => $this->loginCustomerId,
|
|
'query' => $query,
|
|
]);
|
|
|
|
$response = $service->search($request);
|
|
|
|
$metrics = [];
|
|
|
|
foreach ($response->iterateAllElements() as $row) {
|
|
$ag = $row->getAdGroup();
|
|
$m = $row->getMetrics();
|
|
$segments = $row->getSegments();
|
|
|
|
$metrics[] = [
|
|
'ad_group_resource_name' => $ag->getResourceName(),
|
|
'date' => $segments->getDate(),
|
|
'impressions' => $m->getImpressions(),
|
|
'clicks' => $m->getClicks(),
|
|
'cost_micros' => $m->getCostMicros(),
|
|
'conversions' => $m->getConversions(),
|
|
'ctr' => $m->getCtr(),
|
|
'average_cpc' => $m->getAverageCpc(),
|
|
];
|
|
}
|
|
|
|
return $metrics;
|
|
}
|
|
|
|
public function getKeywordMetricsById(string $clientCustomerId, string $keywordId, string $startDate = '', string $endDate = ''): array
|
|
{
|
|
$customerId = str_replace('-', '', $clientCustomerId);
|
|
$client = $this->buildClient($this->loginCustomerId);
|
|
$service = $client->getGoogleAdsServiceClient();
|
|
|
|
if (empty($startDate)) {
|
|
$startDate = date('Y-m-d');
|
|
}
|
|
|
|
if (empty($endDate)) {
|
|
$endDate = date('Y-m-d');
|
|
}
|
|
|
|
$query = <<<QUERY
|
|
SELECT
|
|
ad_group_criterion.criterion_id,
|
|
ad_group_criterion.keyword.text,
|
|
ad_group_criterion.keyword.match_type,
|
|
metrics.impressions,
|
|
metrics.clicks,
|
|
metrics.cost_micros,
|
|
metrics.conversions,
|
|
segments.date
|
|
FROM keyword_view
|
|
WHERE ad_group_criterion.criterion_id = $keywordId
|
|
AND segments.date BETWEEN '$startDate' AND '$endDate'
|
|
ORDER BY segments.date ASC
|
|
QUERY;
|
|
|
|
$request = new SearchGoogleAdsRequest([
|
|
'customer_id' => $customerId,
|
|
'query' => $query,
|
|
]);
|
|
|
|
$response = $service->search($request);
|
|
$metrics = [];
|
|
|
|
foreach ($response->iterateAllElements() as $row) {
|
|
$criterion = $row->getAdGroupCriterion();
|
|
$m = $row->getMetrics();
|
|
|
|
$metrics[] = [
|
|
'keyword_id' => $criterion->getCriterionId(),
|
|
'text' => $criterion->getKeyword()->getText(),
|
|
'match_type' => KeywordMatchType::name($criterion->getKeyword()->getMatchType()),
|
|
'date' => $row->getSegments()->getDate(),
|
|
'impressions' => $m->getImpressions(),
|
|
'clicks' => $m->getClicks(),
|
|
'actual_spend' => round($m->getCostMicros() / 1000000, 2),
|
|
'conversions' => $m->getConversions(),
|
|
];
|
|
}
|
|
|
|
return $metrics;
|
|
}
|
|
|
|
public function getAdGroupMetricsById(string $clientCustomerId, string $adGroupId, string $startDate = '', string $endDate = ''): array
|
|
{
|
|
$customerId = str_replace('-', '', $clientCustomerId);
|
|
$client = $this->buildClient($this->loginCustomerId);
|
|
$service = $client->getGoogleAdsServiceClient();
|
|
|
|
if (empty($startDate)) {
|
|
$startDate = date('Y-m-d');
|
|
}
|
|
|
|
if (empty($endDate)) {
|
|
$endDate = date('Y-m-d');
|
|
}
|
|
$query = <<<QUERY
|
|
SELECT
|
|
ad_group.id,
|
|
ad_group.name,
|
|
ad_group.status,
|
|
metrics.impressions,
|
|
metrics.clicks,
|
|
metrics.cost_micros,
|
|
metrics.conversions,
|
|
metrics.conversions_value,
|
|
segments.date
|
|
FROM ad_group
|
|
WHERE ad_group.id = $adGroupId
|
|
AND segments.date BETWEEN '$startDate' AND '$endDate'
|
|
ORDER BY segments.date ASC
|
|
QUERY;
|
|
|
|
$request = new SearchGoogleAdsRequest([
|
|
'customer_id' => $customerId,
|
|
'query' => $query,
|
|
]);
|
|
|
|
$response = $service->search($request);
|
|
$results = [];
|
|
|
|
foreach ($response->iterateAllElements() as $row) {
|
|
$ag = $row->getAdGroup();
|
|
$m = $row->getMetrics();
|
|
|
|
$results[] = [
|
|
'ad_group_id' => $ag->getId(),
|
|
'ad_group_name' => $ag->getName(),
|
|
'date' => $row->getSegments()->getDate(),
|
|
'status' => AdGroupStatus::name($ag->getStatus()),
|
|
'impressions' => $m->getImpressions(),
|
|
'clicks' => $m->getClicks(),
|
|
'actual_spend' => round($m->getCostMicros() / 1000000, 2),
|
|
'conversions' => $m->getConversions(),
|
|
'conversion_value' => $m->getConversionsValue(),
|
|
'ctr' => $m->getImpressions() > 0
|
|
? round(($m->getClicks() / $m->getImpressions()) * 100, 2)
|
|
: 0
|
|
];
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
public function getAdMetricsById(string $clientCustomerId, string $adId, string $startDate = '', string $endDate = ''): array
|
|
{
|
|
$customerId = str_replace('-', '', $clientCustomerId);
|
|
$client = $this->buildClient($this->loginCustomerId);
|
|
$service = $client->getGoogleAdsServiceClient();
|
|
if (empty($startDate)) {
|
|
$startDate = date('Y-m-d');
|
|
}
|
|
|
|
if (empty($endDate)) {
|
|
$endDate = date('Y-m-d');
|
|
}
|
|
$query = <<<QUERY
|
|
SELECT
|
|
ad_group_ad.ad.id,
|
|
ad_group_ad.ad.type,
|
|
ad_group_ad.status,
|
|
ad_group.id,
|
|
metrics.impressions,
|
|
metrics.clicks,
|
|
metrics.cost_micros,
|
|
metrics.conversions,
|
|
segments.date
|
|
FROM ad_group_ad
|
|
WHERE ad_group_ad.ad.id = $adId
|
|
AND segments.date BETWEEN '$startDate' AND '$endDate'
|
|
ORDER BY segments.date ASC
|
|
QUERY;
|
|
|
|
$request = new SearchGoogleAdsRequest([
|
|
'customer_id' => $customerId,
|
|
'query' => $query,
|
|
]);
|
|
|
|
$response = $service->search($request);
|
|
$results = [];
|
|
|
|
foreach ($response->iterateAllElements() as $row) {
|
|
$adGroupAd = $row->getAdGroupAd();
|
|
$m = $row->getMetrics();
|
|
|
|
$results[] = [
|
|
'ad_id' => $adGroupAd->getAd()->getId(),
|
|
'ad_type' => AdType::name($adGroupAd->getAd()->getType()),
|
|
'date' => $row->getSegments()->getDate(),
|
|
'status' => AdGroupAdStatus::name($adGroupAd->getStatus()),
|
|
'impressions' => $m->getImpressions(),
|
|
'clicks' => $m->getClicks(),
|
|
'spend' => round($m->getCostMicros() / 1000000, 2),
|
|
'conversions' => $m->getConversions(),
|
|
'ad_group_id' => $row->getAdGroup()->getId()
|
|
];
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
public function getAssetMetricsById(string $clientCustomerId, string $assetId, string $startDate = '', string $endDate = ''): array
|
|
{
|
|
$customerId = str_replace('-', '', $clientCustomerId);
|
|
$client = $this->buildClient($this->loginCustomerId);
|
|
$service = $client->getGoogleAdsServiceClient();
|
|
if (empty($startDate)) {
|
|
$startDate = date('Y-m-d');
|
|
}
|
|
|
|
if (empty($endDate)) {
|
|
$endDate = date('Y-m-d');
|
|
}
|
|
$query = <<<QUERY
|
|
SELECT
|
|
asset.id,
|
|
asset.name,
|
|
campaign_asset.field_type,
|
|
metrics.impressions,
|
|
metrics.clicks,
|
|
metrics.cost_micros,
|
|
metrics.conversions,
|
|
segments.date,
|
|
campaign.id
|
|
FROM campaign_asset
|
|
WHERE asset.id = $assetId
|
|
AND segments.date BETWEEN '$startDate' AND '$endDate'
|
|
ORDER BY segments.date ASC
|
|
QUERY;
|
|
|
|
$request = new SearchGoogleAdsRequest([
|
|
'customer_id' => $customerId,
|
|
'query' => $query,
|
|
]);
|
|
|
|
$response = $service->search($request);
|
|
$results = [];
|
|
|
|
foreach ($response->iterateAllElements() as $row) {
|
|
$asset = $row->getAsset();
|
|
$ca = $row->getCampaignAsset();
|
|
$m = $row->getMetrics();
|
|
|
|
$results[] = [
|
|
'asset_id' => $asset->getId(),
|
|
'asset_name' => $asset->getName(),
|
|
'date' => $row->getSegments()->getDate(),
|
|
'field_type' => AssetFieldType::name($ca->getFieldType()), // e.g., SITELINK, CALLOUT
|
|
'impressions' => $m->getImpressions(),
|
|
'clicks' => $m->getClicks(),
|
|
'cost' => round($m->getCostMicros() / 1000000, 2),
|
|
'conversions' => $m->getConversions(),
|
|
'campaign_id' => $row->getCampaign()->getId()
|
|
];
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
public function getAccountDetails(string $customerId): array
|
|
{
|
|
$client = $this->buildClient($this->loginCustomerId);
|
|
$service = $client->getGoogleAdsServiceClient();
|
|
|
|
// Querying 'customer' gives you specific settings for that ID
|
|
$query = "SELECT
|
|
customer.id,
|
|
customer.descriptive_name,
|
|
customer.currency_code,
|
|
customer.time_zone,
|
|
customer.tracking_url_template,
|
|
customer.auto_tagging_enabled,
|
|
customer.manager,
|
|
customer.test_account,
|
|
customer.status
|
|
FROM customer";
|
|
|
|
// When querying the 'customer' resource, the customer_id in the request
|
|
// must match the ID you are querying.
|
|
$request = new SearchGoogleAdsRequest([
|
|
'customer_id' => $customerId,
|
|
'query' => $query,
|
|
]);
|
|
|
|
$response = $service->search($request);
|
|
|
|
// Since we are querying a specific ID, we only need the first result
|
|
$row = $response->iterateAllElements()->current();
|
|
|
|
if (! $row) {
|
|
return [];
|
|
}
|
|
|
|
$customer = $row->getCustomer();
|
|
|
|
return [
|
|
'id' => $customer->getId(),
|
|
'name' => $customer->getDescriptiveName(),
|
|
'status' => CustomerStatus::name($customer->getStatus()),
|
|
'currency' => $customer->getCurrencyCode(),
|
|
'time_zone' => $customer->getTimeZone(),
|
|
'is_manager' => $customer->getManager(),
|
|
'is_test_account' => $customer->getTestAccount(),
|
|
'auto_tagging' => $customer->getAutoTaggingEnabled(),
|
|
'tracking_template' => $customer->getTrackingUrlTemplate(),
|
|
];
|
|
}
|
|
|
|
|
|
}
|