google-adwords-api 0.12.1 → 0.13.0

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 (157) hide show
  1. checksums.yaml +8 -8
  2. data/ChangeLog +3 -0
  3. data/examples/v201402/basic_operations/delete_ad_group.rb +1 -22
  4. data/examples/{v201309/basic_operations/delete_ad_group.rb → v201402/basic_operations/delete_ad_group.rb~} +2 -8
  5. data/examples/v201402/basic_operations/delete_campaign.rb +2 -23
  6. data/examples/{v201309/basic_operations/update_campaign.rb → v201402/basic_operations/delete_campaign.rb~} +13 -12
  7. data/examples/v201406/basic_operations/remove_ad_group.rb +1 -22
  8. data/examples/{v201309/basic_operations/update_ad_group.rb → v201406/basic_operations/remove_ad_group.rb~} +14 -13
  9. data/examples/v201406/basic_operations/remove_campaign.rb +4 -24
  10. data/examples/{v201309/basic_operations/delete_campaign.rb → v201406/basic_operations/remove_campaign.rb~} +11 -11
  11. data/lib/adwords_api.rb +5 -8
  12. data/lib/adwords_api/api_config.rb +0 -76
  13. data/lib/adwords_api/report_utils.rb +9 -0
  14. data/lib/adwords_api/report_utils.rb~ +283 -0
  15. data/lib/adwords_api/version.rb +1 -1
  16. data/lib/adwords_api/version.rb~ +26 -0
  17. data/test/adwords_api/test_adwords_api.rb +5 -21
  18. data/test/adwords_api/test_adwords_api.rb~ +114 -0
  19. data/test/adwords_api/test_api_config.rb +8 -8
  20. data/test/adwords_api/test_report_utils.rb +29 -1
  21. data/test/adwords_api/test_report_utils.rb~ +216 -0
  22. data/test/templates/{v201309 → v201402}/basic_operations_get_campaigns.def +7 -7
  23. data/test/templates/{v201309 → v201402}/misc_use_oauth2_jwt.def +7 -7
  24. data/test/templates/v201406/basic_operations_get_campaigns.def +114 -0
  25. data/test/templates/v201406/misc_use_oauth2_jwt.def +131 -0
  26. metadata +14 -139
  27. data/examples/v201309/account_management/create_account.rb +0 -95
  28. data/examples/v201309/account_management/get_account_alerts.rb +0 -122
  29. data/examples/v201309/account_management/get_account_changes.rb +0 -145
  30. data/examples/v201309/account_management/get_account_hierarchy.rb +0 -103
  31. data/examples/v201309/advanced_operations/add_ad_group_bid_modifier.rb +0 -105
  32. data/examples/v201309/advanced_operations/add_click_to_download_ad.rb +0 -137
  33. data/examples/v201309/advanced_operations/add_site_links.rb +0 -306
  34. data/examples/v201309/advanced_operations/create_and_attach_shared_keyword_set.rb +0 -147
  35. data/examples/v201309/advanced_operations/find_and_remove_criteria_from_shared_set.rb +0 -181
  36. data/examples/v201309/advanced_operations/get_ad_group_bid_modifiers.rb +0 -106
  37. data/examples/v201309/advanced_operations/update_site_links.rb +0 -194
  38. data/examples/v201309/advanced_operations/upload_offline_conversions.rb +0 -117
  39. data/examples/v201309/advanced_operations/use_shared_bidding_strategy.rb +0 -163
  40. data/examples/v201309/basic_operations/add_ad_groups.rb +0 -143
  41. data/examples/v201309/basic_operations/add_campaigns.rb +0 -162
  42. data/examples/v201309/basic_operations/add_keywords.rb +0 -116
  43. data/examples/v201309/basic_operations/add_text_ads.rb +0 -113
  44. data/examples/v201309/basic_operations/delete_ad.rb +0 -93
  45. data/examples/v201309/basic_operations/delete_keyword.rb +0 -98
  46. data/examples/v201309/basic_operations/get_ad_groups.rb +0 -106
  47. data/examples/v201309/basic_operations/get_campaigns.rb +0 -101
  48. data/examples/v201309/basic_operations/get_campaigns_with_awql.rb +0 -93
  49. data/examples/v201309/basic_operations/get_keywords.rb +0 -112
  50. data/examples/v201309/basic_operations/get_text_ads.rb +0 -114
  51. data/examples/v201309/basic_operations/pause_ad.rb +0 -92
  52. data/examples/v201309/basic_operations/update_keyword.rb +0 -110
  53. data/examples/v201309/campaign_management/add_experiment.rb +0 -166
  54. data/examples/v201309/campaign_management/add_keywords_in_bulk.rb +0 -158
  55. data/examples/v201309/campaign_management/add_location_extension.rb +0 -125
  56. data/examples/v201309/campaign_management/get_all_disapproved_ads.rb +0 -101
  57. data/examples/v201309/campaign_management/get_all_disapproved_ads_with_awql.rb +0 -93
  58. data/examples/v201309/campaign_management/promote_experiment.rb +0 -85
  59. data/examples/v201309/campaign_management/set_ad_parameters.rb +0 -122
  60. data/examples/v201309/campaign_management/set_criterion_bid_modifier.rb +0 -108
  61. data/examples/v201309/campaign_management/validate_text_ad.rb +0 -114
  62. data/examples/v201309/error_handling/handle_captcha_challenge.rb +0 -93
  63. data/examples/v201309/error_handling/handle_partial_failures.rb +0 -134
  64. data/examples/v201309/error_handling/handle_policy_violation_error.rb +0 -145
  65. data/examples/v201309/error_handling/handle_two_factor_authorization_error.rb +0 -88
  66. data/examples/v201309/misc/get_all_images_and_videos.rb +0 -108
  67. data/examples/v201309/misc/setup_oauth2.rb +0 -88
  68. data/examples/v201309/misc/upload_image.rb +0 -97
  69. data/examples/v201309/misc/use_oauth2_jwt.rb +0 -97
  70. data/examples/v201309/optimization/estimate_keyword_traffic.rb +0 -137
  71. data/examples/v201309/optimization/get_keyword_bid_simulations.rb +0 -100
  72. data/examples/v201309/optimization/get_keyword_ideas.rb +0 -130
  73. data/examples/v201309/optimization/get_placement_ideas.rb +0 -112
  74. data/examples/v201309/remarketing/add_audience.rb +0 -123
  75. data/examples/v201309/remarketing/add_conversion_tracker.rb +0 -104
  76. data/examples/v201309/reporting/download_criteria_report.rb +0 -87
  77. data/examples/v201309/reporting/download_criteria_report_with_awql.rb +0 -86
  78. data/examples/v201309/reporting/get_report_fields.rb +0 -79
  79. data/examples/v201309/reporting/parallel_report_download.rb +0 -171
  80. data/examples/v201309/targeting/add_campaign_targeting_criteria.rb +0 -123
  81. data/examples/v201309/targeting/add_demographic_targeting_criteria.rb +0 -116
  82. data/examples/v201309/targeting/get_campaign_targeting_criteria.rb +0 -110
  83. data/examples/v201309/targeting/get_targetable_languages_and_carriers.rb +0 -94
  84. data/examples/v201309/targeting/lookup_location.rb +0 -112
  85. data/lib/adwords_api/v201309/ad_group_ad_service.rb +0 -42
  86. data/lib/adwords_api/v201309/ad_group_ad_service_registry.rb +0 -46
  87. data/lib/adwords_api/v201309/ad_group_bid_modifier_service.rb +0 -38
  88. data/lib/adwords_api/v201309/ad_group_bid_modifier_service_registry.rb +0 -46
  89. data/lib/adwords_api/v201309/ad_group_criterion_service.rb +0 -42
  90. data/lib/adwords_api/v201309/ad_group_criterion_service_registry.rb +0 -46
  91. data/lib/adwords_api/v201309/ad_group_feed_service.rb +0 -38
  92. data/lib/adwords_api/v201309/ad_group_feed_service_registry.rb +0 -46
  93. data/lib/adwords_api/v201309/ad_group_service.rb +0 -42
  94. data/lib/adwords_api/v201309/ad_group_service_registry.rb +0 -46
  95. data/lib/adwords_api/v201309/ad_param_service.rb +0 -38
  96. data/lib/adwords_api/v201309/ad_param_service_registry.rb +0 -46
  97. data/lib/adwords_api/v201309/adwords_user_list_service.rb +0 -38
  98. data/lib/adwords_api/v201309/adwords_user_list_service_registry.rb +0 -46
  99. data/lib/adwords_api/v201309/alert_service.rb +0 -34
  100. data/lib/adwords_api/v201309/alert_service_registry.rb +0 -46
  101. data/lib/adwords_api/v201309/bidding_strategy_service.rb +0 -38
  102. data/lib/adwords_api/v201309/bidding_strategy_service_registry.rb +0 -46
  103. data/lib/adwords_api/v201309/budget_order_service.rb +0 -42
  104. data/lib/adwords_api/v201309/budget_order_service_registry.rb +0 -46
  105. data/lib/adwords_api/v201309/budget_service.rb +0 -38
  106. data/lib/adwords_api/v201309/budget_service_registry.rb +0 -46
  107. data/lib/adwords_api/v201309/campaign_ad_extension_service.rb +0 -38
  108. data/lib/adwords_api/v201309/campaign_ad_extension_service_registry.rb +0 -46
  109. data/lib/adwords_api/v201309/campaign_criterion_service.rb +0 -42
  110. data/lib/adwords_api/v201309/campaign_criterion_service_registry.rb +0 -46
  111. data/lib/adwords_api/v201309/campaign_feed_service.rb +0 -38
  112. data/lib/adwords_api/v201309/campaign_feed_service_registry.rb +0 -46
  113. data/lib/adwords_api/v201309/campaign_service.rb +0 -42
  114. data/lib/adwords_api/v201309/campaign_service_registry.rb +0 -46
  115. data/lib/adwords_api/v201309/campaign_shared_set_service.rb +0 -38
  116. data/lib/adwords_api/v201309/campaign_shared_set_service_registry.rb +0 -47
  117. data/lib/adwords_api/v201309/constant_data_service.rb +0 -62
  118. data/lib/adwords_api/v201309/constant_data_service_registry.rb +0 -46
  119. data/lib/adwords_api/v201309/conversion_tracker_service.rb +0 -38
  120. data/lib/adwords_api/v201309/conversion_tracker_service_registry.rb +0 -46
  121. data/lib/adwords_api/v201309/customer_service.rb +0 -34
  122. data/lib/adwords_api/v201309/customer_service_registry.rb +0 -46
  123. data/lib/adwords_api/v201309/customer_sync_service.rb +0 -34
  124. data/lib/adwords_api/v201309/customer_sync_service_registry.rb +0 -47
  125. data/lib/adwords_api/v201309/data_service.rb +0 -38
  126. data/lib/adwords_api/v201309/data_service_registry.rb +0 -46
  127. data/lib/adwords_api/v201309/experiment_service.rb +0 -38
  128. data/lib/adwords_api/v201309/experiment_service_registry.rb +0 -46
  129. data/lib/adwords_api/v201309/feed_item_service.rb +0 -38
  130. data/lib/adwords_api/v201309/feed_item_service_registry.rb +0 -46
  131. data/lib/adwords_api/v201309/feed_mapping_service.rb +0 -38
  132. data/lib/adwords_api/v201309/feed_mapping_service_registry.rb +0 -46
  133. data/lib/adwords_api/v201309/feed_service.rb +0 -38
  134. data/lib/adwords_api/v201309/feed_service_registry.rb +0 -46
  135. data/lib/adwords_api/v201309/geo_location_service.rb +0 -34
  136. data/lib/adwords_api/v201309/geo_location_service_registry.rb +0 -46
  137. data/lib/adwords_api/v201309/location_criterion_service.rb +0 -34
  138. data/lib/adwords_api/v201309/location_criterion_service_registry.rb +0 -46
  139. data/lib/adwords_api/v201309/managed_customer_service.rb +0 -50
  140. data/lib/adwords_api/v201309/managed_customer_service_registry.rb +0 -46
  141. data/lib/adwords_api/v201309/media_service.rb +0 -38
  142. data/lib/adwords_api/v201309/media_service_registry.rb +0 -46
  143. data/lib/adwords_api/v201309/mutate_job_service.rb +0 -42
  144. data/lib/adwords_api/v201309/mutate_job_service_registry.rb +0 -46
  145. data/lib/adwords_api/v201309/offline_conversion_feed_service.rb +0 -34
  146. data/lib/adwords_api/v201309/offline_conversion_feed_service_registry.rb +0 -46
  147. data/lib/adwords_api/v201309/report_definition_service.rb +0 -34
  148. data/lib/adwords_api/v201309/report_definition_service_registry.rb +0 -46
  149. data/lib/adwords_api/v201309/shared_criterion_service.rb +0 -38
  150. data/lib/adwords_api/v201309/shared_criterion_service_registry.rb +0 -47
  151. data/lib/adwords_api/v201309/shared_set_service.rb +0 -38
  152. data/lib/adwords_api/v201309/shared_set_service_registry.rb +0 -47
  153. data/lib/adwords_api/v201309/targeting_idea_service.rb +0 -38
  154. data/lib/adwords_api/v201309/targeting_idea_service_registry.rb +0 -46
  155. data/lib/adwords_api/v201309/traffic_estimator_service.rb +0 -34
  156. data/lib/adwords_api/v201309/traffic_estimator_service_registry.rb +0 -46
  157. data/test/bugs/test_issue_00000031.rb +0 -75
