bing_ads_api_v9 0.0.6

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 (56) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +74 -0
  3. data/lib/ads_common_for_bing_ads.rb +47 -0
  4. data/lib/ads_common_for_bing_ads/api_config.rb +41 -0
  5. data/lib/ads_common_for_bing_ads/auth/client_login_handler.rb +161 -0
  6. data/lib/ads_common_for_bing_ads/auth/oauth2_handler.rb +33 -0
  7. data/lib/ads_common_for_bing_ads/build/savon_generator.rb +23 -0
  8. data/lib/ads_common_for_bing_ads/build/savon_registry.rb +17 -0
  9. data/lib/ads_common_for_bing_ads/parameters_validator.rb +36 -0
  10. data/lib/ads_common_for_bing_ads/savon_headers/base_header_handler.rb +13 -0
  11. data/lib/ads_common_for_bing_ads/savon_headers/client_login_header_handler.rb +24 -0
  12. data/lib/ads_common_for_bing_ads/savon_headers/oauth_header_handler.rb +31 -0
  13. data/lib/ads_common_for_bing_ads/savon_headers_base_header_handler.rb +9 -0
  14. data/lib/ads_common_for_bing_ads/savon_service.rb +143 -0
  15. data/lib/bing_ads_api.rb +215 -0
  16. data/lib/bing_ads_api/api_config.rb +164 -0
  17. data/lib/bing_ads_api/client_login_header_handler.rb +21 -0
  18. data/lib/bing_ads_api/credential_handler.rb +91 -0
  19. data/lib/bing_ads_api/errors.rb +564 -0
  20. data/lib/bing_ads_api/report_header_handler.rb +46 -0
  21. data/lib/bing_ads_api/report_utils.rb +202 -0
  22. data/lib/bing_ads_api/v8/ad_intelligence_service.rb +86 -0
  23. data/lib/bing_ads_api/v8/ad_intelligence_service_registry.rb +30 -0
  24. data/lib/bing_ads_api/v8/administration_service.rb +38 -0
  25. data/lib/bing_ads_api/v8/administration_service_registry.rb +30 -0
  26. data/lib/bing_ads_api/v8/bulk_service.rb +42 -0
  27. data/lib/bing_ads_api/v8/bulk_service_registry.rb +30 -0
  28. data/lib/bing_ads_api/v8/campaign_management_service.rb +390 -0
  29. data/lib/bing_ads_api/v8/campaign_management_service_registry.rb +30 -0
  30. data/lib/bing_ads_api/v8/customer_billing_service.rb +62 -0
  31. data/lib/bing_ads_api/v8/customer_billing_service_registry.rb +30 -0
  32. data/lib/bing_ads_api/v8/customer_management_service.rb +162 -0
  33. data/lib/bing_ads_api/v8/customer_management_service_registry.rb +30 -0
  34. data/lib/bing_ads_api/v8/notification_service.rb +38 -0
  35. data/lib/bing_ads_api/v8/notification_service_registry.rb +30 -0
  36. data/lib/bing_ads_api/v8/optimizer_service.rb +46 -0
  37. data/lib/bing_ads_api/v8/optimizer_service_registry.rb +30 -0
  38. data/lib/bing_ads_api/v8/reporting_service.rb +38 -0
  39. data/lib/bing_ads_api/v8/reporting_service_registry.rb +30 -0
  40. data/lib/bing_ads_api/v9/ad_intelligence_service.rb +86 -0
  41. data/lib/bing_ads_api/v9/ad_intelligence_service_registry.rb +30 -0
  42. data/lib/bing_ads_api/v9/bulk_service.rb +58 -0
  43. data/lib/bing_ads_api/v9/bulk_service_registry.rb +30 -0
  44. data/lib/bing_ads_api/v9/campaign_management_service.rb +298 -0
  45. data/lib/bing_ads_api/v9/campaign_management_service_registry.rb +30 -0
  46. data/lib/bing_ads_api/v9/customer_billing_service.rb +66 -0
  47. data/lib/bing_ads_api/v9/customer_billing_service_registry.rb +30 -0
  48. data/lib/bing_ads_api/v9/customer_management_service.rb +154 -0
  49. data/lib/bing_ads_api/v9/customer_management_service_registry.rb +30 -0
  50. data/lib/bing_ads_api/v9/optimizer_service.rb +62 -0
  51. data/lib/bing_ads_api/v9/optimizer_service_registry.rb +30 -0
  52. data/lib/bing_ads_api/v9/reporting_service.rb +38 -0
  53. data/lib/bing_ads_api/v9/reporting_service_registry.rb +30 -0
  54. data/lib/bing_ads_api/version.rb +5 -0
  55. data/rakefile.rb +54 -0
  56. metadata +168 -0
