adcenter_api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/README.md +57 -0
  2. data/lib/adcenter_api.rb +180 -0
  3. data/lib/adcenter_api/api_config.rb +163 -0
  4. data/lib/adcenter_api/client_login_header_handler.rb +70 -0
  5. data/lib/adcenter_api/credential_handler.rb +104 -0
  6. data/lib/adcenter_api/errors.rb +565 -0
  7. data/lib/adcenter_api/report_header_handler.rb +46 -0
  8. data/lib/adcenter_api/report_utils.rb +203 -0
  9. data/lib/adcenter_api/v7/administration_service.rb +38 -0
  10. data/lib/adcenter_api/v7/administration_service_registry.rb +30 -0
  11. data/lib/adcenter_api/v7/campaign_management_service.rb +398 -0
  12. data/lib/adcenter_api/v7/campaign_management_service_registry.rb +30 -0
  13. data/lib/adcenter_api/v7/customer_billing_service.rb +58 -0
  14. data/lib/adcenter_api/v7/customer_billing_service_registry.rb +30 -0
  15. data/lib/adcenter_api/v7/customer_management_service.rb +98 -0
  16. data/lib/adcenter_api/v7/customer_management_service_registry.rb +30 -0
  17. data/lib/adcenter_api/v7/notification_service.rb +38 -0
  18. data/lib/adcenter_api/v7/notification_service_registry.rb +30 -0
  19. data/lib/adcenter_api/v7/reporting_service.rb +38 -0
  20. data/lib/adcenter_api/v7/reporting_service_registry.rb +30 -0
  21. data/lib/adcenter_api/v8/ad_intelligence_service.rb +86 -0
  22. data/lib/adcenter_api/v8/ad_intelligence_service_registry.rb +30 -0
  23. data/lib/adcenter_api/v8/administration_service.rb +38 -0
  24. data/lib/adcenter_api/v8/administration_service_registry.rb +30 -0
  25. data/lib/adcenter_api/v8/bulk_service.rb +42 -0
  26. data/lib/adcenter_api/v8/bulk_service_registry.rb +30 -0
  27. data/lib/adcenter_api/v8/campaign_management_service.rb +390 -0
  28. data/lib/adcenter_api/v8/campaign_management_service_registry.rb +30 -0
  29. data/lib/adcenter_api/v8/customer_billing_service.rb +62 -0
  30. data/lib/adcenter_api/v8/customer_billing_service_registry.rb +30 -0
  31. data/lib/adcenter_api/v8/customer_management_service.rb +162 -0
  32. data/lib/adcenter_api/v8/customer_management_service_registry.rb +30 -0
  33. data/lib/adcenter_api/v8/notification_service.rb +38 -0
  34. data/lib/adcenter_api/v8/notification_service_registry.rb +30 -0
  35. data/lib/adcenter_api/v8/optimizer_service.rb +46 -0
  36. data/lib/adcenter_api/v8/optimizer_service_registry.rb +30 -0
  37. data/lib/adcenter_api/v8/reporting_service.rb +38 -0
  38. data/lib/adcenter_api/v8/reporting_service_registry.rb +30 -0
  39. data/lib/adcenter_api/version.rb +5 -0
  40. data/lib/ads_common/api_config_decorator.rb +43 -0
  41. data/lib/ads_common/auth/client_login_handler_decorator.rb +168 -0
  42. data/lib/ads_common/build/savon_registry_decorator.rb +16 -0
  43. data/lib/ads_common/parameters_validator_decorator.rb +37 -0
  44. data/lib/ads_common/savon_headers_base_header_handler_decorator.rb +23 -0
  45. data/lib/ads_common/savon_service_decorator.rb +109 -0
  46. data/rakefile.rb +54 -0
  47. metadata +157 -0