data/lib/adwords_api.rb CHANGED
@@ -64,14 +64,11 @@ module AdwordsApi
64
64
  auth_method = @config.read('authentication.method', :OAUTH2)
65
65
  handler_class = case auth_method
66
66
  when :CLIENTLOGIN
67
- if version.to_s[/\d+/].to_i > 201309
68
- raise AdsCommon::Errors::AuthError,
69
- "ClientLogin is not supported for versions after v201309. " +
70
- "Please use OAuth2 instead. See here for details:\n\t\t" +
71
- "https://developers.google.com/adwords/api/" +
72
- "docs/guides/authentication"
73
- end
74
- AdwordsApi::ClientLoginHeaderHandler
67
+ raise AdsCommon::Errors::AuthError,
68
+ "ClientLogin is not supported. " +
69
+ "Please use OAuth2 instead. See here for details:\n\t\t" +
70
+ "https://developers.google.com/adwords/api/" +
71
+ "docs/guides/authentication"
75
72
  when :OAUTH2, :OAUTH2_JWT
76
73
  AdsCommon::SavonHeaders::OAuthHeaderHandler
77
74
  else
@@ -45,44 +45,6 @@ module AdwordsApi
45
45
 
46
46
  # Configure the services available to each version
47
47
  @@service_config = {
48
- :v201309 => [
49
- :AdGroupAdService,
50
- :AdGroupBidModifierService,
51
- :AdGroupCriterionService,
52
- :AdGroupFeedService,
53
- :AdGroupService,
54
- :AdParamService,
55
- :AdwordsUserListService,
56
- :AlertService,
57
- :BiddingStrategyService,
58
- :BudgetOrderService,
59
- :BudgetService,
60
- :CampaignAdExtensionService,
61
- :CampaignCriterionService,
62
- :CampaignFeedService,
63
- :CampaignService,
64
- :CampaignSharedSetService,
65
- :ConstantDataService,
66
- :ConversionTrackerService,
67
- :CustomerService,
68
- :CustomerSyncService,
69
- :DataService,
70
- :ExperimentService,
71
- :FeedItemService,
72
- :FeedMappingService,
73
- :FeedService,
74
- :GeoLocationService,
75
- :LocationCriterionService,
76
- :ManagedCustomerService,
77
- :MediaService,
78
- :MutateJobService,
79
- :OfflineConversionFeedService,
80
- :ReportDefinitionService,
81
- :SharedCriterionService,
82
- :SharedSetService,
83
- :TargetingIdeaService,
84
- :TrafficEstimatorService
85
- ],
86
48
  :v201402 => [
87
49
  :AdGroupAdService,
88
50
  :AdGroupBidModifierService,
@@ -169,7 +131,6 @@ module AdwordsApi
169
131
  :PRODUCTION => {
170
132
  :oauth_scope => 'https://www.googleapis.com/auth/adwords',
171
133
  :header_ns => 'https://adwords.google.com/api/adwords/cm/',
172
- :v201309 => 'https://adwords.google.com/api/adwords/',
173
134
  :v201402 => 'https://adwords.google.com/api/adwords/',
174
135
  :v201406 => 'https://adwords.google.com/api/adwords/'
175
136
  }
@@ -178,43 +139,6 @@ module AdwordsApi
178
139
  # Configure the subdirectories for each version / service pair.
179
140
  # A missing pair means that only the base URL is used.
180
141
  @@subdir_config = {
181
- # v201309
182
- [:v201309, :AdGroupAdService] => 'cm/',
183
- [:v201309, :AdGroupBidModifierService] => 'cm/',
184
- [:v201309, :AdGroupCriterionService] => 'cm/',
185
- [:v201309, :AdGroupFeedService] => 'cm/',
186
- [:v201309, :AdGroupService] => 'cm/',
187
- [:v201309, :AdParamService] => 'cm/',
188
- [:v201309, :AlertService] => 'mcm/',
189
- [:v201309, :BudgetOrderService] => 'billing/',
190
- [:v201309, :CampaignAdExtensionService] => 'cm/',
191
- [:v201309, :CampaignCriterionService] => 'cm/',
192
- [:v201309, :CampaignFeedService] => 'cm/',
193
- [:v201309, :CampaignService] => 'cm/',
194
- [:v201309, :CampaignSharedSetService] => 'cm/',
195
- [:v201309, :ConstantDataService] => 'cm/',
196
- [:v201309, :ConversionTrackerService] => 'cm/',
197
- [:v201309, :CustomerSyncService] => 'ch/',
198
- [:v201309, :DataService] => 'cm/',
199
- [:v201309, :ExperimentService] => 'cm/',
200
- [:v201309, :FeedItemService] => 'cm/',
201
- [:v201309, :FeedMappingService] => 'cm/',
202
- [:v201309, :FeedService] => 'cm/',
203
- [:v201309, :GeoLocationService] => 'cm/',
204
- [:v201309, :LocationCriterionService] => 'cm/',
205
- [:v201309, :MediaService] => 'cm/',
206
- [:v201309, :MutateJobService] => 'cm/',
207
- [:v201309, :OfflineConversionFeedService] => 'cm/',
208
- [:v201309, :ReportDefinitionService] => 'cm/',
209
- [:v201309, :SharedCriterionService] => 'cm/',
210
- [:v201309, :SharedSetService] => 'cm/',
211
- [:v201309, :TargetingIdeaService] => 'o/',
212
- [:v201309, :TrafficEstimatorService] => 'o/',
213
- [:v201309, :ManagedCustomerService] => 'mcm/',
214
- [:v201309, :CustomerService] => 'mcm/',
215
- [:v201309, :BudgetService] => 'cm/',
216
- [:v201309, :BiddingStrategyService] => 'cm/',
217
- [:v201309, :AdwordsUserListService] => 'rm/',
218
142
  # v201402
219
143
  [:v201402, :AdGroupAdService] => 'cm/',
220
144
  [:v201402, :AdGroupBidModifierService] => 'cm/',
@@ -249,6 +249,15 @@ module AdwordsApi
249
249
  raise AdwordsApi::Errors::InvalidReportDefinitionError,
250
250
  'At least one field needs to be requested'
251
251
  end
252
+ # returnMoneyInMicros option is no longer supported as of v201406
253
+ if report_definition.include?(:return_money_in_micros) &&
254
+ @version != :v201402
255
+ raise AdwordsApi::Errors::InvalidReportDefinitionError,
256
+ 'returnMoneyInMicros was sunset as of v201406. ' +
257
+ 'See the migration guide for info:' +
258
+ 'https://developers.google.com/adwords/api/docs/' +
259
+ 'guides/migration/v201406'
260
+ end
252
261
  end
253
262
 
254
263
  # Adds fields order hint to generator based on specification.
@@ -0,0 +1,283 @@
1
+ # Encoding: utf-8
2
+ #
3
+ # Author:: api.dklimkin@gmail.com (Danial Klimkin)
4
+ #
5
+ # Copyright:: Copyright 2011, Google Inc. All Rights Reserved.
6
+ #
7
+ # License:: Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16
+ # implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+ # Contains utility methods specific to reporting.
21
+
22
+ require 'cgi'
23
+ require 'gyoku'
24
+ require 'nori'
25
+
26
+ require 'ads_common/http'
27
+ require 'adwords_api/errors'
28
+ require 'adwords_api/report_header_handler'
29
+
30
+ module AdwordsApi
31
+ class ReportUtils
32
+ # Default constructor.
33
+ #
34
+ # Args:
35
+ # - api: AdwordsApi object
36
+ # - version: API version to use
37
+ #
38
+ def initialize(api, version)
39
+ @api, @version = api, version
40
+ end
41
+
42
+ # Downloads and returns a report.
43
+ #
44
+ # Args:
45
+ # - report_definition: definition of the report in XML text or hash
46
+ # - cid: optional customer ID to run against
47
+ #
48
+ # Returns:
49
+ # - report body
50
+ #
51
+ # Raises:
52
+ # - AdwordsApi::Errors::InvalidReportDefinitionError if the report
53
+ # definition is invalid
54
+ # - AdwordsApi::Errors::ReportError if server-side error occurred
55
+ #
56
+ def download_report(report_definition, cid = nil)
57
+ return get_report_response(report_definition, cid).body
58
+ end
59
+
60
+ # Downloads a report and saves it to a file.
61
+ #
62
+ # Args:
63
+ # - report_definition: definition of the report in XML text or hash
64
+ # - path: path to save report to
65
+ # - cid: optional customer ID to run against
66
+ #
67
+ # Returns:
68
+ # - nil
69
+ #
70
+ # Raises:
71
+ # - AdwordsApi::Errors::InvalidReportDefinitionError if the report
72
+ # definition is invalid
73
+ # - AdwordsApi::Errors::ReportError if server-side error occurred
74
+ #
75
+ def download_report_as_file(report_definition, path, cid = nil)
76
+ report_body = download_report(report_definition, cid)
77
+ save_to_file(report_body, path)
78
+ return nil
79
+ end
80
+
81
+ # Downloads and returns a report with AWQL.
82
+ #
83
+ # Args:
84
+ # - report_query: query for the report as string
85
+ # - format: format for the report as string
86
+ # - cid: optional customer ID to run report against
87
+ #
88
+ # Returns:
89
+ # - report body
90
+ #
91
+ # Raises:
92
+ # - AdwordsApi::Errors::ReportError if a server-side error has occurred
93
+ #
94
+ def download_report_with_awql(report_query, format, cid = nil)
95
+ return get_report_response_with_awql(report_query, format, cid).body
96
+ end
97
+
98
+ # Downloads a report with AWQL and saves it to a file.
99
+ #
100
+ # Args:
101
+ # - report_query: query for the report as string
102
+ # - format: format for the report as string
103
+ # - path: path to save report to
104
+ # - cid: optional customer ID to run report against
105
+ #
106
+ # Returns:
107
+ # - nil
108
+ #
109
+ # Raises:
110
+ # - AdwordsApi::Errors::ReportError if server-side error occurred
111
+ #
112
+ def download_report_as_file_with_awql(report_query, format, path, cid = nil)
113
+ report_body = download_report_with_awql(report_query, format, cid)
114
+ save_to_file(report_body, path)
115
+ return nil
116
+ end
117
+
118
+ private
119
+
120
+ # Minimal set of required fields for report definition.
121
+ REQUIRED_FIELDS = [:selector, :report_name, :report_type, :date_range_type]
122
+
123
+ # Definition fields have to be in particular order in the XML. Here is its
124
+ # specification.
125
+ REPORT_DEFINITION_ORDER = {
126
+ :root => [:selector, :report_name, :report_type, :date_range_type,
127
+ :download_format, :include_zero_impressions],
128
+ :selector => [:fields, :predicates, :date_range, :ordering, :paging],
129
+ :predicates => [:field, :operator, :values],
130
+ :ordering => [:field, :sort_order],
131
+ :paging => [:start_index, :number_results],
132
+ :date_range => [:min, :max]
133
+ }
134
+
135
+ # Send POST request for a report and returns Response object.
136
+ def get_report_response(report_definition, cid)
137
+ definition_text = get_report_definition_text(report_definition)
138
+ data = '__rdxml=%s' % CGI.escape(definition_text)
139
+ return make_adhoc_request(data, cid)
140
+ end
141
+
142
+ # Send POST request for a report with AWQL and returns Response object.
143
+ def get_report_response_with_awql(report_query, format, cid)
144
+ data = '__rdquery=%s&__fmt=%s' %
145
+ [CGI.escape(report_query), CGI.escape(format)]
146
+ return make_adhoc_request(data, cid)
147
+ end
148
+
149
+ # Makes request and AdHoc service and returns response.
150
+ def make_adhoc_request(data, cid)
151
+ url = @api.api_config.adhoc_report_download_url(
152
+ @api.config.read('service.environment'), @version)
153
+ headers = get_report_request_headers(url, cid)
154
+ log_request(url, headers, data)
155
+ response = AdsCommon::Http.post_response(url, data, @api.config, headers)
156
+ check_for_errors(response)
157
+ return response
158
+ end
159
+
160
+ # Converts passed object to XML text. Currently support String (no changes)
161
+ # and Hash (renders XML).
162
+ def get_report_definition_text(report_definition)
163
+ return case report_definition
164
+ when String then report_definition
165
+ when Hash then report_definition_to_xml(report_definition)
166
+ else
167
+ raise AdwordsApi::Errors::InvalidReportDefinitionError,
168
+ 'Unknown object for report definition: %s' %
169
+ report_definition.class
170
+ end
171
+ end
172
+
173
+ # Prepares headers for report request.
174
+ def get_report_request_headers(url, cid)
175
+ @header_handler ||= AdwordsApi::ReportHeaderHandler.new(
176
+ @api.credential_handler, @api.get_auth_handler(), @api.config)
177
+ return @header_handler.headers(url, cid)
178
+ end
179
+
180
+ # Saves raw data to a file.
181
+ def save_to_file(data, path)
182
+ open(path, 'wb') { |file| file.write(data) } if path
183
+ end
184
+
185
+ # Logs the request on debug level.
186
+ def log_request(url, headers, body)
187
+ logger = @api.logger
188
+ logger.debug("Report request to: '%s'" % url)
189
+ logger.debug('HTTP headers: [%s]' %
190
+ (headers.map { |k, v| [k, v].join(': ') }.join(', ')))
191
+ logger.debug(body)
192
+ end
193
+
194
+ # Checks downloaded data for error signature. Raises ReportError if it
195
+ # detects an error.
196
+ def check_for_errors(response)
197
+ # Check for error code.
198
+ if response.code != 200
199
+ # Check for error in body.
200
+ report_body = response.body
201
+ check_for_xml_error(report_body, response.code)
202
+ # No XML error found nor raised, falling back to a default message.
203
+ raise AdwordsApi::Errors::ReportError.new(response.code,
204
+ 'HTTP code: %d, body: %s' % [response.code, response.body])
205
+ end
206
+ return nil
207
+ end
208
+
209
+ # Checks for an XML error in the response body and raises an exception if
210
+ # it was found.
211
+ def check_for_xml_error(report_body, response_code)
212
+ error_response = Nori.parse(report_body)
213
+ if error_response.include?(:report_download_error) and
214
+ error_response[:report_download_error].include?(:api_error)
215
+ api_error = error_response[:report_download_error][:api_error]
216
+ raise AdwordsApi::Errors::ReportXmlError.new(response_code,
217
+ api_error[:type], api_error[:trigger], api_error[:field_path])
218
+ end
219
+ end
220
+
221
+ # Renders a report definition hash into XML text.
222
+ def report_definition_to_xml(report_definition)
223
+ check_report_definition_hash(report_definition)
224
+ add_report_definition_hash_order(report_definition)
225
+ return Gyoku.xml({:report_definition => report_definition})
226
+ end
227
+
228
+ # Checks if the report definition looks correct.
229
+ def check_report_definition_hash(report_definition)
230
+ # Minimal set of fields required.
231
+ REQUIRED_FIELDS.each do |field|
232
+ unless report_definition.include?(field)
233
+ raise AdwordsApi::Errors::InvalidReportDefinitionError,
234
+ "Required field '%s' is missing in the definition" % field
235
+ end
236
+ end
237
+ # Fields list is also required.
238
+ unless report_definition[:selector].include?(:fields)
239
+ raise AdwordsApi::Errors::InvalidReportDefinitionError,
240
+ 'Fields list is required'
241
+ end
242
+ # 'Fields' must be an Array.
243
+ unless report_definition[:selector][:fields].kind_of?(Array)
244
+ raise AdwordsApi::Errors::InvalidReportDefinitionError,
245
+ 'Fields list must be an array'
246
+ end
247
+ # We should request at least one field.
248
+ if report_definition[:selector][:fields].empty?
249
+ raise AdwordsApi::Errors::InvalidReportDefinitionError,
250
+ 'At least one field needs to be requested'
251
+ end
252
+ # returnMoneyInMicros option is no longer supported as of v201406
253
+ if report_definition.include?(:return_money_in_micros) &&
254
+ @version != :v201402
255
+ raise AdwordsApi::Errors::InvalidReportDefinitionError,
256
+ 'returnMoneyInMicros was sunset as of v201406. ' +
257
+ 'See the migration guide for info:' +
258
+ 'https://developers.google.com/adwords/api/docs/' +
259
+ 'guides/migration/v201406'
260
+ end
261
+ end
262
+
263
+ # Adds fields order hint to generator based on specification.
264
+ def add_report_definition_hash_order(node, name = :root)
265
+ def_order = REPORT_DEFINITION_ORDER[name]
266
+ var_order = def_order.reject { |field| !node.include?(field) }
267
+ node.keys.each do |key|
268
+ if REPORT_DEFINITION_ORDER.include?(key)
269
+ case node[key]
270
+ when Hash
271
+ add_report_definition_hash_order(node[key], key)
272
+ when Array
273
+ node[key].each do |item|
274
+ add_report_definition_hash_order(item, key)
275
+ end
276
+ end
277
+ end
278
+ end
279
+ node[:order!] = var_order
280
+ return nil
281
+ end
282
+ end
283
+ end
@@ -21,6 +21,6 @@
21
21
 
22
22
  module AdwordsApi
23
23
  module ApiConfig
24
- CLIENT_LIB_VERSION = '0.12.1'
24
+ CLIENT_LIB_VERSION = '0.13.0'
25
25
  end
26
26
  end
@@ -0,0 +1,26 @@
1
+ # Encoding: utf-8
2
+ #
3
+ # Authors:: api.dklimkin@gmail.com (Danial Klimkin)
4
+ #
5
+ # Copyright:: Copyright 2012, Google Inc. All Rights Reserved.
6
+ #
7
+ # License:: Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16
+ # implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+ # Module to keep the current library version.
21
+
22
+ module AdwordsApi
23
+ module ApiConfig
24
+ CLIENT_LIB_VERSION = '0.12.1'
25
+ end
26
+ end