blurb 0.4.8 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/blurb.gemspec +1 -1
- data/lib/blurb/base_class.rb +2 -1
- data/lib/blurb/campaign_requests.rb +24 -0
- data/lib/blurb/history_request.rb +54 -0
- data/lib/blurb/profile.rb +36 -4
- data/lib/blurb/report_requests.rb +127 -3
- data/lib/blurb/request.rb +1 -0
- data/lib/blurb/request_collection.rb +5 -5
- data/lib/blurb/request_collection_with_campaign_type.rb +5 -3
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc759e7143938c4b655af1c4ea8b72af388933f065d84230c0353451c6ffc9f2
|
4
|
+
data.tar.gz: 3e300e444044b62ef1dcb07dcbe2c29e03ff0d0973ec3afa25b1666f5a08510e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06dc8e873b618c4ba50ffa6bf3c889841c2e1816d06dccbf1b538d74f0442f8895b68172bb656f020cf91bd86c9264b027c64722fb22d3b2f129494b09ccbc07
|
7
|
+
data.tar.gz: 2ec363459a1f8751cc0dbe79abcbc06699bac1b90804520627886b72e358b544d93fa55b5c097a7d3725db6e49cd476cdb02be14082d9acbbe6e7f37dbc4be61
|
data/blurb.gemspec
CHANGED
data/lib/blurb/base_class.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'blurb/request_collection_with_campaign_type'
|
2
|
+
|
3
|
+
class Blurb
|
4
|
+
class CampaignRequests < RequestCollectionWithCampaignType
|
5
|
+
def create_bulk(create_array)
|
6
|
+
create_array = map_campaign_payload(create_array)
|
7
|
+
super(create_array)
|
8
|
+
end
|
9
|
+
|
10
|
+
def update_bulk(update_array)
|
11
|
+
update_array = map_campaign_payload(update_array)
|
12
|
+
super(update_array)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def map_campaign_payload(payload)
|
18
|
+
campaign_type_string = "sponsoredProducts" if @campaign_type == CAMPAIGN_TYPE_CODES[:sp]
|
19
|
+
campaign_type_string = "sponsoredBrands" if @campaign_type == CAMPAIGN_TYPE_CODES[:sb]
|
20
|
+
campaign_type_string = "sponsoredDisplays" if @campaign_type == CAMPAIGN_TYPE_CODES[:sd]
|
21
|
+
payload.each{ |p| p[:campaign_type] = campaign_type_string }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'blurb/request_collection'
|
2
|
+
|
3
|
+
class Blurb
|
4
|
+
class HistoryRequest < RequestCollection
|
5
|
+
FROM_DATE = (DateTime.now - 30).strftime('%Q')
|
6
|
+
TO_DATE = DateTime.now.strftime('%Q')
|
7
|
+
MAX_COUNT = 200.freeze
|
8
|
+
MIN_COUNT = 50.freeze
|
9
|
+
FILTERS = []
|
10
|
+
PARENT_CAMPAIGN_ID = nil
|
11
|
+
|
12
|
+
def initialize(base_url:, headers:)
|
13
|
+
@base_url = base_url
|
14
|
+
@headers = headers
|
15
|
+
end
|
16
|
+
|
17
|
+
def retrieve(
|
18
|
+
from_date: FROM_DATE,
|
19
|
+
to_date: TO_DATE,
|
20
|
+
campaign_ids:,
|
21
|
+
filters: FILTERS,
|
22
|
+
parent_campaign_id: PARENT_CAMPAIGN_ID,
|
23
|
+
count: MAX_COUNT
|
24
|
+
)
|
25
|
+
|
26
|
+
count = MIN_COUNT if count < MIN_COUNT
|
27
|
+
count = MAX_COUNT if count > MAX_COUNT
|
28
|
+
|
29
|
+
payload = {
|
30
|
+
sort: {
|
31
|
+
key: 'DATE',
|
32
|
+
direction: 'ASC'
|
33
|
+
},
|
34
|
+
fromDate: from_date.to_i,
|
35
|
+
toDate: to_date.to_i,
|
36
|
+
eventTypes: {
|
37
|
+
CAMPAIGN: {
|
38
|
+
eventTypeIds: campaign_ids
|
39
|
+
}
|
40
|
+
},
|
41
|
+
count: count
|
42
|
+
}
|
43
|
+
|
44
|
+
payload[:eventTypes][:CAMPAIGN].merge!({ filters: filters }) if filters.present?
|
45
|
+
payload[:eventTypes][:CAMPAIGN].merge!({ parents: [{ campaignId: parent_campaign_id }] }) if parent_campaign_id.present?
|
46
|
+
|
47
|
+
execute_request(
|
48
|
+
api_path: "/history",
|
49
|
+
request_type: :post,
|
50
|
+
payload: payload
|
51
|
+
)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/blurb/profile.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require "blurb/account"
|
2
|
+
require "blurb/campaign_requests"
|
2
3
|
require "blurb/snapshot_requests"
|
3
4
|
require "blurb/report_requests"
|
4
5
|
require "blurb/request_collection"
|
5
6
|
require "blurb/request_collection_with_campaign_type"
|
6
7
|
require "blurb/suggested_keyword_requests"
|
8
|
+
require "blurb/history_request"
|
7
9
|
|
8
10
|
class Blurb
|
9
11
|
class Profile < BaseClass
|
@@ -11,29 +13,40 @@ class Blurb
|
|
11
13
|
attr_accessor(
|
12
14
|
:account,
|
13
15
|
:ad_groups,
|
16
|
+
:sd_ad_groups,
|
14
17
|
:campaign_negative_keywords,
|
15
18
|
:portfolios,
|
16
19
|
:product_ads,
|
20
|
+
:sd_product_ads,
|
17
21
|
:profile_id,
|
18
22
|
:suggested_keywords,
|
19
|
-
:targets
|
23
|
+
:targets,
|
24
|
+
:history
|
20
25
|
)
|
21
26
|
|
22
27
|
def initialize(profile_id:, account:)
|
23
28
|
@profile_id = profile_id
|
24
29
|
@account = account
|
25
30
|
|
26
|
-
@sp_campaigns =
|
31
|
+
@sp_campaigns = CampaignRequests.new(
|
27
32
|
headers: headers_hash,
|
28
33
|
base_url: @account.api_url,
|
29
34
|
resource: "campaigns",
|
30
35
|
campaign_type: CAMPAIGN_TYPE_CODES[:sp]
|
31
36
|
)
|
32
|
-
@sb_campaigns =
|
37
|
+
@sb_campaigns = CampaignRequests.new(
|
33
38
|
headers: headers_hash,
|
34
39
|
base_url: @account.api_url,
|
35
40
|
resource: "campaigns",
|
36
|
-
campaign_type: CAMPAIGN_TYPE_CODES[:sb]
|
41
|
+
campaign_type: CAMPAIGN_TYPE_CODES[:sb],
|
42
|
+
bulk_api_limit: 10
|
43
|
+
)
|
44
|
+
@sd_campaigns = CampaignRequests.new(
|
45
|
+
headers: headers_hash,
|
46
|
+
base_url: @account.api_url,
|
47
|
+
resource: "campaigns",
|
48
|
+
campaign_type: CAMPAIGN_TYPE_CODES[:sd],
|
49
|
+
bulk_api_limit: 10
|
37
50
|
)
|
38
51
|
@sp_keywords = RequestCollectionWithCampaignType.new(
|
39
52
|
headers: headers_hash,
|
@@ -62,6 +75,11 @@ class Blurb
|
|
62
75
|
base_url: @account.api_url,
|
63
76
|
campaign_type: CAMPAIGN_TYPE_CODES[:sp]
|
64
77
|
)
|
78
|
+
@sd_reports = ReportRequests.new(
|
79
|
+
headers: headers_hash,
|
80
|
+
base_url: @account.api_url,
|
81
|
+
campaign_type: CAMPAIGN_TYPE_CODES[:sd]
|
82
|
+
)
|
65
83
|
@sb_reports = ReportRequests.new(
|
66
84
|
headers: headers_hash,
|
67
85
|
base_url: @account.api_url,
|
@@ -71,10 +89,18 @@ class Blurb
|
|
71
89
|
headers: headers_hash,
|
72
90
|
base_url: "#{@account.api_url}/v2/sp/adGroups"
|
73
91
|
)
|
92
|
+
@sd_ad_groups = RequestCollection.new(
|
93
|
+
headers: headers_hash,
|
94
|
+
base_url: "#{@account.api_url}/sd/adGroups"
|
95
|
+
)
|
74
96
|
@product_ads = RequestCollection.new(
|
75
97
|
headers: headers_hash,
|
76
98
|
base_url: "#{account.api_url}/v2/sp/productAds"
|
77
99
|
)
|
100
|
+
@sd_product_ads = RequestCollection.new(
|
101
|
+
headers: headers_hash,
|
102
|
+
base_url: "#{account.api_url}/sd/productAds"
|
103
|
+
)
|
78
104
|
@sp_negative_keywords = RequestCollectionWithCampaignType.new(
|
79
105
|
headers: headers_hash,
|
80
106
|
base_url: @account.api_url,
|
@@ -103,11 +129,16 @@ class Blurb
|
|
103
129
|
headers: headers_hash,
|
104
130
|
base_url: "#{@account.api_url}/v2/sp"
|
105
131
|
)
|
132
|
+
@history = HistoryRequest.new(
|
133
|
+
headers: headers_hash,
|
134
|
+
base_url: @account.api_url
|
135
|
+
)
|
106
136
|
end
|
107
137
|
|
108
138
|
def campaigns(campaign_type)
|
109
139
|
return @sp_campaigns if campaign_type == :sp
|
110
140
|
return @sb_campaigns if campaign_type == :sb || campaign_type == :hsa
|
141
|
+
return @sd_campaigns if campaign_type == :sd
|
111
142
|
end
|
112
143
|
|
113
144
|
def keywords(campaign_type)
|
@@ -128,6 +159,7 @@ class Blurb
|
|
128
159
|
def reports(campaign_type)
|
129
160
|
return @sp_reports if campaign_type == :sp
|
130
161
|
return @sb_reports if campaign_type == :sb || campaign_type == :hsa
|
162
|
+
return @sd_reports if campaign_type == :sd
|
131
163
|
end
|
132
164
|
|
133
165
|
def request(api_path: "",request_type: :get, payload: nil, url_params: nil, headers: headers_hash)
|
@@ -2,6 +2,8 @@ require 'blurb/request_collection_with_campaign_type'
|
|
2
2
|
|
3
3
|
class Blurb
|
4
4
|
class ReportRequests < RequestCollectionWithCampaignType
|
5
|
+
SD_TACTIC = 'T00020'.freeze
|
6
|
+
|
5
7
|
def initialize(campaign_type:, base_url:, headers:)
|
6
8
|
@campaign_type = campaign_type
|
7
9
|
@base_url = "#{base_url}/v2/#{@campaign_type}"
|
@@ -15,12 +17,13 @@ class Blurb
|
|
15
17
|
segment: nil
|
16
18
|
)
|
17
19
|
# create payload
|
18
|
-
metrics = get_default_metrics(record_type.to_s.underscore.to_sym) if metrics.nil?
|
20
|
+
metrics = get_default_metrics(record_type.to_s.underscore.to_sym, segment) if metrics.nil?
|
19
21
|
payload = {
|
20
22
|
metrics: metrics.map{ |m| m.to_s.camelize(:lower) }.join(","),
|
21
23
|
report_date: report_date
|
22
24
|
}
|
23
25
|
payload[:segment] = segment if segment
|
26
|
+
payload[:tactic] = SD_TACTIC if @campaign_type.to_sym == :sd
|
24
27
|
|
25
28
|
execute_request(
|
26
29
|
api_path: "/#{record_type.to_s.camelize(:lower)}/report",
|
@@ -45,7 +48,7 @@ class Blurb
|
|
45
48
|
|
46
49
|
private
|
47
50
|
|
48
|
-
def get_default_metrics(record_type)
|
51
|
+
def get_default_metrics(record_type, segment = nil)
|
49
52
|
if @campaign_type == CAMPAIGN_TYPE_CODES[:sb]
|
50
53
|
return [
|
51
54
|
"campaignId",
|
@@ -79,7 +82,16 @@ class Blurb
|
|
79
82
|
"attributedSales14dSameSKU",
|
80
83
|
"attributedConversions14d",
|
81
84
|
"attributedConversions14dSameSKU"
|
82
|
-
] if record_type == :keywords
|
85
|
+
] if record_type == :keywords && segment.nil?
|
86
|
+
return [
|
87
|
+
"adGroupId",
|
88
|
+
"campaignId",
|
89
|
+
"impressions",
|
90
|
+
"clicks",
|
91
|
+
"cost",
|
92
|
+
"attributedSales14d",
|
93
|
+
"attributedConversions14d",
|
94
|
+
] if record_type == :keywords && segment.present?
|
83
95
|
elsif @campaign_type == CAMPAIGN_TYPE_CODES[:sp]
|
84
96
|
return [
|
85
97
|
"campaignId",
|
@@ -242,6 +254,118 @@ class Blurb
|
|
242
254
|
"attributedSales14dSameSKU",
|
243
255
|
"attributedSales30dSameSKU"
|
244
256
|
] if record_type == :portfolios
|
257
|
+
elsif @campaign_type == CAMPAIGN_TYPE_CODES[:sd]
|
258
|
+
return [
|
259
|
+
"campaignId",
|
260
|
+
"impressions",
|
261
|
+
"clicks",
|
262
|
+
"cost",
|
263
|
+
"currency",
|
264
|
+
"attributedConversions1d",
|
265
|
+
"attributedConversions7d",
|
266
|
+
"attributedConversions14d",
|
267
|
+
"attributedConversions30d",
|
268
|
+
"attributedConversions1dSameSKU",
|
269
|
+
"attributedConversions7dSameSKU",
|
270
|
+
"attributedConversions14dSameSKU",
|
271
|
+
"attributedConversions30dSameSKU",
|
272
|
+
"attributedUnitsOrdered1d",
|
273
|
+
"attributedUnitsOrdered7d",
|
274
|
+
"attributedUnitsOrdered14d",
|
275
|
+
"attributedUnitsOrdered30d",
|
276
|
+
"attributedSales1d",
|
277
|
+
"attributedSales7d",
|
278
|
+
"attributedSales14d",
|
279
|
+
"attributedSales30d",
|
280
|
+
"attributedSales1dSameSKU",
|
281
|
+
"attributedSales7dSameSKU",
|
282
|
+
"attributedSales14dSameSKU",
|
283
|
+
"attributedSales30dSameSKU"
|
284
|
+
] if record_type == :campaigns
|
285
|
+
return [
|
286
|
+
"campaignId",
|
287
|
+
"adGroupId",
|
288
|
+
"impressions",
|
289
|
+
"clicks",
|
290
|
+
"cost",
|
291
|
+
"currency",
|
292
|
+
"attributedConversions1d",
|
293
|
+
"attributedConversions7d",
|
294
|
+
"attributedConversions14d",
|
295
|
+
"attributedConversions30d",
|
296
|
+
"attributedConversions1dSameSKU",
|
297
|
+
"attributedConversions7dSameSKU",
|
298
|
+
"attributedConversions14dSameSKU",
|
299
|
+
"attributedConversions30dSameSKU",
|
300
|
+
"attributedUnitsOrdered1d",
|
301
|
+
"attributedUnitsOrdered7d",
|
302
|
+
"attributedUnitsOrdered14d",
|
303
|
+
"attributedUnitsOrdered30d",
|
304
|
+
"attributedSales1d",
|
305
|
+
"attributedSales7d",
|
306
|
+
"attributedSales14d",
|
307
|
+
"attributedSales30d",
|
308
|
+
"attributedSales1dSameSKU",
|
309
|
+
"attributedSales7dSameSKU",
|
310
|
+
"attributedSales14dSameSKU",
|
311
|
+
"attributedSales30dSameSKU"
|
312
|
+
] if record_type == :ad_groups
|
313
|
+
return [
|
314
|
+
"campaignId",
|
315
|
+
"adGroupId",
|
316
|
+
"impressions",
|
317
|
+
"clicks",
|
318
|
+
"cost",
|
319
|
+
"currency",
|
320
|
+
"attributedConversions1d",
|
321
|
+
"attributedConversions7d",
|
322
|
+
"attributedConversions14d",
|
323
|
+
"attributedConversions30d",
|
324
|
+
"attributedConversions1dSameSKU",
|
325
|
+
"attributedConversions7dSameSKU",
|
326
|
+
"attributedConversions14dSameSKU",
|
327
|
+
"attributedConversions30dSameSKU",
|
328
|
+
"attributedUnitsOrdered1d",
|
329
|
+
"attributedUnitsOrdered7d",
|
330
|
+
"attributedUnitsOrdered14d",
|
331
|
+
"attributedUnitsOrdered30d",
|
332
|
+
"attributedSales1d",
|
333
|
+
"attributedSales7d",
|
334
|
+
"attributedSales14d",
|
335
|
+
"attributedSales30d",
|
336
|
+
"attributedSales1dSameSKU",
|
337
|
+
"attributedSales7dSameSKU",
|
338
|
+
"attributedSales14dSameSKU",
|
339
|
+
"attributedSales30dSameSKU"
|
340
|
+
] if record_type == :product_ads
|
341
|
+
return [
|
342
|
+
"campaignId",
|
343
|
+
"targetId",
|
344
|
+
"impressions",
|
345
|
+
"clicks",
|
346
|
+
"cost",
|
347
|
+
"currency",
|
348
|
+
"attributedConversions1d",
|
349
|
+
"attributedConversions7d",
|
350
|
+
"attributedConversions14d",
|
351
|
+
"attributedConversions30d",
|
352
|
+
"attributedConversions1dSameSKU",
|
353
|
+
"attributedConversions7dSameSKU",
|
354
|
+
"attributedConversions14dSameSKU",
|
355
|
+
"attributedConversions30dSameSKU",
|
356
|
+
"attributedUnitsOrdered1d",
|
357
|
+
"attributedUnitsOrdered7d",
|
358
|
+
"attributedUnitsOrdered14d",
|
359
|
+
"attributedUnitsOrdered30d",
|
360
|
+
"attributedSales1d",
|
361
|
+
"attributedSales7d",
|
362
|
+
"attributedSales14d",
|
363
|
+
"attributedSales30d",
|
364
|
+
"attributedSales1dSameSKU",
|
365
|
+
"attributedSales7dSameSKU",
|
366
|
+
"attributedSales14dSameSKU",
|
367
|
+
"attributedSales30dSameSKU"
|
368
|
+
] if record_type == :targets
|
245
369
|
end
|
246
370
|
end
|
247
371
|
end
|
data/lib/blurb/request.rb
CHANGED
@@ -4,9 +4,10 @@ require "blurb/base_class"
|
|
4
4
|
class Blurb
|
5
5
|
class RequestCollection < BaseClass
|
6
6
|
|
7
|
-
def initialize(headers:, base_url:)
|
7
|
+
def initialize(headers:, base_url:, bulk_api_limit: 100)
|
8
8
|
@base_url = base_url
|
9
9
|
@headers = headers
|
10
|
+
@api_limit = bulk_api_limit
|
10
11
|
end
|
11
12
|
|
12
13
|
def list(url_params=nil)
|
@@ -46,7 +47,6 @@ class Blurb
|
|
46
47
|
execute_bulk_request(
|
47
48
|
request_type: :post,
|
48
49
|
payload: create_array,
|
49
|
-
api_limit: 100
|
50
50
|
)
|
51
51
|
end
|
52
52
|
|
@@ -58,7 +58,6 @@ class Blurb
|
|
58
58
|
execute_bulk_request(
|
59
59
|
request_type: :put,
|
60
60
|
payload: update_array,
|
61
|
-
api_limit: 100
|
62
61
|
)
|
63
62
|
end
|
64
63
|
|
@@ -73,6 +72,7 @@ class Blurb
|
|
73
72
|
|
74
73
|
def execute_request(api_path: "", request_type:, payload: nil, url_params: nil)
|
75
74
|
url = "#{@base_url}#{api_path}"
|
75
|
+
url.sub!('/sd/', '/') if request_type == :get && url.include?('sd/reports') && url_params.nil?
|
76
76
|
|
77
77
|
request = Request.new(
|
78
78
|
url: url,
|
@@ -86,9 +86,9 @@ class Blurb
|
|
86
86
|
end
|
87
87
|
|
88
88
|
# Split up bulk requests to match the api limit
|
89
|
-
def execute_bulk_request(
|
89
|
+
def execute_bulk_request(**execute_request_params)
|
90
90
|
results = []
|
91
|
-
payloads = execute_request_params[:payload].each_slice(api_limit).to_a
|
91
|
+
payloads = execute_request_params[:payload].each_slice(@api_limit).to_a
|
92
92
|
payloads.each do |p|
|
93
93
|
execute_request_params[:payload] = p
|
94
94
|
results << execute_request(execute_request_params)
|
@@ -3,10 +3,12 @@ require 'blurb/request_collection'
|
|
3
3
|
class Blurb
|
4
4
|
class RequestCollectionWithCampaignType < RequestCollection
|
5
5
|
|
6
|
-
def initialize(campaign_type:, resource:, base_url:, headers:)
|
6
|
+
def initialize(campaign_type:, resource:, base_url:, headers:, bulk_api_limit: 100)
|
7
7
|
@campaign_type = campaign_type
|
8
|
-
|
8
|
+
base_url = campaign_type.to_s == 'sd' ? base_url : "#{base_url}/v2"
|
9
|
+
@base_url = "#{base_url}/#{@campaign_type}/#{resource}"
|
9
10
|
@headers = headers
|
11
|
+
@api_limit = bulk_api_limit
|
10
12
|
end
|
11
13
|
end
|
12
|
-
end
|
14
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blurb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- dlbunker
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2020-
|
13
|
+
date: 2020-08-07 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -175,10 +175,12 @@ files:
|
|
175
175
|
- lib/blurb.rb
|
176
176
|
- lib/blurb/account.rb
|
177
177
|
- lib/blurb/base_class.rb
|
178
|
+
- lib/blurb/campaign_requests.rb
|
178
179
|
- lib/blurb/client.rb
|
179
180
|
- lib/blurb/errors/failed_request.rb
|
180
181
|
- lib/blurb/errors/invalid_report_request.rb
|
181
182
|
- lib/blurb/errors/request_throttled.rb
|
183
|
+
- lib/blurb/history_request.rb
|
182
184
|
- lib/blurb/profile.rb
|
183
185
|
- lib/blurb/report_requests.rb
|
184
186
|
- lib/blurb/request.rb
|