معرفی
این راهنما به شما نشان می دهد که چگونه یک گزارش را با API اجرا و دانلود کنید. هم استفاده از پرس و جوی گزارش ذخیره شده موجود و هم ایجاد یک درخواست گزارش موقت را پوشش می دهد.
پیش نیازها
- دسترسی به یک شبکه Production Google Ad Manager
- کتابخانه مشتری Ad Manager
آغازگر
اگر با گزارشدهی در Ad Manager آشنا نیستید، برای مروری بر نحوه اجرای گزارش در رابط کاربری Ad Manager به ایجاد گزارش جدید مراجعه کنید. رابط کاربری دارای پیش نمایشی از خروجی و همچنین نکاتی است که توضیح می دهد کدام ستون و ترکیب ابعاد پشتیبانی می شود. هنگام ایجاد یک پرس و جو گزارش پیچیده، ممکن است ساده تر باشد که ابتدا آن را در UI ایجاد کنید، و سپس پرس و جو را با API بازیابی کنید.
بازیابی یک ReportQuery ذخیره شده
شی ReportQuery شامل تمام جزئیات گزارش است. میتوانید درخواستهای گزارش را در رابط کاربری Ad Manager ایجاد کنید و آنها را با روش ReportService.getSavedQueriesByStatement بازیابی کنید. شناسه پرس و جو ذخیره شده هنگام مشاهده درخواست در UI در URL گنجانده می شود. برای مثال، در نشانی اینترنتی https://www.google.com/admanager/1234#reports/report/detail/report_id=456789
شناسه درخواست 456789
است.
اگر درخواستی با نسخه API شما سازگار نباشد، SavedQuery.reportQuery null
و SavedQuery.isCompatibleWithApiVersion false
خواهد بود.
پرس و جوهای ذخیره شده سازگار را می توان با یا بدون تغییر اجرا کرد.
جاوا
StatementBuilder statementBuilder = new StatementBuilder() .where("id = :id") .orderBy("id ASC") .limit(1) .withBindVariableValue("id", savedQueryId); SavedQueryPage page = reportService.getSavedQueriesByStatement(statementBuilder.toStatement()); SavedQuery savedQuery = Iterables.getOnlyElement(Arrays.asList(page.getResults())); if (!savedQuery.getIsCompatibleWithApiVersion()) { throw new IllegalStateException("The saved query is not compatible with this API version."); } ReportQuery reportQuery = savedQuery.getReportQuery();
پایتون
statement = (ad_manager.StatementBuilder(version='v202402') .Where('id = :id') .WithBindVariable('id', int(saved_query_id)) .Limit(1)) response = report_service.getSavedQueriesByStatement( statement.ToStatement()) if 'results' in response and len(response['results']): saved_query = response['results'][0] if saved_query['isCompatibleWithApiVersion']: report_job = {} # Set report query and optionally modify it. report_job['reportQuery'] = saved_query['reportQuery']
PHP
$statementBuilder = (new StatementBuilder())->where('id = :id') ->orderBy('id ASC') ->limit(1) ->withBindVariableValue('id', $savedQueryId); $savedQueryPage = $reportService->getSavedQueriesByStatement( $statementBuilder->toStatement() ); $savedQuery = $savedQueryPage->getResults()[0]; if ($savedQuery->getIsCompatibleWithApiVersion() === false) { throw new UnexpectedValueException( 'The saved query is not compatible with this API version.' ); } $reportQuery = $savedQuery->getReportQuery();
سی شارپ
StatementBuilder statementBuilder = new StatementBuilder() .Where("id = :id") .OrderBy("id ASC") .Limit(1) .AddValue("id", savedQueryId); SavedQueryPage page = reportService.getSavedQueriesByStatement(statementBuilder.ToStatement()); SavedQuery savedQuery = page.results[0]; if (!savedQuery.isCompatibleWithApiVersion) { throw new InvalidOperationException("Saved query is not compatible with this " + "API version"); } // Optionally modify the query. ReportQuery reportQuery = savedQuery.reportQuery;
روبی
statement = ad_manager.new_statement_builder do |sb| sb.where = 'id = :saved_query_id' sb.with_bind_variable('saved_query_id', saved_query_id) end saved_query_page = report_service.get_saved_queries_by_statement( statement.to_statement() ) unless saved_query_page[:results].nil? saved_query = saved_query_page[:results].first if saved_query[:is_compatible_with_api_version] # Create report job. report_job = {:report_query => saved_query[:report_query]} else raise StandardError, 'Report query is not compatible with the API' end
برای اجرای پرس و جو، به ایجاد ReportJob مراجعه کنید.
ساخت ReportQuery
علاوه بر استفاده از کوئری های ذخیره شده، می توانید یک ReportQuery موقت نیز ایجاد کنید. برای انجام این کار، باید ابعاد گزارش، ویژگیهای ابعاد ، ستونها ، فیلتر و محدوده تاریخ را تنظیم کنید. این مثال برای گزارش تحویل اولیه در یک سفارش است.
جاوا
// Create report query. ReportQuery reportQuery = new ReportQuery(); reportQuery.setDimensions(new Dimension[] {Dimension.DATE, Dimension.ORDER_ID}); reportQuery.setColumns( new Column[] { Column.AD_SERVER_IMPRESSIONS, Column.AD_SERVER_CLICKS, Column.AD_SERVER_CTR, Column.AD_SERVER_CPM_AND_CPC_REVENUE }); reportQuery.setDimensionAttributes( new DimensionAttribute[] { DimensionAttribute.ORDER_TRAFFICKER, DimensionAttribute.ORDER_START_DATE_TIME, DimensionAttribute.ORDER_END_DATE_TIME }); // Create statement to filter for an order. StatementBuilder statementBuilder = new StatementBuilder() .where("ORDER_ID = :orderId") .withBindVariableValue("orderId", orderId); // Set the filter statement. reportQuery.setStatement(statementBuilder.toStatement()); // Set the start and end dates or choose a dynamic date range type. reportQuery.setDateRangeType(DateRangeType.CUSTOM_DATE); reportQuery.setStartDate( DateTimes.toDateTime("2013-05-01T00:00:00", "America/New_York").getDate()); reportQuery.setEndDate( DateTimes.toDateTime("2013-05-31T00:00:00", "America/New_York").getDate());
پایتون
# Create statement object to filter for an order. statement = (ad_manager.StatementBuilder(version='v202402') .Where('ORDER_ID = :id') .WithBindVariable('id', int(order_id)) .Limit(None) # No limit or offset for reports .Offset(None)) # Set the start and end dates of the report to run (past 8 days). end_date = datetime.now().date() start_date = end_date - timedelta(days=8) # Create report job. report_job = { 'reportQuery': { 'dimensions': ['ORDER_ID', 'ORDER_NAME'], 'dimensionAttributes': ['ORDER_TRAFFICKER', 'ORDER_START_DATE_TIME', 'ORDER_END_DATE_TIME'], 'statement': statement.ToStatement(), 'columns': ['AD_SERVER_IMPRESSIONS', 'AD_SERVER_CLICKS', 'AD_SERVER_CTR', 'AD_SERVER_CPM_AND_CPC_REVENUE', 'AD_SERVER_WITHOUT_CPD_AVERAGE_ECPM'], 'dateRangeType': 'CUSTOM_DATE', 'startDate': start_date, 'endDate': end_date } }
PHP
// Create report query. $reportQuery = new ReportQuery(); $reportQuery->setDimensions( [ Dimension::ORDER_ID, Dimension::ORDER_NAME ] ); $reportQuery->setDimensionAttributes( [ DimensionAttribute::ORDER_TRAFFICKER, DimensionAttribute::ORDER_START_DATE_TIME, DimensionAttribute::ORDER_END_DATE_TIME ] ); $reportQuery->setColumns( [ Column::AD_SERVER_IMPRESSIONS, Column::AD_SERVER_CLICKS, Column::AD_SERVER_CTR, Column::AD_SERVER_CPM_AND_CPC_REVENUE, Column::AD_SERVER_WITHOUT_CPD_AVERAGE_ECPM ] ); // Create statement to filter for an order. $statementBuilder = (new StatementBuilder()) ->where('ORDER_ID = :orderId') ->withBindVariableValue( 'orderId', $orderId ); // Set the filter statement. $reportQuery->setStatement($statementBuilder->toStatement()); // Set the start and end dates or choose a dynamic date range type. $reportQuery->setDateRangeType(DateRangeType::CUSTOM_DATE); $reportQuery->setStartDate( AdManagerDateTimes::fromDateTime( new DateTime( '-10 days', new DateTimeZone('America/New_York') ) ) ->getDate() ); $reportQuery->setEndDate( AdManagerDateTimes::fromDateTime( new DateTime( 'now', new DateTimeZone('America/New_York') ) ) ->getDate() );
سی شارپ
// Create report job. ReportJob reportJob = new ReportJob(); reportJob.reportQuery = new ReportQuery(); reportJob.reportQuery.dimensions = new Dimension[] { Dimension.ORDER_ID, Dimension.ORDER_NAME }; reportJob.reportQuery.dimensionAttributes = new DimensionAttribute[] { DimensionAttribute.ORDER_TRAFFICKER, DimensionAttribute.ORDER_START_DATE_TIME, DimensionAttribute.ORDER_END_DATE_TIME }; reportJob.reportQuery.columns = new Column[] { Column.AD_SERVER_IMPRESSIONS, Column.AD_SERVER_CLICKS, Column.AD_SERVER_CTR, Column.AD_SERVER_CPM_AND_CPC_REVENUE, Column.AD_SERVER_WITHOUT_CPD_AVERAGE_ECPM }; // Set a custom date range for the last 8 days reportJob.reportQuery.dateRangeType = DateRangeType.CUSTOM_DATE; System.DateTime endDateTime = System.DateTime.Now; reportJob.reportQuery.startDate = DateTimeUtilities .FromDateTime(endDateTime.AddDays(-8), "America/New_York").date; reportJob.reportQuery.endDate = DateTimeUtilities .FromDateTime(endDateTime, "America/New_York").date; // Create statement object to filter for an order. StatementBuilder statementBuilder = new StatementBuilder().Where("ORDER_ID = :id") .AddValue("id", orderId); reportJob.reportQuery.statement = statementBuilder.ToStatement();
روبی
# Specify a report to run for the last 7 days. report_end_date = ad_manager.today() report_start_date = report_end_date - 7 # Create statement object to filter for an order. statement = ad_manager.new_report_statement_builder do |sb| sb.where = 'ORDER_ID = :order_id' sb.with_bind_variable('order_id', order_id) end # Create report query. report_query = { :date_range_type => 'CUSTOM_DATE', :start_date => report_start_date.to_h, :end_date => report_end_date.to_h, :dimensions => ['ORDER_ID', 'ORDER_NAME'], :dimension_attributes => ['ORDER_TRAFFICKER', 'ORDER_START_DATE_TIME', 'ORDER_END_DATE_TIME'], :columns => ['AD_SERVER_IMPRESSIONS', 'AD_SERVER_CLICKS', 'AD_SERVER_CTR', 'AD_SERVER_CPM_AND_CPC_REVENUE', 'AD_SERVER_WITHOUT_CPD_AVERAGE_ECPM'], :statement => statement.to_statement() }
ایجاد ReportJob
هنگامی که یک ReportQuery دارید، نوبت به اجرای گزارش می رسد. شی ReportJob وضعیت یک گزارش را نگه می دارد و به شما اطلاع می دهد که چه زمانی برای دانلود آماده است. برای شروع اجرای گزارش خود، از روش ReportService.runReportJob استفاده کنید.
جاوا
// Create report job. ReportJob reportJob = new ReportJob(); reportJob.setReportQuery(reportQuery); // Run report job. reportJob = reportService.runReportJob(reportJob);
پایتون
# Initialize a DataDownloader. report_downloader = client.GetDataDownloader(version='v202402') try: # Run the report and wait for it to finish. report_job_id = report_downloader.WaitForReport(report_job) except errors.AdManagerReportError as e: print('Failed to generate report. Error was: %s' % e)
PHP
// Create report job and start it. $reportJob = new ReportJob(); $reportJob->setReportQuery($reportQuery); $reportJob = $reportService->runReportJob($reportJob);
سی شارپ
// Run report job. reportJob = reportService.runReportJob(reportJob);
روبی
# Create report job. report_job = {:report_query => report_query} # Run report job. report_job = report_service.run_report_job(report_job);
در حال دانلود گزارش
پس از شروع کار گزارش، یک شناسه تنظیم شده توسط سرور خواهد داشت. از این شناسه با روش ReportService.getReportJobStatus برای بررسی وضعیت گزارش خود استفاده کنید. هنگامی که وضعیت ReportJobStatus.COMPLETED شد، گزارش آماده دانلود است.
برخی از کتابخانههای مشتری ما ابزارهای کمکی دارند که API را نظرسنجی میکنند و منتظر تکمیل گزارش میمانند. پس از تکمیل گزارش، می توانید URL دانلود را با روش ReportService.getReportDownloadURL دریافت کنید. یک گزارش را می توان در قالب های مختلف دانلود کرد. اگر میخواهید پردازش ماشینی بیشتری را با گزارش انجام دهید، باید از قالب CSV_DUMP استفاده کنید.
جاوا
// Create report downloader. ReportDownloader reportDownloader = new ReportDownloader(reportService, reportJob.getId()); // Wait for the report to be ready. if (reportDownloader.waitForReportReady()) { // Change to your file location. File file = File.createTempFile("delivery-report-", ".csv.gz"); System.out.printf("Downloading report to %s ...", file.toString()); // Download the report. ReportDownloadOptions options = new ReportDownloadOptions(); options.setExportFormat(ExportFormat.CSV_DUMP); options.setUseGzipCompression(true); URL url = reportDownloader.getDownloadUrl(options); Resources.asByteSource(url).copyTo(Files.asByteSink(file)); System.out.println("done."); } else { System.out.printf("Report job %d failed.%n", reportJob.getId()); }
پایتون
# Change to your preferred export format. export_format = 'CSV_DUMP' report_file = tempfile.NamedTemporaryFile(suffix='.csv.gz', delete=False) # Download report data. report_downloader.DownloadReportToFile( report_job_id, export_format, report_file) report_file.close() # Display results. print('Report job with id "%s" downloaded to:\n%s' % ( report_job_id, report_file.name))
PHP
// Create report downloader to poll report's status and download when // ready. $reportDownloader = new ReportDownloader( $reportService, $reportJob->getId() ); if ($reportDownloader->waitForReportToFinish()) { // Write to system temp directory by default. $filePath = sprintf( '%s.csv.gz', tempnam(sys_get_temp_dir(), 'delivery-report-') ); printf("Downloading report to %s ...%s", $filePath, PHP_EOL); // Download the report. $reportDownloader->downloadReport( ExportFormat::CSV_DUMP, $filePath ); print "done.\n"; } else { print "Report failed.\n"; }
سی شارپ
ReportUtilities reportUtilities = new ReportUtilities(reportService, reportJob.id); // Set download options. ReportDownloadOptions options = new ReportDownloadOptions(); options.exportFormat = ExportFormat.CSV_DUMP; options.useGzipCompression = true; reportUtilities.reportDownloadOptions = options; // Download the report. using (ReportResponse reportResponse = reportUtilities.GetResponse()) { reportResponse.Save(filePath); } Console.WriteLine("Report saved to \"{0}\".", filePath);
روبی
MAX_RETRIES.times do |retry_count| # Get the report job status. report_job_status = report_service.get_report_job_status(report_job[:id]) break unless report_job_status == 'IN_PROGRESS' puts 'Report with ID %d is still running.' % report_job[:id] sleep(RETRY_INTERVAL) end puts 'Report job with ID %d finished with status "%s".' % [report_job[:id], report_service.get_report_job_status(report_job[:id])] # Get the report URL. download_url = report_service.get_report_download_url( report_job_id, export_format ) puts 'Downloading "%s" to "%s"...' % [download_url, file_name] open(file_name, 'wb') do |local_file| local_file << open(download_url).read() end
خواندن داده های گزارش
بسیاری از کتابخانه های مشتری ما دارای ابزارهایی برای خواندن داده های گزارش هستند. این برای انجام پردازش های اضافی روی داده های گزارش یا ترکیب گزارش ها از محدوده های مختلف تاریخ مفید است. توجه داشته باشید که کد مثال فرض می کند که فایل فشرده نشده است.
جاوا
Listrows = CsvFiles.getCsvDataArray(filePath, true); for (String[] row : rows) { // Additional row processing processReportRow(row); }
پایتون
with open(report_file.name, 'rb') as report: report_reader = csv.reader(report) for row in report_reader: # Additional row processing process_row(row)
PHP
$report = fopen($filePath, 'r'); while (!feof($report)) { // Additional row processing processRow(fgetcsv($report)); } fclose($report);
سی شارپ
CsvFile file = new CsvFile(); file.Read(fileName, true); for (String[] row : file.Records) { // Additional row processing ProcessReportRow(row); }
روبی
CSV.foreach(file_name, converters: :numeric, headers: true) do |row| # Additional row processing process_row(row) end
برای نمونه های گزارش بیشتر، کتابخانه های مشتری ما را در GitHub بررسی کنید.
سوالات متداول
- چرا همه نتایج گزارش در شبکه آزمایشی من خالی است؟
- شبکههای آزمایشی تبلیغات ارائه نمیکنند، بنابراین گزارشهای تحویل دادهای ندارند.
- چرا همه نتایج گزارش در شبکه تولید من خالی است؟
- کاربری که شما احراز هویت می کنید زیرا ممکن است به داده هایی که می خواهید گزارش دهید دسترسی نداشته باشد. بررسی کنید که مجوزهای نقش و تیم آنها به درستی تنظیم شده باشد.
- چرا خطای
ReportError.COLUMNS_NOT_SUPPORTED_FOR_REQUESTED_DIMENSIONS
را برای گزارش خود دریافت می کنم؟ - همه ترکیبهای ستونها و ابعاد در Ad Manager پشتیبانی نمیشوند. برای گزارشهای پیچیده، ساختن یک گزارش معتبر در رابط کاربری و سپس بازیابی آن با روش ReportService.getSavedQueriesByStatement ممکن است آسانتر باشد.
- چرا گزارش ذخیره شده من در API برگردانده نمی شود؟
- مطمئن شوید که مالک گزارش گزارش را با کاربری که به عنوان احراز هویت شما احراز هویت می کنید به اشتراک گذاشته است.
- چرا گزارش ذخیره شده من با API سازگار نیست؟
- برخی از ویژگیهای گزارشدهی در API در دسترس نیستند. این شامل ستونها، ویژگیهای ابعاد، ابعاد و انواع محدوده تاریخ است. برای انواع محدوده تاریخ ناسازگار، می توانید گزارش را با یک نوع پشتیبانی شده ذخیره کنید تا قابل بازیابی باشد، سپس
ReportQuery
تغییر دهید تا محدوده تاریخ ثابت مورد نظر شما را برآورده کند. - چرا کلیک ها/برداشت های مادام العمر با گزارش من در رابط کاربری مطابقت ندارند؟
- نمایشهای مادامالعمر برای کل عمر مورد خط، صرفنظر از محدوده تاریخ گزارش، هستند. اگر یک مورد خطی همچنان در حال تحویل است، مقدار آن احتمالاً بین اجرای هر دو گزارش تغییر خواهد کرد.
- گزارشهای من بیش از حد طولانی میشوند و گهگاهی زمان میبرند. چه می توانم بکنم؟
- کاهش محدوده تاریخ یا تعداد ابعاد به بهبود عملکرد کمک می کند. به جای آن، چندین گزارش را برای بازه های تاریخ کوچکتر اجرا کنید. سپس می توانید داده های گزارش را ادغام کنید تا محدوده تاریخ مورد نظر را پوشش دهید.
- تفاوت بین ستون های
INVENTORY_LEVEL
وLINE_ITEM_LEVEL
چیست؟ از کدوم استفاده کنم؟ ستونهای دارای
LINE_ITEM_LEVEL
تنها در صورتی میتوانند استفاده شوند که تخصیص پویا سطح آیتم خط را در شبکه خود فعال کرده باشید. این ستونها شامل دادههایی از تخصیص پویا سطح آیتم خط به AdSense یا Ad Exchange است. به طور مشابه، ستون هایINVENTORY_LEVEL
شامل داده هایی از تخصیص پویا در سطح موجودی است. برای اطلاعات بیشتر درباره تخصیص پویا، به موارد خط Ad Exchange مراجعه کنید.اگر هنوز مطمئن نیستید از کدام ستون های API استفاده کنید، یک پرس و جو ذخیره شده در رابط کاربری Ad Manager ایجاد کنید و آن را با روش ReportService.getSavedQueriesByStatement بازیابی کنید.