Introduzione
Questa guida mostra come eseguire e scaricare un report con l'API. Vengono trattati sia l'utilizzo di una query di report salvata esistente sia la creazione di una query di report ad hoc.
Prerequisiti
- Accesso a una rete Google Ad Manager di produzione
- Una libreria client Ad Manager
Primer
Se non hai familiarità con i report in Ad Manager, consulta la sezione Crea un nuovo report per una panoramica su come eseguire un report nell'interfaccia utente di Ad Manager. L'interfaccia utente mostra un'anteprima dell'output, nonché descrizioni comando che spiegano quali combinazioni di colonne e dimensioni sono supportate. Quando crei una query di report complessa, potrebbe essere più facile crearla prima nell'interfaccia utente e poi recuperarla con l'API.
Recupero di una ReportQuery salvata
L'oggetto ReportQuery
contiene tutti i dettagli del report. Puoi creare query sui report nell'interfaccia utente di Ad Manager e recuperarle con il metodo ReportService.getSavedQueriesByStatement. L'ID query salvata è incluso nell'URL quando visualizzi una query nell'interfaccia utente. Ad esempio, nell'URL
https://www.google.com/admanager/1234#reports/report/detail/report_id=456789
l'ID query è 456789.
Se una query non è compatibile con la tua versione dell'API,
SavedQuery.reportQuery
sarà null e
SavedQuery.isCompatibleWithApiVersion
sarà false.
Le query salvate compatibili possono essere eseguite con o senza modifiche.
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='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
Per eseguire la query, consulta Creazione di ReportJob.
Creazione di una ReportQuery
Oltre a utilizzare le query salvate, puoi anche creare una ReportQuery ad hoc. Per farlo, devi impostare le dimensioni, gli attributi delle dimensioni, le colonne, il filtro e l'intervallo di date del report. Questo esempio riguarda un report di consegna di base per un singolo ordine.
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='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() }
Creazione di ReportJob
Una volta creata una ReportQuery, è il momento di eseguire il report. L'oggetto ReportJob contiene lo stato di un report e ti avvisa quando è pronto per il download. Per iniziare a eseguire il report, utilizza il metodo 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='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);
Scaricare il report
Dopo aver avviato il job di report, questo avrà un ID impostato dal server. Utilizza questo ID con il metodo ReportService.getReportJobStatus per controllare lo stato del report. Quando lo stato è ReportJobStatus.COMPLETED il report è pronto per il download.
Alcune delle nostre librerie client dispongono di utilità helper che eseguono il polling dell'API e attendono il completamento del report. Al termine della generazione del report, puoi ottenere l'URL di download con il metodo ReportService.getReportDownloadURL. Un report può essere scaricato in diversi formati. Se vuoi eseguire un'ulteriore elaborazione automatica con il report, devi utilizzare il formato 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 << URI.open(download_url).read() end
Leggere i dati del report
Molte delle nostre librerie client includono utilità per la lettura dei dati dei report. Questa funzionalità è utile per eseguire un'ulteriore elaborazione dei dati del report o per combinare report di intervalli di date diversi. Tieni presente che il codice di esempio presuppone che il file non sia compresso.
Java
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
Per altri esempi di report, consulta le nostre librerie client su GitHub.
Domande frequenti
- Perché tutti i risultati dei report sulla mia rete di test sono vuoti?
- Le reti di test non pubblicano annunci, pertanto i report sulla pubblicazione non avranno dati.
- Perché tutti i risultati dei report sulla mia rete di produzione sono vuoti?
- L'utente per cui esegui l'autenticazione potrebbe non avere accesso ai dati che stai tentando di includere nel report. Verifica che le autorizzazioni del ruolo e team siano impostati correttamente.
- Perché ricevo l'errore
ReportError.COLUMNS_NOT_SUPPORTED_FOR_REQUESTED_DIMENSIONSper il mio report? - Non tutte le combinazioni di colonne e dimensioni sono supportate in Ad Manager. Per i report complessi, potrebbe essere più facile creare un report valido nella UI e poi recuperarlo con il metodo ReportService.getSavedQueriesByStatement.
- Perché il report salvato non viene restituito nell'API?
- Assicurati che il proprietario del report lo abbia condiviso con l'utente per cui stai eseguendo l'autenticazione.
- Perché il mio report salvato non è compatibile con l'API?
- Alcune funzionalità di reporting non sono disponibili nell'API. Sono inclusi
colonne, attributi delle dimensioni, dimensioni e tipi di intervallo di date. Per i tipi di intervallo di date incompatibili, puoi salvare il report con un tipo supportato per renderlo recuperabile, quindi modificare
ReportQueryper soddisfare l'intervallo di date fisso che preferisci. - Perché i clic/le impressioni totali non corrispondono a quelli del report nell'interfaccia utente?
- Le impressioni totali si riferiscono all'intera durata dell'elemento pubblicitario, indipendentemente dall'intervallo di date del report. Se un elemento pubblicitario è ancora in pubblicazione, il valore probabilmente cambierà tra l'esecuzione di due report.
- I miei report richiedono troppo tempo e a volte vanno in timeout. Che cosa posso fare?
- Ridurre l'intervallo di date o il numero di dimensioni contribuirà a migliorare le prestazioni. Prova invece a generare più report per intervalli di date più brevi. Puoi quindi unire i dati del report per coprire l'intervallo di date desiderato.
- Qual è la differenza tra le colonne
INVENTORY_LEVELeLINE_ITEM_LEVEL? Quale devo utilizzare? Le colonne con
LINE_ITEM_LEVELpossono essere utilizzate solo se hai attivato l'allocazione dinamica a livello di elemento pubblicitario nella tua rete. Queste colonne includono i dati dell'allocazione dinamica a livello di elemento pubblicitario ad AdSense o Ad Exchange. Allo stesso modo, le colonneINVENTORY_LEVELincludono i dati dell'allocazione dinamica a livello di inventario. Per ulteriori informazioni sull'allocazione dinamica, consulta la sezione Elementi pubblicitari Ad Exchange.Se non sai ancora quali colonne dell'API utilizzare, crea una query salvata nell'interfaccia utente di Ad Manager e recuperala con il metodo ReportService.getSavedQueriesByStatement.