稽核帳戶限制

有特定 Display & Video 360 資源中可供有效使用的實體數量設有限制。這些帳戶上限相對較大且很少觸及,但您可以依照本指南列出的步驟,主動避免達到這些上限。

本頁面將說明如何使用 Display & Video 360 API 取得實體數量並將其最佳化。

稽核廣告客戶

您可以透過 advertisers.audit 擷取計入資源限制的已使用實體總數。這些實體數量包括無法透過 API 擷取或編輯的類型,例如 Gmail 委刊項。

以下範例說明如何稽核並顯示特定廣告客戶目前的數量:

Java

// Create read mask to restrict audit results to
// the relevant account limits.
String auditMask = "usedInsertionOrdersCount,usedLineItemsCount,negativeKeywordListsCount";

// Configure the audit request.
Advertisers.Audit request =
    service.advertisers().audit(advertiser-id);

// Set the read mask for the request.
request.setReadMask(auditMask);

// Execute the request.
AuditAdvertiserResponse response = request.execute();

// Print resulting advertiser used entity counts.
System.out.println("Advertiser Audit:");

if (response.getUsedInsertionOrdersCount() != null) {
  System.out.printf("Used Insertion Orders: %s of 9999 \n",
      response.getUsedInsertionOrdersCount());
} else {
  System.out.println("Used Insertion Orders: 0 of 9999");
}

if (response.getUsedLineItemsCount() != null) {
  System.out.printf("Used Line Items: %s of 9999 \n",
      response.getUsedLineItemsCount());
} else {
  System.out.println("Used Line Items: 0 of 9999");
}

if (response.getNegativeKeywordListsCount() != null) {
  System.out.printf("Negative Keyword Lists: %s of 20 \n",
      response.getNegativeKeywordListsCount());
} else {
  System.out.println("Negative Keyword Lists: 0 of 20");
}

Python

# Create read mask to restrict audit results to
# the relevant account limits.
audit_mask = 'usedInsertionOrdersCount,usedLineItemsCount,negativeKeywordListsCount'

# Build and execute request.
response = service.advertisers().audit(
    advertiserId=advertiser-id,
    readMask=audit_mask
).execute()

# Print resulting advertiser used entity counts.
print('Advertiser audit:')

if 'usedInsertionOrdersCount' in response:
  print('Used Insertion Orders: %s of 9999' %
        response['usedInsertionOrdersCount'])
else:
  print('Used Insertion Orders: 0 of 9999')

if 'usedLineItemsCount' in response:
  print('Used Line Items: %s of 9999' % response['usedLineItemsCount'])
else:
  print('Used Line Items: 0 of 9999')

if 'negativeKeywordListsCount' in response:
  print('Negative Keyword Lists: %s of 20' % response['negativeKeywordListsCount'])
else:
  print('Negative Keyword Lists: 0 of 20')

PHP

// Create read mask to restrict audit results to the
// relevant account limits.
$optParams = array(
    'readMask' => 'usedInsertionOrdersCount,usedLineItemsCount,negativeKeywordListsCount'
);

// Call the API, getting the account limit audit counts for the identified
// advertiser.
$response = $this->service->advertisers->audit(
    advertiser-id,
    $optParams
);

# Print resulting advertiser used entity counts.
print('Advertiser audit:\n');

if ($response->getUsedInsertionOrdersCount()) {
    printf(
        'Used Insertion Orders: %s of 9999\n',
        $response->getUsedInsertionOrdersCount()
    );
} else {
    print('Used Insertion Orders: 0 of 9999\n');
}

if ($response->getUsedLineItemsCount()) {
    printf(
        'Used Line Items: %s of 9999\n',
        $response->getUsedLineItemsCount()
    );
} else {
    print('Used Line Items: 0 of 9999\n');
}

if ($response->getNegativeKeywordListsCount()) {
    printf(
        'Negative Keyword Lists: %s of 20\n',
        $response->getNegativeKeywordListsCount()
    );
} else {
    print('Negative Keyword Lists: 0 of 20\n');
}

最佳化實體數量

為確保不會達到帳戶限制,請在不再需要資源時刪除或封存。

封存已完成的委刊項

如果廣告客戶稽核顯示廣告客戶內使用的委刊項數量即將達到設定上限,請封存已放送廣告的現有委刊項,以便繼續建立新的委刊項。

請使用 advertisers.lineItems.listfilter 欄位,然後使用 advertisers.lineItems.patch 封存這些委刊項。

以下範例說明如何擷取及封存在特定日期之後停止放送的委刊項:

Java

