مقدمه
این راهنما به شما نشان میدهد که چگونه بااستفاده از API گزارشی را اجرا و بارگیری کنید. این دوره هم شامل استفاده از پُرسمان گزارش ذخیرهشده موجود و هم ایجاد پُرسمان گزارش موردی میشود.
پیشنیازها
- دسترسی به شبکه Google Ad Manager تولید
- کتابخانه مشتری Ad Manager
Primer
اگر با گزارشدهی در Ad Manager آشنا نیستید، برای دریافت نمای کلی از نحوه اجرای گزارش در واسط کاربر Ad Manager، به ایجاد گزارش جدید مراجعه کنید. رابط کاربری پیشنمایشی از خروجی و همچنین نکتهابزارهایی دارد که توضیح میدهند کدام ترکیبهای ستون و بُعد پشتیبانی میشوند. هنگام ایجاد یک پُرسمان گزارش پیچیده، ممکن است ایجاد آن در واسط کاربر در ابتدا آسانتر باشد و سپس پُرسمان را با API بازیابی کنید.
درحال بازیابی ReportQuery ذخیرهشده
شیء ReportQuery
حاوی همه جزئیات گزارش است. میتوانید پُرسمانهای گزارش را در
میانای کاربری Ad Manager ایجاد کنید و آنها را با
روش ReportService.getSavedQueriesByStatement
بازیابی کنید. شناسه پُرسمان ذخیرهشده در نشانی وب گنجانده شده است، هنگام مشاهده پُرسمان در
رابط کاربری. برای مثال، در نشانی وب
https://www.google.com/admanager/1234#reports/report/detail/report_id=456789
شناسه پُرسمان 456789 است.
اگر پُرسمانی با نسخه میانای برنامهسازی کاربردی شما سازگار نباشد،
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();
Python
statement = (ad_manager.StatementBuilder(version='v202608') .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();
C#
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;
Ruby
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());
Python
# Create statement object to filter for an order. statement = (ad_manager.StatementBuilder(version='v202608') .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() );
C#
// 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();
Ruby
# 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);
Python
# Initialize a DataDownloader. report_downloader = client.GetDataDownloader(version='v202608') 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);
C#
// Run report job. reportJob = reportService.runReportJob(reportJob);
Ruby
# 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 باشد، گزارش برای بارگیری آماده است.
برخیاز کتابخانههای مشتری ما ابزارهای کمکی دارند که میانای برنامهسازی کاربردی را نظرسنجی میکنند و منتظر میمانند تا گزارش تکمیل شود. وقتی گزارش تکمیل شد، میتوانید نشانی وب بارگیری را با روش 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()); }
Python
# 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"; }
C#
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);
Ruby
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 << URI.open(download_url).read() end
خواندن دادههای گزارش
بسیاری از کتابخانههای مشتری ما شامل ابزارهای کمکی برای خواندن دادههای گزارش هستند. این کار برای انجام پردازش بیشتر روی دادههای گزارش یا ترکیب گزارشهای مربوط به محدودههای تاریخ مختلف مفید است. توجه داشته باشید که کد نمونه فرض میکند فایل فشرده نشده است.
جاوا
List<String[]> rows = CsvFiles.getCsvDataArray(filePath, true); for (String[] row : rows) { // Additional row processing processReportRow(row); }
Python
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);
C#
CsvFile file = new CsvFile(); file.Read(fileName, true); for (String[] row : file.Records) { // Additional row processing ProcessReportRow(row); }
Ruby
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 بازیابی کنید.