執行報表

您可以使用 Ad Manager API 建立互動式報表、執行現有報表,以及讀取報表結果。

如果您不熟悉 Ad Manager 中的互動式報表,請參閱「建立互動式報表」,瞭解如何在 Ad Manager UI 中使用互動式報表。

如果是複雜的報表,您可以使用 Ad Manager 使用者介面檢查維度和指標的相容性。所有 UI 報表都可以透過 API 執行。

本指南將說明如何啟動 Report 的非同步執行作業、輪詢傳回的 Operation 狀態、從已完成的 Operation 取得 Result 資源名稱,以及擷取分頁式結果 Rows

修課條件

繼續操作前,請確認您有權存取 Google Ad Manager 聯播網。如要取得存取權,請參閱「開始使用 Google Ad Manager」。

執行報表

您需要報告 ID 才能執行報表。您可以透過報表網址,在 Ad Manager UI 中取得報表 ID。例如,在網址 https://www.google.com/admanager/234093456#reports/interactive/detail/report_id=4555265029 中,報表 ID 為 4555265029

您也可以使用 networks.reports.list 方法讀取使用者可存取的報表,並從資源名稱取得 ID:

networks/234093456/reports/4555265029

取得報表 ID 後,您可以使用 networks.reports.run 方法啟動報表的非同步執行作業。這個方法會傳回長期執行的 Operation 資源名稱。請注意,在下列範例程式碼中,[REPORT] 是報表 ID 的預留位置,[NETWORK] 則是網路代碼的預留位置。如要找出聯播網代碼,請參閱「找出 Ad Manager 帳戶資訊」。

Java

import com.google.ads.admanager.v1.ReportName;
import com.google.ads.admanager.v1.ReportServiceClient;
import com.google.ads.admanager.v1.RunReportResponse;

public class SyncRunReportReportname {

  public static void main(String[] args) throws Exception {
    syncRunReportReportname();
  }

  public static void syncRunReportReportname() throws Exception {
    try (ReportServiceClient reportServiceClient = ReportServiceClient.create()) {
      ReportName name = ReportName.of("[NETWORK_CODE]", "[REPORT]");
      RunReportResponse response = reportServiceClient.runReportAsync(name).get();
    }
  }
}

Python

from google.ads import admanager_v1


def sample_run_report():
    # Create a client
    client = admanager_v1.ReportServiceClient()

    # Initialize request argument(s)
    request = admanager_v1.RunReportRequest(
        name="networks/[NETWORK_CODE]/reports/[REPORT]",
    )

    # Make the request
    operation = client.run_report(request=request)

    print("Waiting for operation to complete...")

    response = operation.result()

    # Handle the response
    print(response)

.NET

using Google.Ads.AdManager.V1;
using Google.LongRunning;

public sealed partial class GeneratedReportServiceClientSnippets
{
    public void RunReportResourceNames()
    {
        // Create client
        ReportServiceClient reportServiceClient = ReportServiceClient.Create();
        // Initialize request argument(s)
        ReportName name = ReportName.FromNetworkCodeReport("[NETWORK_CODE]", "[REPORT]");
        // Make the request
        Operation<RunReportResponse, RunReportMetadata> response = reportServiceClient.RunReport(name);

        // Poll until the returned long-running operation is complete
        Operation<RunReportResponse, RunReportMetadata> completedResponse = response.PollUntilCompleted();
        // Retrieve the operation result
        RunReportResponse result = completedResponse.Result;

        // Or get the name of the operation
        string operationName = response.Name;
        // This name can be stored, then the long-running operation retrieved later by name
        Operation<RunReportResponse, RunReportMetadata> retrievedResponse = reportServiceClient.PollOnceRunReport(operationName);
        // Check if the retrieved long-running operation has completed
        if (retrievedResponse.IsCompleted)
        {
            // If it has completed, then access the result
            RunReportResponse retrievedResult = retrievedResponse.Result;
        }
    }
}