// Create constants for input variables.
Long ADVERTISER_ID = advertiser-id
String FILTER_DATE = filter-date

// Create the empty line items list.
ArrayList<Long> oldLineItems = new ArrayList<Long>();

// Create the filter string with the desired date.
// The filter date must be in the format YYYY-MM-DD.
String dateFilter =
    "flight.dateRange.endDate<".concat(FILTER_DATE);

// Configure the list request.
LineItems.List listRequest =
    service.advertisers().lineItems().list(ADVERTISER_ID);

// Set the filter for the request
listRequest.setFilter(dateFilter);

// Create the response and nextPageToken variables.
ListLineItemsResponse listResponse;
String nextPageToken = null;

do {
  // Create and execute the list request.
  listResponse = listRequest.setPageToken(nextPageToken).execute();

  // Check if response is empty.
  if (listResponse.isEmpty()) {
    System.out.print("List request returned no Line Items");
    break;
  }

  // Iterate over retrieved line items and add to total list.
  for (LineItem lineItem : listResponse.getLineItems()) {
    oldLineItems.add(lineItem.getLineItemId());
  }

  // Update the next page token.
  nextPageToken = listResponse.getNextPageToken();
} while (!Strings.isNullOrEmpty(nextPageToken));

// Create the line item structure.
LineItem lineItem = new LineItem();
lineItem.setEntityStatus("ENTITY_STATUS_ARCHIVED");

for (Long lineItemId : oldLineItems) {
  // Build the patch request.
  LineItems.Patch patchRequest = service.advertisers().lineItems()
      .patch(ADVERTISER_ID, lineItemId, lineItem);

  // Set update mask to only update entity status.
  patchRequest.setUpdateMask("entityStatus");

  // Execute the request.
  LineItem patchResponse = patchRequest.execute();

  // Display the updated entity status of the line item.
  System.out.printf("LineItem %s now has entity status %s",
      patchResponse.getName(),
      patchResponse.getEntityStatus());
}

Python

# Create constants for input variables.
ADVERTISER_ID = advertiser-id
FILTER_DATE = filter-date

# Create the empty line items list.
old_line_items = []

# Create the filter string with the desired date.
# The filter date must be in the format YYYY-MM-DD.
date_filter = 'flight.dateRange.endDate<%s' % FILTER_DATE

# Create the page token variable.
next_page_token = ''

while True:
  # Request line item list.
  response = service.advertisers().lineItems().list(
      advertiserId=ADVERTISER_ID,
      filter=date_filter,
      fields='lineItems(lineItemId),nextPageToken',
      pageToken=next_page_token
  ).execute()

  # Check if the response is empty.
  if not response:
    print('List request returned no line items')
    return

  for item in response['lineItems']:
    old_line_items.append(item['lineItemId'])

  # Break out of the loop if there is no next page.
  if 'nextPageToken' not in response:
    break

  next_page_token = response['nextPageToken']

# Create the general line item update object.
line_item_obj = {
   'entityStatus': 'ENTITY_STATUS_ARCHIVED',
}

# Archive each old line item by updating the entity status
for id in old_line_items:
  # Build and execute the request.
  response = service.advertisers().lineItems().patch(
      advertiserId=ADVERTISER_ID,
      lineItemId=id,
      updateMask='entityStatus',
      body=line_item_obj,
      fields='name,entityStatus'
  ).execute()

  print('Line Item %s now has entity status %s.'
        % (response['name'], response['entityStatus']))

PHP

// Create constants for input variables.
const ADVERTISER_ID = advertiser-id;
const FILTER_DATE = filter-date;

// Create empty line item list.
$oldLineItems = array();

// Create the filter string with the desired date.
// The filter date must be in the format YYYY-MM-DD.
$dateFilter = 'flight.dateRange.endDate<' . FILTER_DATE;

# Create the page token variable.
$nextPageToken = '';

do {
    // Build argument parameters for list call.
    $optParams = array(
        'filter' => $dateFilter,
        'pageToken' => $nextPageToken
    );

    // Call the API, getting the line items with flights ending before the
    // given date.
    $response = $this->service->advertisers_lineItems->listAdvertisersLineItems(
        ADVERTISER_ID,
        $optParams
    );

    // If no line items are returned, break loop.
    if (!($response->getLineItems())) {
        break;
    }

    // Add returned line items to existing array.
    $oldLineItems = array_merge($oldLineItems, $response->getLineItems());

    $nextPageToken = $response->getNextPageToken();
} while ($nextPageToken);

