Pengantar
Panduan ini akan menunjukkan cara menjalankan dan mendownload laporan dengan API. Panduan ini membahas penggunaan kueri laporan tersimpan yang ada, dan pembuatan kueri laporan ad hoc.
Prasyarat
- Akses ke jaringan Produksi Google Ad Manager
- Library klien Ad Manager
Primer
Jika Anda tidak memahami pelaporan di Ad Manager, lihat Membuat laporan baru untuk mengetahui ringkasan cara menjalankan laporan di UI Ad Manager. UI memiliki pratinjau output, serta tooltip yang menjelaskan kombinasi kolom dan dimensi mana yang didukung. Saat membuat kueri laporan yang kompleks, mungkin lebih mudah untuk membuatnya di UI terlebih dahulu, lalu mengambil kueri tersebut dengan API.
Mengambil ReportQuery yang tersimpan
Objek ReportQuery
berisi semua detail laporan. Anda dapat membuat kueri laporan di UI Ad Manager, dan mengambilnya dengan metode ReportService.getSavedQueriesByStatement. ID kueri tersimpan disertakan dalam URL saat melihat kueri di
UI. Misalnya, di URL
https://www.google.com/admanager/1234#reports/report/detail/report_id=456789
,
ID kuerinya adalah 456789
.
Jika kueri tidak kompatibel dengan versi API Anda,
SavedQuery.reportQuery
akan null
dan
SavedQuery.isCompatibleWithApiVersion
akan menjadi false
.
Kueri tersimpan yang kompatibel dapat dijalankan dengan atau tanpa perubahan.
Java
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='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();
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
Untuk menjalankan kueri, lihat Membuat ReportJob.
Membuat ReportQuery
Selain menggunakan kueri tersimpan, Anda juga dapat membuat Laporan Kueri ad hoc. Untuk melakukannya, Anda harus menetapkan dimensi, atribut dimensi, kolom, filter, dan rentang tanggal laporan. Contoh ini adalah laporan pengiriman dasar untuk satu pesanan.
Java
// 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='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() );
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() }
Membuat ReportJob
Setelah Anda memiliki ReportQuery, saatnya menjalankan laporan. Objek ReportJob menyimpan status laporan, dan memberi tahu Anda kapan laporan siap didownload. Untuk mulai menjalankan laporan, gunakan metode ReportService.runReportJob.
Java
// 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='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);
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);
Mendownload Laporan
Setelah Anda memulai tugas laporan, tugas tersebut akan memiliki ID yang disetel oleh server. Gunakan ID ini dengan metode ReportService.getReportJobStatus untuk memeriksa status laporan Anda. Setelah statusnya ReportJobStatus.COMPLETED laporan siap didownload.
Beberapa library klien kami memiliki utilitas helper yang akan melakukan polling API dan menunggu laporan selesai. Setelah laporan selesai, Anda bisa mendapatkan URL download dengan metode ReportService.getReportDownloadURL. Laporan dapat didownload dalam berbagai format. Jika ingin melakukan pemrosesan mesin lebih lanjut dengan laporan, Anda harus menggunakan format CSV_DUMP.
Java
// 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 << open(download_url).read() end
Membaca Data Laporan
Banyak library klien kami menyertakan utilitas untuk membaca data laporan. Hal ini berguna untuk melakukan pemrosesan tambahan pada data laporan, atau menggabungkan laporan dari rentang tanggal yang berbeda. Perlu diperhatikan bahwa kode contoh mengasumsikan file tidak dikompresi.
Java
Listrows = 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
Untuk contoh pelaporan lainnya, lihat library klien kami di GitHub.
FAQ
- Mengapa semua hasil laporan di jaringan pengujian saya kosong?
- Jaringan pengujian tidak menayangkan iklan, sehingga laporan pengiriman tidak akan memiliki data.
- Mengapa semua hasil laporan di jaringan produksi saya kosong?
- Pengguna yang Anda autentikasi mungkin tidak memiliki akses ke data yang ingin Anda laporkan. Pastikan izin peran dan tim mereka sudah ditetapkan dengan benar.
- Mengapa saya mendapatkan error
ReportError.COLUMNS_NOT_SUPPORTED_FOR_REQUESTED_DIMENSIONS
untuk laporan saya? - Tidak semua kombinasi kolom dan dimensi didukung di Ad Manager. Untuk laporan yang kompleks, mungkin lebih mudah untuk membuat laporan yang valid di UI, lalu mengambilnya dengan metode ReportService.getSavedQueriesByStatement.
- Mengapa laporan tersimpan saya tidak ditampilkan di API?
- Pastikan pemilik laporan telah membagikan laporan kepada pengguna yang Anda autentikasi.
- Mengapa laporan tersimpan saya tidak kompatibel dengan API?
- Fitur pelaporan tertentu tidak tersedia di API. Ini mencakup kolom, atribut dimensi, dimensi, dan jenis rentang tanggal. Untuk jenis rentang tanggal yang tidak kompatibel, Anda dapat menyimpan laporan dengan jenis yang didukung agar dapat diambil, lalu mengubah
ReportQuery
untuk memenuhi rentang tanggal tetap yang Anda inginkan. - Mengapa klik/tayangan sepanjang waktu tidak cocok dengan laporan saya di UI?
- Tayangan sepanjang waktu berlaku selama masa aktif item baris, terlepas dari rentang tanggal laporan. Jika item baris masih ditayangkan, nilainya mungkin akan berubah antara menjalankan dua laporan.
- Laporan saya memakan waktu terlalu lama dan terkadang waktu habis. What can I do?
- Mengurangi rentang tanggal atau jumlah dimensi akan membantu meningkatkan performa. Coba jalankan beberapa laporan untuk rentang tanggal yang lebih kecil. Selanjutnya, Anda dapat menggabungkan data laporan untuk mencakup rentang tanggal yang diinginkan.
- Apa perbedaan antara kolom
INVENTORY_LEVEL
danLINE_ITEM_LEVEL
? Mana yang harus saya gunakan? Kolom dengan
LINE_ITEM_LEVEL
hanya dapat digunakan jika Anda mengaktifkan alokasi dinamis tingkat item baris di jaringan. Kolom ini menyertakan data dari alokasi dinamis tingkat item baris ke AdSense atau Ad Exchange. Demikian pula, KolomINVENTORY_LEVEL
menyertakan data dari alokasi dinamis tingkat inventaris. Untuk informasi lebih lanjut tentang alokasi dinamis, lihat Item baris Ad Exchange.Jika Anda masih tidak yakin kolom API mana yang harus digunakan, buat kueri tersimpan di UI Ad Manager dan ambil dengan metode ReportService.getSavedQueriesByStatement.