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,176 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ module GnibAdsApi
4
+
5
+ # Public : Base class for service object
6
+ #
7
+ # Author:: jlopezn@neonline.cl
8
+ #
9
+ class Service
10
+
11
+ attr_accessor :client_proxy, :environment
12
+
13
+ # Default logger for services
14
+ LOGGER = Logger.new(STDOUT)
15
+
16
+
17
+ # Public : Constructor
18
+ #
19
+ # Author:: jlopezn@neonline.cl
20
+ #
21
+ # === Parameters
22
+ # * +options+ - Hash with autentication and environment settings
23
+ #
24
+ # === Options
25
+ # * environment - +:production+ or +:sandbox+
26
+ # * username - Bing Ads username
27
+ # * passwrod - Bing Ads user's sign-in password
28
+ # * developer_token - client application's developer access token
29
+ # * customer_id - identifier for the customer that owns the account
30
+ # * account_id - identifier of the account that own the entities in the request
31
+ # * proxy - Hash with any Client Proxy additional options (such as header, logger or enconding)
32
+ #
33
+ # === Examples
34
+ # service = GnibAdsApi::Service.new(
35
+ # :environment => :sandbox,
36
+ # :username => 'username',
37
+ # :password => 'pass',
38
+ # :developer_token => 'SOME_TOKEN',
39
+ # :account_id => 123456,
40
+ # :customer_id => 654321,
41
+ # :proxy => {:logger => Rails.logger}
42
+ # )
43
+ # # => <Service>
44
+ def initialize(options={})
45
+
46
+ # Service Environment
47
+ self.environment = options[:environment]
48
+
49
+ # ClientProxy settings
50
+ clientProxySettings = {
51
+ :username => options[:username],
52
+ :password => options[:password],
53
+ :developer_token => options[:developer_token],
54
+ :account_id => options[:account_id],
55
+ :customer_id => options[:customer_id],
56
+ :wsdl_url => options[:wdsl] || solve_wsdl_url
57
+ }
58
+
59
+ # Additionsl ClientProxy settings
60
+ clientProxySettings[:proxy] = options[:proxy] if options[:proxy]
61
+
62
+ # ClientProxy creation
63
+ self.client_proxy = GnibAdsApi::ClientProxy.new(clientProxySettings)
64
+
65
+ end
66
+
67
+
68
+ # Public : This is a utility wrapper for calling services into the
69
+ # +ClientProxy+. This methods handle all the +Novas::Client+ Exceptions
70
+ # and returns a Hash with the call response
71
+ #
72
+ # Author:: jlopezn@neonline.cl
73
+ #
74
+ # === Parameters
75
+ # +operation+ - name of the operation to be called
76
+ # +message+ - hash with the parameters to the operation
77
+ #
78
+ # === Examples
79
+ # service.call(:some_operation, {key: value})
80
+ # # => <Hash>
81
+ #
82
+ # Returns:: Hash with the result of the service call
83
+ # Raises:: ServiceError if the SOAP call, the ClientProxy fails or the response is invalid
84
+ def call(operation, message, &block)
85
+ raise "You must provide an operation" if operation.nil?
86
+ begin
87
+ LOGGER.debug "GnibAdsApi Service"
88
+ LOGGER.debug " Calling #{operation.to_s}"
89
+ LOGGER.debug " Message: #{message}"
90
+ response = self.client_proxy.call(operation.to_sym,
91
+ message: message)
92
+
93
+ LOGGER.debug "response header:"
94
+ LOGGER.debug "\t#{response.header}"
95
+
96
+ LOGGER.info "Operation #{operation.to_s} call success"
97
+ return response.hash
98
+ rescue Novas::SOAPFault => error
99
+ LOGGER.error "SOAP Error calling #{operation.to_s}: #{error.http.code}"
100
+ fault_detail = error.to_hash[:fault][:detail]
101
+ if fault_detail.key?(:api_fault_detail)
102
+ api_fault_detail = GnibAdsApi::ApiFaultDetail.new(fault_detail[:api_fault_detail])
103
+ raise GnibAdsApi::ApiException.new(
104
+ api_fault_detail, "SOAP Error calling #{operation.to_s}")
105
+ elsif fault_detail.key?(:ad_api_fault_detail)
106
+ ad_api_fault_detail = GnibAdsApi::AdApiFaultDetail.new(fault_detail[:ad_api_fault_detail])
107
+ raise GnibAdsApi::ApiException.new(
108
+ ad_api_fault_detail, "SOAP Error calling #{operation.to_s}")
109
+ else
110
+ raise
111
+ end
112
+ rescue Novas::HTTPError => error
113
+ LOGGER.error "Http Error calling #{operation.to_s}: #{error.http.code}"
114
+ raise
115
+ rescue Novas::InvalidResponseError => error
116
+ LOGGER.error "Invalid server reponse calling #{operation.to_s}"
117
+ raise
118
+ end
119
+ end
120
+
121
+
122
+ # Public : Extracts the actual response from the entire response hash.
123
+ # For example, if you specify 'AddCampaigns', this method will return
124
+ # the content of 'AddCampaignsResponse' tag as a Hash
125
+ #
126
+ # Author:: jlopezn@neonline.cl
127
+ #
128
+ # === Parameters
129
+ # response - The complete response hash received from a Operation call
130
+ # method - Name of the method of with the 'reponse' tag is require
131
+ #
132
+ # === Examples
133
+ # service.get_response_hash(Hash, 'add_campaigns')
134
+ # # => Hash
135
+ #
136
+ # Returns:: Hash with the inner structure of the method response hash
137
+ # Raises:: exception
138
+ def get_response_hash(response, method)
139
+ return response[:envelope][:body]["#{method}_response".to_sym]
140
+ end
141
+
142
+ private
143
+
144
+ # Private : This method must be overriden by specific services.
145
+ # Returns:: the service name
146
+ #
147
+ # Author:: jlopezn@neonline.cl
148
+ #
149
+ # Examples
150
+ # get_service_name
151
+ # # => "service_name"
152
+ #
153
+ # Returns:: String with the service name
154
+ # Raises:: exception if the specific Service class hasn't overriden this method
155
+ def get_service_name
156
+ raise "Should return the a service name from config.wsdl keys"
157
+ end
158
+
159
+
160
+ # Private : Solves the service WSDL URL based on his service name
161
+ # and environment values
162
+ #
163
+ # Author:: jlopezn@neonline.cl
164
+ #
165
+ # Examples
166
+ # solve_wsdl_url
167
+ # # => "https://bing.wsdl.url.com"
168
+ #
169
+ # Returns:: String with the Service url
170
+ def solve_wsdl_url
171
+ config = GnibAdsApi::Config.instance
172
+ return config.service_wsdl(environment, get_service_name)
173
+ end
174
+ end
175
+
176
+ end
@@ -0,0 +1,483 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module GnibAdsApi
3
+
4
+
5
+ # Public : This class represents the Campaign Management Services
6
+ # defined in the Bing Ads API, to manage advertising campaigns
7
+ #
8
+ # Author:: jlopezn@neonline.cl
9
+ #
10
+ # Examples
11
+ # options = {
12
+ # :environment => :sandbox,
13
+ # :username => "username",
14
+ # :password => "pass",
15
+ # :developer_token => "SOME_TOKEN",
16
+ # :customer_id => "1234567",
17
+ # :account_id => "9876543" }
18
+ # service = GnibAdsApi::CampaignManagement.new(options)
19
+ class CampaignManagement < GnibAdsApi::Service
20
+
21
+
22
+ # Public : Constructor
23
+ #
24
+ # Author:: jlopezn@neonline.cl
25
+ #
26
+ # options - Hash with the parameters for the client proxy and the environment
27
+ #
28
+ # Examples
29
+ # options = {
30
+ # :environment => :sandbox,
31
+ # :username => "username",
32
+ # :password => "password",
33
+ # :developer_token => "DEV_TOKEN",
34
+ # :customer_id => "123456",
35
+ # :account_id => "654321"
36
+ # }
37
+ # service = GnibAdsApi::CampaignManagement.new(options)
38
+ def initialize(options={})
39
+ super(options)
40
+ end
41
+
42
+
43
+ #########################
44
+ ## Operations Wrappers ##
45
+ #########################
46
+
47
+ # Public : Returns all the campaigns found in the specified account
48
+ #
49
+ # Author:: jlopezn@neonline.cl
50
+ #
51
+ # === Parameters
52
+ # account_id - account who owns the campaigns
53
+ #
54
+ # === Examples
55
+ # campaign_management_service.get_campaigns_by_account_id(1)
56
+ # # => Array[GnibAdsApi::Campaign]
57
+ #
58
+ # Returns:: Array of GnibAdsApi::Campaign
59
+ #
60
+ # Raises:: exception
61
+ def get_campaigns_by_account_id(account_id)
62
+ response = call(:get_campaigns_by_account_id,
63
+ {account_id: account_id})
64
+ response_hash = get_response_hash(response, __method__)
65
+ campaigns = response_hash[:campaigns][:campaign].map do |camp_hash|
66
+ GnibAdsApi::Campaign.new(camp_hash)
67
+ end
68
+ return campaigns
69
+ end
70
+
71
+
72
+ # Public : Adds a campaign to the specified account
73
+ #
74
+ # Author:: jlopezn@neonline.cl
75
+ #
76
+ # === Parameters
77
+ # account_id - account who will own the newly campaigns
78
+ # campaigns - An array of GnibAdsApi::Campaign
79
+ #
80
+ # === Examples
81
+ # service.add_campaigns(1, [<GnibAdsApi::Campaign>])
82
+ # # => <Hash>
83
+ #
84
+ # Returns:: hash with the 'add_campaigns_response' structure
85
+ #
86
+ # Raises:: exception
87
+ def add_campaigns(account_id, campaigns)
88
+
89
+ camps = []
90
+ if campaigns.is_a? Array
91
+ camps = campaigns.map{ |camp| camp.to_hash(:camelcase) }
92
+ elsif campaigns.is_a? GnibAdsApi::Campaign
93
+ camps = campaigns.to_hash
94
+ else
95
+ raise "campaigns must be an array of GnibAdsApi::Campaigns"
96
+ end
97
+ message = {
98
+ :account_id => account_id,
99
+ :campaigns => {:campaign => camps} }
100
+ puts message
101
+ response = call(:add_campaigns, message)
102
+ return get_response_hash(response, __method__)
103
+ end
104
+
105
+
106
+ # Public : Updates on or more campaigns for the specified account
107
+ #
108
+ # Author:: jlopezn@neonline.cl
109
+ #
110
+ # === Parameters
111
+ # account_id - account who own the updated campaigns
112
+ # campaigns - Array with the campaigns to be updated
113
+ #
114
+ # === Examples
115
+ # service_update_campaigns(1, [<GnibAdsApi::Campaign])
116
+ # # => true
117
+ #
118
+ # Returns:: boolean. true if the update was successful. false otherwise
119
+ #
120
+ # Raises:: exception
121
+ def update_campaigns(account_id, campaigns)
122
+ camps = []
123
+ if campaigns.is_a? Array
124
+ camps = campaigns.map do |camp|
125
+ camp.to_hash(:camelcase)
126
+ end
127
+ elsif campaigns.is_a? GnibAdsApi::Campaign
128
+ camps = campaigns.to_hash
129
+ else
130
+ raise "campaigns must be an array of GnibAdsApi::Campaigns"
131
+ end
132
+ message = {
133
+ :account_id => account_id,
134
+ :campaigns => {:campaign => camps} }
135
+ puts message
136
+ response = call(:update_campaigns, message)
137
+ return get_response_hash(response, __method__)
138
+
139
+ end
140
+
141
+
142
+ # Public : Returns all the ad groups that belongs to the
143
+ # specified campaign
144
+ #
145
+ # Author:: jlopezn@neonline.cl
146
+ #
147
+ # === Parameters
148
+ # campaign_id - campaign id
149
+ #
150
+ # === Examples
151
+ # service.get_ad_groups_by_campaign_id(1)
152
+ # # => Array[AdGroups]
153
+ #
154
+ # Returns:: Array with all the ad groups present in campaign_id
155
+ #
156
+ # Raises:: exception
157
+ def get_ad_groups_by_campaign_id(campaign_id)
158
+ response = call(:get_ad_groups_by_campaign_id,
159
+ {campaign_id: campaign_id})
160
+ response_hash = get_response_hash(response, __method__)
161
+ ad_groups = response_hash[:ad_groups][:ad_group].map do |ad_group_hash|
162
+ GnibAdsApi::AdGroup.new(ad_group_hash)
163
+ end
164
+ return ad_groups
165
+ end
166
+
167
+
168
+ # Public : Returns the specified ad groups that belongs to the
169
+ # specified campaign
170
+ #
171
+ # Author:: jlopezn@neonline.cl
172
+ #
173
+ # === Parameters
174
+ # campaign_id - campaign id
175
+ # ad_groups_ids - array with ids from ad groups
176
+ #
177
+ # === Examples
178
+ # service.get_ad_groups_by_ids(1, [1,2,3])
179
+ # # => Array[AdGroups]
180
+ #
181
+ # Returns:: Array with the ad groups specified in the ad_groups_ids array
182
+ #
183
+ # Raises:: exception
184
+ def get_ad_groups_by_ids(campaign_id, ad_groups_ids)
185
+
186
+ message = {
187
+ :campaign_id => campaign_id,
188
+ :ad_group_ids => {"ins1:long" => ad_groups_ids} }
189
+ response = call(:get_ad_groups_by_ids, message)
190
+ response_hash = get_response_hash(response, __method__)
191
+ ad_groups = response_hash[:ad_groups][:ad_group].map do |ad_group_hash|
192
+ GnibAdsApi::AdGroup.new(ad_group_hash)
193
+ end
194
+ return ad_groups
195
+
196
+ end
197
+
198
+
199
+ # Public : Adds 1 or more AdGroups to a Campaign
200
+ #
201
+ # Author:: jlopezn@neonline.cl
202
+ #
203
+ # === Parameters
204
+ # campaing_id - the campaign id where the ad groups will be added
205
+ # ad_groups - Array[GnibAdsApi::AdGroup] ad groups to be added
206
+ #
207
+ # === Examples
208
+ # service.add_ad_groups(1, [<GnibAdsApi::AdGroup>])
209
+ # # => <Hash>
210
+ #
211
+ # Returns:: Hash with the 'add_ad_groups_response' structure
212
+ #
213
+ # Raises:: exception
214
+ def add_ad_groups(campaign_id, ad_groups)
215
+
216
+ groups = []
217
+ if ad_groups.is_a? Array
218
+ groups = ad_groups.map{ |gr| gr.to_hash(:camelcase) }
219
+ elsif ad_groups.is_a? GnibAdsApi::AdGroup
220
+ groups = ad_groups.to_hash
221
+ else
222
+ raise "ad_groups must be an array of GnibAdsApi::AdGroup"
223
+ end
224
+ message = {
225
+ :campaign_id => campaign_id,
226
+ :ad_groups => {:ad_group => groups} }
227
+ puts message
228
+ response = call(:add_ad_groups, message)
229
+ return get_response_hash(response, __method__)
230
+ end
231
+
232
+
233
+ # Public : Updates on or more ad groups in a specified campaign
234
+ #
235
+ # Author:: jlopezn@neonline.cl
236
+ #
237
+ # === Parameters
238
+ # campaign_id - campaign who owns the updated ad groups
239
+ #
240
+ # === Examples
241
+ # service.update_ad_groups(1, [<GnibAdsApi::AdGroup])
242
+ # # => true
243
+ #
244
+ # Returns:: boolean. true if the updates is successfull. false otherwise
245
+ #
246
+ # Raises:: exception
247
+ def update_ad_groups(campaign_id, ad_groups)
248
+ groups = []
249
+ if ad_groups.is_a? Array
250
+ groups = ad_groups.map{ |gr| gr.to_hash(:camelcase) }
251
+ elsif ad_groups.is_a? GnibAdsApi::AdGroup
252
+ groups = ad_groups.to_hash(:camelcase)
253
+ else
254
+ raise "ad_groups must be an array or instance of GnibAdsApi::AdGroup"
255
+ end
256
+ message = {
257
+ :campaign_id => campaign_id,
258
+ :ad_groups => {:ad_group => groups} }
259
+ puts message
260
+ response = call(:update_ad_groups, message)
261
+ return get_response_hash(response, __method__)
262
+ end
263
+
264
+
265
+ # Public : Obtains all the ads associated to the specified ad group
266
+ #
267
+ # Author:: jlopezn@neonline.cl
268
+ #
269
+ # === Parameters
270
+ # ad_group_id - long with the ad group id
271
+ #
272
+ # === Examples
273
+ # service.get_ads_by_ad_group_id(1)
274
+ # # => [<GnibAdsApi::Ad]
275
+ #
276
+ # Returns:: An array of GnibAdsApi::Ad
277
+ #
278
+ # Raises:: exception
279
+ def get_ads_by_ad_group_id(ad_group_id)
280
+ response = call(:get_ads_by_ad_group_id,
281
+ {ad_group_id: ad_group_id})
282
+ response_hash = get_response_hash(response, __method__)
283
+
284
+ if response_hash[:ads][:ad].is_a?(Array)
285
+ ads = response_hash[:ads][:ad].map do |ad_hash|
286
+ initialize_ad(ad_hash)
287
+ end
288
+ else
289
+ ads = [ initialize_ad(response_hash[:ads][:ad]) ]
290
+ end
291
+ return ads
292
+ end
293
+
294
+
295
+ # Public : Obtains the ads indicated in ad_ids associated to the specified ad group
296
+ #
297
+ # Author:: jlopezn@neonline.cl
298
+ #
299
+ # === Parameters
300
+ # ad_group_id - long with the ad group id
301
+ # ads_id - an Array io ads ids, that are associated to the ad_group_id provided
302
+ #
303
+ # === Examples
304
+ # service.get_ads_by_ids(1, [1,2,3])
305
+ # # => [<GnibAdsApi::Ad>]
306
+ #
307
+ # Returns:: An array of GnibAdsApi::Ad
308
+ #
309
+ # Raises:: exception
310
+ def get_ads_by_ids(ad_group_id, ad_ids)
311
+
312
+
313
+ message = {
314
+ :ad_group_id => ad_group_id,
315
+ :ad_ids => {"ins1:long" => ad_ids} }
316
+ response = call(:get_ads_by_ids, message)
317
+ response_hash = get_response_hash(response, __method__)
318
+
319
+ if response_hash[:ads][:ad].is_a?(Array)
320
+ ads = response_hash[:ads][:ad].map do |ad_hash|
321
+ initialize_ad(ad_hash)
322
+ end
323
+ else
324
+ ads = [ initialize_ad(response_hash[:ads][:ad]) ]
325
+ end
326
+ return ads
327
+ end
328
+
329
+
330
+ # Public : Add ads into a specified ad group
331
+ #
332
+ # Author:: jlopezn@neonline.cl
333
+ #
334
+ # === Parameters
335
+ # ad_group_id - a number with the id where the ads should be added
336
+ # ads - an array of GnibAdsApi::Ad instances
337
+ #
338
+ # === Examples
339
+ # # if the operation returns partial errors
340
+ # service.add_ads(1, [GnibAdsApi::Ad])
341
+ # # => {:ad_ids => [], :partial_errors => GnibAdsApi::PartialErrors }
342
+ #
343
+ # # if the operation doesn't return partial errors
344
+ # service.add_ads(1, [GnibAdsApi::Ad])
345
+ # # => {:ad_ids => [] }
346
+ #
347
+ # Returns:: Hash with the AddAdsResponse structure.
348
+ # If the operation returns 'PartialErrors' key,
349
+ # this methods returns those errors as an GnibAdsApi::PartialErrors
350
+ # instance
351
+ #
352
+ # Raises:: exception
353
+ def add_ads(ad_group_id, ads)
354
+
355
+ ads_for_soap = []
356
+ if ads.is_a? Array
357
+ ads_for_soap = ads.map{ |ad| ad_to_hash(ad, :camelcase) }
358
+ elsif ads.is_a? GnibAdsApi::Ad
359
+ ads_for_soap = ad_to_hash(ads, :camelcase)
360
+ else
361
+ raise "ads must be an array or instance of GnibAdsApi::Ad"
362
+ end
363
+ message = {
364
+ :ad_group_id => ad_group_id,
365
+ :ads => {:ad => ads_for_soap} }
366
+ puts message
367
+ response = call(:add_ads, message)
368
+
369
+ response_hash = get_response_hash(response, __method__)
370
+
371
+ # Checks if there are partial errors in the request
372
+ if response_hash[:partial_errors].key?(:batch_error)
373
+ partial_errors = GnibAdsApi::PartialErrors.new(
374
+ response_hash[:partial_errors])
375
+ response_hash[:partial_errors] = partial_errors
376
+ else
377
+ response_hash.delete(:partial_errors)
378
+ end
379
+
380
+ return response_hash
381
+ end
382
+
383
+
384
+ # Public : Updates ads for the specified ad group
385
+ #
386
+ # Author:: jlopezn@neonline.cl
387
+ #
388
+ # === Parameters
389
+ # ad_group_id - long with the ad group id
390
+ # ads - array of GnibAdsApi::Ad subclasses instances to update
391
+ #
392
+ # === Examples
393
+ # service.update_ads(1, [<GnibAdsApi::Ad>])
394
+ # # => Hash
395
+ #
396
+ # Returns:: Hash with the UpdateAddsResponse structure
397
+ #
398
+ # Raises:: exception
399
+ def update_ads(ad_group_id, ads)
400
+
401
+ ads_for_soap = []
402
+ if ads.is_a? Array
403
+ ads_for_soap = ads.map{ |ad| ad_to_hash(ad, :camelcase) }
404
+ elsif ads.is_a? GnibAdsApi::Ad
405
+ ads_for_soap = ad_to_hash(ads, :camelcase)
406
+ else
407
+ raise "ads must be an array or instance of GnibAdsApi::Ad"
408
+ end
409
+ message = {
410
+ :ad_group_id => ad_group_id,
411
+ :ads => {:ad => ads_for_soap} }
412
+ puts message
413
+ response = call(:update_ads, message)
414
+
415
+ response_hash = get_response_hash(response, __method__)
416
+
417
+ # Checks if there are partial errors in the request
418
+ if response_hash[:partial_errors].key?(:batch_error)
419
+ partial_errors = GnibAdsApi::PartialErrors.new(
420
+ response_hash[:partial_errors])
421
+ response_hash[:partial_errors] = partial_errors
422
+ else
423
+ response_hash.delete(:partial_errors)
424
+ end
425
+
426
+ return response_hash
427
+ end
428
+
429
+
430
+ private
431
+ def get_service_name
432
+ "campaign_management"
433
+ end
434
+
435
+ # Private : Returns an instance of any of the subclases of GnibAdsApi::Ad based on the '@i:type' value in the hash
436
+ #
437
+ # Author:: jlopezn@neonline.cl
438
+ #
439
+ # ad_hash - Hash returned by the SOAP request with the Ad attributes
440
+ #
441
+ # Examples
442
+ # initialize_ad({:device_preference=>"0", :editorial_status=>"Active",
443
+ # :forward_compatibility_map=>{:"@xmlns:a"=>"http://schemas.datacontract.org/2004/07/System.Collections.Generic"},
444
+ # :id=>"1", :status=>"Active", :type=>"Text",
445
+ # :destination_url=>"www.some-url.com", :display_url=>"http://www.some-url.com",
446
+ # :text=>"My Page", :title=>"My Page",
447
+ # :"@i:type"=>"TextAd"})
448
+ # # => GnibAdsApi::TextAd
449
+ #
450
+ # Returns:: GnibAdsApi::Ad subclass instance
451
+ def initialize_ad(ad_hash)
452
+ ad = GnibAdsApi::Ad.new(ad_hash)
453
+ case ad_hash["@i:type".to_sym]
454
+ when "TextAd"
455
+ ad = GnibAdsApi::TextAd.new(ad_hash)
456
+ when "MobileAd"
457
+ ad = GnibAdsApi::MobileAd.new(ad_hash)
458
+ when "ProductAd"
459
+ ad = GnibAdsApi::ProductAd.new(ad_hash)
460
+ end
461
+ return ad
462
+ end
463
+
464
+
465
+ # Private : Helper method to correctly assemble the Ad XML for SOAP requests
466
+ #
467
+ # Author:: jlopezn@neonline.cl
468
+ #
469
+ # ad - GnibAdsApi::Ad subclass instance
470
+ #
471
+ # Examples
472
+ # ad_to_hash(GnibAdsApi::Ad, :camelcase)
473
+ # # => Hash
474
+ #
475
+ # Returns:: The same hash that ad.to_hash returns plus the needed key for the Ad Type
476
+ def ad_to_hash(ad, keys)
477
+ hash = ad.to_hash(keys)
478
+ hash["@xsi:type"] = self.client_proxy.class::NAMESPACE.to_s + ":" + ad.class.to_s.demodulize
479
+ return hash
480
+ end
481
+ end
482
+
483
+ end