if (!empty($oldLineItems)) {
    // Create line item with updated fields.
    $updatedLineItem = new Google_Service_DisplayVideo_LineItem();
    $updatedLineItem->setEntityStatus('ENTITY_STATUS_ACTIVE');

    // Create request parameter array with update mask.
    $optParams = array('updateMask' => 'entityStatus');
    foreach ($oldLineItems as $lineItem) {
        // Call the API, updating the entity status for the identified line item.
        $result = $this->service->advertisers_lineItems->patch(
            ADVERTISER_ID,
            $lineItem->getLineItemId(),
            $updatedLineItem,
            $optParams
        );

        printf(
            'Line Item %s now has entity status %s.\n',
            $result['name'],
            $result['entityStatus']
        );
    }
} else {
    printf(
        'No line items with flight end dates before %s\n',
        FILTER_DATE
    );
}

刪除未使用的排除關鍵字清單

如果廣告客戶稽核顯示廣告客戶底下的排除關鍵字清單數量即將達到上限,請刪除目前未使用的排除關鍵字清單,以騰出空間建立新的排除關鍵字清單。

如要識別這些排除關鍵字清單,您可以將指派的排除關鍵字清單指定選項現有的排除關鍵字清單進行比對,然後使用 advertisers.negativeKeywordLists.delete 刪除。

以下舉例說明如何找出並刪除特定廣告客戶目前未使用的排除關鍵字清單:

Java

// Create constants for input variables.
Long ADVERTISER_ID = advertiser-id

// Create empty set for negative keyword lists (NKLs)
// that are currently used in targeting.
Set<String> targetedNKLs = new HashSet<String>();

// Build line item list request
LineItems.List request =
    service
        .advertisers()
        .lineItems()
        .list(ADVERTISER_ID);

// Create the line item list response, assigned targeting option list
// response, and nextPageToken variables.
ListLineItemsResponse response;
ListLineItemAssignedTargetingOptionsResponse atoListResponse;
String nextPageToken = null;

do {
  // Create and execute the list request.
  response = request.setPageToken(nextPageToken).execute();

  // Check if response is empty.
  if (response.isEmpty()) {
    System.out.printf(
        "List request returned no line items for Advertiser ID %s.%n",
        ADVERTISER_ID);
    break;
  }

  // Iterate over retrieved line items and retrieve all assigned negative
  // keyword list targeting.
  for (LineItem lineItem : response.getLineItems()) {
    atoListResponse =
        service
            .advertisers()
            .lineItems()
            .targetingTypes()
            .assignedTargetingOptions()
            .list(
                ADVERTISER_ID,
                lineItem.getLineItemId(),
                "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST"
            ).execute();

    // Check if response is empty.
    if (atoListResponse.isEmpty()) {
      continue;
    }

    // Add all negative keyword list used in targeting to set.
    for (AssignedTargetingOption ato : atoListResponse.getAssignedTargetingOptions()) {
      targetedNKLs.add(ato.getAssignedTargetingOptionId());
    }
  }

  // Update the next page token.
  nextPageToken = response.getNextPageToken();
} while (!Strings.isNullOrEmpty(nextPageToken));

// Retrieve all negative keyword lists under the given advertiser.
ListNegativeKeywordListsResponse nklListResponse =
    service
        .advertisers()
        .negativeKeywordLists()
        .list(
            ADVERTISER_ID
        ).execute();

// Iterate through all available negative keyword lists and delete those
// that are not in the set negative keyword lists used in targeting.
if (nklListResponse.isEmpty()) {
  System.out.printf(
      "Advertiser ID %s has no negative keyword lists.%n",
      ADVERTISER_ID
  );
} else {
  for (NegativeKeywordList nkl : nklListResponse.getNegativeKeywordLists()) {
    if (!targetedNKLs.contains(Long.toString(nkl.getNegativeKeywordListId()))) {
      service
          .advertisers()
          .negativeKeywordLists()
          .delete(
              ADVERTISER_ID,
              nkl.getNegativeKeywordListId()
          ).execute();
      System.out.printf(
          "Unused negative keyword list %s deleted.%n",
          nkl.getNegativeKeywordListId());
    }
  }
}

Python

# Create constants for input variables.
ADVERTISER_ID = advertiser-id

# Create empty set for negative keyword lists (NKLs)
# that are currently used in targeting.
targetedNKLs = set()

# Create the page token variable for list request loop.
nextPageToken = ""

