보고서 실행

Ad Manager API를 사용하여 양방향 보고서를 만들고, 기존 보고서를 실행하고, 보고서 결과를 읽을 수 있습니다.

Ad Manager의 양방향 보고에 익숙하지 않다면 양방향 보고서 만들기에서 Ad Manager UI에서 양방향 보고서를 사용하는 방법을 간략히 알아보세요.

복잡한 보고서의 경우 Ad Manager UI를 사용하여 측정기준 및 측정항목 호환성을 확인할 수 있습니다. 모든 UI 보고서는 API를 사용하여 실행할 수 있습니다.

이 가이드에서는 Report의 비동기 실행을 시작하고, 반환된 Operation 상태를 폴링하고, 완료된 Operation에서 Result 리소스 이름을 가져오고, 페이지로 나눈 결과 집합 Rows을 가져오는 방법을 설명합니다.

기본 요건

계속하기 전에 Google Ad Manager 네트워크에 액세스할 수 있는 권한이 있는지 확인하세요. 액세스 권한을 얻으려면 Google Ad Manager 시작하기를 참고하세요.

보고서 실행

보고서를 실행하려면 보고서 ID가 필요합니다. 보고서 URL을 통해 Ad Manager UI에서 보고서 ID를 가져올 수 있습니다. 예를 들어 URL 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 계정 정보 찾기를 참고하세요.

자바

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 메서드를 사용하여 실행 중인 보고서의 현재 상태를 검색하는 개별 요청을 실행합니다.

자바

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의 리소스 이름이 포함됩니다.

자바

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 필드가 있습니다.

자바



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에서만 양방향 보고서를 읽을 수 있습니다.
테스트 네트워크의 보고서 결과가 비어 있는 이유는 무엇인가요?
테스트 네트워크는 광고를 게재하지 않으므로 전송 보고서에 데이터가 없습니다.
프로덕션 네트워크의 보고서 결과가 비어 있는 이유는 무엇인가요?
인증하는 사용자에게 보고하려는 데이터에 대한 액세스 권한이 없을 수 있습니다. 역할 권한이 올바르게 설정되어 있는지 확인합니다.
전체 기간 클릭수 또는 노출수가 UI의 보고서와 일치하지 않는 이유는 무엇인가요?
전체 기간 노출수는 보고서 기간과 관계없이 광고 항목의 전체 기간에 대한 노출수입니다. 광고 항목이 아직 게재 중인 경우 동일한 보고서를 두 번 실행할 때 값이 달라질 수 있습니다.