cURL

要求

curl -X POST -H "Authorization: Bearer ${ACCESS_TOKEN}" \
"https://admanager.googleapis.com/v1/networks/${NETWORK_CODE}/reports/{$REPORT_ID}:run"

回應

{
  "name": "networks/234093456/operations/reports/runs/6485392645",
  "metadata": {
    "@type": "type.googleapis.com/google.ads.admanager.v1.RunReportMetadata",
    "report": "networks/234093456/reports/4555265029"
  }
}

輪詢報表狀態

如果您使用的是用戶端程式庫,上一個部分的範例程式碼會在建議的間隔內輪詢報表執行狀態 Operation,並在完成時提供結果。如要進一步瞭解建議的輪詢間隔,請參閱 networks.reports.run

如要進一步控管輪詢作業,請使用 networks.operations.reports.runs.get 方法提出個別要求,以便擷取執行中的報表目前狀態:

Java

import com.google.ads.admanager.v1.ReportServiceSettings;
import com.google.api.gax.longrunning.OperationalTimedPollAlgorithm;
import com.google.api.gax.retrying.RetrySettings;
import com.google.api.gax.retrying.TimedRetryAlgorithm;
import java.time.Duration;

public class SyncRunReport {

  public static void main(String[] args) throws Exception {
    syncRunReport();
  }

  public static void syncRunReport() throws Exception {
    ReportServiceSettings.Builder reportServiceSettingsBuilder = ReportServiceSettings.newBuilder();
    TimedRetryAlgorithm timedRetryAlgorithm =
        OperationalTimedPollAlgorithm.create(
            RetrySettings.newBuilder()
                .setInitialRetryDelayDuration(Duration.ofMillis(500))
                .setRetryDelayMultiplier(1.5)
                .setMaxRetryDelayDuration(Duration.ofMillis(5000))
                .setTotalTimeoutDuration(Duration.ofHours(24))
                .build());
    reportServiceSettingsBuilder
        .createClusterOperationSettings()
        .setPollingAlgorithm(timedRetryAlgorithm)
        .build();
  }
}

Python

from google.ads import admanager_v1
from google.longrunning.operations_pb2 import GetOperationRequest

def sample_poll_report():
# Run the report
client = admanager_v1.ReportServiceClient()
response = client.run_report(name="networks/[NETWORK_CODE]/reports/[REPORT_ID]")

# Check if the long-running operation has completed
operation = client.get_operation(
    GetOperationRequest(name=response.operation.name))
if(operation.done):
    # If it has completed, then access the result
    run_report_response = admanager_v1.RunReportResponse.deserialize(payload=operation.response.value)

.NET

Operation<RunReportResponse, RunReportMetadata> retrievedResponse =
  reportServiceClient.PollOnceRunReport(operationName);
// Check if the retrieved long-running operation has completed
if (retrievedResponse.IsCompleted)
{
  // If it has completed, then access the result
  RunReportResponse retrievedResult = retrievedResponse.Result;
}

cURL

要求

curl -H "Authorization: Bearer ${ACCESS_TOKEN}" \
"https://admanager.googleapis.com/v1/networks/${NETWORK_CODE}/operations/reports/runs/${OPERATION_ID}"

回應

{
  "name": "networks/234093456/operations/reports/runs/6485392645",
  "metadata": {
    "@type": "type.googleapis.com/google.ads.admanager.v1.RunReportMetadata",
    "percentComplete": 50,
    "report": "networks/234093456/reports/4555265029"
  },
  "done": false,
}

取得結果資源名稱

報表執行 Operation 完成後,會包含 Result 的資源名稱。

Java

RunReportResponse response = reportServiceClient.runReportAsync(name).get();
// Result name in the format networks/[NETWORK_CODE]/reports/[REPORT_ID]/results/[RESULT_ID]
String resultName = response.getReportResult();

Python

