From 0597f8abfde89bca163853c3e3b304ef0bbd662f Mon Sep 17 00:00:00 2001 From: huangguancheng Date: Fri, 10 Jan 2025 10:09:32 +0800 Subject: [PATCH] googleads:creatives:event --- app/controller/GoogleAdsController.php | 4 +- app/event/GoogleAdsCreatives.php | 73 +++++++++++++ app/process/UpdateGoogleAdsTask.php | 12 ++- app/queue/redis/GoogleAdsCreativeQueue.php | 24 +++++ app/service/GoogleAdsAssetService.php | 115 +++++++++++++++++++++ config/event.php | 7 ++ 6 files changed, 231 insertions(+), 4 deletions(-) create mode 100644 app/event/GoogleAdsCreatives.php create mode 100644 app/queue/redis/GoogleAdsCreativeQueue.php diff --git a/app/controller/GoogleAdsController.php b/app/controller/GoogleAdsController.php index e9f6f7a..e446a8e 100644 --- a/app/controller/GoogleAdsController.php +++ b/app/controller/GoogleAdsController.php @@ -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']); } diff --git a/app/event/GoogleAdsCreatives.php b/app/event/GoogleAdsCreatives.php new file mode 100644 index 0000000..067beee --- /dev/null +++ b/app/event/GoogleAdsCreatives.php @@ -0,0 +1,73 @@ +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 + ]); + } +} diff --git a/app/process/UpdateGoogleAdsTask.php b/app/process/UpdateGoogleAdsTask.php index 1317b6c..77b10f2 100644 --- a/app/process/UpdateGoogleAdsTask.php +++ b/app/process/UpdateGoogleAdsTask.php @@ -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, []); } ); diff --git a/app/queue/redis/GoogleAdsCreativeQueue.php b/app/queue/redis/GoogleAdsCreativeQueue.php new file mode 100644 index 0000000..f9c72dd --- /dev/null +++ b/app/queue/redis/GoogleAdsCreativeQueue.php @@ -0,0 +1,24 @@ +queue.' consumed',$data); + Event::emit(GoogleAdsCreatives::queue, $data); + } + +} \ No newline at end of file diff --git a/app/service/GoogleAdsAssetService.php b/app/service/GoogleAdsAssetService.php index d5068e1..5e6e8fd 100644 --- a/app/service/GoogleAdsAssetService.php +++ b/app/service/GoogleAdsAssetService.php @@ -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(); diff --git a/config/event.php b/config/event.php index 238257a..e08e590 100644 --- a/config/event.php +++ b/config/event.php @@ -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'], ],