gnib-ads-api 0.3

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.
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