google-adwords-api 0.21.0 → 0.21.1

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.
Files changed (188) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +5 -0
  3. data/examples/v201603/shopping_campaigns/add_product_scope.rb +3 -2
  4. data/examples/v201605/shopping_campaigns/add_product_scope.rb +3 -2
  5. data/examples/v201607/shopping_campaigns/add_product_scope.rb +3 -2
  6. data/examples/v201609/account_management/create_account.rb +88 -0
  7. data/examples/v201609/account_management/get_account_changes.rb +135 -0
  8. data/examples/v201609/account_management/get_account_hierarchy.rb +132 -0
  9. data/examples/v201609/advanced_operations/add_ad_customizers.rb +183 -0
  10. data/examples/v201609/advanced_operations/add_ad_group_bid_modifier.rb +101 -0
  11. data/examples/v201609/advanced_operations/add_click_to_download_ad.rb +148 -0
  12. data/examples/v201609/advanced_operations/add_expanded_text_ad_with_upgraded_urls.rb +132 -0
  13. data/examples/v201609/advanced_operations/add_html5_ad.rb +137 -0
  14. data/examples/v201609/advanced_operations/add_responsive_display_ad.rb +130 -0
  15. data/examples/v201609/advanced_operations/add_universal_app_campaign.rb +215 -0
  16. data/examples/v201609/advanced_operations/create_and_attach_shared_keyword_set.rb +141 -0
  17. data/examples/v201609/advanced_operations/find_and_remove_criteria_from_shared_set.rb +174 -0
  18. data/examples/v201609/advanced_operations/get_ad_group_bid_modifiers.rb +102 -0
  19. data/examples/v201609/advanced_operations/use_portfolio_bidding_strategy.rb +146 -0
  20. data/examples/v201609/basic_operations/add_ad_groups.rb +142 -0
  21. data/examples/v201609/basic_operations/add_campaigns.rb +138 -0
  22. data/examples/v201609/basic_operations/add_expanded_text_ads.rb +108 -0
  23. data/examples/v201609/basic_operations/add_keywords.rb +114 -0
  24. data/examples/v201609/basic_operations/get_ad_groups.rb +102 -0
  25. data/examples/v201609/basic_operations/get_campaigns.rb +97 -0
  26. data/examples/v201609/basic_operations/get_campaigns_with_awql.rb +89 -0
  27. data/examples/v201609/basic_operations/get_expanded_text_ads.rb +122 -0
  28. data/examples/v201609/basic_operations/get_keywords.rb +109 -0
  29. data/examples/v201609/basic_operations/get_text_ads.rb +109 -0
  30. data/examples/v201609/basic_operations/pause_ad.rb +87 -0
  31. data/examples/v201609/basic_operations/remove_ad.rb +89 -0
  32. data/examples/v201609/basic_operations/remove_ad_group.rb +85 -0
  33. data/examples/v201609/basic_operations/remove_campaign.rb +87 -0
  34. data/examples/v201609/basic_operations/remove_keyword.rb +94 -0
  35. data/examples/v201609/basic_operations/update_ad_group.rb +85 -0
  36. data/examples/v201609/basic_operations/update_campaign.rb +86 -0
  37. data/examples/v201609/basic_operations/update_keyword.rb +106 -0
  38. data/examples/v201609/campaign_management/add_campaign_labels.rb +82 -0
  39. data/examples/v201609/campaign_management/add_complete_campaigns_using_batch_job.rb +354 -0
  40. data/examples/v201609/campaign_management/add_draft.rb +113 -0
  41. data/examples/v201609/campaign_management/add_keywords_using_incremental_batch_job.rb +210 -0
  42. data/examples/v201609/campaign_management/add_trial.rb +141 -0
  43. data/examples/v201609/campaign_management/get_all_disapproved_ads.rb +97 -0
  44. data/examples/v201609/campaign_management/get_all_disapproved_ads_with_awql.rb +89 -0
  45. data/examples/v201609/campaign_management/get_campaigns_by_label.rb +108 -0
  46. data/examples/v201609/campaign_management/graduate_trial.rb +106 -0
  47. data/examples/v201609/campaign_management/set_ad_parameters.rb +118 -0
  48. data/examples/v201609/campaign_management/set_criterion_bid_modifier.rb +104 -0
  49. data/examples/v201609/campaign_management/validate_text_ad.rb +109 -0
  50. data/examples/v201609/error_handling/handle_partial_failures.rb +130 -0
  51. data/examples/v201609/error_handling/handle_policy_violation_error.rb +141 -0
  52. data/examples/v201609/extensions/add_google_my_business_location_extensions.rb +193 -0
  53. data/examples/v201609/extensions/add_prices.rb +162 -0
  54. data/examples/v201609/extensions/add_site_links.rb +199 -0
  55. data/examples/v201609/extensions/add_site_links_using_feeds.rb +286 -0
  56. data/examples/v201609/migration/migrate_to_extension_settings.rb +386 -0
  57. data/examples/v201609/misc/get_all_images_and_videos.rb +104 -0
  58. data/examples/v201609/misc/setup_oauth2.rb +84 -0
  59. data/examples/v201609/misc/upload_image.rb +93 -0
  60. data/examples/v201609/misc/upload_media_bundle.rb +90 -0
  61. data/examples/v201609/misc/use_oauth2_jwt.rb +93 -0
  62. data/examples/v201609/misc/use_runtime_config.rb +92 -0
  63. data/examples/v201609/optimization/estimate_keyword_traffic.rb +191 -0
  64. data/examples/v201609/optimization/get_campaign_criterion_bid_modifier_simulations.rb +128 -0
  65. data/examples/v201609/optimization/get_keyword_bid_simulations.rb +95 -0
  66. data/examples/v201609/optimization/get_keyword_ideas.rb +136 -0
  67. data/examples/v201609/remarketing/add_audience.rb +118 -0
  68. data/examples/v201609/remarketing/add_conversion_tracker.rb +97 -0
  69. data/examples/v201609/remarketing/add_crm_based_user_list.rb +116 -0
  70. data/examples/v201609/remarketing/add_rule_based_user_lists.rb +167 -0
  71. data/examples/v201609/remarketing/upload_offline_call_conversions.rb +111 -0
  72. data/examples/v201609/remarketing/upload_offline_conversions.rb +98 -0
  73. data/examples/v201609/reporting/download_criteria_report.rb +92 -0
  74. data/examples/v201609/reporting/download_criteria_report_with_awql.rb +93 -0
  75. data/examples/v201609/reporting/get_report_fields.rb +75 -0
  76. data/examples/v201609/reporting/parallel_report_download.rb +164 -0
  77. data/examples/v201609/reporting/stream_criteria_report_results.rb +97 -0
  78. data/examples/v201609/shopping_campaigns/add_product_partition_tree.rb +267 -0
  79. data/examples/v201609/shopping_campaigns/add_product_scope.rb +130 -0
  80. data/examples/v201609/shopping_campaigns/add_shopping_campaign.rb +129 -0
  81. data/examples/v201609/shopping_campaigns/get_product_category_taxonomy.rb +115 -0
  82. data/examples/v201609/targeting/add_campaign_targeting_criteria.rb +166 -0
  83. data/examples/v201609/targeting/add_demographic_targeting_criteria.rb +112 -0
  84. data/examples/v201609/targeting/get_campaign_targeting_criteria.rb +106 -0
  85. data/examples/v201609/targeting/get_targetable_languages_and_carriers.rb +89 -0
  86. data/examples/v201609/targeting/lookup_location.rb +108 -0
  87. data/lib/adwords_api/api_config.rb +96 -4
  88. data/lib/adwords_api/batch_job_utils.rb +6 -0
  89. data/lib/adwords_api/report_utils.rb +9 -4
  90. data/lib/adwords_api/v201609/account_label_service.rb +46 -0
  91. data/lib/adwords_api/v201609/account_label_service_registry.rb +46 -0
  92. data/lib/adwords_api/v201609/ad_customizer_feed_service.rb +46 -0
  93. data/lib/adwords_api/v201609/ad_customizer_feed_service_registry.rb +46 -0
  94. data/lib/adwords_api/v201609/ad_group_ad_service.rb +70 -0
  95. data/lib/adwords_api/v201609/ad_group_ad_service_registry.rb +46 -0
  96. data/lib/adwords_api/v201609/ad_group_bid_modifier_service.rb +54 -0
  97. data/lib/adwords_api/v201609/ad_group_bid_modifier_service_registry.rb +46 -0
  98. data/lib/adwords_api/v201609/ad_group_criterion_service.rb +62 -0
  99. data/lib/adwords_api/v201609/ad_group_criterion_service_registry.rb +46 -0
  100. data/lib/adwords_api/v201609/ad_group_extension_setting_service.rb +54 -0
  101. data/lib/adwords_api/v201609/ad_group_extension_setting_service_registry.rb +46 -0
  102. data/lib/adwords_api/v201609/ad_group_feed_service.rb +54 -0
  103. data/lib/adwords_api/v201609/ad_group_feed_service_registry.rb +46 -0
  104. data/lib/adwords_api/v201609/ad_group_service.rb +62 -0
  105. data/lib/adwords_api/v201609/ad_group_service_registry.rb +46 -0
  106. data/lib/adwords_api/v201609/ad_param_service.rb +46 -0
  107. data/lib/adwords_api/v201609/ad_param_service_registry.rb +46 -0
  108. data/lib/adwords_api/v201609/adwords_user_list_service.rb +62 -0
  109. data/lib/adwords_api/v201609/adwords_user_list_service_registry.rb +46 -0
  110. data/lib/adwords_api/v201609/batch_job_service.rb +54 -0
  111. data/lib/adwords_api/v201609/batch_job_service_registry.rb +46 -0
  112. data/lib/adwords_api/v201609/bidding_strategy_service.rb +54 -0
  113. data/lib/adwords_api/v201609/bidding_strategy_service_registry.rb +46 -0
  114. data/lib/adwords_api/v201609/budget_order_service.rb +54 -0
  115. data/lib/adwords_api/v201609/budget_order_service_registry.rb +46 -0
  116. data/lib/adwords_api/v201609/budget_service.rb +54 -0
  117. data/lib/adwords_api/v201609/budget_service_registry.rb +46 -0
  118. data/lib/adwords_api/v201609/campaign_criterion_service.rb +54 -0
  119. data/lib/adwords_api/v201609/campaign_criterion_service_registry.rb +46 -0
  120. data/lib/adwords_api/v201609/campaign_extension_setting_service.rb +54 -0
  121. data/lib/adwords_api/v201609/campaign_extension_setting_service_registry.rb +46 -0
  122. data/lib/adwords_api/v201609/campaign_feed_service.rb +54 -0
  123. data/lib/adwords_api/v201609/campaign_feed_service_registry.rb +46 -0
  124. data/lib/adwords_api/v201609/campaign_service.rb +62 -0
  125. data/lib/adwords_api/v201609/campaign_service_registry.rb +46 -0
  126. data/lib/adwords_api/v201609/campaign_shared_set_service.rb +54 -0
  127. data/lib/adwords_api/v201609/campaign_shared_set_service_registry.rb +46 -0
  128. data/lib/adwords_api/v201609/constant_data_service.rb +110 -0
  129. data/lib/adwords_api/v201609/constant_data_service_registry.rb +46 -0
  130. data/lib/adwords_api/v201609/conversion_tracker_service.rb +54 -0
  131. data/lib/adwords_api/v201609/conversion_tracker_service_registry.rb +46 -0
  132. data/lib/adwords_api/v201609/customer_extension_setting_service.rb +54 -0
  133. data/lib/adwords_api/v201609/customer_extension_setting_service_registry.rb +46 -0
  134. data/lib/adwords_api/v201609/customer_feed_service.rb +54 -0
  135. data/lib/adwords_api/v201609/customer_feed_service_registry.rb +46 -0
  136. data/lib/adwords_api/v201609/customer_service.rb +62 -0
  137. data/lib/adwords_api/v201609/customer_service_registry.rb +46 -0
  138. data/lib/adwords_api/v201609/customer_sync_service.rb +38 -0
  139. data/lib/adwords_api/v201609/customer_sync_service_registry.rb +47 -0
  140. data/lib/adwords_api/v201609/data_service.rb +94 -0
  141. data/lib/adwords_api/v201609/data_service_registry.rb +46 -0
  142. data/lib/adwords_api/v201609/draft_async_error_service.rb +46 -0
  143. data/lib/adwords_api/v201609/draft_async_error_service_registry.rb +46 -0
  144. data/lib/adwords_api/v201609/draft_service.rb +54 -0
  145. data/lib/adwords_api/v201609/draft_service_registry.rb +46 -0
  146. data/lib/adwords_api/v201609/feed_item_service.rb +54 -0
  147. data/lib/adwords_api/v201609/feed_item_service_registry.rb +46 -0
  148. data/lib/adwords_api/v201609/feed_mapping_service.rb +54 -0
  149. data/lib/adwords_api/v201609/feed_mapping_service_registry.rb +46 -0
  150. data/lib/adwords_api/v201609/feed_service.rb +54 -0
  151. data/lib/adwords_api/v201609/feed_service_registry.rb +46 -0
  152. data/lib/adwords_api/v201609/label_service.rb +54 -0
  153. data/lib/adwords_api/v201609/label_service_registry.rb +46 -0
  154. data/lib/adwords_api/v201609/location_criterion_service.rb +46 -0
  155. data/lib/adwords_api/v201609/location_criterion_service_registry.rb +46 -0
  156. data/lib/adwords_api/v201609/managed_customer_service.rb +78 -0
  157. data/lib/adwords_api/v201609/managed_customer_service_registry.rb +46 -0
  158. data/lib/adwords_api/v201609/media_service.rb +54 -0
  159. data/lib/adwords_api/v201609/media_service_registry.rb +46 -0
  160. data/lib/adwords_api/v201609/offline_call_conversion_feed_service.rb +38 -0
  161. data/lib/adwords_api/v201609/offline_call_conversion_feed_service_registry.rb +46 -0
  162. data/lib/adwords_api/v201609/offline_conversion_feed_service.rb +38 -0
  163. data/lib/adwords_api/v201609/offline_conversion_feed_service_registry.rb +46 -0
  164. data/lib/adwords_api/v201609/report_definition_service.rb +38 -0
  165. data/lib/adwords_api/v201609/report_definition_service_registry.rb +46 -0
  166. data/lib/adwords_api/v201609/shared_criterion_service.rb +54 -0
  167. data/lib/adwords_api/v201609/shared_criterion_service_registry.rb +46 -0
  168. data/lib/adwords_api/v201609/shared_set_service.rb +54 -0
  169. data/lib/adwords_api/v201609/shared_set_service_registry.rb +46 -0
  170. data/lib/adwords_api/v201609/targeting_idea_service.rb +38 -0
  171. data/lib/adwords_api/v201609/targeting_idea_service_registry.rb +46 -0
  172. data/lib/adwords_api/v201609/traffic_estimator_service.rb +38 -0
  173. data/lib/adwords_api/v201609/traffic_estimator_service_registry.rb +46 -0
  174. data/lib/adwords_api/v201609/trial_async_error_service.rb +46 -0
  175. data/lib/adwords_api/v201609/trial_async_error_service_registry.rb +46 -0
  176. data/lib/adwords_api/v201609/trial_service.rb +54 -0
  177. data/lib/adwords_api/v201609/trial_service_registry.rb +46 -0
  178. data/lib/adwords_api/version.rb +1 -1
  179. data/test/adwords_api/test_adwords_api.rb +1 -1
  180. data/test/adwords_api/test_api_config.rb +8 -8
  181. data/test/adwords_api/test_batch_job_utils.rb +2 -2
  182. data/test/adwords_api/test_choices.rb +2 -2
  183. data/test/adwords_api/test_report_stream.rb +1 -1
  184. data/test/adwords_api/test_report_utils.rb +1 -1
  185. data/test/templates/v201609/basic_operations_get_campaigns.def +116 -0
  186. data/test/templates/v201609/basic_operations_update_keyword.def +125 -0
  187. data/test/templates/v201609/misc_use_oauth2_jwt.def +131 -0
  188. metadata +174 -2
