Introducción
En esta guía, se explica cómo ejecutar y descargar un informe con la API. Abarca tanto mediante una consulta de informe guardada existente y la creación de una consulta de informe ad hoc.
Requisitos previos
- Acceso a una red de producción de Google Ad Manager
- Una biblioteca cliente de Ad Manager
Primer
Si no conoces los informes de Ad Manager, consulta Crea un informe nuevo para un Descripción general de cómo ejecutar un informe en la IU de Ad Manager La IU tiene una vista previa de la salida, así como cuadros de información que explican qué combinaciones de columna y dimensión compatibles. Cuando se crea una consulta de informes compleja, es posible que sea más fácil primero en la IU y, luego, recupera la consulta con la API.
Recupera un ReportQuery guardado
La clase ReportQuery
objeto contiene todos los detalles del informe. Puedes crear consultas de informes en
la IU de Ad Manager y recuperarlos con el
ReportService.getSavedQueriesByStatement
. El ID de la consulta guardada se incluye en la URL cuando se ve una consulta en la IU. Por ejemplo, en la URL
https://www.google.com/admanager/1234#reports/report/detail/report_id=456789
el ID de la consulta es 456789
.
Si una consulta no es compatible con tu versión de la API, SavedQuery.reportQuery será null
y SavedQuery.isCompatibleWithApiVersion será false
.
Las consultas guardadas compatibles se pueden ejecutar con modificaciones o sin ellas.
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='v202408') .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
Para ejecutar la consulta, consulta Crea el ReportJob.
Cómo crear un ReportQuery
Además de usar consultas guardadas, también puedes crear una ReportQuery ad hoc. Para ello, debes establecer la política dimensiones, dimensión atributos, columnas, filtrar y durante un período específico. Este ejemplo corresponde a un informe básico de entrega en un solo pedido.
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='v202408') .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();
Rita
# 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() }
Crea el objeto ReportJob
Una vez que tienes una ReportQuery, es momento de ejecutar el informe. El Objeto ReportJob contiene el estado de un informe y te avisa cuándo está listo para descargarse. Para comience a ejecutar su informe, utilice el 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='v202408') 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);
Rita
# Create report job. report_job = {:report_query => report_query} # Run report job. report_job = report_service.run_report_job(report_job);
Cómo descargar el informe
Después de iniciar el trabajo de informe, el servidor establecerá un ID. Usa este ID con el método ReportService.getReportJobStatus para verificar el estado de tu informe. Una vez que el estado es ReportJobStatus.COMPLETED el informe está listo para descargar.
Algunas de nuestras bibliotecas cliente tienen utilidades de ayuda que sondearán la API y esperar a que se complete el informe. Cuando se complete el informe, podrás obtener de descarga de la URL con el ReportService.getReportDownloadURL . Un informe se puede descargar en diferentes formatos. Si quieres hacer más procesamiento automático con el informe, deberías usar el CSV_DUMP de un conjunto de datos tengan un formato común.
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);
Rita
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
Cómo leer los datos del informe
Muchas de nuestras bibliotecas cliente incluyen utilidades para leer datos de informes. Esto es útil para realizar un procesamiento adicional de los datos del informe o combinar informes de diferentes períodos. Ten en cuenta que el código de ejemplo supone que el archivo no es comprimidos.
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); }
Rita
CSV.foreach(file_name, converters: :numeric, headers: true) do |row| # Additional row processing process_row(row) end
Para ver más ejemplos de informes, visita nuestro cliente bibliotecas en GitHub.
Preguntas frecuentes
- ¿Por qué todos los resultados de los informes en mi red de prueba están vacíos?
- Las redes de prueba no publican anuncios, por lo que los informes de publicación no tendrán datos.
- ¿Por qué todos los resultados de los informes en mi red de producción están vacíos?
- Es posible que el usuario con el que te autenticas no tenga acceso a los datos que estás sobre el que intentas generar informes. Verifica que el cliente permisos de roles y los equipos están configurados correctamente.
- ¿Por qué recibo el error
ReportError.COLUMNS_NOT_SUPPORTED_FOR_REQUESTED_DIMENSIONS
en mi informe? - No todas las combinaciones de columnas y dimensiones son compatibles con Ad Manager. Para informes complejos, puede ser más fácil crear un informe válido en la IU y, luego, recuperarlo con el ReportService.getSavedQueriesByStatement .
- ¿Por qué mi informe guardado no se muestra en la API?
- Asegúrate de que el propietario del informe lo haya compartido con el usuario con el que te estás autenticando.
- ¿Por qué mi informe guardado no es compatible con la API?
- Algunas funciones de informes no están disponibles en la API. Esto incluye
como columnas, atributos de dimensión, dimensiones y tipos de períodos. Para
tipos de período incompatibles, puedes guardar el informe con un tipo admitido en
para que sea recuperable y, luego, modifica
ReportQuery
para que coincida con el período fijo deseado. - ¿Por qué los clics o las impresiones totales no coinciden con mi informe en la IU?
- Las impresiones desde el principio corresponden a toda la vida de la línea de pedido, sin importar el período del informe. Si una línea de pedido se sigue publicando, el valor es probable que cambie entre ejecutar dos informes cualesquiera.
- Mis informes tardan demasiado y, a veces, se agota el tiempo de espera. ¿Qué puedo hacer?
- Disminuir el período o la cantidad de dimensiones ayudará a mejorar rendimiento. Intenta ejecutar varios informes para períodos más breves. Tú Luego, puedes combinar los datos del informe para abarcar el período deseado.
- ¿Cuál es la diferencia entre las columnas
INVENTORY_LEVEL
yLINE_ITEM_LEVEL
? ¿Cuál debería usar? Las columnas con
LINE_ITEM_LEVEL
solo se pueden utilizar si tiene un nivel de línea de pedido la asignación dinámica habilitada en tu red. Estas columnas incluyen datos de la asignación dinámica del nivel de la línea de pedido a AdSense o Ad Exchange. De forma similar, el Las columnasINVENTORY_LEVEL
incluyen datos de la asignación dinámica a nivel de inventario. Para obtener más información sobre la asignación dinámica, consulta Líneas de pedido de Ad Exchange.Si aún no estás seguro de qué columnas de API usar, crea una consulta guardada en IU de Ad Manager y la recuperamos con el ReportService.getSavedQueriesByStatement .