تغییر رویداد
با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
رویداد تغییر یک تفکیک دقیق از آنچه در حساب شما تغییر کرده است ارائه می دهد. هنگام گزارش در مورد یک عملیات ایجاد، تمام مقادیر فیلد جدید برگردانده می شوند. و هنگام گزارش عملیات بهروزرسانی، مقادیر جدید و قدیمی برگردانده میشوند و تصویری کامل از تغییرات فردی به شما ارائه میدهند.
علاوه بر این، نوع کلاینت (مانند API یا سرویس گیرنده وب) که برای ایجاد تغییر استفاده شده است، نشان داده می شود و همچنین اینکه چه کاربری این تغییر را انجام داده است، با این فرض که اطلاعات در تاریخچه تغییرات کلاینت وب نیز قابل مشاهده است.
لیست تغییرات باید بر اساس تاریخ فیلتر شود. محدوده تاریخ باید در 30 روز گذشته باشد.
پرس و جو همچنین باید شامل یک بند LIMIT باشد که نتایج را به حداکثر 10000 ردیف محدود می کند. اگر به بیش از 10000 نتیجه علاقه دارید، مهر زمانی آخرین ورودی را در مجموعه نتایج برگشتی یادداشت کنید و سپس محدوده تاریخ خود را در عبارت جستجوی زیر تنظیم کنید تا بعد از آن زمان شروع شود تا از همان جایی که کار را متوقف کردید ادامه دهید.
یک تغییر ممکن است تا سه دقیقه طول بکشد تا در نتایج رویداد تغییر منعکس شود.
مثال زیر نحوه واکشی رویدادهای تغییر و پردازش آنها را نشان می دهد، از جمله تعیین اینکه چه کسی تغییر را ایجاد کرده است، از کدام نوع کلاینت برای ایجاد تغییر استفاده کرده است، و مقادیر قدیمی و جدید هر فیلد در تغییر:
defmain(client:GoogleAdsClient,customer_id:str)-> None:"""Gets specific details about the most recent changes in the given account. Args: client: The Google Ads client. customer_id: The Google Ads customer ID. """googleads_service:GoogleAdsServiceClient=client.get_service("GoogleAdsService")# Construct a query to find details for recent changes in your account.# The LIMIT clause is required for the change_event resource.# The maximum size is 10000, but a low limit was set here for demonstrative# purposes. For more information see:# https://developers.google.com/google-ads/api/docs/change-event#getting_changes# The WHERE clause on change_date_time is also required. It must specify a# window within the past 30 days.tomorrow:str=(datetime.now()+timedelta(1)).strftime("%Y-%m-%d")two_weeks_ago:str=(datetime.now()+timedelta(-14)).strftime("%Y-%m-%d")query:str=f""" SELECT change_event.resource_name, change_event.change_date_time, change_event.change_resource_name, change_event.user_email, change_event.client_type, change_event.change_resource_type, change_event.old_resource, change_event.new_resource, change_event.resource_change_operation, change_event.changed_fields FROM change_event WHERE change_event.change_date_time <= '{tomorrow}' AND change_event.change_date_time >= '{two_weeks_ago}' ORDER BY change_event.change_date_time DESC LIMIT 5"""search_request:SearchGoogleAdsRequest=client.get_type("SearchGoogleAdsRequest")search_request.customer_id=customer_idsearch_request.query=queryresults:SearchPagedResponse=googleads_service.search(request=search_request)row:GoogleAdsRowforrowinresults:event:ChangeEvent=row.change_eventresource_type:str=event.change_resource_type.nameold_resource:Anynew_resource:Anyifresource_type=="AD":old_resource=event.old_resource.adnew_resource=event.new_resource.adelifresource_type=="AD_GROUP":old_resource=event.old_resource.ad_groupnew_resource=event.new_resource.ad_groupelifresource_type=="AD_GROUP_AD":old_resource=event.old_resource.ad_group_adnew_resource=event.new_resource.ad_group_adelifresource_type=="AD_GROUP_ASSET":old_resource=event.old_resource.ad_group_assetnew_resource=event.new_resource.ad_group_assetelifresource_type=="AD_GROUP_CRITERION":old_resource=event.old_resource.ad_group_criterionnew_resource=event.new_resource.ad_group_criterionelifresource_type=="AD_GROUP_BID_MODIFIER":old_resource=event.old_resource.ad_group_bid_modifiernew_resource=event.new_resource.ad_group_bid_modifierelifresource_type=="AD_GROUP_FEED":old_resource=event.old_resource.ad_group_feednew_resource=event.new_resource.ad_group_feedelifresource_type=="ASSET":old_resource=event.old_resource.assetnew_resource=event.new_resource.assetelifresource_type=="ASSET_SET":old_resource=event.old_resource.asset_setnew_resource=event.new_resource.asset_setelifresource_type=="ASSET_SET_ASSET":old_resource=event.old_resource.asset_set_assetnew_resource=event.new_resource.asset_set_assetelifresource_type=="CAMPAIGN":old_resource=event.old_resource.campaignnew_resource=event.new_resource.campaignelifresource_type=="CAMPAIGN_ASSET":old_resource=event.old_resource.campaign_assetnew_resource=event.new_resource.campaign_assetelifresource_type=="CAMPAIGN_ASSET_SET":old_resource=event.old_resource.campaign_asset_setnew_resource=event.new_resource.campaign_asset_setelifresource_type=="CAMPAIGN_BUDGET":old_resource=event.old_resource.campaign_budgetnew_resource=event.new_resource.campaign_budgetelifresource_type=="CAMPAIGN_CRITERION":old_resource=event.old_resource.campaign_criterionnew_resource=event.new_resource.campaign_criterionelifresource_type=="CAMPAIGN_FEED":old_resource=event.old_resource.campaign_feednew_resource=event.new_resource.campaign_feedelifresource_type=="CUSTOMER_ASSET":old_resource=event.old_resource.customer_assetnew_resource=event.new_resource.customer_assetelifresource_type=="FEED":old_resource=event.old_resource.feednew_resource=event.new_resource.feedelifresource_type=="FEED_ITEM":old_resource=event.old_resource.feed_itemnew_resource=event.new_resource.feed_itemelse:print("Unknown change_resource_type: '{event.change_resource_type}'")# If the resource type is unrecognized then we continue to# the next row.continueprint(f"On {event.change_date_time}, user {event.user_email} "f"used interface {event.client_type.name} to perform a(n) "f"{event.resource_change_operation.name} operation on a "f"{event.change_resource_type.name} with resource name "f"'{event.change_resource_name}'")operation_type:str=event.resource_change_operation.nameifoperation_typein("UPDATE","CREATE"):forchanged_field_pathinevent.changed_fields.paths:changed_field:str=changed_field_path# Change field name from "type" to "type_" so that it doesn't# raise an exception when accessed on the protobuf object, see:# https://developers.google.com/google-ads/api/docs/client-libs/python/library-version-10#field_names_that_are_reserved_wordsifchanged_field=="type":changed_field="type_"new_value:Any=get_nested_attr(new_resource,changed_field)# If the field value is an Enum get the human readable name# so that it is printed instead of the field ID integer.ifisinstance(type(new_value),ProtoEnumMeta):new_value=new_value.nameifoperation_type=="CREATE":print(f"\t{changed_field} set to {new_value}")else:old_value:Any=get_nested_attr(old_resource,changed_field)# If the field value is an Enum get the human readable name# so that it is printed instead of the field ID integer.ifisinstance(type(old_value),ProtoEnumMeta):old_value=old_value.nameprint(f"\t{changed_field} changed from {old_value} to {new_value}")
defget_change_details(customer_id)# GoogleAdsClient will read a config file from# ENV['HOME']/google_ads_config.rb when called without parametersclient=Google::Ads::GoogleAds::GoogleAdsClient.new# Construct a query to find details for recent changes in your account.# The LIMIT clause is required for the change_event resource.# The maximum size is 10000, but a low limit was set here for demonstrative# purposes.# The WHERE clause on change_date_time is also required. It must specify a# window of at most 30 days within the past 30 days.query=<<~QUERYSELECTchange_event.resource_name,change_event.change_date_time,change_event.change_resource_name,change_event.user_email,change_event.client_type,change_event.change_resource_type,change_event.old_resource,change_event.new_resource,change_event.resource_change_operation,change_event.changed_fieldsFROMchange_eventWHEREchange_event.change_date_time<='#{(Date.today+1).to_s}'ANDchange_event.change_date_time>='#{(Date.today-14).to_s}'ORDERBYchange_event.change_date_timeDESCLIMIT5QUERY# Execute the query to fetch results from the API.response=client.service.google_ads.search(customer_id:customer_id,query:query,)# Process the results and output changes.response.eachdo|row|event=row.change_eventold_resource,new_resource=caseevent.change_resource_typewhen:AD[event.old_resource.ad,event.new_resource.ad]when:AD_GROUP[event.old_resource.ad_group,event.new_resource.ad_group]when:AD_GROUP_AD[event.old_resource.ad_group_ad,event.new_resource.ad_group_ad]when:AD_GROUP_ASSET[event.old_resource.ad_group_asset,event.new_resource.ad_group_asset]when:AD_GROUP_CRITERION[event.old_resource.ad_group_criterion,event.new_resource.ad_group_criterion]when:AD_GROUP_BID_MODIFIER[event.old_resource.ad_group_bid_modifier,event.new_resource.ad_group_bid_modifier]when:ASSET[event.old_resource.asset,event.new_resource.asset]when:ASSET_SET[event.old_resource.asset_set,event.new_resource.asset_set]when:ASSET_SET_ASSET[event.old_resource.asset_set_asset,event.new_resource.asset_set_asset]when:CAMPAIGN[event.old_resource.campaign,event.new_resource.campaign]when:CAMPAIGN_ASSET[event.old_resource.campaign_asset,event.new_resource.campaign_asset]when:CAMPAIGN_ASSET_SET[event.old_resource.campaign_asset_set,event.new_resource.campaign_asset_set]when:CAMPAIGN_BUDGET[event.old_resource.campaign_budget,event.new_resource.campaign_budget]when:CAMPAIGN_CRITERION[event.old_resource.campaign_criterion,event.new_resource.campaign_criterion]when:ASSET[event.old_resource.asset,event.new_resource.asset]when:CUSTOMER_ASSET[event.old_resource.customer_asset,event.new_resource.customer_asset]elseputs"Unknown change_resource_type #{event.change_resource_type}."nextendputs"On #{event.change_date_time}, user #{event.user_email} used interface "\"#{event.client_type} to perform a(n) #{event.resource_change_operation} "\"operation on a #{event.change_resource_type} with resource name "\"#{event.change_resource_name}."if[:UPDATE,:CREATE].include?event.resource_change_operationevent.changed_fields.paths.eachdo|changed_field|new_value=get_value_from_path(changed_field,new_resource)if:CREATE==event.resource_change_operationputs"\t#{changed_field} set to '#{new_value}'."elseold_value=get_value_from_path(changed_field,old_resource)puts"\t#{changed_field} changed from '#{old_value}' to '#{new_value}'."endendendendend# Given the string value of a path from the response, look up the value of the# field located at that path on the given object.defget_value_from_path(path,object)path.split(".").inject(object){|obj,key|obj.send(key)}end
subget_change_details{my($api_client,$customer_id)=@_;# Construct a query to find details for recent changes in your account.# The LIMIT clause is required for the change_event resource.# The maximum size is 10000, but a low limit was set here for demonstrative# purposes.# The WHERE clause on change_date_time is also required. It must specify a# window of at most 30 days within the past 30 days.my$search_query="SELECT change_event.resource_name, change_event.change_date_time, "."change_event.change_resource_name, change_event.user_email, "."change_event.client_type, change_event.change_resource_type, "."change_event.old_resource, change_event.new_resource, "."change_event.resource_change_operation, change_event.changed_fields "."FROM change_event "."WHERE change_event.change_date_time DURING LAST_14_DAYS "."ORDER BY change_event.change_date_time DESC LIMIT 5";# Create a search Google Ads request that will retrieve all change events using# pages of the specified page size.my$search_request=Google::Ads::GoogleAds::V22::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 event in each row.while($iterator->has_next){my$google_ads_row=$iterator->next;my$change_event=$google_ads_row->{changeEvent};printf"On %s, user %s used interface %s to perform a(n) %s operation "."on a %s with resource name '%s'.\n",$change_event->{changeDateTime},$change_event->{userEmail},$change_event->{clientType},$change_event->{resourceChangeOperation},$change_event->{changeResourceType},$change_event->{changeResourceName};if(grep/$change_event->{resourceChangeOperation}/,(CREATE,UPDATE)){my($old_resource,$new_resource)=_get_changed_resources_for_resource_type($change_event);foreachmy$changed_field(split/,/,$change_event->{changedFields}){my$new_value=_convert_to_string(get_field_value($new_resource,$changed_field))||"";if($change_event->{resourceChangeOperation}eqCREATE){print"\t$changed_field set to '$new_value'.\n";}else{my$old_value=_convert_to_string(get_field_value($old_resource,$changed_field))||"";print"\t$changed_field changed from '$old_value' to '$new_value'.\n";}}}}return1;}# This method converts the specified value to a string.sub_convert_to_string{my$value=shift;my$string_value="";if(ref($value)eq"ARRAY"){$string_value.="[";foreachmy$item(@$value){if(is_hash_ref($item)){$string_value.=(JSON::XS->new->utf8->encode($item).",");}else{$string_value.=($item.",");}}$string_value.="]";}elsif(is_hash_ref($value)){$string_value.=JSON::XS->new->utf8->encode($value);}else{$string_value=$value;}return$string_value;}# This method returns the old resource and new resource based on the change# resource type of a change event.sub_get_changed_resources_for_resource_type{my$change_event=shift;my$resource_type=$change_event->{changeResourceType};if($resource_typeeqAD){return$change_event->{oldResource}{ad},$change_event->{newResource}{ad};}elsif($resource_typeeqAD_GROUP){return$change_event->{oldResource}{adGroup},$change_event->{newResource}{adGroup};}elsif($resource_typeeqAD_GROUP_AD){return$change_event->{oldResource}{adGroupAd},$change_event->{newResource}{adGroupAd};}elsif($resource_typeeqAD_GROUP_ASSET){return$change_event->{oldResource}{adGroupAsset},$change_event->{newResource}{adGroupAsset};}elsif($resource_typeeqAD_GROUP_CRITERION){return$change_event->{oldResource}{adGroupCriterion},$change_event->{newResource}{adGroupCriterion};}elsif($resource_typeeqAD_GROUP_BID_MODIFIER){return$change_event->{oldResource}{adGroupBidModifier},$change_event->{newResource}{adGroupBidModifier};}elsif($resource_typeeqASSET){return$change_event->{oldResource}{asset},$change_event->{newResource}{asset};}elsif($resource_typeeqASSET_SET){return$change_event->{oldResource}{assetSet},$change_event->{newResource}{assetSet};}elsif($resource_typeeqASSET_SET_ASSET){return$change_event->{oldResource}{assetSetAsset},$change_event->{newResource}{assetSetAsset};}elsif($resource_typeeqCAMPAIGN){return$change_event->{oldResource}{campaign},$change_event->{newResource}{campaign};}elsif($resource_typeeqCAMPAIGN_ASSET){return$change_event->{oldResource}{campaignAsset},$change_event->{newResource}{campaignAsset};}elsif($resource_typeeqCAMPAIGN_ASSET_SET){return$change_event->{oldResource}{campaignAssetSet},$change_event->{newResource}{campaignAssetSet};}elsif($resource_typeeqCAMPAIGN_BUDGET){return$change_event->{oldResource}{campaignBudget},$change_event->{newResource}{campaignBudget};}elsif($resource_typeeqCAMPAIGN_CRITERION){return$change_event->{oldResource}{campaignCriterion},$change_event->{newResource}{campaignCriterion};}elsif($resource_typeeqCUSTOMER_ASSET){return$change_event->{oldResource}{customerAsset},$change_event->{newResource}{customerAsset};}else{print"Unknown change_resource_type $resource_type.\n";}}
یک رویداد تغییر ممکن است شامل هر ردیف از تاریخچه تغییرات در سرویس گیرنده وب نباشد. برای نمای مشابه با تاریخچه تغییر، به جای آن از منبع وضعیت تغییر استفاده کنید.
منبع رویداد تغییر برای بررسی جزئیات یک تغییر فردی در نظر گرفته شده است. میتوانید دادههایی مانند مقادیر فیلد خاصی که تغییر کردهاند، چه کسی این تغییر را انجام داده است و از کدام نوع کلاینت برای ایجاد تغییر بازیابی کنید. با این حال، همه تغییرات در حساب شما دارای ورودی رویداد تغییر مربوطه نیستند.
برخی از انواع کلاینت های کلیدی که تغییرات خود را برای استفاده در رویدادهای تغییر ثبت می کنند عبارتند از:
Google Ads API
سرویس گیرنده وب Google Ads
،
رویداد تغییر یک تفکیک دقیق از آنچه در حساب شما تغییر کرده است ارائه می دهد. هنگام گزارش در مورد یک عملیات ایجاد، تمام مقادیر فیلد جدید برگردانده می شوند. و هنگام گزارش عملیات بهروزرسانی، مقادیر جدید و قدیمی برگردانده میشوند و تصویری کامل از تغییرات فردی به شما ارائه میدهند.
علاوه بر این، نوع کلاینت (مانند API یا سرویس گیرنده وب) که برای ایجاد تغییر استفاده شده است، نشان داده می شود و همچنین اینکه چه کاربری این تغییر را انجام داده است، با این فرض که اطلاعات در تاریخچه تغییرات کلاینت وب نیز قابل مشاهده است.
لیست تغییرات باید بر اساس تاریخ فیلتر شود. محدوده تاریخ باید در 30 روز گذشته باشد.
پرس و جو همچنین باید شامل یک بند LIMIT باشد که نتایج را به حداکثر 10000 ردیف محدود می کند. اگر به بیش از 10000 نتیجه علاقه دارید، مهر زمانی آخرین ورودی را در مجموعه نتایج برگشتی یادداشت کنید و سپس محدوده تاریخ خود را در عبارت جستجوی زیر تنظیم کنید تا بعد از آن زمان شروع شود تا از همان جایی که کار را متوقف کردید ادامه دهید.
یک تغییر ممکن است تا سه دقیقه طول بکشد تا در نتایج رویداد تغییر منعکس شود.
مثال زیر نحوه واکشی رویدادهای تغییر و پردازش آنها را نشان می دهد، از جمله تعیین اینکه چه کسی تغییر را ایجاد کرده است، از کدام نوع کلاینت برای ایجاد تغییر استفاده کرده است، و مقادیر قدیمی و جدید هر فیلد در تغییر:
defmain(client:GoogleAdsClient,customer_id:str)-> None:"""Gets specific details about the most recent changes in the given account. Args: client: The Google Ads client. customer_id: The Google Ads customer ID. """googleads_service:GoogleAdsServiceClient=client.get_service("GoogleAdsService")# Construct a query to find details for recent changes in your account.# The LIMIT clause is required for the change_event resource.# The maximum size is 10000, but a low limit was set here for demonstrative# purposes. For more information see:# https://developers.google.com/google-ads/api/docs/change-event#getting_changes# The WHERE clause on change_date_time is also required. It must specify a# window within the past 30 days.tomorrow:str=(datetime.now()+timedelta(1)).strftime("%Y-%m-%d")two_weeks_ago:str=(datetime.now()+timedelta(-14)).strftime("%Y-%m-%d")query:str=f""" SELECT change_event.resource_name, change_event.change_date_time, change_event.change_resource_name, change_event.user_email, change_event.client_type, change_event.change_resource_type, change_event.old_resource, change_event.new_resource, change_event.resource_change_operation, change_event.changed_fields FROM change_event WHERE change_event.change_date_time <= '{tomorrow}' AND change_event.change_date_time >= '{two_weeks_ago}' ORDER BY change_event.change_date_time DESC LIMIT 5"""search_request:SearchGoogleAdsRequest=client.get_type("SearchGoogleAdsRequest")search_request.customer_id=customer_idsearch_request.query=queryresults:SearchPagedResponse=googleads_service.search(request=search_request)row:GoogleAdsRowforrowinresults:event:ChangeEvent=row.change_eventresource_type:str=event.change_resource_type.nameold_resource:Anynew_resource:Anyifresource_type=="AD":old_resource=event.old_resource.adnew_resource=event.new_resource.adelifresource_type=="AD_GROUP":old_resource=event.old_resource.ad_groupnew_resource=event.new_resource.ad_groupelifresource_type=="AD_GROUP_AD":old_resource=event.old_resource.ad_group_adnew_resource=event.new_resource.ad_group_adelifresource_type=="AD_GROUP_ASSET":old_resource=event.old_resource.ad_group_assetnew_resource=event.new_resource.ad_group_assetelifresource_type=="AD_GROUP_CRITERION":old_resource=event.old_resource.ad_group_criterionnew_resource=event.new_resource.ad_group_criterionelifresource_type=="AD_GROUP_BID_MODIFIER":old_resource=event.old_resource.ad_group_bid_modifiernew_resource=event.new_resource.ad_group_bid_modifierelifresource_type=="AD_GROUP_FEED":old_resource=event.old_resource.ad_group_feednew_resource=event.new_resource.ad_group_feedelifresource_type=="ASSET":old_resource=event.old_resource.assetnew_resource=event.new_resource.assetelifresource_type=="ASSET_SET":old_resource=event.old_resource.asset_setnew_resource=event.new_resource.asset_setelifresource_type=="ASSET_SET_ASSET":old_resource=event.old_resource.asset_set_assetnew_resource=event.new_resource.asset_set_assetelifresource_type=="CAMPAIGN":old_resource=event.old_resource.campaignnew_resource=event.new_resource.campaignelifresource_type=="CAMPAIGN_ASSET":old_resource=event.old_resource.campaign_assetnew_resource=event.new_resource.campaign_assetelifresource_type=="CAMPAIGN_ASSET_SET":old_resource=event.old_resource.campaign_asset_setnew_resource=event.new_resource.campaign_asset_setelifresource_type=="CAMPAIGN_BUDGET":old_resource=event.old_resource.campaign_budgetnew_resource=event.new_resource.campaign_budgetelifresource_type=="CAMPAIGN_CRITERION":old_resource=event.old_resource.campaign_criterionnew_resource=event.new_resource.campaign_criterionelifresource_type=="CAMPAIGN_FEED":old_resource=event.old_resource.campaign_feednew_resource=event.new_resource.campaign_feedelifresource_type=="CUSTOMER_ASSET":old_resource=event.old_resource.customer_assetnew_resource=event.new_resource.customer_assetelifresource_type=="FEED":old_resource=event.old_resource.feednew_resource=event.new_resource.feedelifresource_type=="FEED_ITEM":old_resource=event.old_resource.feed_itemnew_resource=event.new_resource.feed_itemelse:print("Unknown change_resource_type: '{event.change_resource_type}'")# If the resource type is unrecognized then we continue to# the next row.continueprint(f"On {event.change_date_time}, user {event.user_email} "f"used interface {event.client_type.name} to perform a(n) "f"{event.resource_change_operation.name} operation on a "f"{event.change_resource_type.name} with resource name "f"'{event.change_resource_name}'")operation_type:str=event.resource_change_operation.nameifoperation_typein("UPDATE","CREATE"):forchanged_field_pathinevent.changed_fields.paths:changed_field:str=changed_field_path# Change field name from "type" to "type_" so that it doesn't# raise an exception when accessed on the protobuf object, see:# https://developers.google.com/google-ads/api/docs/client-libs/python/library-version-10#field_names_that_are_reserved_wordsifchanged_field=="type":changed_field="type_"new_value:Any=get_nested_attr(new_resource,changed_field)# If the field value is an Enum get the human readable name# so that it is printed instead of the field ID integer.ifisinstance(type(new_value),ProtoEnumMeta):new_value=new_value.nameifoperation_type=="CREATE":print(f"\t{changed_field} set to {new_value}")else:old_value:Any=get_nested_attr(old_resource,changed_field)# If the field value is an Enum get the human readable name# so that it is printed instead of the field ID integer.ifisinstance(type(old_value),ProtoEnumMeta):old_value=old_value.nameprint(f"\t{changed_field} changed from {old_value} to {new_value}")
defget_change_details(customer_id)# GoogleAdsClient will read a config file from# ENV['HOME']/google_ads_config.rb when called without parametersclient=Google::Ads::GoogleAds::GoogleAdsClient.new# Construct a query to find details for recent changes in your account.# The LIMIT clause is required for the change_event resource.# The maximum size is 10000, but a low limit was set here for demonstrative# purposes.# The WHERE clause on change_date_time is also required. It must specify a# window of at most 30 days within the past 30 days.query=<<~QUERYSELECTchange_event.resource_name,change_event.change_date_time,change_event.change_resource_name,change_event.user_email,change_event.client_type,change_event.change_resource_type,change_event.old_resource,change_event.new_resource,change_event.resource_change_operation,change_event.changed_fieldsFROMchange_eventWHEREchange_event.change_date_time<='#{(Date.today+1).to_s}'ANDchange_event.change_date_time>='#{(Date.today-14).to_s}'ORDERBYchange_event.change_date_timeDESCLIMIT5QUERY# Execute the query to fetch results from the API.response=client.service.google_ads.search(customer_id:customer_id,query:query,)# Process the results and output changes.response.eachdo|row|event=row.change_eventold_resource,new_resource=caseevent.change_resource_typewhen:AD[event.old_resource.ad,event.new_resource.ad]when:AD_GROUP[event.old_resource.ad_group,event.new_resource.ad_group]when:AD_GROUP_AD[event.old_resource.ad_group_ad,event.new_resource.ad_group_ad]when:AD_GROUP_ASSET[event.old_resource.ad_group_asset,event.new_resource.ad_group_asset]when:AD_GROUP_CRITERION[event.old_resource.ad_group_criterion,event.new_resource.ad_group_criterion]when:AD_GROUP_BID_MODIFIER[event.old_resource.ad_group_bid_modifier,event.new_resource.ad_group_bid_modifier]when:ASSET[event.old_resource.asset,event.new_resource.asset]when:ASSET_SET[event.old_resource.asset_set,event.new_resource.asset_set]when:ASSET_SET_ASSET[event.old_resource.asset_set_asset,event.new_resource.asset_set_asset]when:CAMPAIGN[event.old_resource.campaign,event.new_resource.campaign]when:CAMPAIGN_ASSET[event.old_resource.campaign_asset,event.new_resource.campaign_asset]when:CAMPAIGN_ASSET_SET[event.old_resource.campaign_asset_set,event.new_resource.campaign_asset_set]when:CAMPAIGN_BUDGET[event.old_resource.campaign_budget,event.new_resource.campaign_budget]when:CAMPAIGN_CRITERION[event.old_resource.campaign_criterion,event.new_resource.campaign_criterion]when:ASSET[event.old_resource.asset,event.new_resource.asset]when:CUSTOMER_ASSET[event.old_resource.customer_asset,event.new_resource.customer_asset]elseputs"Unknown change_resource_type #{event.change_resource_type}."nextendputs"On #{event.change_date_time}, user #{event.user_email} used interface "\"#{event.client_type} to perform a(n) #{event.resource_change_operation} "\"operation on a #{event.change_resource_type} with resource name "\"#{event.change_resource_name}."if[:UPDATE,:CREATE].include?event.resource_change_operationevent.changed_fields.paths.eachdo|changed_field|new_value=get_value_from_path(changed_field,new_resource)if:CREATE==event.resource_change_operationputs"\t#{changed_field} set to '#{new_value}'."elseold_value=get_value_from_path(changed_field,old_resource)puts"\t#{changed_field} changed from '#{old_value}' to '#{new_value}'."endendendendend# Given the string value of a path from the response, look up the value of the# field located at that path on the given object.defget_value_from_path(path,object)path.split(".").inject(object){|obj,key|obj.send(key)}end
subget_change_details{my($api_client,$customer_id)=@_;# Construct a query to find details for recent changes in your account.# The LIMIT clause is required for the change_event resource.# The maximum size is 10000, but a low limit was set here for demonstrative# purposes.# The WHERE clause on change_date_time is also required. It must specify a# window of at most 30 days within the past 30 days.my$search_query="SELECT change_event.resource_name, change_event.change_date_time, "."change_event.change_resource_name, change_event.user_email, "."change_event.client_type, change_event.change_resource_type, "."change_event.old_resource, change_event.new_resource, "."change_event.resource_change_operation, change_event.changed_fields "."FROM change_event "."WHERE change_event.change_date_time DURING LAST_14_DAYS "."ORDER BY change_event.change_date_time DESC LIMIT 5";# Create a search Google Ads request that will retrieve all change events using# pages of the specified page size.my$search_request=Google::Ads::GoogleAds::V22::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 event in each row.while($iterator->has_next){my$google_ads_row=$iterator->next;my$change_event=$google_ads_row->{changeEvent};printf"On %s, user %s used interface %s to perform a(n) %s operation "."on a %s with resource name '%s'.\n",$change_event->{changeDateTime},$change_event->{userEmail},$change_event->{clientType},$change_event->{resourceChangeOperation},$change_event->{changeResourceType},$change_event->{changeResourceName};if(grep/$change_event->{resourceChangeOperation}/,(CREATE,UPDATE)){my($old_resource,$new_resource)=_get_changed_resources_for_resource_type($change_event);foreachmy$changed_field(split/,/,$change_event->{changedFields}){my$new_value=_convert_to_string(get_field_value($new_resource,$changed_field))||"";if($change_event->{resourceChangeOperation}eqCREATE){print"\t$changed_field set to '$new_value'.\n";}else{my$old_value=_convert_to_string(get_field_value($old_resource,$changed_field))||"";print"\t$changed_field changed from '$old_value' to '$new_value'.\n";}}}}return1;}# This method converts the specified value to a string.sub_convert_to_string{my$value=shift;my$string_value="";if(ref($value)eq"ARRAY"){$string_value.="[";foreachmy$item(@$value){if(is_hash_ref($item)){$string_value.=(JSON::XS->new->utf8->encode($item).",");}else{$string_value.=($item.",");}}$string_value.="]";}elsif(is_hash_ref($value)){$string_value.=JSON::XS->new->utf8->encode($value);}else{$string_value=$value;}return$string_value;}# This method returns the old resource and new resource based on the change# resource type of a change event.sub_get_changed_resources_for_resource_type{my$change_event=shift;my$resource_type=$change_event->{changeResourceType};if($resource_typeeqAD){return$change_event->{oldResource}{ad},$change_event->{newResource}{ad};}elsif($resource_typeeqAD_GROUP){return$change_event->{oldResource}{adGroup},$change_event->{newResource}{adGroup};}elsif($resource_typeeqAD_GROUP_AD){return$change_event->{oldResource}{adGroupAd},$change_event->{newResource}{adGroupAd};}elsif($resource_typeeqAD_GROUP_ASSET){return$change_event->{oldResource}{adGroupAsset},$change_event->{newResource}{adGroupAsset};}elsif($resource_typeeqAD_GROUP_CRITERION){return$change_event->{oldResource}{adGroupCriterion},$change_event->{newResource}{adGroupCriterion};}elsif($resource_typeeqAD_GROUP_BID_MODIFIER){return$change_event->{oldResource}{adGroupBidModifier},$change_event->{newResource}{adGroupBidModifier};}elsif($resource_typeeqASSET){return$change_event->{oldResource}{asset},$change_event->{newResource}{asset};}elsif($resource_typeeqASSET_SET){return$change_event->{oldResource}{assetSet},$change_event->{newResource}{assetSet};}elsif($resource_typeeqASSET_SET_ASSET){return$change_event->{oldResource}{assetSetAsset},$change_event->{newResource}{assetSetAsset};}elsif($resource_typeeqCAMPAIGN){return$change_event->{oldResource}{campaign},$change_event->{newResource}{campaign};}elsif($resource_typeeqCAMPAIGN_ASSET){return$change_event->{oldResource}{campaignAsset},$change_event->{newResource}{campaignAsset};}elsif($resource_typeeqCAMPAIGN_ASSET_SET){return$change_event->{oldResource}{campaignAssetSet},$change_event->{newResource}{campaignAssetSet};}elsif($resource_typeeqCAMPAIGN_BUDGET){return$change_event->{oldResource}{campaignBudget},$change_event->{newResource}{campaignBudget};}elsif($resource_typeeqCAMPAIGN_CRITERION){return$change_event->{oldResource}{campaignCriterion},$change_event->{newResource}{campaignCriterion};}elsif($resource_typeeqCUSTOMER_ASSET){return$change_event->{oldResource}{customerAsset},$change_event->{newResource}{customerAsset};}else{print"Unknown change_resource_type $resource_type.\n";}}
یک رویداد تغییر ممکن است شامل هر ردیف از تاریخچه تغییرات در سرویس گیرنده وب نباشد. برای نمای مشابه با تاریخچه تغییر، به جای آن از منبع وضعیت تغییر استفاده کنید.
منبع رویداد تغییر برای بررسی جزئیات یک تغییر فردی در نظر گرفته شده است. میتوانید دادههایی مانند مقادیر فیلد خاصی که تغییر کردهاند، چه کسی این تغییر را انجام داده است و از کدام نوع کلاینت برای ایجاد تغییر بازیابی کنید. با این حال، همه تغییرات در حساب شما دارای ورودی رویداد تغییر مربوطه نیستند.
برخی از انواع کلاینت های کلیدی که تغییرات خود را برای استفاده در رویدادهای تغییر ثبت می کنند عبارتند از:
تاریخ آخرین بهروزرسانی 2025-12-21 بهوقت ساعت هماهنگ جهانی.
[[["درک آسان","easyToUnderstand","thumb-up"],["مشکلم را برطرف کرد","solvedMyProblem","thumb-up"],["غیره","otherUp","thumb-up"]],[["اطلاعاتی که نیاز دارم وجود ندارد","missingTheInformationINeed","thumb-down"],["بیشازحد پیچیده/ مراحل بسیار زیاد","tooComplicatedTooManySteps","thumb-down"],["قدیمی","outOfDate","thumb-down"],["مشکل ترجمه","translationIssue","thumb-down"],["مشکل کد / نمونهها","samplesCodeIssue","thumb-down"],["غیره","otherDown","thumb-down"]],["تاریخ آخرین بهروزرسانی 2025-12-21 بهوقت ساعت هماهنگ جهانی."],[],[]]