@@ -0,0 +1,354 @@
1
+ #!/usr/bin/env ruby
2
+ # Encoding: utf-8
3
+ #
4
+ # Copyright:: Copyright 2015, Google Inc. All Rights Reserved.
5
+ #
6
+ # License:: Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15
+ # implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ # This code sample illustrates how to use BatchJobService to create a complete
20
+ # campaign, including ad groups and keywords.
21
+
22
+ require 'adwords_api'
23
+
24
+ def add_complete_campaigns_using_batch_job()
25
+ # AdwordsApi::Api will read a config file from ENV['HOME']/adwords_api.yml
26
+ # when called without parameters.
27
+ adwords = AdwordsApi::Api.new
28
+
29
+ # To enable logging of SOAP requests, set the log_level value to 'DEBUG' in
30
+ # the configuration file or provide your own logger:
31
+ # adwords.logger = Logger.new('adwords_xml.log')
32
+
33
+ batch_job_srv = adwords.service(:BatchJobService, API_VERSION)
34
+ batch_job_utils = adwords.batch_job_utils(API_VERSION)
35
+
36
+ # Create a BatchJob.
37
+ add_op = {
38
+ :operator => 'ADD',
39
+ :operand => {}
40
+ }
41
+
42
+ response = batch_job_srv.mutate([add_op])
43
+ batch_job = response[:value].first
44
+
45
+ # Get the upload URL from the new job.
46
+ upload_url = batch_job[:upload_url][:url]
47
+ puts "Created BatchJob with ID %d, status '%s', and upload URL %s." %
48
+ [batch_job[:id], batch_job[:status], upload_url]
49
+
50
+ # Create a temporary ID generator that will produce a sequence of descending
51
+ # negative numbers.
52
+ temp_id_generator = TempIdGenerator.new()
53
+
54
+ # Create an array of hashed operations generated from the batch_job_utils.
55
+ operations = []
56
+
57
+ # Create an operation to create a new budget.
58
+ budget_operation = build_budget_operation(temp_id_generator)
59
+ operations << budget_operation
60
+
61
+ # Create operations to create new campaigns.
62
+ campaign_operations = build_campaign_operations(
63
+ temp_id_generator, budget_operation)
64
+ operations += campaign_operations
65
+
66
+ # Create operations to create new negative keyword criteria for each
67
+ # campaign.
68
+ operations += build_campaign_criterion_operations(campaign_operations)
69
+
70
+ # Create operations to create new ad groups.
71
+ ad_group_operations = build_ad_group_operations(
72
+ temp_id_generator, campaign_operations)
73
+ operations += ad_group_operations
74
+
75
+ # Create operations to create new ad group criteria (keywords).
76
+ operations += build_ad_group_criterion_operations(ad_group_operations)
77
+
78
+ # Create operations to create new ad group ads (text ads).
79
+ operations += build_ad_group_ad_operations(ad_group_operations)
80
+
81
+ # Use the batch_job_utils to upload all operations.
82
+ batch_job_utils.upload_operations(operations, upload_url)
83
+ puts "Uploaded %d operations for batch job with ID %d." %
84
+ [operations.size, batch_job[:id]]
85
+
86
+ # Poll for completion of the batch job using an exponential back off.
87
+ poll_attempts = 0
88
+ is_pending = true
89
+ selector = {
90
+ :fields => ['Id', 'Status', 'DownloadUrl', 'ProcessingErrors',
91
+ 'ProgressStats'],
92
+ :predicates => [{
93
+ :field => 'Id',
94
+ :operator => 'IN',
95
+ :values => [batch_job[:id]]
96
+ }]
97
+ }
98
+
99
+ begin
100
+ sleep_seconds = 30 * (2 ** poll_attempts)
101
+ puts "Sleeping for %d seconds" % sleep_seconds
102
+ sleep(sleep_seconds)
103
+
104
+ batch_job = batch_job_srv.get(selector)[:entries].first
105
+
106
+ puts "Batch job ID %d has status '%s'." %
107
+ [batch_job[:id], batch_job[:status]]
108
+
109
+ poll_attempts += 1
110
+ is_pending = PENDING_STATUSES.include?(batch_job[:status])
111
+ end while is_pending and poll_attempts < MAX_POLL_ATTEMPTS
112
+
113
+ if is_pending
114
+ raise StandardError,
115
+ "Job is still in pending state after polling %d times." %
116
+ MAX_POLL_ATTEMPTS
117
+ end
118
+
119
+ unless batch_job[:processing_errors].nil?
120
+ batch_job[:processing_errors].each_with_index do |processing_error, i|
121
+ puts ("Processing error [%d]: errorType=%s, trigger=%s, errorString=%s" +
122
+ "fieldPath=%s, reason=%s") % [i, processing_error[:api_error_type],
123
+ processing_error[:trigger], processing_error[:error_string],
124
+ processing_error[:field_path], processing_error[:reason]]
125
+ end
126
+ end
127
+
128
+ unless batch_job[:download_url].nil? or batch_job[:download_url][:url].nil?
129
+ mutate_response = batch_job_utils.get_job_results(
130
+ batch_job[:download_url][:url])
131
+ puts "Downloaded results from '%s':" % batch_job[:download_url][:url]
132
+ mutate_response.each do |mutate_result|
133
+ outcome = "FAILURE"
134
+ outcome = "SUCCESS" if mutate_result[:error_list].nil?
135
+ puts " Operation [%d] - %s" % [mutate_result[:index], outcome]
136
+ end
137
+ end
138
+ end
139
+
140
+ # Custom class to generate temporary negative IDs for created entities to
141
+ # reference each other.
142
+ class TempIdGenerator
143
+ def initialize()
144
+ @counter = -1
145
+ end
146
+
147
+ def next()
148
+ ret = @counter
149
+ @counter -= 1
150
+ return ret
151
+ end
152
+ end
153
+
154
+ def get_time_microseconds()
155
+ return (Time.now.to_f * 1000000).to_i
156
+ end
157
+
158
+ def build_budget_operation(temp_id_generator)
159
+ budget = {
160
+ :budget_id => temp_id_generator.next,
161
+ :name => "Interplanetary Cruise %d" % get_time_microseconds(),
162
+ :amount => {
163
+ :micro_amount => 50000000
164
+ },
165
+ :delivery_method => 'STANDARD'
166
+ }
167
+ budget_operation = {
168
+ # The xsi_type of the operation can usually be guessed by the API because
169
+ # a given service only handles one type of operation. However, batch jobs
170
+ # process operations of different types, so the xsi_type must always be
171
+ # explicitly defined for these operations.
172
+ :xsi_type => 'BudgetOperation',
173
+ :operator => 'ADD',
174
+ :operand => budget
175
+ }
176
+ return budget_operation
177
+ end
178
+
179
+ def build_campaign_operations(temp_id_generator, budget_operation)
180
+ budget_id = budget_operation[:operand][:budget_id]
181
+
182
+ operations = []
183
+ NUMBER_OF_CAMPAIGNS_TO_ADD.times do
184
+ campaign = {
185
+ :name => "Batch Campaign %s" % get_time_microseconds(),
186
+ :status => 'PAUSED',
187
+ :id => temp_id_generator.next,
188
+ :advertising_channel_type => 'SEARCH',
189
+ :budget => {
190
+ :budget_id => budget_id
191
+ },
192
+ :bidding_strategy_configuration => {
193
+ :bidding_strategy_type => 'MANUAL_CPC',
194
+ # You can optionally provide a bidding scheme in place of the type.
195
+ :bidding_scheme => {
196
+ :xsi_type => 'ManualCpcBiddingScheme',
197
+ :enhanced_cpc_enabled => false
198
+ }
199
+ }
200
+ }
201
+ operation = {
202
+ :xsi_type => 'CampaignOperation',
203
+ :operator => 'ADD',
204
+ :operand => campaign
205
+ }
206
+ operations << operation
207
+ end
208
+
209
+ return operations
210
+ end
211
+
212
+ def build_campaign_criterion_operations(campaign_operations)
213
+ operations = []
214
+ campaign_operations.each do |campaign_operation|
215
+ keyword = {
216
+ :xsi_type => 'Keyword',
217
+ :match_type => 'BROAD',
218
+ :text => 'venus'
219
+ }
220
+ negative_criterion = {
221
+ :xsi_type => 'NegativeCampaignCriterion',
222
+ :campaign_id => campaign_operation[:operand][:id],
223
+ :criterion => keyword
224
+ }
225
+ operation = {
226
+ :xsi_type => 'CampaignCriterionOperation',
227
+ :operator => 'ADD',
228
+ :operand => negative_criterion
229
+ }
230
+ operations << operation
231
+ end
232
+
233
+ return operations
234
+ end
235
+
236
+ def build_ad_group_operations(temp_id_generator, campaign_operations)
237
+ operations = []
238
+ campaign_operations.each do |campaign_operation|
239
+ NUMBER_OF_ADGROUPS_TO_ADD.times do
240
+ ad_group = {
241
+ :campaign_id => campaign_operation[:operand][:id],
242
+ :id => temp_id_generator.next,
243
+ :name => "Batch Ad Group %s" % get_time_microseconds(),
244
+ :bidding_strategy_configuration => {
245
+ :bids => [
246
+ {
247
+ :xsi_type => 'CpcBid',
248
+ :bid => {:micro_amount => 10000000}
249
+ }
250
+ ]
251
+ }
252
+ }
253
+ operation = {
254
+ :xsi_type => 'AdGroupOperation',
255
+ :operator => 'ADD',
256
+ :operand => ad_group
257
+ }
258
+ operations << operation
259
+ end
260
+ end
261
+
262
+ return operations
263
+ end
264
+
265
+ def build_ad_group_criterion_operations(ad_group_operations)
266
+ operations = []
267
+ ad_group_operations.each do |ad_group_operation|
268
+ NUMBER_OF_KEYWORDS_TO_ADD.times do |i|
269
+ text = "mars%d" % i
270
+
271
+ # Make 50% of keywords invalid to demonstrate error handling.
272
+ text = text + "!!!" if i % 2 == 0
273
+ keyword = {
274
+ :xsi_type => 'Keyword',
275
+ :text => text,
276
+ :match_type => 'BROAD'
277
+ }
278
+ biddable_criterion = {
279
+ :xsi_type => 'BiddableAdGroupCriterion',
280
+ :ad_group_id => ad_group_operation[:operand][:id],
281
+ :criterion => keyword
282
+ }
283
+ operation = {
284
+ :xsi_type => 'AdGroupCriterionOperation',
285
+ :operator => 'ADD',
286
+ :operand => biddable_criterion
287
+ }
288
+ operations << operation
289
+ end
290
+ end
291
+
292
+ return operations
293
+ end
294
+
295
+ def build_ad_group_ad_operations(ad_group_operations)
296
+ operations = []
297
+ ad_group_operations.each do |ad_group_operation|
298
+ text_ad = {
299
+ :xsi_type => 'ExpandedTextAd',
300
+ :headline_part1 => 'Luxury Cruise to Mars',
301
+ :headling_part2 => 'Visit the Red Planet in style.',
302
+ :description => 'Low-gravity fun for everyone!',
303
+ :final_urls => ['http://www.example.com/1']
304
+ }
305
+ ad_group_ad = {
306
+ :ad_group_id => ad_group_operation[:operand][:id],
307
+ :ad => text_ad
308
+ }
309
+ operation = {
310
+ :xsi_type => 'AdGroupAdOperation',
311
+ :operator => 'ADD',
312
+ :operand => ad_group_ad
313
+ }
314
+ operations << operation
315
+ end
316
+
317
+ return operations
318
+ end
319
+
320
+ if __FILE__ == $0
321
+ API_VERSION = :v201609
322
+ NUMBER_OF_CAMPAIGNS_TO_ADD = 2
323
+ NUMBER_OF_ADGROUPS_TO_ADD = 2
324
+ NUMBER_OF_KEYWORDS_TO_ADD = 5
325
+ MAX_POLL_ATTEMPTS = 5
326
+ PENDING_STATUSES = ['ACTIVE', 'AWAITING_FILE', 'CANCELING']
327
+
328
+ begin
329
+ add_complete_campaigns_using_batch_job()
330
+
331
+ # Authorization error.
332
+ rescue AdsCommon::Errors::OAuth2VerificationRequired => e
333
+ puts "Authorization credentials are not valid. Edit adwords_api.yml for " +
334
+ "OAuth2 client ID and secret and run misc/setup_oauth2.rb example " +
335
+ "to retrieve and store OAuth2 tokens."
336
+ puts "See this wiki page for more details:\n\n " +
337
+ 'https://github.com/googleads/google-api-ads-ruby/wiki/OAuth2'
338
+
339
+ # HTTP errors.
340
+ rescue AdsCommon::Errors::HttpError => e
341
+ puts "HTTP Error: %s" % e
342
+
343
+ # API errors.
344
+ rescue AdwordsApi::Errors::ApiException => e
345
+ puts "Message: %s" % e.message
346
+ puts 'Errors:'
347
+ e.errors.each_with_index do |error, index|
348
+ puts "\tError [%d]:" % (index + 1)
349
+ error.each do |field, value|
350
+ puts "\t\t%s: %s" % [field, value]
351
+ end
352
+ end
353
+ end
354
+ end
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env ruby
2
+ # Encoding: utf-8
3
+ #
4
+ # Copyright:: Copyright 2016, Google Inc. All Rights Reserved.
5
+ #
6
+ # License:: Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15
+ # implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ # This example illustrates how to create a draft and access its associated
20
+ # draft campaign.
21
+ #
22
+ # See the Campaign Drafts and Experiments guide for more information:
23
+ # https://developers.google.com/adwords/api/docs/guides/campaign-drafts-experiments
24
+
25
+ require 'adwords_api'
26
+ require 'date'
27
+
28
+ def add_draft(base_campaign_id)
29
+ # AdwordsApi::Api will read a config file from ENV['HOME']/adwords_api.yml
30
+ # when called without parameters.
31
+ adwords = AdwordsApi::Api.new
32
+
33
+ # To enable logging of SOAP requests, set the log_level value to 'DEBUG' in
34
+ # the configuration file or provide your own logger:
35
+ # adwords.logger = Logger.new('adwords_xml.log')
36
+
37
+ draft_srv = adwords.service(:DraftService, API_VERSION)
38
+
39
+ draft = {
40
+ :base_campaign_id => base_campaign_id,
41
+ :draft_name => 'Test Draft #%d' % (Time.new.to_f * 1000).to_i
42
+ }
43
+ draft_operation = {:operator => 'ADD', :operand => draft}
44
+
45
+ draft_result = draft_srv.mutate([draft_operation])
46
+
47
+ draft = draft_result[:value].first
48
+ draft_id = draft[:draft_id]
49
+ draft_campaign_id = draft[:draft_campaign_id]
50
+
51
+ puts "Draft with id %d and base campaign %d and draft campaign %d created" %
52
+ [draft_id, draft[:base_campaign_id], draft_campaign_id]
53
+
54
+ # Once the draft is created, you can modify the draft campaign as if it
55
+ # were a real campaign. For example, you may add criteria, adjust bids,
56
+ # or even include additional ads. Adding a criterion is shown here.
57
+ campaign_criterion_srv =
58
+ adwords.service(:CampaignCriterionService, API_VERSION)
59
+
60
+ criterion = {
61
+ :xsi_type => 'Language',
62
+ :id => 1003 # Spanish
63
+ }
64
+
65
+ criterion_operation = {
66
+ # Make sure to use the draft_campaign_id when modifying the virtual draft
67
+ # campaign.
68
+ :operator => 'ADD',
69
+ :operand => {
70
+ :campaign_id => draft_campaign_id,
71
+ :criterion => criterion
72
+ }
73
+ }
74
+
75
+ criterion_result = campaign_criterion_srv.mutate([criterion_operation])
76
+
77
+ criterion = criterion_result[:value].first
78
+
79
+ puts "Draft updated to include criteria in campaign %d" % draft_campaign_id
80
+ end
81
+
82
+ if __FILE__ == $0
83
+ API_VERSION = :v201609
84
+
85
+ begin
86
+ base_campaign_id = 'INSERT_BASE_CAMPAIGN_ID_HERE'.to_i
87
+
88
+ add_draft(base_campaign_id)
89
+
90
+ # Authorization error.
91
+ rescue AdsCommon::Errors::OAuth2VerificationRequired => e
92
+ puts "Authorization credentials are not valid. Edit adwords_api.yml for " +
93
+ "OAuth2 client ID and secret and run misc/setup_oauth2.rb example " +
94
+ "to retrieve and store OAuth2 tokens."
95
+ puts "See this wiki page for more details:\n\n " +
96
+ 'https://github.com/googleads/google-api-ads-ruby/wiki/OAuth2'
97
+
98
+ # HTTP errors.
99
+ rescue AdsCommon::Errors::HttpError => e
100
+ puts "HTTP Error: %s" % e
101
+
102
+ # API errors.
103
+ rescue AdwordsApi::Errors::ApiException => e
104
+ puts "Message: %s" % e.message
105
+ puts 'Errors:'
106
+ e.errors.each_with_index do |error, index|
107
+ puts "\tError [%d]:" % (index + 1)
108
+ error.each do |field, value|
109
+ puts "\t\t%s: %s" % [field, value]
110
+ end
111
+ end
112
+ end
113
+ end