@@ -0,0 +1,57 @@
1
+ AdCenter Api Client
2
+ =============
3
+
4
+ Description
5
+ -------------
6
+ A simple ruby wrapper for the AdCenter API based on the gem "google-ads-common".
7
+
8
+ Usage
9
+ -------------
10
+
11
+ # install in your gem file
12
+ gem 'adcenter_api', :git => 'https://github.com/weboglobin/adcenter_api.git'
13
+
14
+ # initialize the client
15
+ client = AdcenterApi::Api.new(
16
+ {
17
+ :authentication => {
18
+ :method => 'ClientLogin',
19
+ :developer_token => 'DEVELOPER_TOKEN',
20
+ :user_name => 'USERNAME',
21
+ :password => 'PASSWORD',
22
+ :customer_id => 'customer_id', # may be optional for some requests
23
+ :customer_account_id => 'customer_account_id' # may be optional for some requests
24
+ },
25
+ :service => {:environment => 'PRODUCTION'},
26
+ :library => {:log_level => 'DEBUG'}
27
+ })
28
+
29
+ # select the service and the API version (:v7 or :v8)
30
+ administration_service = client.service(:AdministrationService, :v7)
31
+
32
+ # send your request
33
+ result = administration_service.get_assigned_quota()
34
+
35
+ # select another service
36
+ campaign_service = client.service(:CampaignManagementService, :v7)
37
+
38
+ # send another request
39
+ result = campaign_service.get_campaigns_by_account_id({:account_id => 00000})
40
+
41
+ # create a campaign
42
+ result2 = campaign_service.add_campaigns({:account_id => 00000,
43
+ :campaigns => {:campaign => [{:budget_type => "DailyBudgetWithMaximumMonthlySpend",
44
+ :conversion_tracking_enabled => false,
45
+ :daily_budget => 5,
46
+ :daylight_saving => false,
47
+ :description => "A perfect new campaign",
48
+ :monthly_budget => 50,
49
+ :name => "perfectcampaign",
50
+ :time_zone => "BrusselsCopenhagenMadridParis"}]
51
+ }
52
+ })
53
+
54
+ About the gem
55
+ -------------
56
+ The tests still have to be written.
57
+ Any help is welcome !
@@ -0,0 +1,180 @@
1
+ require 'savon'
2
+ require 'httpi'
3
+ require 'active_support/inflector'
4
+ require 'ads_common/api'
5
+ #require 'ads_common/savon_headers/oauth_header_handler'
6
+
7
+ require 'adcenter_api/api_config'
8
+ require 'adcenter_api/client_login_header_handler'
9
+ require 'adcenter_api/credential_handler'
10
+ require 'adcenter_api/errors'
11
+ require 'adcenter_api/report_utils'
12
+ require 'ads_common/api_config_decorator'
13
+ require 'ads_common/parameters_validator_decorator'
14
+ require 'ads_common/auth/client_login_handler_decorator'
15
+ require 'ads_common/savon_service_decorator'
16
+ require 'ads_common/savon_headers_base_header_handler_decorator'
17
+
18
+ module AdcenterApi
19
+
20
+ # Wrapper class that serves as the main point of access for all the API usage.
21
+ #
22
+ # Holds all the services, as well as login credentials.
23
+ #
24
+ class Api < AdsCommon::Api
25
+
26
+ # Constructor for API.
27
+ def initialize(provided_config = nil)
28
+ super(provided_config)
29
+ @credential_handler = AdcenterApi::CredentialHandler.new(@config)
30
+ end
31
+
32
+ # Getter for the API service configurations
33
+ def api_config()
34
+ AdcenterApi::ApiConfig
35
+ end
36
+
37
+ # Retrieve correct soap_header_handler.
38
+ #
39
+ # Args:
40
+ # - auth_handler: instance of an AdsCommon::Auth::BaseHandler subclass to
41
+ # handle authentication
42
+ # - version: intended API version
43
+ # - namespace: namespace to use as default for body
44
+ #
45
+ # Returns:
46
+ # - a list of SOAP header handlers; one per provided header
47
+ #
48
+ def soap_header_handler(auth_handler, version, namespace)
49
+ auth_method = @config.read('authentication.method', :CLIENTLOGIN)
50
+ handler =
51
+ case auth_method
52
+ when :CLIENTLOGIN
53
+ #auth_ns = api_config.client_login_config(:AUTH_NAMESPACE_PREAMBLE) + version.to_s
54
+ #AdcenterApi::ClientLoginHeaderHandler.new(@credential_handler, auth_handler, namespace, auth_ns, version)
55
+ AdcenterApi::ClientLoginHeaderHandler.new(@credential_handler, auth_handler, namespace, version)
56
+ when :OAUTH, :OAUTH2
57
+ AdsCommon::SavonHeaders::OAuthHeaderHandler.new(@credential_handler, auth_handler, namespace, version)
58
+ end
59
+ return handler
60
+ end
61
+
62
+ # Helper method to provide a simple way of doing an MCC-level operation
63
+ # without the need to change credentials. Executes a block of code as an
64
+ # MCC-level operation and/or returns the current status of the property.
65
+ #
66
+ # Args:
67
+ # - accepts a block, which it will execute as an MCC-level operation
68
+ #
69
+ # Returns:
70
+ # - block execution result, if block given
71
+ # - boolean indicating whether MCC-level operations are currently
72
+ # enabled or disabled, if no block provided
73
+ #
74
+ def use_mcc(&block)
75
+ return (block_given?) ?
76
+ run_with_temporary_flag(:@use_mcc, true, block) :
77
+ @credential_handler.use_mcc
78
+ end
79
+
80
+ # Helper method to provide a simple way of doing an MCC-level operation
81
+ # without the need to change credentials. Sets the value of the property
82
+ # that controls whether MCC-level operations are enabled or disabled.
83
+ #
84
+ # Args:
85
+ # - value: the new value for the property (boolean)
86
+ #
87
+ def use_mcc=(value)
88
+ @credential_handler.use_mcc = value
89
+ end
90
+
91
+ # Helper method to provide a simple way of doing a validate-only operation
92
+ # without the need to change credentials. Executes a block of code as an
93
+ # validate-only operation and/or returns the current status of the property.
94
+ #
95
+ # Args:
96
+ # - accepts a block, which it will execute as a validate-only operation
97
+ #
98
+ # Returns:
99
+ # - block execution result, if block given
100
+ # - boolean indicating whether validate-only operations are currently
101
+ # enabled or disabled, if no block provided
102
+ #
103
+ def validate_only(&block)
104
+ return (block_given?) ?
105
+ run_with_temporary_flag(:@validate_only, true, block) :
106
+ @credential_handler.validate_only
107
+ end
108
+
109
+ # Helper method to provide a simple way of performing validate-only
110
+ # operations. Sets the value of the property
111
+ # that controls whether validate-only operations are enabled or disabled.
112
+ #
113
+ # Args:
114
+ # - value: the new value for the property (boolean)
115
+ #
116
+ def validate_only=(value)
117
+ @credential_handler.validate_only = value
118
+ end
119
+
120
+ # Helper method to provide a simple way of performing requests with support
121
+ # for partial failures. Executes a block of code with partial failures
122
+ # enabled and/or returns the current status of the property.
123
+ #
124
+ # Args:
125
+ # - accepts a block, which it will execute as a partial failure operation
126
+ #
127
+ # Returns:
128
+ # - block execution result, if block given
129
+ # - boolean indicating whether partial failure operations are currently
130
+ # enabled or disabled, if no block provided
131
+ #
132
+ def partial_failure(&block)
133
+ return (block_given?) ?
134
+ run_with_temporary_flag(:@partial_failure, true, block) :
135
+ @credential_handler.partial_failure
136
+ end
137
+
138
+ # Helper method to provide a simple way of performing requests with support
139
+ # for partial failures.
140
+ #
141
+ # Args:
142
+ # - value: the new value for the property (boolean)
143
+ #
144
+ def partial_failure=(value)
145
+ @credential_handler.partial_failure = value
146
+ end
147
+
148
+ # Returns an instance of ReportUtils object with all utilities relevant to
149
+ # the reporting.
150
+ #
151
+ # Args:
152
+ # - version: version of the API to use (optional).
153
+ #
154
+ def report_utils(version = nil)
155
+ version = api_config.default_version if version.nil?
156
+ # Check if version exists.
157
+ if !api_config.versions.include?(version)
158
+ raise AdsCommon::Errors::Error, "Unknown version '%s'" % version
159
+ end
160
+ return AdcenterApi::ReportUtils.new(self, version)
161
+ end
162
+
163
+ private
164
+
165
+ # Executes block with a temporary flag set to a given value. Returns block
166
+ # result.
167
+ def run_with_temporary_flag(flag_name, flag_value, block)
168
+ previous = @credential_handler.instance_variable_get(flag_name)
169
+ @credential_handler.instance_variable_set(flag_name, flag_value)
170
+ begin
171
+ return block.call
172
+ ensure
173
+ @credential_handler.instance_variable_set(flag_name, previous)
174
+ end
175
+ end
176
+
177
+ end
178
+
179
+
180
+ end
@@ -0,0 +1,163 @@
1
+ # encoding: utf-8
2
+ # Helper methods for loading and managing the available services in the AdCenter API.
3
+
4
+ require 'ads_common/api_config'
5
+
6
+ require 'adcenter_api/version'
7
+
8
+ module AdcenterApi
9
+
10
+ # Contains helper methods for loading and managing the available services.
11
+ module ApiConfig
12
+
13
+ # Inherit from AdsCommon::ApiConfig
14
+ class << ApiConfig
15
+ include AdsCommon::ApiConfig
16
+ end
17
+
18
+ # Set defaults
19
+ DEFAULT_VERSION = :v8
20
+ DEFAULT_ENVIRONMENT = :PRODUCTION
21
+ LATEST_VERSION = :v8
22
+
23
+ # Set other constants
24
+ API_NAME = 'AdcenterApi'
25
+ DEFAULT_CONFIG_FILENAME = 'adcenter_api.yml'
26
+
27
+ # Configure the services available to each version
28
+ @@service_config = {
29
+ :v7 => [
30
+ :AdministrationService,
31
+ :CampaignManagementService,
32
+ :CustomerBillingService,
33
+ :CustomerManagementService,
34
+ :NotificationService,
35
+ :ReportingService
36
+ ],
37
+ :v8 => [
38
+ :AdIntelligenceService,
39
+ :AdministrationService,
40
+ :BulkService,
41
+ :CampaignManagementService,
42
+ :CustomerBillingService,
43
+ :CustomerManagementService,
44
+ :NotificationService,
45
+ :OptimizerService,
46
+ :ReportingService
47
+ ]
48
+ }
49
+
50
+ # Configure the different environments, with the base URL for each one
51
+ @@environment_config = {
52
+ :PRODUCTION => {
53
+ :oauth_scope => '',
54
+ :v7 => '',
55
+ :v8 => ''
56
+ },
57
+ :SANDBOX => {
58
+ :oauth_scope => '',
59
+ :v7 => '',
60
+ :v8 => ''
61
+ }
62
+ }
63
+
64
+ # Configure the subdirectories for each version / service pair.
65
+ # A missing pair means that only the base URL is used.
66
+ @@subdir_config = {}
67
+
68
+ @@address_config = {
69
+ :v8 => {
70
+ :AdIntelligenceService => {:PRODUCTION => "https://adcenterapi.microsoft.com/Api/Advertiser/v8/CampaignManagement/AdIntelligenceService.svc?wsdl", :SANDBOX => ""},
71
+ :AdministrationService => {:PRODUCTION => "https://adcenterapi.microsoft.com/Api/Advertiser/v8/Administration/AdministrationService.svc?wsdl", :SANDBOX => ""},
72
+ :BulkService => {:PRODUCTION => "https://adcenterapi.microsoft.com/Api/Advertiser/v8/CampaignManagement/BulkService.svc?wsdl", :SANDBOX => ""},
73
+ :CampaignManagementService => {:PRODUCTION => "https://adcenterapi.microsoft.com/Api/Advertiser/v8/CampaignManagement/CampaignManagementService.svc?wsdl", :SANDBOX => ""},
74
+ :CustomerBillingService => {:PRODUCTION => "https://sharedservices.adcenterapi.microsoft.com/Api/Billing/v8/CustomerBillingService.svc?wsdl", :SANDBOX => ""},
75
+ :CustomerManagementService => {:PRODUCTION => "https://sharedservices.adcenterapi.microsoft.com/Api/CustomerManagement/v8/CustomerManagementService.svc?wsdl", :SANDBOX => ""},
76
+ :NotificationService => {:PRODUCTION => "https://sharedservices.adcenterapi.microsoft.com/Api/Notification/v8/NotificationService.svc?wsdl", :SANDBOX => ""},
77
+ :OptimizerService => {:PRODUCTION => "https://adcenterapi.microsoft.com/Api/Advertiser/v8/Optimizer/OptimizerService.svc?wsdl", :SANDBOX => ""},
78
+ :ReportingService => {:PRODUCTION => "https://adcenterapi.microsoft.com/Api/Advertiser/v8/Reporting/ReportingService.svc?wsdl", :SANDBOX => ""}
79
+ },
80
+ :v7 => {
81
+ :AdministrationService => {:PRODUCTION => "https://adcenterapi.microsoft.com/Api/Advertiser/v7/Administration/AdministrationService.svc?wsdl", :SANDBOX => "https://sandboxapi.adcenter.microsoft.com/Api/Advertiser/v7/Administration/AdministrationService.svc?wsdl"},
82
+ :CampaignManagementService => {:PRODUCTION => "https://adcenterapi.microsoft.com/Api/Advertiser/v7/CampaignManagement/CampaignManagementService.svc?wsdl", :SANDBOX => "https://sandboxapi.adcenter.microsoft.com/Api/Advertiser/v7/CampaignManagement/CampaignManagementService.svc?wsdl"},
83
+ :CustomerBillingService => {:PRODUCTION => "https://sharedservices.adcenterapi.microsoft.com/Api/Billing/v7/CustomerBillingService.svc?wsdl", :SANDBOX => "https://sharedservices-sbx.adcenterapi.microsoft.com/Api/Billing/v7/CustomerBillingService.svc?wsdl"},
84
+ :CustomerManagementService => {:PRODUCTION => "https://sharedservices.adcenterapi.microsoft.com/Api/CustomerManagement/v7/CustomerManagementService.svc?wsdl", :SANDBOX => "https://sharedservices-sbx.adcenterapi.microsoft.com/Api/CustomerManagement/v7/CustomerManagementService.svc?wsdl"},
85
+ :NotificationService => {:PRODUCTION => "https://sharedservices.adcenterapi.microsoft.com/Api/Notification/v8/NotificationService.svc?wsdl", :SANDBOX => ""},
86
+ :ReportingService => {:PRODUCTION => "https://adcenterapi.microsoft.com/Api/Advertiser/v7/Reporting/ReportingService.svc?wsdl", :SANDBOX => "https://sandboxapi.adcenter.microsoft.com/Api/Advertiser/v7/Reporting/ReportingService.svc?wsdl"}
87
+ }
88
+ }
89
+
90
+ # Auth constants for ClientLogin method.
91
+ #TODO: remove client_login_config
92
+ @@client_login_config = {
93
+ :AUTH_SERVER => 'https://www.microsoft.com',
94
+ :AUTH_NAMESPACE_PREAMBLE => 'https://adcenter.microsoft.com/api/adcenter/',
95
+ :LOGIN_SERVICE_NAME => 'adcenter'
96
+ }
97
+
98
+ public
99
+
100
+ # Getters for constants and module variables.
101
+ def self.default_version
102
+ DEFAULT_VERSION
103
+ end
104
+
105
+ def self.default_environment
106
+ DEFAULT_ENVIRONMENT
107
+ end
108
+
109
+ def self.latest_version
110
+ LATEST_VERSION
111
+ end
112
+
113
+ def self.api_name
114
+ API_NAME
115
+ end
116
+
117
+ def self.service_config
118
+ @@service_config
119
+ end
120
+
121
+ def self.environment_config(environment, key)
122
+ return @@environment_config.include?(environment) ?
123
+ @@environment_config[environment][key] : nil
124
+ end
125
+
126
+ def self.address_config
127
+ @@address_config
128
+ end
129
+
130
+ def self.subdir_config
131
+ @@subdir_config
132
+ end
133
+
134
+ def self.client_login_config(key)
135
+ return @@client_login_config[key]
136
+ end
137
+
138
+ def self.default_config_filename
139
+ DEFAULT_CONFIG_FILENAME
140
+ end
141
+
142
+ def self.headers_config
143
+ @@headers_config
144
+ end
145
+
146
+ # Get the download URL for Ad Hoc reports.
147
+ #
148
+ # Args:
149
+ # - environment: the service environment to be used
150
+ # - version: the API version (as a symbol)
151
+ #
152
+ # Returns:
153
+ # - The endpoint URL (as a string)
154
+ #
155
+ def self.adhoc_report_download_url(environment, version)
156
+ base = get_wsdl_base(environment, version)
157
+ if base
158
+ base += 'reportdownload/%s' % version.to_s
159
+ end
160
+ return base
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,70 @@
1
+ # Handles SOAP headers and namespaces definition for ClientLogin type header.
2
+ require 'ads_common/savon_headers/base_header_handler'
3
+
4
+ module AdcenterApi
5
+ class ClientLoginHeaderHandler < AdsCommon::SavonHeaders::BaseHeaderHandler
6
+ # Initializes a header handler.
7
+ #
8
+ # Args:
9
+ # - credential_handler: a header with credential data
10
+ # - auth_handler: a header with auth data
11
+ # - element_name: an API-specific name of header element
12
+ # - namespace: default namespace to use
13
+ # - auth_namespace: namespace to use for auth headers
14
+ # - version: services version
15
+ #
16
+ #def initialize(credential_handler, auth_handler, namespace, auth_namespace, version)
17
+ def initialize(credential_handler, auth_handler, namespace, version)
18
+ super(credential_handler, auth_handler, namespace, version)
19
+ #@auth_namespace = auth_namespace
20
+ end
21
+
22
+ # Enriches soap object with API-specific headers like namespaces, login
23
+ # credentials etc. Sets the default namespace for the body to the one
24
+ # specified in initializer.
25
+ #
26
+ # Args:
27
+ # - request: a HTTPI Request for extra configuration (unused)
28
+ # - soap: a Savon soap object to fill fields in
29
+ #
30
+ # Returns:
31
+ # - modified soap structure
32
+ #
33
+ def prepare_request(request, soap)
34
+ super(request, soap)
35
+ soap.header[:attributes!] ||= {}
36
+ header_name = prepend_namespace(get_header_element_name())
37
+ soap.header[:attributes!][header_name] ||= {}
38
+ #soap.header[:attributes!][header_name]['xmlns'] = @auth_namespace
39
+ return soap
40
+ end
41
+
42
+ private
43
+ # Skips namespace prefixes for all elements except top level. Use default
44
+ # (inherited) prefixing for the top level key.
45
+ #
46
+ # Args:
47
+ # - str: String to prepend with a namespace
48
+ #
49
+ # Returns:
50
+ # - String with a namespace
51
+ #
52
+ def prepend_namespace(str)
53
+ #return get_header_element_name().eql?(str) ? super(str) : str
54
+ super(str)
55
+ end
56
+
57
+ # Generates Adcenter API specific request header with ClientLogin data.
58
+ def generate_request_header()
59
+ request_header = super()
60
+ #puts "--------------- generate_request_header >> request_header >>\n#{request_header}"
61
+ credentials = @credential_handler.credentials
62
+ #puts "--------------- generate_request_header >> credentials >>\n#{credentials}"
63
+ #request_header['authToken'] = @auth_handler.get_token(credentials)
64
+ credentials.each {|k,v| request_header[prepend_namespace(k.to_s.camelize)] = v}
65
+ request_header.select!{|k,_| ['ApplicationToken', 'CustomerAccountId', 'CustomerId', 'DeveloperToken', 'UserName', 'Password'].map{|h| prepend_namespace(h)}.include?(k.to_s)}
66
+ #puts "--------------- generate_request_header >> request_header final >>\n#{request_header}"
67
+ return request_header
68
+ end
69
+ end
70
+ end