google-adwords-api 0.9.2 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +5 -0
- data/README +3 -3
- data/examples/v201302/account_management/create_account.rb +8 -0
- data/examples/v201302/account_management/get_account_alerts.rb +8 -0
- data/examples/v201302/account_management/get_account_changes.rb +8 -0
- data/examples/v201302/account_management/get_account_hierarchy.rb +8 -0
- data/examples/v201302/advanced_operations/add_ad_group_bid_modifier.rb +8 -0
- data/examples/v201302/advanced_operations/add_click_to_download_ad.rb +8 -0
- data/examples/v201302/advanced_operations/add_site_links.rb +8 -0
- data/examples/v201302/advanced_operations/create_and_attach_shared_keyword_set.rb +8 -0
- data/examples/v201302/advanced_operations/find_and_remove_criteria_from_shared_set.rb +8 -0
- data/examples/v201302/advanced_operations/get_ad_group_bid_modifiers.rb +8 -0
- data/examples/v201302/basic_operations/add_ad_groups.rb +8 -0
- data/examples/v201302/basic_operations/add_campaigns.rb +8 -0
- data/examples/v201302/basic_operations/add_keywords.rb +8 -0
- data/examples/v201302/basic_operations/add_text_ads.rb +8 -0
- data/examples/v201302/basic_operations/delete_ad.rb +8 -0
- data/examples/v201302/basic_operations/delete_ad_group.rb +8 -0
- data/examples/v201302/basic_operations/delete_campaign.rb +8 -0
- data/examples/v201302/basic_operations/delete_keyword.rb +8 -0
- data/examples/v201302/basic_operations/get_ad_groups.rb +8 -0
- data/examples/v201302/basic_operations/get_campaigns.rb +8 -0
- data/examples/v201302/basic_operations/get_campaigns_with_awql.rb +8 -0
- data/examples/v201302/basic_operations/get_keywords.rb +8 -0
- data/examples/v201302/basic_operations/get_text_ads.rb +8 -0
- data/examples/v201302/basic_operations/pause_ad.rb +8 -0
- data/examples/v201302/basic_operations/update_ad_group.rb +8 -0
- data/examples/v201302/basic_operations/update_campaign.rb +8 -0
- data/examples/v201302/basic_operations/update_keyword.rb +8 -0
- data/examples/v201302/campaign_management/add_experiment.rb +8 -0
- data/examples/v201302/campaign_management/add_keywords_in_bulk.rb +8 -0
- data/examples/v201302/campaign_management/add_location_extension.rb +8 -0
- data/examples/v201302/campaign_management/add_location_extension_override.rb +8 -0
- data/examples/v201302/campaign_management/get_all_disapproved_ads.rb +8 -0
- data/examples/v201302/campaign_management/get_all_disapproved_ads_with_awql.rb +8 -0
- data/examples/v201302/campaign_management/promote_experiment.rb +8 -0
- data/examples/v201302/campaign_management/set_ad_parameters.rb +8 -0
- data/examples/v201302/campaign_management/set_criterion_bid_modifier.rb +8 -0
- data/examples/v201302/campaign_management/validate_text_ad.rb +8 -0
- data/examples/v201302/error_handling/handle_partial_failures.rb +8 -0
- data/examples/v201302/error_handling/handle_policy_violation_error.rb +8 -0
- data/examples/v201302/migration/set_campaign_enhanced.rb +8 -0
- data/examples/v201302/migration/upgrade_legacy_sitelinks.rb +8 -0
- data/examples/v201302/misc/get_all_images_and_videos.rb +8 -0
- data/examples/v201302/misc/{use_oauth2.rb → setup_oauth2.rb} +16 -25
- data/examples/v201302/misc/upload_image.rb +8 -0
- data/examples/v201302/optimization/estimate_keyword_traffic.rb +8 -0
- data/examples/v201302/optimization/get_keyword_bid_simulations.rb +8 -0
- data/examples/v201302/optimization/get_keyword_ideas.rb +8 -0
- data/examples/v201302/optimization/get_placement_ideas.rb +8 -0
- data/examples/v201302/remarketing/add_audience.rb +8 -0
- data/examples/v201302/remarketing/add_conversion_tracker.rb +8 -0
- data/examples/v201302/reporting/download_criteria_report.rb +8 -0
- data/examples/v201302/reporting/download_criteria_report_with_awql.rb +8 -0
- data/examples/v201302/reporting/get_campaign_stats.rb +8 -0
- data/examples/v201302/reporting/get_report_fields.rb +8 -0
- data/examples/v201302/reporting/parallel_report_download.rb +8 -0
- data/examples/v201302/targeting/add_campaign_targeting_criteria.rb +8 -0
- data/examples/v201302/targeting/add_demographic_targeting_criteria.rb +8 -0
- data/examples/v201302/targeting/get_campaign_targeting_criteria.rb +8 -0
- data/examples/v201302/targeting/get_targetable_languages_and_carriers.rb +8 -0
- data/examples/v201302/targeting/lookup_location.rb +8 -0
- data/examples/v201306/account_management/create_account.rb +95 -0
- data/examples/v201306/account_management/get_account_alerts.rb +122 -0
- data/examples/v201306/account_management/get_account_changes.rb +145 -0
- data/examples/v201306/account_management/get_account_hierarchy.rb +103 -0
- data/examples/v201306/advanced_operations/add_ad_group_bid_modifier.rb +105 -0
- data/examples/v201306/advanced_operations/add_click_to_download_ad.rb +137 -0
- data/examples/v201306/advanced_operations/add_site_links.rb +244 -0
- data/examples/v201306/advanced_operations/create_and_attach_shared_keyword_set.rb +147 -0
- data/examples/v201306/advanced_operations/find_and_remove_criteria_from_shared_set.rb +181 -0
- data/examples/v201306/advanced_operations/get_ad_group_bid_modifiers.rb +106 -0
- data/examples/v201306/basic_operations/add_ad_groups.rb +143 -0
- data/examples/v201306/basic_operations/add_campaigns.rb +162 -0
- data/examples/v201306/basic_operations/add_keywords.rb +116 -0
- data/examples/v201306/basic_operations/add_text_ads.rb +113 -0
- data/examples/v201306/basic_operations/delete_ad.rb +93 -0
- data/examples/v201306/basic_operations/delete_ad_group.rb +110 -0
- data/examples/v201306/basic_operations/delete_campaign.rb +111 -0
- data/examples/v201306/basic_operations/delete_keyword.rb +98 -0
- data/examples/v201306/basic_operations/get_ad_groups.rb +106 -0
- data/examples/v201306/basic_operations/get_campaigns.rb +101 -0
- data/examples/v201306/basic_operations/get_campaigns_with_awql.rb +93 -0
- data/examples/v201306/basic_operations/get_keywords.rb +112 -0
- data/examples/v201306/basic_operations/get_text_ads.rb +114 -0
- data/examples/v201306/basic_operations/pause_ad.rb +92 -0
- data/examples/v201306/basic_operations/update_ad_group.rb +89 -0
- data/examples/v201306/basic_operations/update_campaign.rb +90 -0
- data/examples/v201306/basic_operations/update_keyword.rb +110 -0
- data/examples/v201306/campaign_management/add_experiment.rb +166 -0
- data/examples/v201306/campaign_management/add_keywords_in_bulk.rb +158 -0
- data/examples/v201306/campaign_management/add_location_extension.rb +125 -0
- data/examples/v201306/campaign_management/add_location_extension_override.rb +91 -0
- data/examples/v201306/campaign_management/get_all_disapproved_ads.rb +101 -0
- data/examples/v201306/campaign_management/get_all_disapproved_ads_with_awql.rb +92 -0
- data/examples/v201306/campaign_management/promote_experiment.rb +85 -0
- data/examples/v201306/campaign_management/set_ad_parameters.rb +122 -0
- data/examples/v201306/campaign_management/set_criterion_bid_modifier.rb +110 -0
- data/examples/v201306/campaign_management/validate_text_ad.rb +114 -0
- data/examples/v201306/error_handling/handle_captcha_challenge.rb +93 -0
- data/examples/v201306/error_handling/handle_partial_failures.rb +134 -0
- data/examples/v201306/error_handling/handle_policy_violation_error.rb +145 -0
- data/examples/v201306/error_handling/handle_two_factor_authorization_error.rb +88 -0
- data/examples/v201306/migration/upgrade_legacy_sitelinks.rb +313 -0
- data/examples/v201306/misc/get_all_images_and_videos.rb +108 -0
- data/examples/v201306/misc/setup_oauth2.rb +88 -0
- data/examples/v201306/misc/upload_image.rb +97 -0
- data/examples/v201306/misc/use_oauth2_jwt.rb +93 -0
- data/examples/v201306/optimization/estimate_keyword_traffic.rb +137 -0
- data/examples/v201306/optimization/get_keyword_bid_simulations.rb +100 -0
- data/examples/v201306/optimization/get_keyword_ideas.rb +130 -0
- data/examples/v201306/optimization/get_placement_ideas.rb +112 -0
- data/examples/v201306/remarketing/add_audience.rb +123 -0
- data/examples/v201306/remarketing/add_conversion_tracker.rb +104 -0
- data/examples/v201306/reporting/download_criteria_report.rb +87 -0
- data/examples/v201306/reporting/download_criteria_report_with_awql.rb +86 -0
- data/examples/v201306/reporting/get_campaign_stats.rb +113 -0
- data/examples/v201306/reporting/get_report_fields.rb +79 -0
- data/examples/v201306/reporting/parallel_report_download.rb +171 -0
- data/examples/v201306/targeting/add_campaign_targeting_criteria.rb +123 -0
- data/examples/v201306/targeting/add_demographic_targeting_criteria.rb +116 -0
- data/examples/v201306/targeting/get_campaign_targeting_criteria.rb +110 -0
- data/examples/v201306/targeting/get_targetable_languages_and_carriers.rb +94 -0
- data/examples/v201306/targeting/lookup_location.rb +112 -0
- data/lib/adwords_api/api_config.rb +80 -4
- data/lib/adwords_api/v201306/ad_extension_override_service.rb +38 -0
- data/lib/adwords_api/v201306/ad_extension_override_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/ad_group_ad_service.rb +42 -0
- data/lib/adwords_api/v201306/ad_group_ad_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/ad_group_bid_modifier_service.rb +38 -0
- data/lib/adwords_api/v201306/ad_group_bid_modifier_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/ad_group_criterion_service.rb +42 -0
- data/lib/adwords_api/v201306/ad_group_criterion_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/ad_group_feed_service.rb +38 -0
- data/lib/adwords_api/v201306/ad_group_feed_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/ad_group_service.rb +42 -0
- data/lib/adwords_api/v201306/ad_group_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/ad_param_service.rb +38 -0
- data/lib/adwords_api/v201306/ad_param_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/adwords_user_list_service.rb +38 -0
- data/lib/adwords_api/v201306/adwords_user_list_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/alert_service.rb +34 -0
- data/lib/adwords_api/v201306/alert_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/bidding_strategy_service.rb +38 -0
- data/lib/adwords_api/v201306/bidding_strategy_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/budget_order_service.rb +42 -0
- data/lib/adwords_api/v201306/budget_order_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/budget_service.rb +38 -0
- data/lib/adwords_api/v201306/budget_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/campaign_ad_extension_service.rb +38 -0
- data/lib/adwords_api/v201306/campaign_ad_extension_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/campaign_criterion_service.rb +42 -0
- data/lib/adwords_api/v201306/campaign_criterion_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/campaign_feed_service.rb +38 -0
- data/lib/adwords_api/v201306/campaign_feed_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/campaign_service.rb +42 -0
- data/lib/adwords_api/v201306/campaign_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/campaign_shared_set_service.rb +38 -0
- data/lib/adwords_api/v201306/campaign_shared_set_service_registry.rb +47 -0
- data/lib/adwords_api/v201306/constant_data_service.rb +62 -0
- data/lib/adwords_api/v201306/constant_data_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/conversion_tracker_service.rb +38 -0
- data/lib/adwords_api/v201306/conversion_tracker_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/customer_service.rb +34 -0
- data/lib/adwords_api/v201306/customer_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/customer_sync_service.rb +34 -0
- data/lib/adwords_api/v201306/customer_sync_service_registry.rb +47 -0
- data/lib/adwords_api/v201306/data_service.rb +38 -0
- data/lib/adwords_api/v201306/data_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/experiment_service.rb +38 -0
- data/lib/adwords_api/v201306/experiment_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/feed_item_service.rb +38 -0
- data/lib/adwords_api/v201306/feed_item_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/feed_mapping_service.rb +38 -0
- data/lib/adwords_api/v201306/feed_mapping_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/feed_service.rb +38 -0
- data/lib/adwords_api/v201306/feed_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/geo_location_service.rb +34 -0
- data/lib/adwords_api/v201306/geo_location_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/location_criterion_service.rb +34 -0
- data/lib/adwords_api/v201306/location_criterion_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/managed_customer_service.rb +50 -0
- data/lib/adwords_api/v201306/managed_customer_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/media_service.rb +38 -0
- data/lib/adwords_api/v201306/media_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/mutate_job_service.rb +42 -0
- data/lib/adwords_api/v201306/mutate_job_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/report_definition_service.rb +34 -0
- data/lib/adwords_api/v201306/report_definition_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/shared_criterion_service.rb +38 -0
- data/lib/adwords_api/v201306/shared_criterion_service_registry.rb +47 -0
- data/lib/adwords_api/v201306/shared_set_service.rb +38 -0
- data/lib/adwords_api/v201306/shared_set_service_registry.rb +47 -0
- data/lib/adwords_api/v201306/targeting_idea_service.rb +38 -0
- data/lib/adwords_api/v201306/targeting_idea_service_registry.rb +46 -0
- data/lib/adwords_api/v201306/traffic_estimator_service.rb +34 -0
- data/lib/adwords_api/v201306/traffic_estimator_service_registry.rb +46 -0
- data/lib/adwords_api/version.rb +1 -1
- data/test/adwords_api/test_adwords_api.rb +1 -1
- data/test/adwords_api/test_api_config.rb +8 -8
- data/test/adwords_api/test_report_utils.rb +1 -1
- data/test/bugs/test_issue_00000031.rb +2 -2
- data/test/bugs/test_issue_00000063.rb +6 -6
- data/test/suite_exampletests_v201302.rb +1 -1
- data/test/suite_exampletests_v201306.rb +37 -0
- data/test/templates/v201209/basic_operations_get_campaigns.def +1 -1
- data/test/templates/v201302/basic_operations_get_campaigns.def +1 -1
- data/test/templates/v201302/misc_use_oauth2_jwt.def +1 -1
- data/test/templates/v201306/basic_operations_get_campaigns.def +114 -0
- data/test/templates/v201306/misc_use_oauth2_jwt.def +131 -0
- metadata +142 -5
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# Encoding: utf-8
|
|
3
|
+
#
|
|
4
|
+
# Author:: api.sgomes@gmail.com (Sérgio Gomes)
|
|
5
|
+
#
|
|
6
|
+
# Copyright:: Copyright 2011, Google Inc. All Rights Reserved.
|
|
7
|
+
#
|
|
8
|
+
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
# you may not use this file except in compliance with the License.
|
|
10
|
+
# You may obtain a copy of the License at
|
|
11
|
+
#
|
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
#
|
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
17
|
+
# implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
# This example demonstrates how to handle policy violation errors. To create
|
|
22
|
+
# an ad group, run add_ad_group.rb.
|
|
23
|
+
#
|
|
24
|
+
# Tags: AdGroupAdService.mutate
|
|
25
|
+
|
|
26
|
+
require 'adwords_api'
|
|
27
|
+
require 'adwords_api/utils'
|
|
28
|
+
|
|
29
|
+
def handle_policy_violation_error(ad_group_id)
|
|
30
|
+
# AdwordsApi::Api will read a config file from ENV['HOME']/adwords_api.yml
|
|
31
|
+
# when called without parameters.
|
|
32
|
+
adwords = AdwordsApi::Api.new
|
|
33
|
+
|
|
34
|
+
# To enable logging of SOAP requests, set the log_level value to 'DEBUG' in
|
|
35
|
+
# the configuration file or provide your own logger:
|
|
36
|
+
# adwords.logger = Logger.new('adwords_xml.log')
|
|
37
|
+
|
|
38
|
+
ad_group_ad_srv = adwords.service(:AdGroupAdService, API_VERSION)
|
|
39
|
+
|
|
40
|
+
# Create text ad.
|
|
41
|
+
text_ad_operation = {
|
|
42
|
+
:operator => 'ADD',
|
|
43
|
+
:operand => {
|
|
44
|
+
:ad_group_id => ad_group_id,
|
|
45
|
+
:ad => {
|
|
46
|
+
# The 'xsi_type' field allows you to specify the xsi:type of the object
|
|
47
|
+
# being created. It's only necessary when you must provide an explicit
|
|
48
|
+
# type that the client library can't infer.
|
|
49
|
+
:xsi_type => 'TextAd',
|
|
50
|
+
:headline => 'Mars Cruise!!!',
|
|
51
|
+
:description1 => 'Visit the Red Planet in style.',
|
|
52
|
+
:description2 => 'Low-gravity fun for everyone!',
|
|
53
|
+
:url => 'http://www.example.com',
|
|
54
|
+
:display_url => 'www.example.com',
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
operations = [text_ad_operation]
|
|
60
|
+
|
|
61
|
+
# Validate ad.
|
|
62
|
+
begin
|
|
63
|
+
# Enable "validate only" for the length of this block
|
|
64
|
+
adwords.validate_only do
|
|
65
|
+
ad_group_ad_srv.mutate(operations)
|
|
66
|
+
end
|
|
67
|
+
puts 'Validation successful, no errors returned.'
|
|
68
|
+
rescue AdwordsApi::Errors::ApiException => e
|
|
69
|
+
e.errors.each do |error|
|
|
70
|
+
if error[:xsi_type] == 'PolicyViolationError'
|
|
71
|
+
operation_index = AdwordsApi::Utils.operation_index_for_error(error)
|
|
72
|
+
operation = operations[operation_index]
|
|
73
|
+
puts "Ad with headline '%s' violated %s policy '%s'." %
|
|
74
|
+
[operation[:operand][:ad][:headline],
|
|
75
|
+
error[:is_exemptable] ? 'exemptable' : 'non-exemptable',
|
|
76
|
+
error[:external_policy_name]]
|
|
77
|
+
if error[:is_exemptable]
|
|
78
|
+
# Add exemption request to the operation.
|
|
79
|
+
puts "Adding exemption request for policy name '%s' on text '%s'." %
|
|
80
|
+
[error[:key][:policy_name], error[:key][:violating_text]]
|
|
81
|
+
unless operation[:exemption_requests]
|
|
82
|
+
operation[:exemption_requests] = []
|
|
83
|
+
end
|
|
84
|
+
operation[:exemption_requests] << {
|
|
85
|
+
:key => error[:key]
|
|
86
|
+
}
|
|
87
|
+
else
|
|
88
|
+
# Remove non-exemptable operation
|
|
89
|
+
puts "Removing the operation from the request."
|
|
90
|
+
operations.delete(operation)
|
|
91
|
+
end
|
|
92
|
+
else
|
|
93
|
+
# Non-policy error returned, re-throw exception.
|
|
94
|
+
raise e
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Add ads.
|
|
100
|
+
if operations.size > 0
|
|
101
|
+
response = ad_group_ad_srv.mutate(operations)
|
|
102
|
+
if response and response[:value]
|
|
103
|
+
ads = response[:value]
|
|
104
|
+
puts "Added #{ads.length} ad(s) to ad group #{ad_group_id}."
|
|
105
|
+
ads.each do |ad|
|
|
106
|
+
puts " Ad id is #{ad[:ad][:id]}, type is #{ad[:ad][:xsi_type]} and " +
|
|
107
|
+
"status is \"#{ad[:status]}\"."
|
|
108
|
+
end
|
|
109
|
+
else
|
|
110
|
+
puts "No ads were added."
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
if __FILE__ == $0
|
|
116
|
+
API_VERSION = :v201306
|
|
117
|
+
|
|
118
|
+
begin
|
|
119
|
+
ad_group_id = 'INSERT_AD_GROUP_ID_HERE'.to_i
|
|
120
|
+
handle_policy_violation_error(ad_group_id)
|
|
121
|
+
|
|
122
|
+
# Authorization error.
|
|
123
|
+
rescue AdsCommon::Errors::OAuth2VerificationRequired => e
|
|
124
|
+
puts "Authorization credentials are not valid. Edit adwords_api.yml for " +
|
|
125
|
+
"OAuth2 client ID and secret and run misc/setup_oauth2.rb example " +
|
|
126
|
+
"to retrieve and store OAuth2 tokens."
|
|
127
|
+
puts "See this wiki page for more details:\n\n " +
|
|
128
|
+
'http://code.google.com/p/google-api-ads-ruby/wiki/OAuth2'
|
|
129
|
+
|
|
130
|
+
# HTTP errors.
|
|
131
|
+
rescue AdsCommon::Errors::HttpError => e
|
|
132
|
+
puts "HTTP Error: %s" % e
|
|
133
|
+
|
|
134
|
+
# API errors.
|
|
135
|
+
rescue AdwordsApi::Errors::ApiException => e
|
|
136
|
+
puts "Message: %s" % e.message
|
|
137
|
+
puts 'Errors:'
|
|
138
|
+
e.errors.each_with_index do |error, index|
|
|
139
|
+
puts "\tError [%d]:" % (index + 1)
|
|
140
|
+
error.each do |field, value|
|
|
141
|
+
puts "\t\t%s: %s" % [field, value]
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# Encoding: utf-8
|
|
3
|
+
#
|
|
4
|
+
# Author:: api.dklimkin@gmail.com (Danial Klimkin)
|
|
5
|
+
#
|
|
6
|
+
# Copyright:: Copyright 2011, Google Inc. All Rights Reserved.
|
|
7
|
+
#
|
|
8
|
+
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
# you may not use this file except in compliance with the License.
|
|
10
|
+
# You may obtain a copy of the License at
|
|
11
|
+
#
|
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
#
|
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
17
|
+
# implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
# This example illustrates how to handle 'two factor' authorization error.
|
|
22
|
+
|
|
23
|
+
require 'adwords_api'
|
|
24
|
+
|
|
25
|
+
def handle_two_factor_authorization_error()
|
|
26
|
+
# Set up credentials with an account that has 2Factor enabled.
|
|
27
|
+
config = {
|
|
28
|
+
:authentication => {
|
|
29
|
+
:method => 'ClientLogin',
|
|
30
|
+
:email => '2steptester@gmail.com',
|
|
31
|
+
:password => 'testaccount',
|
|
32
|
+
:user_agent => 'Ruby 2 Factor Sample',
|
|
33
|
+
:developer_token => 'qwerty'
|
|
34
|
+
},
|
|
35
|
+
:service => {
|
|
36
|
+
:environment => 'PRODUCTION'
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
adwords = AdwordsApi::Api.new(config)
|
|
40
|
+
|
|
41
|
+
# To enable logging of SOAP requests, set the log_level value to 'DEBUG' in
|
|
42
|
+
# the configuration file or provide your own logger:
|
|
43
|
+
# adwords.logger = Logger.new('adwords_xml.log')
|
|
44
|
+
|
|
45
|
+
begin
|
|
46
|
+
# Forcing library to request authorization token.
|
|
47
|
+
auth_token = adwords.authorize()
|
|
48
|
+
puts 'Successfully retrieved the token.'
|
|
49
|
+
|
|
50
|
+
# Second factor error is one of AuthErrors.
|
|
51
|
+
rescue AdsCommon::Errors::AuthError => e
|
|
52
|
+
puts "Authorization failed with message:"
|
|
53
|
+
puts "\t%s" % e.message
|
|
54
|
+
# Checking 'Info' field for particular auth error type.
|
|
55
|
+
if e.info and e.info.casecmp('InvalidSecondFactor') == 0
|
|
56
|
+
puts "The user has enabled two factor authentication in this account." +
|
|
57
|
+
" Please use OAuth authentication method or have the user generate an" +
|
|
58
|
+
" application-specific password to make calls against the AdWords" +
|
|
59
|
+
" API. See \n" +
|
|
60
|
+
" http://adwordsapi.blogspot.com/2011/02/authentication-changes-with" +
|
|
61
|
+
"-2-step.html\n" +
|
|
62
|
+
"for more details."
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
if __FILE__ == $0
|
|
68
|
+
API_VERSION = :v201306
|
|
69
|
+
|
|
70
|
+
begin
|
|
71
|
+
handle_two_factor_authorization_error()
|
|
72
|
+
|
|
73
|
+
# HTTP errors.
|
|
74
|
+
rescue AdsCommon::Errors::HttpError => e
|
|
75
|
+
puts "HTTP Error: %s" % e
|
|
76
|
+
|
|
77
|
+
# API errors.
|
|
78
|
+
rescue AdwordsApi::Errors::ApiException => e
|
|
79
|
+
puts "Message: %s" % e.message
|
|
80
|
+
puts 'Errors:'
|
|
81
|
+
e.errors.each_with_index do |error, index|
|
|
82
|
+
puts "\tError [%d]:" % (index + 1)
|
|
83
|
+
error.each do |field, value|
|
|
84
|
+
puts "\t\t%s: %s" % [field, value]
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# Encoding: utf-8
|
|
3
|
+
#
|
|
4
|
+
# Author:: api.dklimkin@gmail.com (Danial Klimkin)
|
|
5
|
+
#
|
|
6
|
+
# Copyright:: Copyright 2013, Google Inc. All Rights Reserved.
|
|
7
|
+
#
|
|
8
|
+
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
# you may not use this file except in compliance with the License.
|
|
10
|
+
# You may obtain a copy of the License at
|
|
11
|
+
#
|
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
#
|
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
17
|
+
# implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
# This example migrates legacy sitelinks to upgraded sitelinks for a given list
|
|
22
|
+
# of campaigns. The campaigns must be upgraded to enhanced campaigns before you
|
|
23
|
+
# can run this example. To upgrade a campaign to enhanced, run
|
|
24
|
+
# set_campaign_enhanced.rb. To get all campaigns, run get_campaigns.rb.
|
|
25
|
+
#
|
|
26
|
+
# Tags: CampaignAdExtensionService.get, CampaignAdExtensionService.mutate
|
|
27
|
+
# Tags: FeedService.mutate, FeedItemService.mutate, FeedMappingService.mutate
|
|
28
|
+
# Tags: CampaignFeedService.mutate
|
|
29
|
+
|
|
30
|
+
require 'adwords_api'
|
|
31
|
+
|
|
32
|
+
def upgrade_legacy_sitelinks(campaign_ids)
|
|
33
|
+
# AdwordsApi::Api will read a config file from ENV['HOME']/adwords_api.yml
|
|
34
|
+
# when called without parameters.
|
|
35
|
+
adwords = AdwordsApi::Api.new
|
|
36
|
+
|
|
37
|
+
# To enable logging of SOAP requests, set the log_level value to 'DEBUG' in
|
|
38
|
+
# the configuration file or provide your own logger:
|
|
39
|
+
# adwords.logger = Logger.new('adwords_xml.log')
|
|
40
|
+
|
|
41
|
+
# Obtain the required services.
|
|
42
|
+
campaign_ad_extension_srv =
|
|
43
|
+
adwords.service(:CampaignAdExtensionService, API_VERSION)
|
|
44
|
+
feed_mapping_srv = adwords.service(:FeedMappingService, API_VERSION)
|
|
45
|
+
feed_srv = adwords.service(:FeedService, API_VERSION)
|
|
46
|
+
feed_item_srv = adwords.service(:FeedItemService, API_VERSION)
|
|
47
|
+
campaign_feed_srv = adwords.service(:CampaignFeedService, API_VERSION)
|
|
48
|
+
|
|
49
|
+
# Try to retrieve an existing feed that has been mapped for use with
|
|
50
|
+
# sitelinks. If multiple such feeds exist, the first matching feed is
|
|
51
|
+
# retrieved. You could modify this code example to retrieve all the feeds
|
|
52
|
+
# and pick the appropriate feed based on user input.
|
|
53
|
+
site_links_feed = get_existing_feed(feed_mapping_srv)
|
|
54
|
+
if site_links_feed.nil?
|
|
55
|
+
# Create a feed for storing sitelinks.
|
|
56
|
+
site_links_feed = create_site_links_feed(feed_srv)
|
|
57
|
+
# Map the feed for using with sitelinks.
|
|
58
|
+
create_site_links_feed_mapping(feed_mapping_srv, site_links_feed)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
campaign_ids.each do |campaign_id|
|
|
62
|
+
# Get legacy extensions for the campaign.
|
|
63
|
+
legacy_extensions = get_legacy_extensions_for_campaign(
|
|
64
|
+
campaign_ad_extension_srv, campaign_id)
|
|
65
|
+
legacy_extensions.each do |extension|
|
|
66
|
+
# Get the sitelinks.
|
|
67
|
+
legacy_site_links = extension[:ad_extension][:sitelinks]
|
|
68
|
+
|
|
69
|
+
# Add the sitelinks to the feed.
|
|
70
|
+
site_link_feed_item_ids = create_site_link_feed_items(feed_item_srv,
|
|
71
|
+
site_links_feed,
|
|
72
|
+
legacy_site_links)
|
|
73
|
+
|
|
74
|
+
# Associate feeditems to the campaign.
|
|
75
|
+
associate_sitelink_feed_items_with_campaign(campaign_feed_srv,
|
|
76
|
+
site_links_feed,
|
|
77
|
+
site_link_feed_item_ids,
|
|
78
|
+
campaign_id)
|
|
79
|
+
|
|
80
|
+
# Once the upgraded sitelinks are added to a campaign, the legacy
|
|
81
|
+
# sitelinks will stop serving. You can delete the legacy sitelinks
|
|
82
|
+
# once you have verified that the migration went fine. In case the
|
|
83
|
+
# migration didn't succeed, you can roll back the migration by deleting
|
|
84
|
+
# the campaign feed you created in the previous step.
|
|
85
|
+
campaign_ad_extension_srv.mutate([
|
|
86
|
+
{:operator => 'REMOVE', :operand => extension}
|
|
87
|
+
])
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Create a feed for holding upgraded sitelinks.
|
|
93
|
+
def create_site_links_feed(feed_srv)
|
|
94
|
+
# Create the feed.
|
|
95
|
+
site_links_feed = {
|
|
96
|
+
:name => 'Feed For Sitelinks',
|
|
97
|
+
:attributes => [
|
|
98
|
+
{:type => 'STRING', :name => 'Link Text'},
|
|
99
|
+
{:type => 'URL', :name => 'Link URL'}
|
|
100
|
+
],
|
|
101
|
+
:origin => 'USER'
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
# Add the feed.
|
|
105
|
+
response = feed_srv.mutate([
|
|
106
|
+
{:operator => 'ADD', :operand => site_links_feed}
|
|
107
|
+
])
|
|
108
|
+
|
|
109
|
+
saved_feed = response[:value].first
|
|
110
|
+
return {
|
|
111
|
+
:site_links_feed_id => saved_feed[:id],
|
|
112
|
+
:saved_attributes => saved_feed[:attributes],
|
|
113
|
+
:link_text_feed_attribute_id => saved_feed[:attributes][0][:id],
|
|
114
|
+
:link_url_feed_attribute_id => saved_feed[:attributes][1][:id]
|
|
115
|
+
}
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Map the feed for use with Sitelinks.
|
|
119
|
+
def create_site_links_feed_mapping(feed_mapping_srv, site_links_feed)
|
|
120
|
+
# Map the feedAttributeIds to the fieldId constants.
|
|
121
|
+
link_text_field_mapping = {
|
|
122
|
+
:feed_attribute_id => site_links_feed[:link_text_feed_attribute_id],
|
|
123
|
+
:field_id => PLACEHOLDER_FIELD_SITELINK_TEXT
|
|
124
|
+
}
|
|
125
|
+
link_url_field_mapping = {
|
|
126
|
+
:feed_attribute_id => site_links_feed[:link_url_feed_attribute_id],
|
|
127
|
+
:field_id => PLACEHOLDER_FIELD_SITELINK_URL
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
# Create the field mapping.
|
|
131
|
+
feed_mapping = {
|
|
132
|
+
:placeholder_type => PLACEHOLDER_SITELINKS,
|
|
133
|
+
:feed_id => site_links_feed[:site_links_feed_id],
|
|
134
|
+
:attribute_field_mappings =>
|
|
135
|
+
[link_text_field_mapping, link_url_field_mapping]
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
# Save the field mapping.
|
|
139
|
+
feed_mapping_srv.mutate([{:operator => 'ADD', :operand => feed_mapping}])
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Retrieves an existing feed that is mapped to hold sitelinks. The first active
|
|
143
|
+
# sitelinks feed is retrieved by this method.
|
|
144
|
+
def get_existing_feed(feed_mapping_srv)
|
|
145
|
+
selector = {
|
|
146
|
+
:fields => ['FeedId', 'FeedMappingId', 'PlaceholderType', 'Status',
|
|
147
|
+
'AttributeFieldMappings'],
|
|
148
|
+
:predicates => [
|
|
149
|
+
{
|
|
150
|
+
:field => 'PlaceholderType',
|
|
151
|
+
:operator => 'EQUALS',
|
|
152
|
+
:values => [PLACEHOLDER_SITELINKS]
|
|
153
|
+
},
|
|
154
|
+
{:field => 'Status', :operator => 'EQUALS', :values => ['ACTIVE']}
|
|
155
|
+
]
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
response = feed_mapping_srv.get(selector)
|
|
159
|
+
if response and response[:entries]
|
|
160
|
+
response[:entries].each do |feed_mapping|
|
|
161
|
+
feed_id = feed_mapping[:feed_id]
|
|
162
|
+
text_attribute_id = nil
|
|
163
|
+
url_attribute_id = nil
|
|
164
|
+
feed_mapping[:attribute_field_mappings].each do |attribute_mapping|
|
|
165
|
+
case attribute_mapping[:field_id].to_i
|
|
166
|
+
when PLACEHOLDER_FIELD_SITELINK_TEXT
|
|
167
|
+
text_attribute_id = attribute_mapping[:feed_attribute_id]
|
|
168
|
+
when PLACEHOLDER_FIELD_SITELINK_URL
|
|
169
|
+
url_attribute_id = attribute_mapping[:feed_attribute_id]
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
unless feed_id.nil? or text_attribute_id.nil? or url_attribute_id.nil?
|
|
173
|
+
return {
|
|
174
|
+
:site_links_feed_id => feed_id,
|
|
175
|
+
:link_text_feed_attribute_id => text_attribute_id,
|
|
176
|
+
:link_url_feed_attribute_id => url_attribute_id
|
|
177
|
+
}
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
return nil
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Gets legacy sitelink extensions for a campaign.
|
|
185
|
+
def get_legacy_extensions_for_campaign(campaign_ad_extension_srv, campaign_id)
|
|
186
|
+
# Create the selector.
|
|
187
|
+
selector = {
|
|
188
|
+
:fields => ['CampaignId', 'AdExtensionId',
|
|
189
|
+
'Status', 'DisplayText', 'DestinationUrl'],
|
|
190
|
+
:predicates => [
|
|
191
|
+
# Filter the results for specified campaign id.
|
|
192
|
+
{:field => 'CampaignId', :operator => 'EQUALS', :values => [campaign_id]},
|
|
193
|
+
# Filter the results for active campaign ad extensions. You may add
|
|
194
|
+
# additional filtering conditions here as required.
|
|
195
|
+
{:field => 'Status', :operator => 'EQUALS', :values => ['ACTIVE']},
|
|
196
|
+
{
|
|
197
|
+
:field => 'AdExtensionType',
|
|
198
|
+
:operator => 'EQUALS',
|
|
199
|
+
:values => ['SITELINKS_EXTENSION']
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
}
|
|
203
|
+
response = campaign_ad_extension_srv.get(selector)
|
|
204
|
+
return (response and response[:entries]) ? response[:entries] : []
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Adds legacy sitelinks to the sitelinks feed.
|
|
208
|
+
def create_site_link_feed_items(feed_item_srv, site_links_feed, site_links)
|
|
209
|
+
# Create operation for adding each legacy sitelink to the sitelinks feed.
|
|
210
|
+
feed_item_operations = site_links.map do |site_link|
|
|
211
|
+
{
|
|
212
|
+
:operator => 'ADD',
|
|
213
|
+
:operand => {
|
|
214
|
+
:feed_id => site_links_feed[:site_links_feed_id],
|
|
215
|
+
:attribute_values => [
|
|
216
|
+
{
|
|
217
|
+
:feed_attribute_id => site_links_feed[:link_text_feed_attribute_id],
|
|
218
|
+
:string_value => site_link[:display_text]
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
:feed_attribute_id => site_links_feed[:link_url_feed_attribute_id],
|
|
222
|
+
:string_value => site_link[:destination_url]
|
|
223
|
+
}
|
|
224
|
+
]
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
response = feed_item_srv.mutate(feed_item_operations);
|
|
230
|
+
# Retrieve the feed item ids.
|
|
231
|
+
site_link_feed_item_ids = response[:value].map {|item| item[:feed_item_id]}
|
|
232
|
+
return site_link_feed_item_ids
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# Associates sitelink feed items with a campaign.
|
|
236
|
+
def associate_sitelink_feed_items_with_campaign(campaign_feed_srv,
|
|
237
|
+
site_links_feed, site_link_feed_item_ids, campaign_id)
|
|
238
|
+
# Create a custom matching function that matches the given feed items to the
|
|
239
|
+
# campaign.
|
|
240
|
+
request_context_operand = {
|
|
241
|
+
:xsi_type => 'RequestContextOperand',
|
|
242
|
+
:context_type => 'FEED_ITEM_ID'
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
operands = site_link_feed_item_ids.map do |feed_item_id|
|
|
246
|
+
{
|
|
247
|
+
:xsi_type => 'ConstantOperand',
|
|
248
|
+
:long_value => feed_item_id,
|
|
249
|
+
:type => 'LONG'
|
|
250
|
+
}
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
function = {
|
|
254
|
+
:operator => 'IN',
|
|
255
|
+
:lhs_operand => [request_context_operand],
|
|
256
|
+
:rhs_operand => operands
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
# Create upgraded sitelinks for the campaign. Use the sitelinks feed we
|
|
260
|
+
# created, and restrict feed items by matching function.
|
|
261
|
+
campaign_feed = {
|
|
262
|
+
:feed_id => site_links_feed[:site_links_feed_id],
|
|
263
|
+
:campaign_id => campaign_id,
|
|
264
|
+
:matching_function => function,
|
|
265
|
+
:placeholder_types => [PLACEHOLDER_SITELINKS]
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
campaign_feed_srv.mutate([{:operator => 'ADD', :operand => campaign_feed}])
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
if __FILE__ == $0
|
|
272
|
+
API_VERSION = :v201306
|
|
273
|
+
|
|
274
|
+
# See the Placeholder reference page for a list of all the placeholder types
|
|
275
|
+
# and fields, see:
|
|
276
|
+
# https://developers.google.com/adwords/api/docs/appendix/placeholders
|
|
277
|
+
PLACEHOLDER_SITELINKS = 1
|
|
278
|
+
PLACEHOLDER_FIELD_SITELINK_TEXT = 1
|
|
279
|
+
PLACEHOLDER_FIELD_SITELINK_URL = 2
|
|
280
|
+
|
|
281
|
+
begin
|
|
282
|
+
# IDs of campaigns to add upgrade legacy sitelinks for.
|
|
283
|
+
campaign_ids = [
|
|
284
|
+
'INSERT_CAMPAIGN_ID_HERE'.to_i,
|
|
285
|
+
'INSERT_CAMPAIGN_ID_HERE'.to_i
|
|
286
|
+
]
|
|
287
|
+
|
|
288
|
+
upgrade_legacy_sitelinks(campaign_ids)
|
|
289
|
+
|
|
290
|
+
# Authorization error.
|
|
291
|
+
rescue AdsCommon::Errors::OAuth2VerificationRequired => e
|
|
292
|
+
puts "Authorization credentials are not valid. Edit adwords_api.yml for " +
|
|
293
|
+
"OAuth2 client ID and secret and run misc/setup_oauth2.rb example " +
|
|
294
|
+
"to retrieve and store OAuth2 tokens."
|
|
295
|
+
puts "See this wiki page for more details:\n\n " +
|
|
296
|
+
'http://code.google.com/p/google-api-ads-ruby/wiki/OAuth2'
|
|
297
|
+
|
|
298
|
+
# HTTP errors.
|
|
299
|
+
rescue AdsCommon::Errors::HttpError => e
|
|
300
|
+
puts "HTTP Error: %s" % e
|
|
301
|
+
|
|
302
|
+
# API errors.
|
|
303
|
+
rescue AdwordsApi::Errors::ApiException => e
|
|
304
|
+
puts "Message: %s" % e.message
|
|
305
|
+
puts 'Errors:'
|
|
306
|
+
e.errors.each_with_index do |error, index|
|
|
307
|
+
puts "\tError [%d]:" % (index + 1)
|
|
308
|
+
error.each do |field, value|
|
|
309
|
+
puts "\t\t%s: %s" % [field, value]
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
end
|