operation = client.run_report(request=request)
response = operation.result()
# Result name in the format networks/[NETWORK_CODE]/reports/[REPORT_ID]/results/[RESULT_ID]
result_name = response.report_result

.NET

Operation<RunReportResponse, RunReportMetadata> response = reportServiceClient.RunReport(request);
// Poll until the returned long-running operation is complete
Operation<RunReportResponse, RunReportMetadata> completedResponse = response.PollUntilCompleted();
RunReportResponse result = completedResponse.Result;
// Result name in the format networks/[NETWORK_CODE]/reports/[REPORT_ID]/results/[RESULT_ID]
string resultName = result.ReportResult;

cURL

要求

curl -H "Authorization: Bearer ${ACCESS_TOKEN}" \
"https://admanager.googleapis.com/v1/networks/${NETWORK_CODE}/operations/reports/runs/${OPERATION_ID}"

回應

{
  "name": "networks/234093456/operations/reports/runs/6485392645",
  "metadata": {
    "@type": "type.googleapis.com/google.ads.admanager.v1.RunReportMetadata",
    "percentComplete": 100,
    "report": "networks/234093456/reports/4555265029"
  },
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.ads.admanager.v1.RunReportResponse",
    "reportResult": "networks/234093456/reports/4555265029/results/7031632628"
  }
}

讀取結果資料列

Result 資源有一個 networks.reports.results.fetchRows 方法,可讀取分頁的資料列清單。每個資料列都包含維度值清單和分組指標值清單。每個群組都包含指標值和任何比較值或標記。如要進一步瞭解標記,請參閱「在互動式報表中使用標記」。

對於沒有日期範圍比較或分割的報表,報表的整個日期範圍會顯示單一 MetricValueGroup,其中包含指標值 (例如曝光或點擊)。

維度和指標值的順序與 ReportReportDefinition 相同。

以下是 ReportDefinition 和對應 fetchRows 回應的 JSON 範例:

{
  "name": "networks/234093456/reports/4555265029",
  "visibility": "SAVED",
  "reportId": "4555265029",
  "reportDefinition": {
     "dimensions": [
      "LINE_ITEM_NAME",
      "LINE_ITEM_ID"
    ],
    "metrics": [
      "AD_SERVER_IMPRESSIONS"
    ], 
    "currencyCode": "USD",
    "dateRange": {
      "relative": "YESTERDAY"
    },
    "reportType": "HISTORICAL"
  },
  "displayName": "Example Report",
  "updateTime": "2024-09-01T13:00:00Z",
  "createTime": "2024-08-01T02:00:00Z",
  "locale": "en-US",
  "scheduleOptions": {}
}
{
  "rows": [
    {
      "dimensionValues": [
        {
          "stringValue": "Line Item #1"
        },
        {
          "intValue": "6378470710"
        }
      ],
      "metricValueGroups": [
        {
          "primaryValues": [
            {
              "intValue": "100"
            }
          ]
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "stringValue": "Line Item #2"
        },
        {
          "intValue": "5457147368"
        }
      ],
      "metricValueGroups": [
        {
          "primaryValues": [
            {
              "intValue": "95"
            }
          ]
        }
      ]
    }
],
"runTime": "2024-10-02T10:00:00Z",
  "dateRanges": [
    {
      "startDate": {
        "year": 2024,
        "month": 10,
        "day": 1
      },
      "endDate": {
        "year": 2024,
        "month": 10,
        "day": 1
      }
    }
  ],
  "totalRowCount": 2
}

如果您使用的是用戶端程式庫,回應會包含一個迭代器,可延後要求其他頁面。您也可以使用 pageTokenpageSize 參數。如要進一步瞭解這些參數,請參閱「查詢參數」一節。如果有其他頁面,回應會包含 nextPageToken 欄位,其中包含要在下一個要求中使用的符記。

Java



import com.google.ads.admanager.v1.Report;
import com.google.ads.admanager.v1.ReportServiceClient;

