googleads:creatives:event

This commit is contained in:
huangguancheng 2025-01-10 10:09:32 +08:00
parent d759d3e53b
commit 0597f8abfd
6 changed files with 231 additions and 4 deletions

View File

@ -282,7 +282,9 @@ class GoogleAdsController
*/
public function getAssets($options): Response
{
$resourceName = $this->googleAdsAssetService->runListAssets($options['customer_id']);
$options['login_customer_id'] = 1401879025;
$options['refresh_token'] = '1//0en4AWGamrTnOCgYIARAAGA4SNwF-L9IrMOw2DkHF2y3DL2kDiEmOUzk5KTsR1f1iU_axBNi-LgxfT_76JHK4AY1KChZWfyNc0Qs';
$resourceName = $this->googleAdsAssetService->runListCreatives($options['customer_id'],$options);
// return $this->successResponse(['assets_list' => $resourceName]);
return $this->successResponse(['assets_list' => 'succeed added']);
}

View File

@ -0,0 +1,73 @@
<?php
namespace app\event;
use app\service\GoogleAdsAssetService;
use app\service\GoogleOAuthService;
use Google\ApiCore\ApiException;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use support\Db;
use Webman\RedisQueue\Redis;
use support\Response;
use DI\Annotation\Inject;
//use QL\QueryList;
class GoogleAdsCreatives
{
/**
* @Inject
* @var GoogleOAuthService
*/
private $googleOAuthService;
const event = 'googleads:creatives:event';
const queue = 'googleads:creatives:queue';
public function syncCreatives($options = [])
{
$queue = self::queue;
$customers = $this->googleOAuthService->getGoogleAdCustomers($options);
foreach ($customers as $customer) {
if ($customer['login_customer_id'] > 0) {
Redis::send($queue, $customer,rand(1,10));
}
}
return self::event.' send queue ok';
}
/**
* get assets
* @throws ApiException
*/
public function getCreatives($customer)
{
$googleAdsAssetService = new GoogleAdsAssetService($customer['customer_id']);
if ($customer['login_customer_id'] >0){
$resourceName = $googleAdsAssetService->runListCreatives($customer['customer_id'],$customer);
}
// return $this->successResponse(['ads_list' => $resourceName]);
}
// 可以加入一些公共方法
protected function successResponse($data): Response
{
return Json([
'code' => 0,
'msg' => 'ok',
'data' => $data,
]);
}
protected function errorResponse($code, $message, $data = []): Response
{
return Json([
'code' => $code,
'msg' => $message ?: 'error',
'data' => $data
]);
}
}

View File

