bing-ads 0.1.11 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +109 -4
- data/lib/bing/ads.rb +1 -0
- data/lib/bing/ads/api/errors.rb +3 -0
- data/lib/bing/ads/api/http_client.rb +22 -0
- data/lib/bing/ads/api/v11/data.rb +1 -0
- data/lib/bing/ads/api/v11/data/report_request.rb +106 -0
- data/lib/bing/ads/api/v11/services.rb +1 -0
- data/lib/bing/ads/api/v11/services/base.rb +7 -6
- data/lib/bing/ads/api/v11/services/bulk.rb +2 -0
- data/lib/bing/ads/api/v11/services/reporting.rb +51 -0
- data/lib/bing/ads/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69fd2b5280eafbb14724463be4492828935ebbc4
|
4
|
+
data.tar.gz: 0fa11c1a1c80a3788b42637248340933455488d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c07d81eb68e2f058b0ec7a1ca6fca6a426e89c61f4efad82d8f12a8ead814c1771859f74ac3b7ec5dc114e36ca067f302baa4352dc511e3f567c8dbb64501a32
|
7
|
+
data.tar.gz: b7ed4a73f67e5daa38b16e12512e49322cc5b74f05ce7b4645a72c419dde7f961a9ad8452e48b82ee18406cfe9840496d7f121a0d4e78d24cd910158599fe6ad
|
data/README.md
CHANGED
@@ -312,16 +312,121 @@ response = service.delete_keywords(ad_group_id, keyword_ids_to_delete)
|
|
312
312
|
```
|
313
313
|
|
314
314
|
### Bulk Service
|
315
|
-
|
315
|
+
#### Initialization
|
316
|
+
```ruby
|
317
|
+
# Authentication token is not supported in sandbox, use `username` and `password` instead
|
318
|
+
# https://msdn.microsoft.com/en-us/library/dn277356.aspx
|
319
|
+
|
320
|
+
options = {
|
321
|
+
environment: :sandbox,
|
322
|
+
authentication_token: '39b290146bea6ce975c37cfc23',
|
323
|
+
developer_token: 'BBD37VB98',
|
324
|
+
customer_id: '21027149',
|
325
|
+
account_id: '5278183',
|
326
|
+
# client_settings: { logger: LOGGER::STDOUT }
|
327
|
+
}
|
328
|
+
|
329
|
+
service = Bing::Ads::API::V11::Services::Bulk.new(options)
|
330
|
+
```
|
331
|
+
|
332
|
+
#### Submit a request for a URL where a bulk upload file may be posted.
|
333
|
+
```ruby
|
334
|
+
response = service.get_bulk_upload_url
|
335
|
+
|
336
|
+
# @return
|
337
|
+
# {
|
338
|
+
# request_id: 4981237213
|
339
|
+
# upload_url: '-'
|
340
|
+
# }
|
341
|
+
```
|
342
|
+
|
343
|
+
#### Get the status and completion percentage of a bulk upload request.
|
344
|
+
```ruby
|
345
|
+
response = service.get_bulk_upload_status(request_id)
|
346
|
+
|
347
|
+
# @return
|
348
|
+
# {
|
349
|
+
# errors: [],
|
350
|
+
# percent_complete: 100,
|
351
|
+
# request_status: '-',
|
352
|
+
# result_file_url: '-'
|
353
|
+
# }
|
354
|
+
```
|
316
355
|
|
317
356
|
### Reporting Service
|
318
|
-
|
357
|
+
|
358
|
+
#### Initialization
|
359
|
+
```ruby
|
360
|
+
# Authentication token is not supported in sandbox, use `username` and `password` instead
|
361
|
+
# https://msdn.microsoft.com/en-us/library/dn277356.aspx
|
362
|
+
|
363
|
+
options = {
|
364
|
+
environment: :sandbox,
|
365
|
+
authentication_token: '39b290146bea6ce975c37cfc23',
|
366
|
+
developer_token: 'BBD37VB98',
|
367
|
+
customer_id: '21027149',
|
368
|
+
# client_settings: { logger: LOGGER::STDOUT }
|
369
|
+
}
|
370
|
+
|
371
|
+
service = Bing::Ads::API::V11::Services::Reporting.new(options)
|
372
|
+
```
|
373
|
+
|
374
|
+
#### Submit Generate Report
|
375
|
+
To get reports from Bing, you must first submit a report generation request.
|
376
|
+
|
377
|
+
The method `submit_generate_report` receive two params as input, first the `report_type` and then a hash with the report options.
|
378
|
+
|
379
|
+
Example:
|
380
|
+
|
381
|
+
```ruby
|
382
|
+
response = service.submit_generate_report(:keyword_performance, {
|
383
|
+
exclude_column_headers: false,
|
384
|
+
exclude_report_footer: false,
|
385
|
+
exclude_report_header: false,
|
386
|
+
language: 'English',
|
387
|
+
format: 'Tsv',
|
388
|
+
report_name: 'keyword_performance_report',
|
389
|
+
return_only_complete_data: false,
|
390
|
+
aggregation: 'Daily',
|
391
|
+
columns: [:destination_url, :average_cpc],
|
392
|
+
from_date: '2017-10-23',
|
393
|
+
to_date: '2017-10-25'
|
394
|
+
account_ids: [144012349, 224002158]
|
395
|
+
})
|
396
|
+
```
|
397
|
+
|
398
|
+
The required options depend on the report type you are using.
|
399
|
+
|
400
|
+
Response example:
|
401
|
+
|
402
|
+
```ruby
|
403
|
+
{:report_request_id=>"30000000999745662", :@xmlns=>"https://bingads.microsoft.com/Reporting/v11"}
|
404
|
+
```
|
405
|
+
|
406
|
+
#### Poll Generate Report
|
407
|
+
|
408
|
+
To retrieve the report generated you have a few options:
|
409
|
+
|
410
|
+
You can check if the report is ready and then get the url:
|
411
|
+
```ruby
|
412
|
+
service.report_url(report_request_id) if service.report_ready?(report_request_id)
|
413
|
+
```
|
414
|
+
|
415
|
+
Or you can download the body of the report when it's ready. (and then write to a file for example)
|
416
|
+
```ruby
|
417
|
+
service.report_body(report_request_id) if service.report_ready?(report_request_id)
|
418
|
+
```
|
419
|
+
|
420
|
+
You can also get the entire poll_generate_reportl report object:
|
421
|
+
```ruby
|
422
|
+
service.poll_generate_report(report_request_id)
|
423
|
+
```
|
319
424
|
|
320
425
|
### Errors raised
|
321
|
-
* `Bing::Ads::API::Errors::AuthenticationParamsMissing`
|
322
|
-
No username/password or authentication_token.
|
426
|
+
* `Bing::Ads::API::Errors::AuthenticationParamsMissing` No username/password or authentication_token.
|
323
427
|
* `Bing::Ads::API::Errors::AuthenticationTokenExpired` Authentication token needs to be refreshed.
|
324
428
|
* `Bing::Ads::API::Errors::LimitError` An API limit has been exceeded on a specific request. Check message for details.
|
429
|
+
* `Bing::Ads::API::Errors::DownloadError` Error when downloading a report body.
|
325
430
|
|
326
431
|
## Development
|
327
432
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/bing/ads.rb
CHANGED
data/lib/bing/ads/api/errors.rb
CHANGED
@@ -11,6 +11,9 @@ module Bing
|
|
11
11
|
# Bing::Ads::API::Errors::UnhandledSOAPFault
|
12
12
|
class UnhandledSOAPFault < RuntimeError; end;
|
13
13
|
|
14
|
+
# Bing::Ads::API::Errors::DownloadError
|
15
|
+
class DownloadError < RuntimeError; end;
|
16
|
+
|
14
17
|
# Bing::Ads::API::Errors::LimitError
|
15
18
|
class LimitError < RuntimeError
|
16
19
|
def initialize(operation, limit, type)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Bing
|
2
|
+
module Ads
|
3
|
+
module API
|
4
|
+
# Bing::Ads::API::HttpClient
|
5
|
+
class HttpClient
|
6
|
+
API_CALL_RETRY_COUNT = 3
|
7
|
+
|
8
|
+
def self.download(url, retry_count = API_CALL_RETRY_COUNT)
|
9
|
+
1.upto(retry_count + 1) do |retry_index|
|
10
|
+
response = Net::HTTP.get_response(URI(url))
|
11
|
+
if response.is_a?(Net::HTTPSuccess)
|
12
|
+
break response.body
|
13
|
+
else
|
14
|
+
next if retry_index <= retry_count
|
15
|
+
raise Bing::Ads::API::Errors::DownloadError, "#{response.code} #{response.msg}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Bing
|
2
|
+
module Ads
|
3
|
+
module API
|
4
|
+
module V11
|
5
|
+
module Data
|
6
|
+
# Bing::Ads::API::V11::Data::ReportRequest
|
7
|
+
class ReportRequest
|
8
|
+
|
9
|
+
# @order
|
10
|
+
# https://msdn.microsoft.com/en-us/library/bing-ads-reporting-reportrequest.aspx
|
11
|
+
KEYS_ORDER = [
|
12
|
+
:exclude_column_headers,
|
13
|
+
:exclude_report_footer,
|
14
|
+
:exclude_report_header,
|
15
|
+
:format,
|
16
|
+
:language,
|
17
|
+
:report_name,
|
18
|
+
:return_only_complete_data,
|
19
|
+
:aggregation,
|
20
|
+
:columns,
|
21
|
+
:filter,
|
22
|
+
:scope,
|
23
|
+
:time
|
24
|
+
]
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def prepare(type, report_request_raw)
|
28
|
+
report_request_raw[:columns] = prepare_columns(
|
29
|
+
columns: report_request_raw[:columns],
|
30
|
+
type: type.to_s.classify
|
31
|
+
)
|
32
|
+
|
33
|
+
report_request_raw[:scope] = prepare_scope(
|
34
|
+
account_ids: report_request_raw[:account_ids]
|
35
|
+
)
|
36
|
+
|
37
|
+
report_request_raw[:time] = prepare_time_period(
|
38
|
+
from_date: report_request_raw[:from_date],
|
39
|
+
to_date: report_request_raw[:to_date]
|
40
|
+
)
|
41
|
+
|
42
|
+
report_request_raw.except!(:from_date, :to_date, :account_ids)
|
43
|
+
|
44
|
+
report_request = Bing::Ads::Utils.sort_keys(report_request_raw, KEYS_ORDER)
|
45
|
+
namespace_identifier = Bing::Ads::API::V11::NAMESPACE_IDENTIFIER
|
46
|
+
{
|
47
|
+
report_request: Bing::Ads::Utils.camelcase_keys(report_request),
|
48
|
+
:attributes! => {
|
49
|
+
report_request: {
|
50
|
+
"xmlns:i" => "http://www.w3.org/2001/XMLSchema-instance",
|
51
|
+
"i:type" => "#{namespace_identifier}:#{type.to_s.classify}ReportRequest"
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def prepare_columns(type:, columns:)
|
60
|
+
{
|
61
|
+
"#{type}ReportColumn" => columns.map(&:to_s).map(&:camelcase)
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def prepare_scope(account_ids:)
|
66
|
+
account_ids_elements =
|
67
|
+
if account_ids.nil?
|
68
|
+
nil
|
69
|
+
else
|
70
|
+
{
|
71
|
+
'a1:long' => account_ids,
|
72
|
+
'@xmlns:a1' => 'http://schemas.microsoft.com/2003/10/Serialization/Arrays'
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
{
|
77
|
+
account_ids: account_ids_elements,
|
78
|
+
ad_groups: nil,
|
79
|
+
campaigns: nil
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
def prepare_time_period(from_date:, to_date:)
|
84
|
+
from_date = Date.parse(from_date)
|
85
|
+
to_date = Date.parse(to_date)
|
86
|
+
|
87
|
+
{
|
88
|
+
custom_date_range_end: {
|
89
|
+
day: to_date.day,
|
90
|
+
month: to_date.month,
|
91
|
+
year: to_date.year
|
92
|
+
},
|
93
|
+
custom_date_range_start: {
|
94
|
+
day: from_date.day,
|
95
|
+
month: from_date.month,
|
96
|
+
year: from_date.year
|
97
|
+
}
|
98
|
+
}
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -51,11 +51,12 @@ module Bing
|
|
51
51
|
response = soap_client.call(operation: operation.to_sym, payload: payload)
|
52
52
|
return response.hash
|
53
53
|
rescue Savon::SOAPFault => error
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
54
|
+
fault = error.to_hash[:fault]
|
55
|
+
|
56
|
+
if fault.dig(:detail, :api_fault_detail)
|
57
|
+
handle_soap_fault(operation, fault[:detail], :api_fault_detail)
|
58
|
+
elsif fault.dig(:detail, :ad_api_fault_detail)
|
59
|
+
handle_soap_fault(operation, fault[:detail], :ad_api_fault_detail)
|
59
60
|
else
|
60
61
|
if retries_made < retry_attempts
|
61
62
|
sleep(2**retries_made)
|
@@ -63,7 +64,7 @@ module Bing
|
|
63
64
|
retry
|
64
65
|
else
|
65
66
|
raise Bing::Ads::API::Errors::UnhandledSOAPFault,
|
66
|
-
"SOAP error (#{
|
67
|
+
"SOAP error (#{fault.keys.join(', ')}) while calling #{operation}. #{error.message}"
|
67
68
|
end
|
68
69
|
end
|
69
70
|
rescue Savon::HTTPError => error
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Bing
|
2
|
+
module Ads
|
3
|
+
module API
|
4
|
+
module V11
|
5
|
+
module Services
|
6
|
+
# Bing::Ads::API::V11::Services::CampaignManagement
|
7
|
+
class Reporting < Base
|
8
|
+
def initialize(options = {})
|
9
|
+
super(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def submit_generate_report(type, report_options)
|
13
|
+
payload = Bing::Ads::API::V11::Data::ReportRequest.prepare(type, report_options)
|
14
|
+
response = call(:submit_generate_report, payload)
|
15
|
+
response_body = response_body(response, __method__)
|
16
|
+
response_body
|
17
|
+
end
|
18
|
+
|
19
|
+
def poll_generate_report(report_request_id)
|
20
|
+
response = call(:poll_generate_report, report_request_id: report_request_id)
|
21
|
+
response_body = response_body(response, __method__)
|
22
|
+
response_body
|
23
|
+
end
|
24
|
+
|
25
|
+
def report_ready?(report_request_id)
|
26
|
+
polled = poll_generate_report(report_request_id)
|
27
|
+
status = polled.dig(:report_request_status, :status)
|
28
|
+
raise "Report status: Error for ID: #{report_request_id}" if status == "Error"
|
29
|
+
status == "Success"
|
30
|
+
end
|
31
|
+
|
32
|
+
def report_url(report_request_id)
|
33
|
+
polled = poll_generate_report(report_request_id)
|
34
|
+
polled.dig(:report_request_status, :report_download_url)
|
35
|
+
end
|
36
|
+
|
37
|
+
def report_body(report_request_id)
|
38
|
+
HttpClient.download(report_url(report_request_id))
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def service_name
|
44
|
+
'reporting'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/bing/ads/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bing-ads
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- oss92
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: savon
|
@@ -117,6 +117,7 @@ files:
|
|
117
117
|
- bing-ads.gemspec
|
118
118
|
- lib/bing/ads.rb
|
119
119
|
- lib/bing/ads/api/errors.rb
|
120
|
+
- lib/bing/ads/api/http_client.rb
|
120
121
|
- lib/bing/ads/api/soap_client.rb
|
121
122
|
- lib/bing/ads/api/v11.rb
|
122
123
|
- lib/bing/ads/api/v11/constants.rb
|
@@ -130,11 +131,13 @@ files:
|
|
130
131
|
- lib/bing/ads/api/v11/data/campaign.rb
|
131
132
|
- lib/bing/ads/api/v11/data/expanded_text_ad.rb
|
132
133
|
- lib/bing/ads/api/v11/data/keyword.rb
|
134
|
+
- lib/bing/ads/api/v11/data/report_request.rb
|
133
135
|
- lib/bing/ads/api/v11/services.rb
|
134
136
|
- lib/bing/ads/api/v11/services/base.rb
|
135
137
|
- lib/bing/ads/api/v11/services/bulk.rb
|
136
138
|
- lib/bing/ads/api/v11/services/campaign_management.rb
|
137
139
|
- lib/bing/ads/api/v11/services/customer_management.rb
|
140
|
+
- lib/bing/ads/api/v11/services/reporting.rb
|
138
141
|
- lib/bing/ads/utils.rb
|
139
142
|
- lib/bing/ads/version.rb
|
140
143
|
homepage: https://github.com/FindHotel/bing-ads
|
@@ -157,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
160
|
version: '0'
|
158
161
|
requirements: []
|
159
162
|
rubyforge_project:
|
160
|
-
rubygems_version: 2.6.
|
163
|
+
rubygems_version: 2.6.13
|
161
164
|
signing_key:
|
162
165
|
specification_version: 4
|
163
166
|
summary: Enhances the experience of developing Bing Ads applications with Ruby
|