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