bing_ads_api_v9 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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