@ -4,6 +4,7 @@ namespace app\process;
use app\event\GoogleAdsCampaigns;
use app\event\GoogleAdsCreatives;
use app\event\GoogleAdsCustomers;
use app\event\GoogleAdsGroups;
use app\event\GoogleAdsAds;
@ -75,10 +76,15 @@ class UpdateGoogleAdsTask
);
// 每15分钟执行一次
new Crontab('25 */10 * * * *', function () {
new Crontab('25 */15 * * * *', function () {
// dump(date('Y-m-d H:i:s') . '更新' . GoogleAdsAssets::event . '开始');
// Event::emit(GoogleAdsAssets::event, []);
dump(date('Y-m-d H:i:s') . '更新' . GoogleAdsCreatives::event . '开始');
Event::emit(GoogleAdsCreatives::event, []);
}
);
new Crontab('25 */14 * * * *', function () {
dump(date('Y-m-d H:i:s') . '更新' . GoogleAdsAssets::event . '开始');
Event::emit(GoogleAdsAssets::event, []);
}
);

View File

@ -0,0 +1,24 @@
<?php
namespace app\queue\redis;
use app\event\GoogleAdsCreatives;
use Webman\Event\Event;
use Webman\RedisQueue\Consumer;
class GoogleAdsCreativeQueue implements Consumer
{
// 要消费的队列名
public $queue = GoogleAdsCreatives::queue;
// 连接名,对应 plugin/webman/redis-queue/redis.php 里的连接`
public $connection = 'default';
// 消费
public function consume($data)
{
// dump($this->queue.' consumed',$data);
Event::emit(GoogleAdsCreatives::queue, $data);
}
}

View File

@ -84,6 +84,25 @@ class GoogleAdsAssetService extends BaseService
return $assetsResourceName;
}
/* @param int $customerId the customer ID
* @param $options
* @return mixed
* @throws ApiException
*/
public function runListCreatives(int $customerId,$options): mixed
{
$googleAdsClient = new GoogleAdsClientService($options['refresh_token'], $options['login_customer_id']);
// Creates a single shared budget to be used by the campaigns added below.
$assetsResourceName = self::getAssetsNew($googleAdsClient->getGoogleAdsClientWithloginCustomerId(), $customerId);
// dump(json_encode($assetsResourceName));
if (is_array($assetsResourceName)) {
self::saveAssetsNew($assetsResourceName);
}
return $assetsResourceName;
}
/* @param int $customerId the customer ID
* @param $options
@ -107,6 +126,33 @@ class GoogleAdsAssetService extends BaseService
}
/**
* 在数据库中保存广告素材信息
* @param $assetsResourceName
* @return void
*/
public static function saveAssetsNew($assetsResourceName)
{
$tableName = 'bps_ads_creative';
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'public' . $tableName;
foreach ($assetsResourceName as $data) {
// 修改后的插入 SQL 语句
$sql = "INSERT INTO {$tableName}
(creative_id, account_id,platform, type, name, url, status, created_at, updated_at)
VALUES (:creative_id, :account_id,:platform, :type, :name, :url, :status, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
ON CONFLICT (creative_id,platform)
DO UPDATE SET
account_id = EXCLUDED.account_id,
type = EXCLUDED.type,
name = EXCLUDED.name,
url = EXCLUDED.url,
status = EXCLUDED.status,
updated_at = CURRENT_TIMESTAMP"; // update_at 使用 CURRENT_TIMESTAMP 自动更新
ThinkDb::execute($sql, $data);
}
}
/**
* 在数据库中保存广告素材信息
* @param $assetsResourceName
@ -147,6 +193,75 @@ class GoogleAdsAssetService extends BaseService
*/
// [START get_campaigns]
public static function getAssetsNew(GoogleAdsClient $googleAdsClient, int $customerId)
{
$googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
// 查询广告素材及其关联的广告、广告组和广告系列
// $query ="SELECT asset.id,asset.name, asset.image_asset.mime_type, asset.image_asset.full_size.url, customer.id FROM asset";
$query = "SELECT asset.id,
asset.name,
asset.type,
asset.resource_name,
asset.source,
asset.image_asset.full_size.url,
asset.image_asset.mime_type,
asset.image_asset.file_size,
asset.image_asset.full_size.height_pixels,
asset.image_asset.full_size.width_pixels,
asset.youtube_video_asset.youtube_video_id,
asset.youtube_video_asset.youtube_video_title,
customer.id
FROM asset
WHERE
asset.type IN ('IMAGE', 'YOUTUBE_VIDEO')
LIMIT 10000";
// 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 */
// 将最终的 URL 列表转换为 PHP 数组
// $finalUrlsArray = iterator_to_array($finalUrlsList);
$resourceName = [];
$asset_type = $googleAdsRow->getAsset()->getType();
if ($asset_type === 2) {
$resourceName['url'] = $googleAdsRow->getAsset()->getYoutubeVideoAsset()->getYoutubeVideoId();
// $resourceName['metadata'] ['youtube_video_id'] = $googleAdsRow->getAsset()->getYoutubeVideoAsset()->getYoutubeVideoId();
// $resourceName['metadata'] ['youtube_video_title'] = $googleAdsRow->getAsset()->getYoutubeVideoAsset()->getYoutubeVideoTitle();
$resourceName['name'] = $resourceName['metadata'] ['youtube_video_title'];
$resourceName['type'] = 2;
// $resourceName['metadata'] = json_encode($resourceName['metadata']);
} elseif ($asset_type === 4) {
$resourceName['name'] = $googleAdsRow->getAsset()->getName();
$resourceName['type'] = 1;
$resourceName['url'] = $googleAdsRow->getAsset()->getImageAsset()->getFullSize()->getUrl();
// $resourceName['metadata'] ['mimeType'] = $googleAdsRow->getAsset()->getImageAsset()->getMimeType();
// $resourceName['metadata'] ['filesize'] = $googleAdsRow->getAsset()->getImageAsset()->getFileSize();
// $resourceName['metadata'] ['height_pixels'] = $googleAdsRow->getAsset()->getImageAsset()->getFullSize()->getHeightPixels();
// $resourceName['metadata'] ['width_pixels'] = $googleAdsRow->getAsset()->getImageAsset()->getFullSize()->getWidthPixels();
// $resourceName['metadata'] = json_encode($resourceName['metadata']);
} else {
continue;
}
$resourceName['creative_id'] = $googleAdsRow->getAsset()->getId();
$resourceName['status'] = 2; //未定义,先占坑
$resourceName['platform'] = 2; //未定义,先占坑
// $resourceName['resource_name'] = $googleAdsRow->getAsset()->getResourceName();
// $resourceName['source'] = $googleAdsRow->getAsset()->getSource();
$resourceName['account_id'] = $googleAdsRow->getCustomer()->getId();
$resourceNames[] = $resourceName;
}
return $resourceNames;
}
public static function getAssets(GoogleAdsClient $googleAdsClient, int $customerId)
{
$googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();

View File

@ -6,6 +6,7 @@ use app\event\TiktokAdsDetails;
use app\event\GoogleAdsCampaigns;
use app\event\GoogleAdsGroups;
use app\event\GoogleAdsAds;
use app\event\GoogleAdsCreatives;
use app\event\GoogleAdsAssets;
use app\event\GoogleAdsAssetRelations;
use app\event\GoogleAdsCustomers;
@ -46,6 +47,12 @@ return [
GoogleAdsAssets::queue => [
[GoogleAdsAssets::class, 'getAssets'],
],
GoogleAdsCreatives::event => [
[GoogleAdsCreatives::class, 'syncCreatives'],
],
GoogleAdsCreatives::queue => [
[GoogleAdsCreatives::class, 'getCreatives'],
],
GoogleAdsAssetRelations::event => [
[GoogleAdsAssetRelations::class, 'syncAssetRelations'],
],