@@ -0,0 +1,13 @@
1
+ module AdsCommonForBingAds
2
+ module SavonHeaders
3
+
4
+ class BaseHeaderHandler
5
+
6
+ # Generates SOAP headers with the default request header element.
7
+ def generate_headers(request, soap)
8
+ soap.header.merge!(generate_request_header())
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ # Handles SOAP headers and namespaces definition for ClientLogin type header.
2
+
3
+ module AdsCommonForBingAds
4
+ module SavonHeaders
5
+
6
+ class ClientLoginHeaderHandler < BaseHeaderHandler
7
+
8
+ private
9
+
10
+ # Generates Bing Ads API specific request header with ClientLogin data.
11
+ def generate_request_header()
12
+ request_header = super()
13
+ #puts "--------------- generate_request_header >> request_header >>\n#{request_header}"
14
+ credentials = @credential_handler.credentials
15
+ #puts "--------------- generate_request_header >> credentials >>\n#{credentials}"
16
+ #request_header['authToken'] = @auth_handler.get_token(credentials)
17
+ credentials.each {|k,v| request_header[prepend_namespace(k.to_s.camelize)] = v}
18
+ request_header.select!{|k,_| ['ApplicationToken', 'CustomerAccountId', 'CustomerId', 'DeveloperToken', 'UserName', 'Password'].map{|h| prepend_namespace(h)}.include?(k.to_s)}
19
+ #puts "--------------- generate_request_header >> request_header final >>\n#{request_header}"
20
+ return request_header
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,31 @@
1
+ module AdsCommonForBingAds
2
+ module SavonHeaders
3
+
4
+ class OAuthHeaderHandler
5
+
6
+ private
7
+
8
+ # Generates SOAP request header with login credentials and namespace
9
+ # definition for OAuth authentication.
10
+ #
11
+ # Args:
12
+ # - request: a HTTPI Request to generate headers for
13
+ # - soap: a Savon soap object to fill fields in
14
+ #
15
+ # Returns:
16
+ # - Hash containing a header with filled in credentials
17
+ #
18
+ def generate_headers(request, soap)
19
+ #super(request, soap)
20
+ credentials = @credential_handler.credentials
21
+
22
+ request.url = soap.endpoint
23
+
24
+ soap.header['wsdl:AuthenticationToken'] = @auth_handler.auth_string(credentials)
25
+ soap.header['wsdl:DeveloperToken'] = credentials[:developer_token]
26
+ soap.header['wsdl:CustomerAccountId'] = credentials[:customer_account_id]
27
+
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,9 @@
1
+
2
+ class AdsCommonForBingAds::SavonHeaders::BaseHeaderHandler
3
+
4
+ # Generates SOAP headers with the default request header element.
5
+ def generate_headers(request, soap)
6
+ soap.header.merge!(generate_request_header())
7
+ end
8
+
9
+ end
@@ -0,0 +1,143 @@
1
+ ####### Overriden for Bing Ads #########
2
+
3
+ class AdsCommonForBingAds::SavonService < AdsCommon::SavonService
4
+
5
+ private
6
+
7
+ # [CHANGES:
8
+ # => ParametersValidator to AdsCommonForBingAds::ParametersValidator
9
+ # => ResultsExtractor to AdsCommon::ResultsExtractor]
10
+ # Executes SOAP action specified as a string with given arguments.
11
+ def execute_action(action_name, args, &block)
12
+ registry = get_service_registry()
13
+ validator = AdsCommonForBingAds::ParametersValidator.new(registry)
14
+ args = validator.validate_args(action_name, args)
15
+ response = execute_soap_request(
16
+ action_name.to_sym, args, validator.extra_namespaces)
17
+ log_headers(response.http.headers)
18
+ handle_errors(response)
19
+ extractor = AdsCommon::ResultsExtractor.new(registry)
20
+ result = extractor.extract_result(response, action_name, &block)
21
+ run_user_block(extractor, response, result, &block) if block_given?
22
+ return result
23
+ end
24
+
25
+ # Adds namespace to the given string.
26
+ #
27
+ # Args:
28
+ # - str: String to prepend with a namespace
29
+ #
30
+ # Returns:
31
+ # - String with a namespace
32
+ #
33
+ def prepend_namespace(str, namespace = AdsCommonForBingAds::SavonHeaders::BaseHeaderHandler::DEFAULT_NAMESPACE)
34
+ return "%s:%s" % [namespace, str]
35
+ end
36
+
37
+ # Executes the SOAP request with original SOAP name.
38
+ def execute_soap_request(action, args, extra_namespaces)
39
+ ns = AdsCommonForBingAds::SavonHeaders::BaseHeaderHandler::DEFAULT_NAMESPACE
40
+ original_input_name = get_service_registry.get_method_signature(action)[:input][:name].to_s.camelize
41
+ original_action_name = get_service_registry.get_method_signature(action)[:original_name].to_s.camelize
42
+ original_action_name = action if original_action_name.nil?
43
+ args = args.first if args.is_a?(Array)
44
+ additional_headers = args.delete(:headers) unless args.nil?
45
+ prepend_namespace_to_hash(args, ns)
46
+ prepend_namespace_to_hash(additional_headers, ns)
47
+ puts "**************************************args = #{args}"
48
+ response = @client.request(ns, original_input_name) do |soap, wsdl, http|
49
+ http.headers["SOAPAction"] = %{"#{original_action_name}"}
50
+ soap.body = args
51
+ header_handler.prepare_request(http, soap)
52
+ soap.namespaces.merge!(extra_namespaces) unless extra_namespaces.nil?
53
+ end
54
+ return response
55
+ end
56
+
57
+
58
+ def prepend_namespace_to_hash h, namespace
59
+ if h.is_a?(Hash)
60
+ h.dup.each do |k,v|
61
+ h.delete(k)
62
+ if k.to_s=~/!$/ || k.to_s=~/:/ #on ne transforme pas les noms finissant par ! ou contenant : (exemple: attributes! ou xsi:type)
63
+ h[k] = prepend_namespace_to_hash(v, namespace)
64
+ else
65
+ h[k.to_s=~ /^#{namespace}:/ ? k : prepend_namespace(k.to_s.camelize, namespace)] = prepend_namespace_to_hash(v, namespace)
66
+ end
67
+ end
68
+ elsif h.is_a?(Array) # e.g: h = {:campaigns => {:campaign => [{:name => 'foo'}, {:name => 'foofoo'}]}}
69
+ h.map!{|e| prepend_namespace_to_hash(e, namespace)}
70
+ end
71
+ return h
72
+ end
73
+
74
+ # Creates and sets up Savon client.
75
+ def create_savon_client(endpoint, namespace)
76
+ Nori.advanced_typecasting = false
77
+ client = Savon::Client.new do |wsdl, httpi|
78
+ wsdl.endpoint = endpoint
79
+ wsdl.namespace = namespace
80
+ wsdl.element_form_default = :qualified
81
+ AdsCommonForBingAds::Http.configure_httpi(@config, httpi)
82
+ end
83
+ client.config.raise_errors = false
84
+ client.config.logger.subject = get_logger()
85
+ return client
86
+ end
87
+
88
+ # Finds an exception object for a given response.
89
+ def exception_for_soap_fault(response)
90
+ begin
91
+ fault = response[:fault]
92
+ if fault[:detail] and fault[:detail][:api_exception_fault]
93
+ exception_fault = fault[:detail][:api_exception_fault]
94
+ exception_name = exception_fault[:application_exception_type]
95
+ exception_class = get_module().const_get(exception_name)
96
+ return exception_class.new(exception_fault)
97
+ # Specific to Bing Ads
98
+ elsif fault[:detail] and fault[:detail][:api_fault]
99
+ operation_error = fault[:detail][:api_fault][:operation_errors][:operation_error]
100
+ operation_error = operation_error.first if operation_error.is_a?(Array) # if we get several errors, we only raise the first one
101
+ if exception_name = BingAdsApi::Errors::CODES[operation_error[:code]]
102
+ exception_class = BingAdsApi::Errors.const_get(exception_name)
103
+ else
104
+ raise Exception.new("code #{operation_error[:code]}")
105
+ end
106
+ return exception_class.new("#{operation_error[:message]} (#{operation_error[:details]})")
107
+ # Specific to Bing Ads (batches)
108
+ elsif fault[:detail] and fault[:detail][:api_fault_detail]
109
+ operation_error = fault[:detail][:api_fault_detail][:batch_errors][:batch_error]
110
+ operation_error = operation_error.first if operation_error.is_a?(Array) # if we get several errors, we only raise the first one
111
+ if exception_name = BingAdsApi::Errors::CODES[operation_error[:code]]
112
+ exception_class = BingAdsApi::Errors.const_get(exception_name)
113
+ else
114
+ raise Exception.new("code #{operation_error[:code]}")
115
+ end
116
+ return exception_class.new("#{operation_error[:message]} (#{operation_error[:details]})")
117
+ # Specific to Bing Ads (ad api)
118
+ elsif fault[:detail] and fault[:detail][:ad_api_fault_detail]
119
+ operation_error = fault[:detail][:ad_api_fault_detail][:errors][:ad_api_error]
120
+ operation_error = operation_error.first if operation_error.is_a?(Array) # if we get several errors, we only raise the first one
121
+ if exception_name = BingAdsApi::Errors::CODES[operation_error[:code]]
122
+ exception_class = BingAdsApi::Errors.const_get(exception_name)
123
+ else
124
+ raise Exception.new("code #{operation_error[:code]}")
125
+ end
126
+ return exception_class.new("#{operation_error[:message]} (#{operation_error[:details]})")
127
+ elsif fault[:faultstring]
128
+ fault_message = fault[:faultstring]
129
+ return AdsCommonForBingAds::Errors::ApiException.new(
130
+ "Unknown exception with error: %s" % fault_message)
131
+ else
132
+ raise ArgumentError.new(fault.to_s)
133
+ end
134
+ rescue Exception => e
135
+ operation_error ||= response[:fault][:detail][:api_fault][:operation_errors][:operation_error] rescue {}
136
+ return AdsCommonForBingAds::Errors::ApiException.new(
137
+ "Failed to resolve exception (%s), details: %s, SOAP fault: %s" %
138
+ [e.message, "#{operation_error[:message]} (#{operation_error[:details]})", response.soap_fault])
139
+ end
140
+ end
141
+
142
+
143
+ end
@@ -0,0 +1,215 @@
1
+ require 'savon'
2
+ require 'httpi'
3
+ require 'active_support/inflector'
4
+
5
+ require 'ads_common_for_bing_ads'
6
+ require 'ads_common_for_bing_ads/api_config'
7
+ require 'ads_common_for_bing_ads/parameters_validator'
8
+ require 'ads_common_for_bing_ads/auth/client_login_handler'
9
+ require 'ads_common_for_bing_ads/auth/oauth2_handler'
10
+ require 'ads_common_for_bing_ads/savon_service'
11
+ require 'ads_common_for_bing_ads/savon_headers/base_header_handler'
12
+ require 'ads_common_for_bing_ads/savon_headers/client_login_header_handler'
13
+ require 'ads_common_for_bing_ads/savon_headers/oauth_header_handler'
14
+ require 'bing_ads_api/api_config'
15
+ require 'bing_ads_api/credential_handler'
16
+ require 'bing_ads_api/errors'
17
+ require 'bing_ads_api/report_utils'
18
+
19
+ module BingAdsApi
20
+
21
+ # Wrapper class that serves as the main point of access for all the API usage.
22
+ #
23
+ # Holds all the services, as well as login credentials.
24
+ #
25
+ class Api < AdsCommonForBingAds::Api
26
+
27
+ # Constructor for API.
28
+ def initialize(provided_config = nil)
29
+ super(provided_config)
30
+ @credential_handler = BingAdsApi::CredentialHandler.new(@config)
31
+ end
32
+
33
+ # Getter for the API service configurations
34
+ def api_config()
35
+ BingAdsApi::ApiConfig
36
+ end
37
+
38
+ # Auxiliary method to create an authentication handler.
39
+ #
40
+ # Returns:
41
+ # - auth handler
42
+ #
43
+ def create_auth_handler
44
+ auth_method = @config.read('authentication.method', :OAUTH2)
45
+ return case auth_method
46
+ when :CLIENTLOGIN
47
+ @logger.warn("ClientLogin authentication method is now deprecated")
48
+ AdsCommonForBingAds::Auth::ClientLoginHandler.new(
49
+ @config,
50
+ api_config.client_login_config(:AUTH_SERVER),
51
+ api_config.client_login_config(:LOGIN_SERVICE_NAME)
52
+ )
53
+ when :OAUTH
54
+ raise AdsCommon::Errors::Error,
55
+ 'OAuth authorization method is deprecated, use OAuth2 instead.'
56
+ when :OAUTH2
57
+ environment = @config.read('service.environment',
58
+ api_config.default_environment())
59
+ AdsCommonForBingAds::Auth::OAuth2Handler.new(
60
+ @config,
61
+ api_config.environment_config(environment, :oauth_scope)
62
+ )
63
+ when :OAUTH2_JWT
64
+ environment = @config.read('service.environment',
65
+ api_config.default_environment())
66
+ AdsCommon::Auth::OAuth2JwtHandler.new(
67
+ @config,
68
+ api_config.environment_config(environment, :oauth_scope)
69
+ )
70
+ else
71
+ raise AdsCommon::Errors::Error,
72
+ "Unknown authentication method '%s'" % auth_method
73
+ end
74
+ end
75
+
76
+ # Retrieve correct soap_header_handler.
77
+ #
78
+ # Args:
79
+ # - auth_handler: instance of an AdsCommonForBingAds::Auth::BaseHandler subclass to
80
+ # handle authentication
81
+ # - version: intended API version
82
+ # - header_ns: header namespace
83
+ # - default_ns: default namespace
84
+ #
85
+ # Returns:
86
+ # - SOAP header handler
87
+ #
88
+ def soap_header_handler(auth_handler, version, header_ns, default_ns)
89
+ auth_method = @config.read('authentication.method', :CLIENTLOGIN)
90
+ handler_class = case auth_method
91
+ when :CLIENTLOGIN then AdsCommonForBingAds::SavonHeaders::ClientLoginHeaderHandler
92
+ when :OAUTH,:OAUTH2 then AdsCommonForBingAds::SavonHeaders::OAuthHeaderHandler
93
+ end
94
+ return handler_class.new(@credential_handler, auth_handler, header_ns, default_ns, version)
95
+ end
96
+
97
+ # Helper method to provide a simple way of doing an MCC-level operation
98
+ # without the need to change credentials. Executes a block of code as an
99
+ # MCC-level operation and/or returns the current status of the property.
100
+ #
101
+ # Args:
102
+ # - accepts a block, which it will execute as an MCC-level operation
103
+ #
104
+ # Returns:
105
+ # - block execution result, if block given
106
+ # - boolean indicating whether MCC-level operations are currently
107
+ # enabled or disabled, if no block provided
108
+ #
109
+ def use_mcc(&block)
110
+ return (block_given?) ?
111
+ run_with_temporary_flag(:@use_mcc, true, block) :
112
+ @credential_handler.use_mcc
113
+ end
114
+
115
+ # Helper method to provide a simple way of doing an MCC-level operation
116
+ # without the need to change credentials. Sets the value of the property
117
+ # that controls whether MCC-level operations are enabled or disabled.
118
+ #
119
+ # Args:
120
+ # - value: the new value for the property (boolean)
121
+ #
122
+ def use_mcc=(value)
123
+ @credential_handler.use_mcc = value
124
+ end
125
+
126
+ # Helper method to provide a simple way of doing a validate-only operation
127
+ # without the need to change credentials. Executes a block of code as an
128
+ # validate-only operation and/or returns the current status of the property.
129
+ #
130
+ # Args:
131
+ # - accepts a block, which it will execute as a validate-only operation
132
+ #
133
+ # Returns:
134
+ # - block execution result, if block given
135
+ # - boolean indicating whether validate-only operations are currently
136
+ # enabled or disabled, if no block provided
137
+ #
138
+ def validate_only(&block)
139
+ return (block_given?) ?
140
+ run_with_temporary_flag(:@validate_only, true, block) :
141
+ @credential_handler.validate_only
142
+ end
143
+
144
+ # Helper method to provide a simple way of performing validate-only
145
+ # operations. Sets the value of the property
146
+ # that controls whether validate-only operations are enabled or disabled.
147
+ #
148
+ # Args:
149
+ # - value: the new value for the property (boolean)
150
+ #
151
+ def validate_only=(value)
152
+ @credential_handler.validate_only = value
153
+ end
154
+
155
+ # Helper method to provide a simple way of performing requests with support
156
+ # for partial failures. Executes a block of code with partial failures
157
+ # enabled and/or returns the current status of the property.
158
+ #
159
+ # Args:
160
+ # - accepts a block, which it will execute as a partial failure operation
161
+ #
162
+ # Returns:
163
+ # - block execution result, if block given
164
+ # - boolean indicating whether partial failure operations are currently
165
+ # enabled or disabled, if no block provided
166
+ #
167
+ def partial_failure(&block)
168
+ return (block_given?) ?
169
+ run_with_temporary_flag(:@partial_failure, true, block) :
170
+ @credential_handler.partial_failure
171
+ end
172
+
173
+ # Helper method to provide a simple way of performing requests with support
174
+ # for partial failures.
175
+ #
176
+ # Args:
177
+ # - value: the new value for the property (boolean)
178
+ #
179
+ def partial_failure=(value)
180
+ @credential_handler.partial_failure = value
181
+ end
182
+
183
+ # Returns an instance of ReportUtils object with all utilities relevant to
184
+ # the reporting.
185
+ #
186
+ # Args:
187
+ # - version: version of the API to use (optional).
188
+ #
189
+ def report_utils(version = nil)
190
+ version = api_config.default_version if version.nil?
191
+ # Check if version exists.
192
+ if !api_config.versions.include?(version)
193
+ raise AdsCommonForBingAds::Errors::Error, "Unknown version '%s'" % version
194
+ end
195
+ return BingAdsApi::ReportUtils.new(self, version)
196
+ end
197
+
198
+ private
199
+
200
+ # Executes block with a temporary flag set to a given value. Returns block
201
+ # result.
202
+ def run_with_temporary_flag(flag_name, flag_value, block)
203
+ previous = @credential_handler.instance_variable_get(flag_name)
204
+ @credential_handler.instance_variable_set(flag_name, flag_value)
205
+ begin
206
+ return block.call
207
+ ensure
208
+ @credential_handler.instance_variable_set(flag_name, previous)
209
+ end
210
+ end
211
+
212
+ end
213
+
214
+
215
+ end
@@ -0,0 +1,164 @@
1
+ # encoding: utf-8
2
+ # Helper methods for loading and managing the available services in the Bing Ads API.
3
+
4
+ require 'bing_ads_api/version'
5
+
6
+ module BingAdsApi
7
+
8
+ # Contains helper methods for loading and managing the available services.
9
+ module ApiConfig
10
+
11
+ # Inherit from AdsCommonForBingAds::ApiConfig
12
+ class << ApiConfig
13
+ include AdsCommonForBingAds::ApiConfig
14
+ end
15
+
16
+ # Set defaults
17
+ DEFAULT_VERSION = :v9
18
+ DEFAULT_ENVIRONMENT = :PRODUCTION
19
+ LATEST_VERSION = :v9
20
+
21
+ # Set other constants
22
+ API_NAME = 'BingAdsApi'
23
+ DEFAULT_CONFIG_FILENAME = 'bing_ads_api.yml'
24
+
25
+ # Configure the services available to each version
26
+ @@service_config = {
27
+ :v8 => [
28
+ :AdIntelligenceService,
29
+ :AdministrationService,
30
+ :BulkService,
31
+ :CampaignManagementService,
32
+ :CustomerBillingService,
33
+ :CustomerManagementService,
34
+ :NotificationService,
35
+ :OptimizerService,
36
+ :ReportingService
37
+ ],
38
+ :v9 => [
39
+ :AdIntelligenceService,
40
+ :BulkService,
41
+ :CampaignManagementService,
42
+ :CustomerBillingService,
43
+ :CustomerManagementService,
44
+ :OptimizerService,
45
+ :ReportingService
46
+ ]
47
+ }
48
+
49
+ # Configure the different environments, with the base URL for each one
50
+ @@environment_config = {
51
+ :PRODUCTION => {
52
+ :oauth_scope => '',
53
+ :header_ns => 'https://adcenter.microsoft.com/api/adcenter/',
54
+ :v8 => '',
55
+ :v9 => ''
56
+ },
57
+ :SANDBOX => {
58
+ :oauth_scope => '',
59
+ :header_ns => 'https://adcenter.microsoft.com/api/adcenter/',
60
+ :v8 => '',
61
+ :v9 => ''
62
+ }
63
+ }
64
+
65
+ # Configure the subdirectories for each version / service pair.
66
+ # A missing pair means that only the base URL is used.
67
+ @@subdir_config = {}
68
+
69
+ @@address_config = {
70
+ :v9 => {
71
+ :AdIntelligenceService => {:PRODUCTION => "https://api.bingads.microsoft.com/Api/Advertiser/AdIntelligence/v9/AdIntelligenceService.svc?wsdl", :SANDBOX => "https://api.sandbox.bingads.microsoft.com/Api/Advertiser/AdIntelligence/v9/AdIntelligenceService.svc?wsdl"},
72
+ :BulkService => {:PRODUCTION => "https://api.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v9/BulkService.svc?wsdl", :SANDBOX => "https://api.sandbox.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v9/BulkService.svc?wsdl"},
73
+ :CampaignManagementService => {:PRODUCTION => "https://api.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v9/CampaignManagementService.svc?wsdl", :SANDBOX => "https://api.sandbox.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v9/CampaignManagementService.svc?wsdl"},
74
+ :CustomerBillingService => {:PRODUCTION => "https://clientcenter.api.bingads.microsoft.com/Api/Billing/v9/CustomerBillingService.svc?wsdl", :SANDBOX => ""},
75
+ :CustomerManagementService => {:PRODUCTION => "https://clientcenter.api.bingads.microsoft.com/Api/CustomerManagement/v9/CustomerManagementService.svc?wsdl", :SANDBOX => "https://clientcenter.api.sandbox.bingads.microsoft.com/Api/CustomerManagement/v9/CustomerManagementService.svc?wsdl"},
76
+ :OptimizerService => {:PRODUCTION => "https://api.bingads.microsoft.com/Api/Advertiser/Optimizer/v9/OptimizerService.svc?wsdl", :SANDBOX => "https://api.sandbox.bingads.microsoft.com/Api/Advertiser/Optimizer/v9/OptimizerService.svc?wsdl"},
77
+ :ReportingService => {:PRODUCTION => "https://api.bingads.microsoft.com/Api/Advertiser/Reporting/v9/ReportingService.svc?wsdl", :SANDBOX => "https://api.sandbox.bingads.microsoft.com/Api/Advertiser/Reporting/v9/ReportingService.svc?wsdl"}
78
+ },
79
+ :v8 => {
80
+ :AdIntelligenceService => {:PRODUCTION => "https://adcenterapi.microsoft.com/Api/Advertiser/v8/CampaignManagement/AdIntelligenceService.svc?wsdl", :SANDBOX => ""},
81
+ :AdministrationService => {:PRODUCTION => "https://adcenterapi.microsoft.com/Api/Advertiser/v8/Administration/AdministrationService.svc?wsdl", :SANDBOX => ""},
82
+ :BulkService => {:PRODUCTION => "https://adcenterapi.microsoft.com/Api/Advertiser/v8/CampaignManagement/BulkService.svc?wsdl", :SANDBOX => ""},
83
+ :CampaignManagementService => {:PRODUCTION => "https://adcenterapi.microsoft.com/Api/Advertiser/v8/CampaignManagement/CampaignManagementService.svc?wsdl", :SANDBOX => "https://api.sandbox.bingads.microsoft.com/Api/Advertiser/v8/CampaignManagement/CampaignManagementService.svc?wsdl"},
84
+ :CustomerBillingService => {:PRODUCTION => "https://sharedservices.adcenterapi.microsoft.com/Api/Billing/v8/CustomerBillingService.svc?wsdl", :SANDBOX => ""},
85
+ :CustomerManagementService => {:PRODUCTION => "https://sharedservices.adcenterapi.microsoft.com/Api/CustomerManagement/v8/CustomerManagementService.svc?wsdl", :SANDBOX => "https://sharedservices.api.sandbox.bingads.microsoft.com/Api/CustomerManagement/v8/CustomerManagementService.svc?wsdl"},
86
+ :NotificationService => {:PRODUCTION => "https://sharedservices.adcenterapi.microsoft.com/Api/Notification/v8/NotificationService.svc?wsdl", :SANDBOX => ""},
87
+ :OptimizerService => {:PRODUCTION => "https://adcenterapi.microsoft.com/Api/Advertiser/v8/Optimizer/OptimizerService.svc?wsdl", :SANDBOX => ""},
88
+ :ReportingService => {:PRODUCTION => "https://adcenterapi.microsoft.com/Api/Advertiser/v8/Reporting/ReportingService.svc?wsdl", :SANDBOX => ""}
89
+ }
90
+ }
91
+
92
+ # Auth constants for ClientLogin method.
93
+ #TODO: remove client_login_config
94
+ @@client_login_config = {
95
+ :AUTH_SERVER => 'https://www.microsoft.com',
96
+ :LOGIN_SERVICE_NAME => 'adcenter'
97
+ }
98
+
99
+ public
100
+
101
+ # Getters for constants and module variables.
102
+ def self.default_version
103
+ DEFAULT_VERSION
104
+ end
105
+
106
+ def self.default_environment
107
+ DEFAULT_ENVIRONMENT
108
+ end
109
+
110
+ def self.latest_version
111
+ LATEST_VERSION
112
+ end
113
+
114
+ def self.api_name
115
+ API_NAME
116
+ end
117
+
118
+ def self.service_config
119
+ @@service_config
120
+ end
121
+
122
+ def self.environment_config(environment, key)
123
+ return @@environment_config.include?(environment) ?
124
+ @@environment_config[environment][key] : nil
125
+ end
126
+
127
+ def self.address_config
128
+ @@address_config
129
+ end
130
+
131
+ def self.subdir_config
132
+ @@subdir_config
133
+ end
134
+
135
+ def self.client_login_config(key)
136
+ return @@client_login_config[key]
137
+ end
138
+
139
+ def self.default_config_filename
140
+ DEFAULT_CONFIG_FILENAME
141
+ end
142
+
143
+ def self.headers_config
144
+ @@headers_config
145
+ end
146
+
147
+ # Get the download URL for Ad Hoc reports.
148
+ #
149
+ # Args:
150
+ # - environment: the service environment to be used
151
+ # - version: the API version (as a symbol)
152
+ #
153
+ # Returns:
154
+ # - The endpoint URL (as a string)
155
+ #
156
+ def self.adhoc_report_download_url(environment, version)
157
+ base = get_wsdl_base(environment, version)
158
+ if base
159
+ base += 'reportdownload/%s' % version.to_s
160
+ end
161
+ return base
162
+ end
163
+ end
164
+ end