gnib-ads-api 0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +121 -0
  4. data/Rakefile +38 -0
  5. data/lib/gnib-ads-api.rb +44 -0
  6. data/lib/gnib-ads-api.yml +355 -0
  7. data/lib/gnib-ads-api/api_exception.rb +42 -0
  8. data/lib/gnib-ads-api/client_proxy.rb +147 -0
  9. data/lib/gnib-ads-api/config.rb +75 -0
  10. data/lib/gnib-ads-api/constants.rb +150 -0
  11. data/lib/gnib-ads-api/data/accounts_info.rb +72 -0
  12. data/lib/gnib-ads-api/data/ad.rb +119 -0
  13. data/lib/gnib-ads-api/data/ad_group.rb +121 -0
  14. data/lib/gnib-ads-api/data/campaign.rb +40 -0
  15. data/lib/gnib-ads-api/data/report_request.rb +78 -0
  16. data/lib/gnib-ads-api/data/report_request_status.rb +48 -0
  17. data/lib/gnib-ads-api/data/reporting/account_performance_report_request.rb +176 -0
  18. data/lib/gnib-ads-api/data/reporting/campaign_performance_report_request.rb +186 -0
  19. data/lib/gnib-ads-api/data/reporting/helpers/column_helper.rb +65 -0
  20. data/lib/gnib-ads-api/data/reporting/helpers/filter_helper.rb +124 -0
  21. data/lib/gnib-ads-api/data/reporting/helpers/scope_helper.rb +51 -0
  22. data/lib/gnib-ads-api/data/reporting/helpers/time_helper.rb +69 -0
  23. data/lib/gnib-ads-api/data/reporting/performance_report_request.rb +78 -0
  24. data/lib/gnib-ads-api/data_object.rb +35 -0
  25. data/lib/gnib-ads-api/fault/ad_api_error.rb +15 -0
  26. data/lib/gnib-ads-api/fault/ad_api_fault_detail.rb +67 -0
  27. data/lib/gnib-ads-api/fault/api_fault_detail.rb +97 -0
  28. data/lib/gnib-ads-api/fault/application_fault.rb +18 -0
  29. data/lib/gnib-ads-api/fault/batch_error.rb +47 -0
  30. data/lib/gnib-ads-api/fault/operation_error.rb +22 -0
  31. data/lib/gnib-ads-api/fault/partial_errors.rb +75 -0
  32. data/lib/gnib-ads-api/service.rb +176 -0
  33. data/lib/gnib-ads-api/service/campaign_management.rb +483 -0
  34. data/lib/gnib-ads-api/service/customer_management.rb +83 -0
  35. data/lib/gnib-ads-api/service/reporting.rb +101 -0
  36. data/lib/gnib-ads-api/soap_hasheable.rb +160 -0
  37. data/lib/gnib-ads-api/version.rb +6 -0
  38. data/lib/locales/es.yml +174 -0
  39. data/lib/tasks/gnib-ads-api_tasks.rake +4 -0
  40. data/test/campaign_management_test.rb +463 -0
  41. data/test/customer_management_test.rb +44 -0
  42. data/test/data_object_test.rb +46 -0
  43. data/test/dummy/README.rdoc +261 -0
  44. data/test/dummy/Rakefile +7 -0
  45. data/test/dummy/app/assets/javascripts/application.js +15 -0
  46. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  47. data/test/dummy/app/controllers/application_controller.rb +3 -0
  48. data/test/dummy/app/helpers/application_helper.rb +2 -0
  49. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  50. data/test/dummy/config.ru +4 -0
  51. data/test/dummy/config/application.rb +56 -0
  52. data/test/dummy/config/boot.rb +10 -0
  53. data/test/dummy/config/database.yml +25 -0
  54. data/test/dummy/config/environment.rb +5 -0
  55. data/test/dummy/config/environments/development.rb +37 -0
  56. data/test/dummy/config/environments/production.rb +67 -0
  57. data/test/dummy/config/environments/test.rb +37 -0
  58. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  59. data/test/dummy/config/initializers/inflections.rb +15 -0
  60. data/test/dummy/config/initializers/mime_types.rb +5 -0
  61. data/test/dummy/config/initializers/secret_token.rb +7 -0
  62. data/test/dummy/config/initializers/session_store.rb +8 -0
  63. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  64. data/test/dummy/config/locales/en.yml +5 -0
  65. data/test/dummy/config/routes.rb +58 -0
  66. data/test/dummy/public/404.html +26 -0
  67. data/test/dummy/public/422.html +26 -0
  68. data/test/dummy/public/500.html +25 -0
  69. data/test/dummy/public/favicon.ico +0 -0
  70. data/test/dummy/script/rails +6 -0
  71. data/test/gnib-ads-api_test.rb +172 -0
  72. data/test/report_request_test.rb +312 -0
  73. data/test/reporting_test.rb +145 -0
  74. data/test/test_helper.rb +11 -0
  75. metadata +193 -0
