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.
- checksums.yaml +7 -0
- data/README.md +74 -0
- data/lib/ads_common_for_bing_ads.rb +47 -0
- data/lib/ads_common_for_bing_ads/api_config.rb +41 -0
- data/lib/ads_common_for_bing_ads/auth/client_login_handler.rb +161 -0
- data/lib/ads_common_for_bing_ads/auth/oauth2_handler.rb +33 -0
- data/lib/ads_common_for_bing_ads/build/savon_generator.rb +23 -0
- data/lib/ads_common_for_bing_ads/build/savon_registry.rb +17 -0
- data/lib/ads_common_for_bing_ads/parameters_validator.rb +36 -0
- data/lib/ads_common_for_bing_ads/savon_headers/base_header_handler.rb +13 -0
- data/lib/ads_common_for_bing_ads/savon_headers/client_login_header_handler.rb +24 -0
- data/lib/ads_common_for_bing_ads/savon_headers/oauth_header_handler.rb +31 -0
- data/lib/ads_common_for_bing_ads/savon_headers_base_header_handler.rb +9 -0
- data/lib/ads_common_for_bing_ads/savon_service.rb +143 -0
- data/lib/bing_ads_api.rb +215 -0
- data/lib/bing_ads_api/api_config.rb +164 -0
- data/lib/bing_ads_api/client_login_header_handler.rb +21 -0
- data/lib/bing_ads_api/credential_handler.rb +91 -0
- data/lib/bing_ads_api/errors.rb +564 -0
- data/lib/bing_ads_api/report_header_handler.rb +46 -0
- data/lib/bing_ads_api/report_utils.rb +202 -0
- data/lib/bing_ads_api/v8/ad_intelligence_service.rb +86 -0
- data/lib/bing_ads_api/v8/ad_intelligence_service_registry.rb +30 -0
- data/lib/bing_ads_api/v8/administration_service.rb +38 -0
- data/lib/bing_ads_api/v8/administration_service_registry.rb +30 -0
- data/lib/bing_ads_api/v8/bulk_service.rb +42 -0
- data/lib/bing_ads_api/v8/bulk_service_registry.rb +30 -0
- data/lib/bing_ads_api/v8/campaign_management_service.rb +390 -0
- data/lib/bing_ads_api/v8/campaign_management_service_registry.rb +30 -0
- data/lib/bing_ads_api/v8/customer_billing_service.rb +62 -0
- data/lib/bing_ads_api/v8/customer_billing_service_registry.rb +30 -0
- data/lib/bing_ads_api/v8/customer_management_service.rb +162 -0
- data/lib/bing_ads_api/v8/customer_management_service_registry.rb +30 -0
- data/lib/bing_ads_api/v8/notification_service.rb +38 -0
- data/lib/bing_ads_api/v8/notification_service_registry.rb +30 -0
- data/lib/bing_ads_api/v8/optimizer_service.rb +46 -0
- data/lib/bing_ads_api/v8/optimizer_service_registry.rb +30 -0
- data/lib/bing_ads_api/v8/reporting_service.rb +38 -0
- data/lib/bing_ads_api/v8/reporting_service_registry.rb +30 -0
- data/lib/bing_ads_api/v9/ad_intelligence_service.rb +86 -0
- data/lib/bing_ads_api/v9/ad_intelligence_service_registry.rb +30 -0
- data/lib/bing_ads_api/v9/bulk_service.rb +58 -0
- data/lib/bing_ads_api/v9/bulk_service_registry.rb +30 -0
- data/lib/bing_ads_api/v9/campaign_management_service.rb +298 -0
- data/lib/bing_ads_api/v9/campaign_management_service_registry.rb +30 -0
- data/lib/bing_ads_api/v9/customer_billing_service.rb +66 -0
- data/lib/bing_ads_api/v9/customer_billing_service_registry.rb +30 -0
- data/lib/bing_ads_api/v9/customer_management_service.rb +154 -0
- data/lib/bing_ads_api/v9/customer_management_service_registry.rb +30 -0
- data/lib/bing_ads_api/v9/optimizer_service.rb +62 -0
- data/lib/bing_ads_api/v9/optimizer_service_registry.rb +30 -0
- data/lib/bing_ads_api/v9/reporting_service.rb +38 -0
- data/lib/bing_ads_api/v9/reporting_service_registry.rb +30 -0
- data/lib/bing_ads_api/version.rb +5 -0
- data/rakefile.rb +54 -0
- 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,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
|
data/lib/bing_ads_api.rb
ADDED
@@ -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
|