# Iterate through all line items, retrieve their NKL targeting, and save the
# NKLs currently used in targeting.
while True:
  # Request the line items list.
  lineItemListResponse = service.advertisers().lineItems().list(
      advertiserId=ADVERTISER_ID,
      pageToken=nextPageToken
  ).execute()

  # Check if response is empty.
  if not lineItemListResponse:
    print('List request returned no line items for advertiser ID %s.'
          % ADVERTISER_ID)
    break

  # Iterate over retrieved line items.
  for lineItem in lineItemListResponse['lineItems']:
    # Request the NKL targeting assigned to the line item.
    targetingListResponse = service.advertisers().lineItems()\
        .targetingTypes().assignedTargetingOptions().list(
            advertiserId=ADVERTISER_ID,
            lineItemId=lineItem['lineItemId'],
            targetingType="TARGETING_TYPE_NEGATIVE_KEYWORD_LIST"
        ).execute()

    # Check if no NKLs are used in targeting.
    if not targetingListResponse:
      continue

    # Iterate through assigned NKL targeting options, add them to set.
    for targetingOption in targetingListResponse['assignedTargetingOptions']:
      targetedNKLs.add(targetingOption['assignedTargetingOptionId'])

  # Break out of loop if there is no next page.
  if 'nextPageToken' not in lineItemListResponse:
    break

  # Update the next page token.
  nextPageToken = response['nextPageToken']

# Request the NKL list.
nklListResponse = service.advertisers().negativeKeywordLists().list(
    advertiserId=ADVERTISER_ID
).execute()

# Iterate through NKLs under advertiser and delete if they are not present
# in the list of NKLs currently used in targeting.
if not nklListResponse:
  print('Advertiser ID %s has no negative keyword lists.'
        % ADVERTISER_ID)
else:
  for nkl in nklListResponse['negativeKeywordLists']:
    if nkl['negativeKeywordListId'] not in targetedNKLs:
      service.advertisers().negativeKeywordLists().delete(
          advertiserId=ADVERTISER_ID,
          negativeKeywordListId=nkl['negativeKeywordListId']
      ).execute()
      print('Unused negative keyword list %s deleted.' % nkl["name"])

PHP

// Create constants for input variables.
const ADVERTISER_ID = advertiser-id;

// Create empty array for negative keyword lists (NKLs)
// that are currently used in targeting.
$targetedNKLs = array();

// Create the line item list response, assigned targeting option list
//response, and page token variables.
$response = null;
$atoListResponse = null;
$nextPageToken = null;

do {
    // Build the query params for the line item list request
    $optParams = array('pageToken' => $nextPageToken);

    // Call the API, retrieving all line items under the advertiser.
    $response = $this
        ->service
        ->advertisers_lineItems
        ->listAdvertisersLineItems(ADVERTISER_ID, $optParams);

    if (empty($response->getLineItems())) {
        printf(
            "List request returned no line items for Advertiser ID %s.\n",
            ADVERTISER_ID
        );
        break;
    }

    // Iterate over retrieved line items and retrieve all assigned negative
    // keyword list targeting options.
    foreach ($response->getLineItems() as $lineItem) {
        $atoListResponse = $this
            ->service
            ->advertisers_lineItems_targetingTypes_assignedTargetingOptions
            ->listAdvertisersLineItemsTargetingTypesAssignedTargetingOptions(
                ADVERTISER_ID,
                $lineItem->getLineItemId(),
                "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST"
            );

        // Add each negative keyword list ID to array as key to associative
        // array
        foreach ($atoListResponse->getAssignedTargetingOptions() as $option) {
            $targetedNKLs[$option->getAssignedTargetingOptionId()] = true;
        }

    }

    // Update the next page token.
    $nextPageToken = $response->getNextPageToken();

} while (!empty($nextPageToken));

// Call the API, retrieving all negative keyword lists under the advertiser
$nklListResponse = $this
    ->service
    ->advertisers_negativeKeywordLists
    ->listAdvertisersNegativeKeywordLists(ADVERTISER_ID);

// Iterate through existing negative keyword lists and check if they are in
// the associative array of negative keyword lists used in targeting.
// If not, delete the negative keyword list.
if (empty($nklListResponse->getNegativeKeywordLists())) {
    printf(
        "Advertiser ID %s has no negative keyword lists.\n",
        ADVERTISER_ID
    );
} else {
    foreach ($nklListResponse->getNegativeKeywordLists() as $nkl) {
        if (!array_key_exists($nkl->getNegativeKeywordListId(), $targetedNKLs)) {
            $this
                ->service
                ->advertisers_negativeKeywordLists
                ->delete(
                    ADVERTISER_ID,
                    $nkl->getNegativeKeywordListId()
                );
            printf(
                "Unused negative keyword list %s was deleted.\n",
                $nkl->getNegativeKeywordListId()
            );
        }
    }
}