@@ -0,0 +1,42 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ module GnibAdsApi
4
+
5
+ # Public : Generic exception thrown by service classes in GnibAdsApi.
6
+ # Exception of this kind wrap an AdApiFaultDetail or ApiFaultDetail instance
7
+ # to look over the specific details of the SOAP request fault.
8
+ #
9
+ # Author:: jlopezn@neonline.cl
10
+ #
11
+ # Example
12
+ #
13
+ #
14
+ #
15
+ #
16
+ class ApiException < Exception
17
+
18
+ attr_accessor :fault_object
19
+
20
+ # Public : Constructor. Based on the default Exception constructor,
21
+ # adds the fault_object instance, that can be an ApiFaultDetail or
22
+ # AdApiFaultDetail instance
23
+ #
24
+ # === Parameters
25
+ # * fault_object - AdApiFaultDetail or ApiFaultDetail instance
26
+ # * msg - optional message
27
+ #
28
+ # Author:: jlopezn@neonline.cl
29
+ def initialize(fault_object, msg=nil)
30
+ super(msg)
31
+ self.fault_object = fault_object
32
+ end
33
+
34
+
35
+ # Public : Specified to string method
36
+ #
37
+ # Author:: jlopezn@neonline.cl
38
+ def to_s
39
+ super.to_s + " - " + fault_object.to_s
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,147 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ module GnibAdsApi
4
+
5
+ # Public : ClientProxy es un objeto para encapsular la conexión y request
6
+ # de servicios a la API de Bing. En su inicialización requiere los datos
7
+ # de autenticación y el WSDL al servicio que se requiere.
8
+ #
9
+ # Author:: jlopezn@neonline.cl
10
+ #
11
+ # Examples
12
+ # # => hash con datos autenticación y WSDL
13
+ # options = {
14
+ # :username => "username",
15
+ # :password => "password",
16
+ # :developer_token => "THE_TOKEN",
17
+ # :customer_id => "123456",
18
+ # :account_id => "123456",
19
+ # :wsdl_url => "https://api.sandbox.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v9/CampaignManagementService.svc?singleWsdl"
20
+ # }
21
+ # # => Instancia de ClientProxy
22
+ # client = GnibAdsApi::ClientProxy.new(options)
23
+ # # => Llamada a servicio 'GetCampaignsByAccountId'
24
+ # response = client.service.call(:get_campaigns_by_account_id,
25
+ # message: { Account_id: client.account_id})
26
+ class ClientProxy
27
+
28
+ # Public : Namespace para atributos bing. Hace referencia a la versión de API usada
29
+ NAMESPACE = :v9
30
+
31
+ # Public : Case empleado los nombres de atributos en los XML
32
+ KEYS_CASE = :camelcase
33
+
34
+
35
+ # Atributos del client proxy
36
+ attr_accessor :username, :password, :developer_token, :authentication_token, :wsdl_url, :account_id, :customer_id, :service, :namespace
37
+
38
+ # Public : Constructor
39
+ #
40
+ # Author:: jlopezn@neonline.cl
41
+ #
42
+ # === Parameters
43
+ # options - Hash con valores de autenticación y WSDL
44
+ #
45
+ #
46
+ # === Options
47
+ # * username - Bing Ads username
48
+ # * passwrod - Bing Ads user's sign-in password
49
+ # * developer_token - client application's developer access token
50
+ # * customer_id - identifier for the customer that owns the account
51
+ # * account_id - identifier of the account that own the entities in the request
52
+ # * wsdl_url - URL for the WSDL to be called
53
+ # * proxy - Hash with any Novas Client additional options (such as header, logger or enconding)
54
+ #
55
+ # === Examples
56
+ # options = {
57
+ # :username => "username",
58
+ # :password => "password",
59
+ # :developer_token => "THE_TOKEN",
60
+ # :customer_id => "123456",
61
+ # :account_id => "123456",
62
+ # :wsdl_url => "https://api.sandbox.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v9/CampaignManagementService.svc?singleWsdl"
63
+ # }
64
+ # # => Instancia de ClientProxy
65
+ # client = GnibAdsApi::ClientProxy.new(options)
66
+ #
67
+ # Returns:: ClientProxy instance
68
+ def initialize(options=nil)
69
+ if options
70
+ if options[:authentication_token]
71
+ @authentication_token ||= options[:authentication_token]
72
+ else
73
+ @username ||= options[:username]
74
+ @password ||= options[:password]
75
+ end
76
+ @developer_token ||= options[:developer_token]
77
+ @wsdl_url ||= options[:wsdl_url]
78
+ @account_id ||= options[:account_id]
79
+ @customer_id ||= options[:customer_id]
80
+ @namespace ||= options[:namespace]
81
+ end
82
+ self.service = get_proxy(options[:proxy])
83
+ end
84
+
85
+
86
+ # Public : Delegate for Novas::Client.call method
87
+ #
88
+ # Author:: jlopezn@neonline.cl
89
+ #
90
+ # === Parameters
91
+ # service_name - Service to be called
92
+ # message - Message for the service
93
+ # options - Additional options for the service
94
+ #
95
+ # === Examples
96
+ # client.call_service(:some_service_name, {key: value})
97
+ # # => <Response>
98
+ #
99
+ # Returns:: Response from the Novas::Client
100
+ # Raises:: Novas::SOAPFault Novas::HTTPError Novas::InvalidResponseError
101
+ def call(service_name, message, options={})
102
+ self.service.call(service_name, message)
103
+ end
104
+
105
+
106
+ private
107
+ # Internal : Wrapper for Novas client instances
108
+ #
109
+ # Author:: jlopezn@neonline.cl
110
+ #
111
+ # Examples
112
+ # get_proxy
113
+ # # => <Novas::Client>
114
+ #
115
+ # Returns:: Novas client instance
116
+ def get_proxy(client_settings)
117
+
118
+ settings = {
119
+ convert_request_keys_to: KEYS_CASE,
120
+ wsdl: self.wsdl_url,
121
+ namespace_identifier: NAMESPACE,
122
+ soap_header: build_headers
123
+ }
124
+ settings.merge(client_settings) if client_settings
125
+ puts "settings"
126
+ puts settings
127
+ return Novas.client(settings)
128
+ end
129
+
130
+
131
+ def build_headers
132
+ headers = {
133
+ "#{NAMESPACE.to_s}:CustomerAccountId" => self.account_id,
134
+ "#{NAMESPACE.to_s}:CustomerId" => self.customer_id,
135
+ "#{NAMESPACE.to_s}:DeveloperToken" => self.developer_token,
136
+ }
137
+ if self.authentication_token
138
+ headers["#{NAMESPACE.to_s}:AuthenticationToken"] = self.authentication_token
139
+ else
140
+ headers["#{NAMESPACE.to_s}:UserName"] = self.username
141
+ headers["#{NAMESPACE.to_s}:Password"] = self.password
142
+ end
143
+ return headers
144
+ end
145
+ end
146
+
147
+ end
@@ -0,0 +1,75 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'singleton'
3
+
4
+ module GnibAdsApi
5
+
6
+ # Public : Helper class for configuration issues like WSDL URLs and constants
7
+ #
8
+ # Author:: author@neonline.cl
9
+ #
10
+ # Examples
11
+ # class_usage
12
+ # # => class_usage_return
13
+ class Config
14
+ include Singleton
15
+
16
+ # Array with Bing Ads API environments: +sandbox+ and +production+
17
+ ENVIRONMENTS = ['sandbox', 'production']
18
+
19
+ attr_accessor :config
20
+ @config = YAML.load_file(File.join(File.dirname(__FILE__),"../gnib-ads-api.yml"))
21
+
22
+ # Public : Constructor
23
+ #
24
+ # Author:: jlopezn@neonline.cl
25
+ def initialize
26
+ @config = YAML.load_file(File.join(File.dirname(__FILE__),"../gnib-ads-api.yml"))
27
+ end
28
+
29
+ # Public : Returns the config file as an Hash instance
30
+ #
31
+ # Author:: jlopezn@neonline.cl
32
+ #
33
+ # Returns:: Hash
34
+ def self.hash_instance
35
+ instance.config
36
+ end
37
+
38
+ ## Constants
39
+ @config['constants'].each do |key, value|
40
+
41
+ define_method("#{key.to_s}_constants") do |constant=nil|
42
+ value[constant.to_s] if constant
43
+ value
44
+ end
45
+
46
+ end
47
+
48
+
49
+ # Public : Returns a String with WSDL url for the service indicated
50
+ #
51
+ # Author:: jlopezn@neonline.cl
52
+ #
53
+ # === Parameters
54
+ # environment - Bing Environment: 'sandbox' or 'production'
55
+ # service - service name
56
+ #
57
+ # === Examples
58
+ # config.service_wsdl(:sandbox, :campaign_management)
59
+ # # => "https://api.sandbox.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v9/CampaignManagementService.svc?singleWsdl"
60
+ #
61
+ # Returns:: returns
62
+ # Raises:: exception
63
+ def service_wsdl(environment, service)
64
+ if (ENVIRONMENTS.include?(environment.to_s))
65
+ if @config['wsdl'][environment.to_s].include?(service.to_s)
66
+ return @config['wsdl'][environment.to_s][service.to_s]
67
+ end
68
+ raise "Unknown service '#{service.to_s}'. Available services: #{@config['wsdl'][environment.to_s].keys.join(", ")}"
69
+ end
70
+ raise "Invalid environment: #{environment}. Value should be 'sandbox' or 'production'"
71
+ end
72
+
73
+ end
74
+
75
+ end
@@ -0,0 +1,150 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ module GnibAdsApi
4
+
5
+ # Public : Utility class for TimeZones values
6
+ #
7
+ # Example
8
+ # GnibAdsApi::TimeZone.SANTIAGO
9
+ # # => 'Santiago'
10
+ #
11
+ # Author:: jlopezn@neonline.cl
12
+ module TimeZone
13
+
14
+
15
+ GnibAdsApi::Config.instance.common_constants['time_zones'].each do |key, value|
16
+ TimeZone.const_set(key.upcase, value)
17
+ end
18
+
19
+ end
20
+
21
+ # Public : Utility class for AdLanguages values
22
+ #
23
+ # Example
24
+ # GnibAdsApi::AdLanguages.SPANISH
25
+ # # => 'Spanish'
26
+ # GnibAdsApi::AdLanguages.SPANISH_CODE
27
+ # # => 'ES'
28
+ #
29
+ # Author:: jlopezn@neonline.cl
30
+ module AdLanguage
31
+
32
+ GnibAdsApi::Config.instance.common_constants['ad_languages'].each do |key, value|
33
+ if key == 'codes'
34
+ value.each do |code_key, code_value|
35
+ AdLanguage.const_set("#{code_key.upcase}_CODE", code_value)
36
+ end
37
+ else
38
+ AdLanguage.const_set(key.upcase, value)
39
+ end
40
+ end
41
+
42
+ end
43
+
44
+
45
+ ## Dynamic classes for campaign management constants
46
+ GnibAdsApi::Config.instance.campaign_management_constants.each do |const_key, const_value|
47
+
48
+ const_module = Module.new do
49
+ # Dynamically create Constants classes for each value found
50
+ const_value.each do |key, value|
51
+ self.const_set(key.upcase, value)
52
+ end
53
+
54
+ end
55
+ GnibAdsApi.const_set(const_key.camelize, const_module)
56
+
57
+ end
58
+
59
+
60
+ ## Dynamic classes for customer management constants
61
+ GnibAdsApi::Config.instance.customer_management_constants.each do |const_key, const_value|
62
+
63
+ const_module = Module.new do
64
+ # Dynamically create Constants classes for each value found
65
+ const_value.each do |key, value|
66
+ self.const_set(key.upcase, value)
67
+ end
68
+
69
+ end
70
+ GnibAdsApi.const_set(const_key.camelize, const_module)
71
+
72
+ end
73
+
74
+
75
+
76
+ # Public : Module for Reporting formats
77
+ #
78
+ # Example
79
+ # GnibAdsApi::ReportFormat.CSV
80
+ # # => 'Csv'
81
+ #
82
+ # Author:: jlopezn@neonline.cl
83
+ module ReportFormat
84
+ GnibAdsApi::Config.instance.reporting_constants['format'].each do |key, value|
85
+ ReportFormat.const_set(key.upcase, value)
86
+ end
87
+ end
88
+
89
+
90
+ # Public : Module for Reporting languages
91
+ #
92
+ # Example
93
+ # GnibAdsApi::ReportLanguage.ENGLISH
94
+ # # => 'English'
95
+ #
96
+ # Author:: jlopezn@neonline.cl
97
+ module ReportLanguage
98
+ GnibAdsApi::Config.instance.reporting_constants['language'].each do |key, value|
99
+ ReportLanguage.const_set(key.upcase, value)
100
+ end
101
+ end
102
+
103
+
104
+ # Public : Module for Reporting languages
105
+ #
106
+ # Example
107
+ # GnibAdsApi::ReportAggregation.SUMMARY
108
+ # # => 'Summary'
109
+ # GnibAdsApi::ReportAggregation.HOURLY
110
+ # # => 'Hourly'
111
+ #
112
+ # Author:: jlopezn@neonline.cl
113
+ module ReportAggregation
114
+ GnibAdsApi::Config.instance.reporting_constants['aggregation'].each do |key, value|
115
+ ReportAggregation.const_set(key.upcase, value)
116
+ end
117
+ end
118
+
119
+
120
+ # Public : Module for Reporting languages
121
+ #
122
+ # Example
123
+ # GnibAdsApi::ReportTimePeriods.TODAY
124
+ # # => 'Today'
125
+ # GnibAdsApi::ReportTimePeriods.LAST_WEEK
126
+ # # => 'LastWeek'
127
+ #
128
+ # Author:: jlopezn@neonline.cl
129
+ module ReportTimePeriods
130
+ GnibAdsApi::Config.instance.reporting_constants['time_periods'].each do |key, value|
131
+ ReportTimePeriods.const_set(key.upcase, value)
132
+ end
133
+ end
134
+
135
+
136
+ ## Dynamic classes for reporting constants
137
+ # GnibAdsApi::Config.instance.reporting_constants.each do |const_key, const_value|
138
+ #
139
+ # const_module = Module.new do
140
+ # # Dynamically create Constants classes for each value found
141
+ # const_value.each do |key, value|
142
+ # self.const_set(key.upcase, value)
143
+ # end
144
+ #
145
+ # end
146
+ # GnibAdsApi.const_set(const_key.camelize, const_module)
147
+ #
148
+ # end
149
+
150
+ end
@@ -0,0 +1,72 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ module GnibAdsApi
4
+
5
+ # Public : Define an account info
6
+ #
7
+ # Author:: jlopezn@neonline.cl
8
+ #
9
+ # Examples
10
+ # campaign = GnibAdsApi::AccountInfo.new(
11
+ # :account_life_cycle_status => GnibAdsApi::AccountsInfo::DRAFT
12
+ # :name => "Account Name",
13
+ # :number => 1234567,
14
+ # :pause_reason => "1")
15
+ # # => <GnibAdsApi::AccountInfo>
16
+ class AccountInfo < GnibAdsApi::DataObject
17
+ include GnibAdsApi::AccountLifeCycleStatuses
18
+
19
+ attr_accessor :id, :account_life_cycle_status, :name, :number, :pause_reason
20
+
21
+ # Public:: Returns true if the account is in status active
22
+ #
23
+ # Author:: jlopezn@neonline.cl
24
+ #
25
+ # Returns:: boolean
26
+ def active?
27
+ return account_life_cycle_status == ACTIVE
28
+ end
29
+
30
+
31
+ # Public:: Returns true if the account is in status draft
32
+ #
33
+ # Author:: jlopezn@neonline.cl
34
+ #
35
+ # Returns:: boolean
36
+ def draft?
37
+ return account_life_cycle_status == DRAFT
38
+ end
39
+
40
+
41
+ # Public:: Returns true if the account is in status inactive
42
+ #
43
+ # Author:: jlopezn@neonline.cl
44
+ #
45
+ # Returns:: boolean
46
+ def inactive?
47
+ return account_life_cycle_status == INACTIVE
48
+ end
49
+
50
+
51
+ # Public:: Returns true if the account is in status pause
52
+ #
53
+ # Author:: jlopezn@neonline.cl
54
+ #
55
+ # Returns:: boolean
56
+ def pause?
57
+ return account_life_cycle_status == PAUSE
58
+ end
59
+
60
+
61
+ # Public:: Returns true if the account is in status pending
62
+ #
63
+ # Author:: jlopezn@neonline.cl
64
+ #
65
+ # Returns:: boolean
66
+ def pending?
67
+ return account_life_cycle_status == PENDING
68
+ end
69
+
70
+ end
71
+
72
+ end