webman_ad/app/service/GoogleAdsAccountService.php
2024-12-20 19:39:36 +08:00

332 lines
13 KiB
PHP

<?php
namespace app\service;
use app\util\Helper;
use app\util\ArgumentNames;
use app\util\ArgumentParser;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\Lib\V18\GoogleAdsClient;
use Google\Ads\GoogleAds\Lib\V18\GoogleAdsClientBuilder;
use Google\Ads\GoogleAds\Lib\V18\GoogleAdsException;
use Google\Ads\GoogleAds\Util\FieldMasks;
use Google\Ads\GoogleAds\Util\V18\ResourceNames;
use Google\Ads\GoogleAds\V18\Enums\ManagerLinkStatusEnum\ManagerLinkStatus;
use Google\Ads\GoogleAds\V18\Errors\GoogleAdsError;
use Google\Ads\GoogleAds\V18\Resources\CustomerClientLink;
use Google\Ads\GoogleAds\V18\Resources\CustomerManagerLink;
use Google\Ads\GoogleAds\V18\Services\CustomerClientLinkOperation;
use Google\Ads\GoogleAds\V18\Services\CustomerManagerLinkOperation;
use Google\Ads\GoogleAds\V18\Services\ListAccessibleCustomersRequest;
use Google\Ads\GoogleAds\V18\Services\MutateCustomerClientLinkRequest;
use Google\Ads\GoogleAds\V18\Services\MutateCustomerManagerLinkRequest;
use Google\Ads\GoogleAds\V18\Services\SearchGoogleAdsRequest;
use Google\ApiCore\ApiException;
class GoogleAdsAccountService
{
// private $googleAdsClient;
// private $customerId;
// private const NUMBER_OF_CAMPAIGNS_TO_ADD = 1;
private $loginCustomerId; // 增加 login-customer-id 属性
public function __construct()
{
// $this->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();
}
/**
* Runs the example.
*
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
*/
// [START list_accessible_customers]
public static function runListAccessibleCustomers()
{
// Creates a client with the manager customer ID as login customer ID.
$googleAdsClient = self::createGoogleAdsClient(0);
$customerServiceClient = $googleAdsClient->getCustomerServiceClient();
// Issues a request for listing all accessible customers.
$accessibleCustomers =
$customerServiceClient->listAccessibleCustomers(new ListAccessibleCustomersRequest());
print 'Total results: ' . count($accessibleCustomers->getResourceNames()) . PHP_EOL;
$resourceNameArray = [];
// Iterates over all accessible customers' resource names and prints them.
foreach ($accessibleCustomers->getResourceNames() as $resourceName) {
/** @var string $resourceName */
printf("Customer resource name: '%s'%s", $resourceName, PHP_EOL);
$resourceNameArray[] = $resourceName;
}
return $resourceNameArray;
}
// [END list_accessible_customers]
/**
* Runs the example.
*
* @param $options
* This example assumes that the same credentials will work for both customers,
* but that may not be the case. If you need to use different credentials
* for each customer, then you may either update the client configuration or
* instantiate the clients accordingly, one for each set of credentials. Always make
* sure to update the configuration before fetching any services you need to use.
* // * @return mixed
* @throws ApiException
*/
public function runLinkManagerToClient($options)
{
// Extends an invitation to the client while authenticating as the manager.
$managerCustomerId = $options['manager_customer_id'];
$clientCustomerId = $options['client_customer_id'];
// Extends an invitation to the client while authenticating as the manager.
$customerClientLinkResourceName = self::createInvitation(
$managerCustomerId,
$clientCustomerId
);
// Retrieves the manager link information.
$managerLinkResourceName = self::getManagerLinkResourceName(
$managerCustomerId,
$clientCustomerId,
$customerClientLinkResourceName
);
// Accepts the manager's invitation while authenticating as the client.
return self::acceptInvitation($clientCustomerId, $managerLinkResourceName);
}
/**
* Extends an invitation from a manager customer to a client customer.
*
* @param int $managerCustomerId the manager customer ID
* @param int $clientCustomerId the customer ID
* @return string the resource name of the customer client link created for the invitation
*/
private static function createInvitation(
int $managerCustomerId,
int $clientCustomerId
)
{
// Creates a client with the manager customer ID as login customer ID.
$googleAdsClient = self::createGoogleAdsClient($managerCustomerId);
// Creates a customer client link.
$customerClientLink = new CustomerClientLink([
// Sets the client customer to invite.
'client_customer' => ResourceNames::forCustomer($clientCustomerId),
'status' => ManagerLinkStatus::PENDING
]);
// Creates a customer client link operation for creating the one above.
$customerClientLinkOperation = new CustomerClientLinkOperation();
$customerClientLinkOperation->setCreate($customerClientLink);
// Issues a mutate request to create the customer client link.
$customerClientLinkServiceClient = $googleAdsClient->getCustomerClientLinkServiceClient();
$response = $customerClientLinkServiceClient->mutateCustomerClientLink(
MutateCustomerClientLinkRequest::build(
$managerCustomerId,
$customerClientLinkOperation
)
);
// Prints the result.
$customerClientLinkResourceName = $response->getResult()->getResourceName();
printf(
"An invitation has been extended from the manager customer %d" .
" to the client customer %d with the customer client link resource name '%s'.%s",
$managerCustomerId,
$clientCustomerId,
$customerClientLinkResourceName,
PHP_EOL
);
// Returns the resource name of the created customer client link.
return $customerClientLinkResourceName;
}
/**
* Retrieves the manager link resource name of a customer client link given its resource name.
*
* @param int $managerCustomerId the manager customer ID
* @param int $clientCustomerId the customer ID
* @param string $customerClientLinkResourceName the customer client link resource name
* @return string the manager link resource name
*/
private static function getManagerLinkResourceName(
int $managerCustomerId,
int $clientCustomerId,
string $customerClientLinkResourceName
)
{
// Creates a client with the manager customer ID as login customer ID.
$googleAdsClient = self::createGoogleAdsClient($managerCustomerId);
// Creates the query.
$query = "SELECT customer_client_link.manager_link_id FROM customer_client_link" .
" WHERE customer_client_link.resource_name = '$customerClientLinkResourceName'";
// Issues a search request.
$googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
$response = $googleAdsServiceClient->search(
SearchGoogleAdsRequest::build($managerCustomerId, $query)
);
// Gets the ID and resource name associated to the manager link found.
$managerLinkId = $response->getIterator()->current()
->getCustomerClientLink()
->getManagerLinkId();
$managerLinkResourceName = ResourceNames::forCustomerManagerLink(
$clientCustomerId,
$managerCustomerId,
$managerLinkId
);
// Prints the result.
printf(
"Retrieved the manager link of the customer client link:" .
" its ID is %d and its resource name is '%s'.%s",
$managerLinkId,
$managerLinkResourceName,
PHP_EOL
);
// Returns the resource name of the manager link found.
return $managerLinkResourceName;
}
/**
* Accepts an invitation.
*
* @param int $clientCustomerId the customer ID
* @param string $managerLinkResourceName the resource name of the manager link to accept
*/
private static function acceptInvitation(
int $clientCustomerId,
string $managerLinkResourceName
)
{
// Creates a client with the client customer ID as login customer ID.
$googleAdsClient = self::createGoogleAdsClient($clientCustomerId);
// Creates the customer manager link with the updated status.
$customerManagerLink = new CustomerManagerLink();
$customerManagerLink->setResourceName($managerLinkResourceName);
$customerManagerLink->setStatus(ManagerLinkStatus::ACTIVE);
// Creates a customer manager link operation for updating the one above.
$customerManagerLinkOperation = new CustomerManagerLinkOperation();
$customerManagerLinkOperation->setUpdate($customerManagerLink);
$customerManagerLinkOperation->setUpdateMask(
FieldMasks::allSetFieldsOf($customerManagerLink)
);
// Issues a mutate request to update the customer manager link.
$customerManagerLinkServiceClient =
$googleAdsClient->getCustomerManagerLinkServiceClient();
$response = $customerManagerLinkServiceClient->mutateCustomerManagerLink(
MutateCustomerManagerLinkRequest::build(
$clientCustomerId,
[$customerManagerLinkOperation]
)
);
// Prints the result.
printf(
"The client %d accepted the invitation with the resource name '%s'.%s",
$clientCustomerId,
$response->getResults()[0]->getResourceName(),
PHP_EOL
);
return $response->getResults()[0]->getResourceName();
}
// [END link_manager_to_client]
/**
* Creates a Google Ads client based on the default configuration file
* and a given login customer id.
*
* @param int $loginCustomerId the login customer ID
* @return GoogleAdsClient the created client
*/
private static function createGoogleAdsClient(int $loginCustomerId)
{
$advertiserId = getenv('GOOGLE_ADS_CUSTOMER_ID');
// 从数据库获取 access_token
$refreshToken = self::getRefreshTokenFromDatabase($advertiserId);
if (!$refreshToken) {
throw new \Exception("Access token not found for advertiserId: " . $advertiserId);
}
// OAuth2 Token Authentication
$oAuth2Credential = (new OAuth2TokenBuilder())
->fromFile() // 如果需要从文件获取其他配置,可以继续使用 fromFile()
->withRefreshToken($refreshToken) // 使用动态获取的 access_token
->build();
if ($loginCustomerId > 0) {
// Builds and returns the Google Ads client
return (
new GoogleAdsClientBuilder())
// Sets the properties based on the default properties file
->fromFile()
// eUses the OAuth2 credentials crated above.
->withOAuth2Credential($oAuth2Credential)
// Overrides the login customer ID with the given one.
->withLoginCustomerId($loginCustomerId)
->build();
} else {
// Builds and returns the Google Ads client
return (new GoogleAdsClientBuilder())
// Sets the properties based on the default properties file
->fromFile()
// eUses the OAuth2 credentials crated above.
->withOAuth2Credential($oAuth2Credential)
// Overrides the login customer ID with the given one.
->build();
}
}
// 从数据库动态获取 google RefreshToken
private function getRefreshTokenFromDatabase($advertiserId)
{
// 使用 ThinkDb 进行联表查询
// $advertiserId = 'your-advertiser-id'; // 假设你已经获得了广告商ID
$user = ThinkDb::table('bps.bps_third_user_advertiser as a')
->join('bps_third_user as u', 'a.doc_ = u.id', 'left') // 连接 bps_third_user 表
->where('a.advertiser_id', $advertiserId)
->select('u.access_token') // 只选择 access_token 字段
->first();
return $user ? $user->access_token : null;
}
}