public class SyncFetchReportResultRowsString {

  public static void main(String[] args) throws Exception {
    syncFetchReportResultRowsString();
  }

  public static void syncFetchReportResultRowsString() throws Exception {
    try (ReportServiceClient reportServiceClient = ReportServiceClient.create()) {
      String name = "networks/[NETWORK_CODE]/reports/[REPORT_ID]/results/[RESULT_ID]";
      for (Report.DataTable.Row element :
          reportServiceClient.fetchReportResultRows(name).iterateAll()) {
      }
    }
  }
}

Python

from google.ads import admanager_v1


def sample_fetch_report_result_rows():
    # Create a client
    client = admanager_v1.ReportServiceClient()

    # Initialize request argument(s)
    request = admanager_v1.FetchReportResultRowsRequest(
    )

    # Make the request
    page_result = client.fetch_report_result_rows(request=request)

    # Handle the response
    for response in page_result:
        print(response)

.NET

using Google.Ads.AdManager.V1;
using Google.Api.Gax;
using System;

public sealed partial class GeneratedReportServiceClientSnippets
{
    public void FetchReportResultRows()
    {
        // Create client
        ReportServiceClient reportServiceClient = ReportServiceClient.Create();
        // Initialize request argument(s)
        string name = "";
        // Make the request
        PagedEnumerable<FetchReportResultRowsResponse, Report.Types.DataTable.Types.Row> response = reportServiceClient.FetchReportResultRows(name);

        // Iterate over all response items, lazily performing RPCs as required
        foreach (Report.Types.DataTable.Types.Row item in response)
        {
            // Do something with each item
            Console.WriteLine(item);
        }

        // Or iterate over pages (of server-defined size), performing one RPC per page
        foreach (FetchReportResultRowsResponse page in response.AsRawResponses())
        {
            // Do something with each page of items
            Console.WriteLine("A page of results:");
            foreach (Report.Types.DataTable.Types.Row item in page)
            {
                // Do something with each item
                Console.WriteLine(item);
            }
        }

        // Or retrieve a single page of known size (unless it's the final page), performing as many RPCs as required
        int pageSize = 10;
        Page<Report.Types.DataTable.Types.Row> singlePage = response.ReadPage(pageSize);
        // Do something with the page of items
        Console.WriteLine($"A page of {pageSize} results (unless it's the final page):");
        foreach (Report.Types.DataTable.Types.Row item in singlePage)
        {
            // Do something with each item
            Console.WriteLine(item);
        }
        // Store the pageToken, for when the next page is required.
        string nextPageToken = singlePage.NextPageToken;
    }
}

cURL

初始要求

curl -H "Authorization: Bearer ${ACCESS_TOKEN}" \
"https://admanager.googleapis.com/v1/networks/${NETWORK_CODE}/reports/${REPORT_ID}/results/${RESULT_ID}:fetchRows"

下一頁要求

curl -H "Authorization: Bearer ${ACCESS_TOKEN}" \
"https://admanager.googleapis.com/v1/networks/${NETWORK_CODE}/reports/${REPORT_ID}/results/${RESULT_ID}:fetchRows?pageToken=${PAGE_TOKEN}"

排解報表問題

為什麼我的報表沒有在 API 中傳回?
請確認您要驗證的 Ad Manager 使用者是否有權存取互動式報表。您只能透過 Ad Manager API 讀取互動式報表。
為什麼測試網路的報表結果為空白?
測試聯播網不會放送廣告,因此放送報表沒有資料。
為什麼我的產品網路的報表結果為空白?
您要驗證的使用者可能無法存取您要回報的資料。確認他們的角色權限團隊設定正確無誤。
為什麼我的報表在使用者介面中顯示的終身點擊次數或曝光次數不符?
生命週期內曝光次數是指委刊項的整個生命週期,不受報表日期範圍影響。如果委刊項仍在放送,值可能會在同一份報表的兩次執行作業之間變更。