“更改状态”提供了一种 在给定时间段内,账号中有哪些资源发生了变化。如果 某资源在给定时间段内发生了多次更改,之后只有 返回最新的更改。然后,您可以确定是否需要同步 本地数据库值与时间段内发生更改的值。
例如,如果您在某个给定时间段内添加并更新了某个给定的
广告系列,只更改 UPDATE
的更改状态,而不更改 ADD
的更改状态
操作。如果您将时间范围的结束时间移至
则会看到 ADD
操作。
如果您希望按字段查看完整结果,并且详细视图与 更改历史记录网页,请参阅更改事件。
变更状态类型
以下资源
类型为
。请注意,资源类型 ID 与枚举值不同
的索引
ChangeStatusResourceType
。
资源类型 | 值 | 资源类型 ID |
---|---|---|
核心实体 | ||
Google Ads 广告组 | AD_GROUP | 2 |
广告组广告 | AD_GROUP_AD | 3 |
广告组出价调节系数 | AD_GROUP_BID_MODIFIER | 11 |
广告组条件 | AD_GROUP_CRITERION | 4 |
广告组 Feed | AD_GROUP_FEED | 12 |
素材资源组 | ASSET_BUNDLE | 19 |
广告系列 | 竞选活动 | 5 |
广告系列条件 | CAMPAIGN_CRITERION | 6 |
Feed | ||
广告系列 Feed | CAMPAIGN_FEED | 9 |
动态 | FEED | 8 |
Feed项 | FEED_ITEM | 10 |
共享集 | ||
共享集 | SHARED_SET | 17 |
广告系列共享集 | CAMPAIGN_SHARED_SET | 18 |
资源 | ||
素材资源 | 素材资源 | 13 |
客户素材资源 | CUSTOMER_ASSET | 14 |
广告系列素材资源 | CAMPAIGN_ASSET | 15 |
广告组素材资源 | AD_GROUP_ASSET | 16 |
按 ID 确定资源类型
对于较早的时间,Google Ads API 可以返回具有 UNKNOWN
资源类型值的行
API 版本,表示该类型在将来的
但当时的当前版本尚未得到完全支持
发布。在这种情况下,您仍然可以确定
行。resource_name
资源名称格式为:
customers/{customer_id}/changeStatus/{timestamp}-{resource_type_id}-{additional_ids}
可以还有一个或多个其他 ID(以 -
字符分隔),但是
相关的第二个 ID 是 resource_type_id
,即第二个 ID
最后一个斜杠。上表列出了所有资源类型 ID。
检索更改
可以按日期和资源类型过滤更改列表。通过
操作属于
ADDED
、
CHANGED
,
或
REMOVED
。
您可以检索所有资源类型的所有更改的列表。返回的
resource_type
是
已更改。系统也会填充所有父级字段。例如,如果
ad_group_criterion
已更改,
那么 ad_group
字段也是
填充。
更改最长可能需要 3 分钟才能反映在更改状态中 结果。
查询必须过滤过去 90 天内的某个日期,并且可以选择
并且必须包含一个设置为最多 10,000 个结果的 LIMIT
子句。
private void runExample(GoogleAdsClient googleAdsClient, long customerId) {
String query =
"SELECT change_status.resource_name, "
+ "change_status.last_change_date_time, "
+ "change_status.resource_status, "
+ "change_status.resource_type, "
+ "change_status.ad_group, "
+ "change_status.ad_group_ad, "
+ "change_status.ad_group_bid_modifier, "
+ "change_status.ad_group_criterion, "
+ "change_status.ad_group_feed, "
+ "change_status.campaign, "
+ "change_status.campaign_criterion, "
+ "change_status.campaign_feed, "
+ "change_status.feed, "
+ "change_status.feed_item "
+ "FROM change_status "
+ "WHERE change_status.last_change_date_time DURING LAST_14_DAYS "
+ "ORDER BY change_status.last_change_date_time "
+ "LIMIT 10000";
try (GoogleAdsServiceClient client =
googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {
SearchPagedResponse response = client.search(String.valueOf(customerId), query);
for (GoogleAdsRow row : response.iterateAll()) {
Optional<String> resourceNameOfChangedEntity =
getResourceNameForResourceType(row.getChangeStatus());
System.out.printf(
"On '%s', change status '%s' shows a resource type of '%s' "
+ "with resource name '%s' was '%s'.%n",
row.getChangeStatus().getLastChangeDateTime(),
row.getChangeStatus().getResourceName(),
row.getChangeStatus().getResourceType().name(),
resourceNameOfChangedEntity.orElse(""),
row.getChangeStatus().getResourceStatus().name());
}
}
}
public void Run(GoogleAdsClient client, long customerId)
{
// Get the GoogleAdsService.
GoogleAdsServiceClient googleAdsService = client.GetService(
Services.V17.GoogleAdsService);
string searchQuery = @"
SELECT
change_status.resource_name,
change_status.last_change_date_time,
change_status.resource_type,
change_status.campaign,
change_status.ad_group,
change_status.resource_status,
change_status.ad_group_ad,
change_status.ad_group_criterion,
change_status.campaign_criterion
FROM change_status
WHERE
change_status.last_change_date_time DURING LAST_14_DAYS
ORDER BY change_status.last_change_date_time
LIMIT 10000";
// Create a request that will retrieve all changes.
SearchGoogleAdsRequest request = new SearchGoogleAdsRequest()
{
Query = searchQuery,
CustomerId = customerId.ToString()
};
try
{
// Issue the search request.
PagedEnumerable<SearchGoogleAdsResponse, GoogleAdsRow> searchPagedResponse =
googleAdsService.Search(request);
// Iterate over all rows in all pages and prints the requested field values for the
// campaign in each row.
foreach (GoogleAdsRow googleAdsRow in searchPagedResponse)
{
Console.WriteLine("Last change: {0}, Resource type: {1}, " +
"Resource name: {2}, Resource status: {3}, Specific resource name: {4}",
googleAdsRow.ChangeStatus.LastChangeDateTime,
googleAdsRow.ChangeStatus.ResourceType,
googleAdsRow.ChangeStatus.ResourceName,
googleAdsRow.ChangeStatus.ResourceStatus,
SpecificResourceName(googleAdsRow.ChangeStatus.ResourceType,
googleAdsRow));
}
}
catch (GoogleAdsException e)
{
Console.WriteLine("Failure:");
Console.WriteLine($"Message: {e.Message}");
Console.WriteLine($"Failure: {e.Failure}");
Console.WriteLine($"Request ID: {e.RequestId}");
throw;
}
}
/// <summary>
/// Return the name of the most specific resource that changed.
/// </summary>
/// <param name="resourceType">Type of the resource.</param>
/// <param name="row">Each returned row contains all possible changed fields</param>
/// <returns>The resource name of the changed field based on the resource type.
/// The changed field's parent is also populated, but is not used.</returns>
private string SpecificResourceName(ChangeStatusResourceType resourceType, GoogleAdsRow row)
{
string resourceName;
switch (resourceType)
{
case ChangeStatusResourceType.AdGroup:
resourceName = row.ChangeStatus.AdGroup;
break;
case ChangeStatusResourceType.AdGroupAd:
resourceName = row.ChangeStatus.AdGroupAd;
break;
case ChangeStatusResourceType.AdGroupCriterion:
resourceName = row.ChangeStatus.AdGroupCriterion;
break;
case ChangeStatusResourceType.Campaign:
resourceName = row.ChangeStatus.Campaign;
break;
case ChangeStatusResourceType.CampaignCriterion:
resourceName = row.ChangeStatus.CampaignCriterion;
break;
case ChangeStatusResourceType.Unknown:
case ChangeStatusResourceType.Unspecified:
default:
resourceName = "";
break;
}
return resourceName;
}
public static function runExample(GoogleAdsClient $googleAdsClient, int $customerId)
{
$googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
// Creates a query to find information about changed resources in your account.
$query = 'SELECT change_status.resource_name, '
. 'change_status.last_change_date_time, '
. 'change_status.resource_status, '
. 'change_status.resource_type, '
. 'change_status.ad_group, '
. 'change_status.ad_group_ad, '
. 'change_status.ad_group_bid_modifier, '
. 'change_status.ad_group_criterion, '
. 'change_status.ad_group_feed, '
. 'change_status.campaign, '
. 'change_status.campaign_criterion, '
. 'change_status.campaign_feed, '
. 'change_status.feed, '
. 'change_status.feed_item '
. 'FROM change_status '
. 'WHERE change_status.last_change_date_time DURING LAST_14_DAYS '
. 'ORDER BY change_status.last_change_date_time '
. 'LIMIT 10000';
// Issues a search request.
$response = $googleAdsServiceClient->search(
SearchGoogleAdsRequest::build($customerId, $query)
);
// Iterates over all rows in all pages and prints the requested field values for
// the change status in each row.
foreach ($response->iterateAllElements() as $googleAdsRow) {
/** @var GoogleAdsRow $googleAdsRow */
printf(
"On %s, change status '%s' shows resource '%s' with type '%s' and status '%s'.%s",
$googleAdsRow->getChangeStatus()->getLastChangeDateTime(),
$googleAdsRow->getChangeStatus()->getResourceName(),
self::getResourceNameForResourceType($googleAdsRow->getChangeStatus()),
ChangeStatusResourceType::name(
$googleAdsRow->getChangeStatus()->getResourceType()
),
ChangeStatusOperation::name($googleAdsRow->getChangeStatus()->getResourceStatus()),
PHP_EOL
);
}
}
/**
* Gets the resource name for the resource type of the change status object.
*
* Each returned row contains all possible changed resources, only one of which is populated
* with the name of the changed resource. This function returns the resource name of the
* changed resource based on the resource type.
*
* @param ChangeStatus $changeStatus the change status object for getting changed resource
* @return string the name of the resource that changed
*/
private static function getResourceNameForResourceType(
ChangeStatus $changeStatus
) {
$resourceType = $changeStatus->getResourceType();
$resourceName = ''; // Default value for UNSPECIFIED or UNKNOWN resource type.
switch ($resourceType) {
case ChangeStatusResourceType::AD_GROUP:
$resourceName = $changeStatus->getAdGroup();
break;
case ChangeStatusResourceType::AD_GROUP_AD:
$resourceName = $changeStatus->getAdGroupAd();
break;
case ChangeStatusResourceType::AD_GROUP_BID_MODIFIER:
$resourceName = $changeStatus->getAdGroupBidModifier();
break;
case ChangeStatusResourceType::AD_GROUP_CRITERION:
$resourceName = $changeStatus->getAdGroupCriterion();
break;
case ChangeStatusResourceType::AD_GROUP_FEED:
$resourceName = $changeStatus->getAdGroupFeed();
break;
case ChangeStatusResourceType::CAMPAIGN:
$resourceName = $changeStatus->getCampaign();
break;
case ChangeStatusResourceType::CAMPAIGN_CRITERION:
$resourceName = $changeStatus->getCampaignCriterion();
break;
case ChangeStatusResourceType::CAMPAIGN_FEED:
$resourceName = $changeStatus->getCampaignFeed();
break;
case ChangeStatusResourceType::FEED:
$resourceName = $changeStatus->getFeed();
break;
case ChangeStatusResourceType::FEED_ITEM:
$resourceName = $changeStatus->getFeedItem();
break;
}
return $resourceName;
}
def main(client, customer_id):
ads_service = client.get_service("GoogleAdsService")
# Construct a query to find information about changed resources in your
# account.
query = """
SELECT
change_status.resource_name,
change_status.last_change_date_time,
change_status.resource_type,
change_status.campaign,
change_status.ad_group,
change_status.resource_status,
change_status.ad_group_ad,
change_status.ad_group_criterion,
change_status.campaign_criterion
FROM change_status
WHERE change_status.last_change_date_time DURING LAST_14_DAYS
ORDER BY change_status.last_change_date_time
LIMIT 10000"""
search_request = client.get_type("SearchGoogleAdsRequest")
search_request.customer_id = customer_id
search_request.query = query
response = ads_service.search(request=search_request)
for row in response:
cs = row.change_status
resource_type = cs.resource_type.name
if resource_type == "AD_GROUP":
resource_name = cs.ad_group
elif resource_type == "AD_GROUP_AD":
resource_name = cs.ad_group_ad
elif resource_type == "AD_GROUP_CRITERION":
resource_name = cs.ad_group_criterion
elif resource_type == "CAMPAIGN":
resource_name = cs.campaign
elif resource_type == "CAMPAIGN_CRITERION":
resource_name = cs.campaign_criterion
else:
resource_name = "UNKNOWN"
resource_status = cs.resource_status.name
print(
f"On '{cs.last_change_date_time}', change status "
f"'{cs.resource_name}' shows that a resource type of "
f"'{resource_type}' with resource name '{resource_name}' was "
f"{resource_status}"
)
def get_change_summary(customer_id)
# GoogleAdsClient will read a config file from
# ENV['HOME']/google_ads_config.rb when called without parameters
client = Google::Ads::GoogleAds::GoogleAdsClient.new
# Construct a query to find information about changed resources in your
# account.
query = <<~QUERY
SELECT
change_status.resource_name,
change_status.last_change_date_time,
change_status.resource_type,
change_status.campaign,
change_status.ad_group,
change_status.resource_status,
change_status.ad_group_ad,
change_status.ad_group_criterion,
change_status.campaign_criterion
FROM
change_status
WHERE change_status.last_change_date_time DURING LAST_14_DAYS
ORDER BY
change_status.last_change_date_time
LIMIT 10000
QUERY
# Execute the query.
response = client.service.google_ads.search(
customer_id: customer_id,
query: query,
page_size: PAGE_SIZE
)
# Process the results.
response.each do |row|
cs = row.change_status
resource_name = case cs.resource_type
when :AD_GROUP
cs.ad_group
when :AD_GROUP_AD
cs.ad_group_ad
when :AD_GROUP_CRITERION
cs.ad_group_criterion
when :CAMPAIGN
cs.campaign
when :CAMPAIGN_CRITERION
cs.campaign_criterion
else
"UNKNOWN"
end
puts "On #{cs.last_change_date_time}, change status #{cs.resource_name} " \
"shows a resource type of #{cs.resource_type} " \
"with resource name #{resource_name} was #{cs.resource_status}."
end
end
sub get_change_summary {
my ($api_client, $customer_id) = @_;
# Construct a search query to find information about changed resources in your
# account.
my $search_query =
"SELECT change_status.resource_name, change_status.last_change_date_time, "
. "change_status.resource_status, "
. "change_status.resource_type, "
. "change_status.ad_group, "
. "change_status.ad_group_ad, "
. "change_status.ad_group_bid_modifier, "
. "change_status.ad_group_criterion, "
. "change_status.ad_group_feed, "
. "change_status.campaign, "
. "change_status.campaign_criterion, "
. "change_status.campaign_feed, "
. "change_status.feed, "
. "change_status.feed_item "
. "FROM change_status "
. "WHERE change_status.last_change_date_time DURING LAST_14_DAYS "
. "ORDER BY change_status.last_change_date_time "
. "LIMIT 10000";
# Create a search Google Ads request that will retrieve all change statuses using
# pages of the specified page size.
my $search_request =
Google::Ads::GoogleAds::V17::Services::GoogleAdsService::SearchGoogleAdsRequest
->new({
customerId => $customer_id,
query => $search_query
});
# Get the GoogleAdsService.
my $google_ads_service = $api_client->GoogleAdsService();
my $iterator = Google::Ads::GoogleAds::Utils::SearchGoogleAdsIterator->new({
service => $google_ads_service,
request => $search_request
});
# Iterate over all rows in all pages and print the requested field values for
# the change status in each row.
while ($iterator->has_next) {
my $google_ads_row = $iterator->next;
my $change_status = $google_ads_row->{changeStatus};
printf "On %s, change status '%s' shows a resource type of '%s' " .
"with resource name '%s' was '%s'.\n",
$change_status->{lastChangeDateTime},
$change_status->{resourceName}, $change_status->{resourceType},
__get_resource_name_for_resource_type($change_status),
$change_status->{resourceStatus};
}
return 1;
}
# This method returns the resource name of the changed field based on the
# resource type. The changed field's parent is also populated but is not used.
sub __get_resource_name_for_resource_type {
my $change_status = shift;
my $resource_type = $change_status->{resourceType};
if ($resource_type eq AD_GROUP) {
return $change_status->{adGroup};
} elsif ($resource_type eq AD_GROUP_AD) {
return $change_status->{adGroupAd};
} elsif ($resource_type eq AD_GROUP_BID_MODIFIER) {
return $change_status->{adGroupBidModifier};
} elsif ($resource_type eq AD_GROUP_CRITERION) {
return $change_status->{adGroupCriterion};
} elsif ($resource_type eq AD_GROUP_FEED) {
return $change_status->{adGroupFeed};
} elsif ($resource_type eq CAMPAIGN) {
return $change_status->{campaign};
} elsif ($resource_type eq CAMPAIGN_CRITERION) {
return $change_status->{campaignCriterion};
} elsif ($resource_type eq CAMPAIGN_FEED) {
return $change_status->{campaignFeed};
} elsif ($resource_type eq FEED) {
return $change_status->{feed};
} elsif ($resource_type eq FEED_ITEM) {
return $change_status->{feedItem};
} else {
return "";
}
}
在本地同步
获取确切的 resource_name
后,
应使用此资源名称创建一个新查询,以获取所有
资源的当前值系统不会跟踪特定更改的状态
资源已更改的值 - 仅限已更改的资源。正在确定
先前值和当前值之间的差异由
调用程序。
更改时间
last_change_date_time
字段指示对资源进行最近一次更改的时间。因此,
可以将本地缓存数据的新鲜度与此字段的值进行比较,
确定本地数据是否已过期。
请注意,此字段也可过滤,这意味着它可在 WHERE
中使用。
子句,从而允许您查询
在指定时间之前或之后发生的资源更改。
例如,查找特定资源类型发生的所有更改 可以使用以下 GAQL 谓词完成搜索 子句:
WHERE change_status.last_change_date_time DURING LAST_7_DAYS