amazon-ads 0.5.0 → 0.7.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca37ac82a931b7caf155e83c72450a70b37b1e00ed1e161ff8df8707d1594940
4
- data.tar.gz: 6595ca8f52d77efd69c38436bb4b8d0f78b27a8bd06c3e444e28cafd16dc8a5a
3
+ metadata.gz: 7fcaddf24ef4055301c168898cc35031d30149ead740c4c4c4ac35f606512d0f
4
+ data.tar.gz: 75086e6378ee6e159e7c189c2a4d0a6ca912d3fd6c5809e30ceb2c9655b25ecf
5
5
  SHA512:
6
- metadata.gz: f974f8dfcd535e8c084a5a3c7d7e790f315d1190dfa5a42a15ed6aeced63d205e15545c9e580b9bafeaf025dc4de11bc3f0190ac961f7efac880e25a4ae4696b
7
- data.tar.gz: 2bbd82c0a5375b827ea8411cf008fc9ad5ee11f7fd20c743da1ec830235fa1853081724c6a0d28d4e97d845f0a88a7ec81eab0462178058fa70e5266c72a2775
6
+ metadata.gz: f1f160656461282472fd35cc506de5adb735a6bf34f0c02ecded0ee3b8018dc84ba4f25ffd1cd74dd1f16cbe4b3e4fd397fe30a62125eaaacaa9ff3f5e4cf526
7
+ data.tar.gz: 9f9beab38557f29b65125698ea9502b67bfe76ca293b290a259a48038686bbcfaa47d01272addf6b9d4be22332accb8a96b7e964e562fe492687cab02d3b0cb5
data/README.md CHANGED
@@ -54,6 +54,8 @@ campaigns = AmazonAds::Campaigns.new(
54
54
  campaigns.list_campaigns
55
55
  ```
56
56
 
57
+ Pass `http:` to inject a configured `HTTP` client (e.g. `http: HTTP.use(logging: { logger: Logger.new($stdout) })`). Note that debug logging prints request headers, exposing access tokens.
58
+
57
59
  ## Error handling
58
60
 
59
61
  Responses with a 4xx or 5xx status raise `AmazonAds::Error`, which carries the full response:
@@ -63,15 +65,30 @@ begin
63
65
  campaigns.list_campaigns
64
66
  rescue AmazonAds::Error => e
65
67
  e.status # 400
68
+ e.code # "FIELD_VALUE_IS_INVALID"
66
69
  e.response.body # Amazon's error document
67
70
  end
68
71
  ```
69
72
 
70
- The error supports pattern matching on status:
73
+ When the response carries one of Amazon's documented error codes, the error is a matching subclass under `AmazonAds::Errors`:
74
+
75
+ ```ruby
76
+ begin
77
+ campaigns.list_campaigns
78
+ rescue AmazonAds::Errors::TooManyRequests
79
+ backoff
80
+ rescue AmazonAds::Errors::Unauthorized
81
+ refresh_token
82
+ end
83
+ ```
84
+
85
+ Unknown or missing codes raise the base `AmazonAds::Error`. Reporting sends the HTTP status as its code, so its errors are always the base class.
86
+
87
+ The error supports pattern matching on status and code:
71
88
 
72
89
  ```ruby
73
90
  case error
74
- in status: 429 then backoff
91
+ in code: "TOO_MANY_REQUESTS" then backoff
75
92
  in status: 500..599 then retry
76
93
  end
77
94
  ```
@@ -15,9 +15,9 @@ module AmazonAds
15
15
  end
16
16
 
17
17
  # List ad groups
18
- #: (ad_product_filter: untyped, ?ad_group_id_filter: untyped?, ?campaign_id_filter: untyped?, ?marketplace_scope_filter: untyped?, ?max_results: Integer?, ?name_filter: untyped?, ?next_token: String?, ?state_filter: untyped?) -> HTTP::Response
19
- def query_ad_group(ad_product_filter:, ad_group_id_filter: nil, campaign_id_filter: nil, marketplace_scope_filter: nil, max_results: nil, name_filter: nil, next_token: nil, state_filter: nil)
20
- request(:post, "/adsApi/v1/query/adGroups", json: { "adGroupIdFilter" => ad_group_id_filter, "adProductFilter" => ad_product_filter, "campaignIdFilter" => campaign_id_filter, "marketplaceScopeFilter" => marketplace_scope_filter, "maxResults" => max_results, "nameFilter" => name_filter, "nextToken" => next_token, "stateFilter" => state_filter }.compact)
18
+ #: (ad_product_filter: untyped, ?ad_group_id_filter: untyped?, ?campaign_id_filter: untyped?, ?inventory_type_filter: untyped?, ?marketplace_scope_filter: untyped?, ?max_results: Integer?, ?name_filter: untyped?, ?next_token: String?, ?retailer_scope_filter: untyped?, ?state_filter: untyped?) -> HTTP::Response
19
+ def query_ad_group(ad_product_filter:, ad_group_id_filter: nil, campaign_id_filter: nil, inventory_type_filter: nil, marketplace_scope_filter: nil, max_results: nil, name_filter: nil, next_token: nil, retailer_scope_filter: nil, state_filter: nil)
20
+ request(:post, "/adsApi/v1/query/adGroups", json: { "adGroupIdFilter" => ad_group_id_filter, "adProductFilter" => ad_product_filter, "campaignIdFilter" => campaign_id_filter, "inventoryTypeFilter" => inventory_type_filter, "marketplaceScopeFilter" => marketplace_scope_filter, "maxResults" => max_results, "nameFilter" => name_filter, "nextToken" => next_token, "retailerScopeFilter" => retailer_scope_filter, "stateFilter" => state_filter }.compact)
21
21
  end
22
22
 
23
23
  # Update ad groups
@@ -15,9 +15,9 @@ module AmazonAds
15
15
  end
16
16
 
17
17
  # List ads
18
- #: (ad_product_filter: untyped, ?ad_group_id_filter: untyped?, ?ad_id_filter: untyped?, ?campaign_id_filter: untyped?, ?marketplace_scope_filter: untyped?, ?max_results: Integer?, ?name_filter: untyped?, ?next_token: String?, ?state_filter: untyped?) -> HTTP::Response
19
- def query_ad(ad_product_filter:, ad_group_id_filter: nil, ad_id_filter: nil, campaign_id_filter: nil, marketplace_scope_filter: nil, max_results: nil, name_filter: nil, next_token: nil, state_filter: nil)
20
- request(:post, "/adsApi/v1/query/ads", json: { "adGroupIdFilter" => ad_group_id_filter, "adIdFilter" => ad_id_filter, "adProductFilter" => ad_product_filter, "campaignIdFilter" => campaign_id_filter, "marketplaceScopeFilter" => marketplace_scope_filter, "maxResults" => max_results, "nameFilter" => name_filter, "nextToken" => next_token, "stateFilter" => state_filter }.compact)
18
+ #: (ad_product_filter: untyped, ?ad_group_id_filter: untyped?, ?ad_id_filter: untyped?, ?campaign_id_filter: untyped?, ?marketplace_scope_filter: untyped?, ?max_results: Integer?, ?name_filter: untyped?, ?next_token: String?, ?retailer_scope_filter: untyped?, ?state_filter: untyped?) -> HTTP::Response
19
+ def query_ad(ad_product_filter:, ad_group_id_filter: nil, ad_id_filter: nil, campaign_id_filter: nil, marketplace_scope_filter: nil, max_results: nil, name_filter: nil, next_token: nil, retailer_scope_filter: nil, state_filter: nil)
20
+ request(:post, "/adsApi/v1/query/ads", json: { "adGroupIdFilter" => ad_group_id_filter, "adIdFilter" => ad_id_filter, "adProductFilter" => ad_product_filter, "campaignIdFilter" => campaign_id_filter, "marketplaceScopeFilter" => marketplace_scope_filter, "maxResults" => max_results, "nameFilter" => name_filter, "nextToken" => next_token, "retailerScopeFilter" => retailer_scope_filter, "stateFilter" => state_filter }.compact)
21
21
  end
22
22
 
23
23
  # Update ads
@@ -2,6 +2,18 @@
2
2
 
3
3
  module AmazonAds
4
4
  class AdvertisingDeals < API
5
+ # Create advertising deals
6
+ #: (advertising_deals: Array[untyped]) -> HTTP::Response
7
+ def create_advertising_deal(advertising_deals:)
8
+ request(:post, "/adsApi/v1/create/advertisingDeals", json: { "advertisingDeals" => advertising_deals }.compact)
9
+ end
10
+
11
+ # Query advertising deals with filters
12
+ #: (ad_product_filter: untyped, ?advertising_deal_id_filter: untyped?, ?broadcasters_filter: untyped?, ?country_code_filter: untyped?, ?creation_date_time_range_filter: untyped?, ?deal_type_filter: untyped?, ?end_date_time_range_filter: untyped?, ?exchange_deal_id_filter: untyped?, ?exchange_id_filter: untyped?, ?leagues_filter: untyped?, ?marketplace_deal_filter: untyped?, ?max_results: Integer?, ?name_filter: untyped?, ?next_token: String?, ?price_range_filter: untyped?, ?price_type_filter: untyped?, ?sort: Array[untyped]?, ?sports_filter: untyped?, ?start_date_time_range_filter: untyped?, ?status_filter: untyped?, ?supply_inventory_types_filter: untyped?) -> HTTP::Response
13
+ def query_advertising_deal(ad_product_filter:, advertising_deal_id_filter: nil, broadcasters_filter: nil, country_code_filter: nil, creation_date_time_range_filter: nil, deal_type_filter: nil, end_date_time_range_filter: nil, exchange_deal_id_filter: nil, exchange_id_filter: nil, leagues_filter: nil, marketplace_deal_filter: nil, max_results: nil, name_filter: nil, next_token: nil, price_range_filter: nil, price_type_filter: nil, sort: nil, sports_filter: nil, start_date_time_range_filter: nil, status_filter: nil, supply_inventory_types_filter: nil)
14
+ request(:post, "/adsApi/v1/query/advertisingDeals", json: { "adProductFilter" => ad_product_filter, "advertisingDealIdFilter" => advertising_deal_id_filter, "broadcastersFilter" => broadcasters_filter, "countryCodeFilter" => country_code_filter, "creationDateTimeRangeFilter" => creation_date_time_range_filter, "dealTypeFilter" => deal_type_filter, "endDateTimeRangeFilter" => end_date_time_range_filter, "exchangeDealIdFilter" => exchange_deal_id_filter, "exchangeIdFilter" => exchange_id_filter, "leaguesFilter" => leagues_filter, "marketplaceDealFilter" => marketplace_deal_filter, "maxResults" => max_results, "nameFilter" => name_filter, "nextToken" => next_token, "priceRangeFilter" => price_range_filter, "priceTypeFilter" => price_type_filter, "sort" => sort, "sportsFilter" => sports_filter, "startDateTimeRangeFilter" => start_date_time_range_filter, "statusFilter" => status_filter, "supplyInventoryTypesFilter" => supply_inventory_types_filter }.compact)
15
+ end
16
+
5
17
  # Create advertisingDeal
6
18
  #: (?advertising_deals: Array[untyped]?) -> HTTP::Response
7
19
  def sb_create_advertising_deal(advertising_deals: nil)
@@ -25,5 +37,11 @@ module AmazonAds
25
37
  def sb_update_advertising_deal(advertising_deals: nil)
26
38
  request(:post, "/adsApi/v1/update/advertisingDeals/sb", json: { "advertisingDeals" => advertising_deals }.compact)
27
39
  end
40
+
41
+ # Update advertising deals
42
+ #: (advertising_deals: Array[untyped]) -> HTTP::Response
43
+ def update_advertising_deal(advertising_deals:)
44
+ request(:post, "/adsApi/v1/update/advertisingDeals", json: { "advertisingDeals" => advertising_deals }.compact)
45
+ end
28
46
  end
29
47
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AmazonAds
4
+ class BuyerSeats < API
5
+ # Create buyer seats for advertisers
6
+ #: (buyer_seats: Array[untyped]) -> HTTP::Response
7
+ def create_buyer_seat(buyer_seats:)
8
+ request(:post, "/adsApi/v1/create/buyerSeats", json: { "buyerSeats" => buyer_seats }.compact)
9
+ end
10
+
11
+ # List buyer seats
12
+ # @rbs ad_product: String -- **AdProduct Enum:** | AdProduct | Description | | --- | --- | | `AMAZON_DSP` | Amazon Demand-Side Platform ad product. |
13
+ # @rbs buyer_seat_type: String -- **BuyerSeatType Enum:** | BuyerSeatType | Description | | --- | --- | | `DEAL_CREATION` | The ID for deal providers to identify the buyer seat when creating deals. | | `SPEND_TRACKING` | The ID passed to exchanges to enable buyer recognition within auctions. This can be used for both real-time decision making and offline reporting. |
14
+ #: (?ad_product: String?, ?buyer_seat_type: String?, ?exchange_id: String?, ?next_token: String?, ?max_results: Integer?) -> HTTP::Response
15
+ def list_buyer_seat(ad_product: nil, buyer_seat_type: nil, exchange_id: nil, next_token: nil, max_results: nil)
16
+ request(:get, "/adsApi/v1/buyerSeats", params: { "adProduct" => ad_product, "buyerSeatType" => buyer_seat_type, "exchangeId" => exchange_id, "nextToken" => next_token, "maxResults" => max_results }.compact)
17
+ end
18
+ end
19
+ end
@@ -15,9 +15,9 @@ module AmazonAds
15
15
  end
16
16
 
17
17
  # Query campaign
18
- #: (ad_product_filter: untyped, ?campaign_id_filter: untyped?, ?goal_filter: untyped?, ?marketplace_scope_filter: untyped?, ?max_results: Integer?, ?name_filter: untyped?, ?next_token: String?, ?portfolio_id_filter: untyped?, ?state_filter: untyped?) -> HTTP::Response
19
- def query_campaign(ad_product_filter:, campaign_id_filter: nil, goal_filter: nil, marketplace_scope_filter: nil, max_results: nil, name_filter: nil, next_token: nil, portfolio_id_filter: nil, state_filter: nil)
20
- request(:post, "/adsApi/v1/query/campaigns", json: { "adProductFilter" => ad_product_filter, "campaignIdFilter" => campaign_id_filter, "goalFilter" => goal_filter, "marketplaceScopeFilter" => marketplace_scope_filter, "maxResults" => max_results, "nameFilter" => name_filter, "nextToken" => next_token, "portfolioIdFilter" => portfolio_id_filter, "stateFilter" => state_filter }.compact)
18
+ #: (ad_product_filter: untyped, ?campaign_id_filter: untyped?, ?goal_filter: untyped?, ?marketplace_scope_filter: untyped?, ?max_results: Integer?, ?name_filter: untyped?, ?next_token: String?, ?portfolio_id_filter: untyped?, ?retailer_scope_filter: untyped?, ?state_filter: untyped?) -> HTTP::Response
19
+ def query_campaign(ad_product_filter:, campaign_id_filter: nil, goal_filter: nil, marketplace_scope_filter: nil, max_results: nil, name_filter: nil, next_token: nil, portfolio_id_filter: nil, retailer_scope_filter: nil, state_filter: nil)
20
+ request(:post, "/adsApi/v1/query/campaigns", json: { "adProductFilter" => ad_product_filter, "campaignIdFilter" => campaign_id_filter, "goalFilter" => goal_filter, "marketplaceScopeFilter" => marketplace_scope_filter, "maxResults" => max_results, "nameFilter" => name_filter, "nextToken" => next_token, "portfolioIdFilter" => portfolio_id_filter, "retailerScopeFilter" => retailer_scope_filter, "stateFilter" => state_filter }.compact)
21
21
  end
22
22
 
23
23
  # Update campaign
@@ -2,12 +2,6 @@
2
2
 
3
3
  module AmazonAds
4
4
  class CommitmentSpends < API
5
- # Retrieve commitment spend (Deprecated legacy ad-product path alias of RetrieveCommitmentSpend; prefer the ad-product-agnostic path.)
6
- #: (commitment_ids: Array[untyped]) -> HTTP::Response
7
- def dsp_retrieve_commitment_spend(commitment_ids:)
8
- request(:post, "/adsApi/v1/retrieve/commitmentSpends/dsp", json: { "commitmentIds" => commitment_ids }.compact)
9
- end
10
-
11
5
  # Retrieve commitment spend
12
6
  #: (commitment_ids: Array[untyped]) -> HTTP::Response
13
7
  def retrieve_commitment_spend(commitment_ids:)
@@ -8,36 +8,6 @@ module AmazonAds
8
8
  request(:post, "/adsApi/v1/create/commitments", json: { "commitments" => commitments }.compact)
9
9
  end
10
10
 
11
- # Create commitments (Deprecated legacy ad-product path alias of CreateCommitment; prefer the ad-product-agnostic path.)
12
- #: (commitments: Array[untyped]) -> HTTP::Response
13
- def dsp_create_commitment(commitments:)
14
- request(:post, "/adsApi/v1/create/commitments/dsp", json: { "commitments" => commitments }.compact)
15
- end
16
-
17
- # List commitments (Deprecated legacy ad-product path alias of ListCommitment; prefer the ad-product-agnostic path.)
18
- #: (?next_token: String?, ?max_results: Integer?) -> HTTP::Response
19
- def dsp_list_commitment(next_token: nil, max_results: nil)
20
- request(:get, "/adsApi/v1/commitments/dsp", params: { "nextToken" => next_token, "maxResults" => max_results }.compact)
21
- end
22
-
23
- # Query commitments with filters (Deprecated legacy ad-product path alias of QueryCommitment; prefer the ad-product-agnostic path.)
24
- #: (?advertiser_ids_filter: untyped?, ?campaign_ids_filter: untyped?, ?commitment_id_filter: untyped?, ?commitment_name_filter: untyped?, ?deal_ids_filter: untyped?, ?max_results: Integer?, ?next_token: String?, ?spend_calculation_mode_filter: untyped?) -> HTTP::Response
25
- def dsp_query_commitment(advertiser_ids_filter: nil, campaign_ids_filter: nil, commitment_id_filter: nil, commitment_name_filter: nil, deal_ids_filter: nil, max_results: nil, next_token: nil, spend_calculation_mode_filter: nil)
26
- request(:post, "/adsApi/v1/query/commitments/dsp", json: { "advertiserIdsFilter" => advertiser_ids_filter, "campaignIdsFilter" => campaign_ids_filter, "commitmentIdFilter" => commitment_id_filter, "commitmentNameFilter" => commitment_name_filter, "dealIdsFilter" => deal_ids_filter, "maxResults" => max_results, "nextToken" => next_token, "spendCalculationModeFilter" => spend_calculation_mode_filter }.compact)
27
- end
28
-
29
- # Get Commitments (Deprecated legacy ad-product path alias of RetrieveCommitment; prefer the ad-product-agnostic path.)
30
- #: (commitment_ids: Array[untyped]) -> HTTP::Response
31
- def dsp_retrieve_commitment(commitment_ids:)
32
- request(:post, "/adsApi/v1/retrieve/commitments/dsp", json: { "commitmentIds" => commitment_ids }.compact)
33
- end
34
-
35
- # Update commitments (Deprecated legacy ad-product path alias of UpdateCommitment; prefer the ad-product-agnostic path.)
36
- #: (commitments: Array[untyped]) -> HTTP::Response
37
- def dsp_update_commitment(commitments:)
38
- request(:post, "/adsApi/v1/update/commitments/dsp", json: { "commitments" => commitments }.compact)
39
- end
40
-
41
11
  # List commitments
42
12
  #: (?next_token: String?, ?max_results: Integer?) -> HTTP::Response
43
13
  def list_commitment(next_token: nil, max_results: nil)
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AmazonAds
4
+ class DealAdvertiserAccessEntries < API
5
+ # Add advertisers to a deal advertiser access list
6
+ #: (deal_advertiser_access_entries: Array[untyped]) -> HTTP::Response
7
+ def create_deal_advertiser_access_entry(deal_advertiser_access_entries:)
8
+ request(:post, "/adsApi/v1/create/dealAdvertiserAccessEntries", json: { "dealAdvertiserAccessEntries" => deal_advertiser_access_entries }.compact)
9
+ end
10
+
11
+ # Remove advertisers from a deal advertiser access list
12
+ #: (deal_advertiser_access_entry_ids: Array[untyped]) -> HTTP::Response
13
+ def delete_deal_advertiser_access_entry(deal_advertiser_access_entry_ids:)
14
+ request(:post, "/adsApi/v1/delete/dealAdvertiserAccessEntries", json: { "dealAdvertiserAccessEntryIds" => deal_advertiser_access_entry_ids }.compact)
15
+ end
16
+
17
+ # Query advertiser entries for a deal advertiser access record
18
+ #: (deal_advertiser_access_id_filter: untyped, ?ad_product_filter: untyped?, ?max_results: Integer?, ?next_token: String?) -> HTTP::Response
19
+ def query_deal_advertiser_access_entry(deal_advertiser_access_id_filter:, ad_product_filter: nil, max_results: nil, next_token: nil)
20
+ request(:post, "/adsApi/v1/query/dealAdvertiserAccessEntries", json: { "adProductFilter" => ad_product_filter, "dealAdvertiserAccessIdFilter" => deal_advertiser_access_id_filter, "maxResults" => max_results, "nextToken" => next_token }.compact)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AmazonAds
4
+ class DealAdvertiserAccesses < API
5
+ # Create a deal advertiser access record with a strategy (ALLOW or BLOCK)
6
+ #: (deal_advertiser_accesses: Array[untyped]) -> HTTP::Response
7
+ def create_deal_advertiser_access(deal_advertiser_accesses:)
8
+ request(:post, "/adsApi/v1/create/dealAdvertiserAccesses", json: { "dealAdvertiserAccesses" => deal_advertiser_accesses }.compact)
9
+ end
10
+
11
+ # Delete a deal advertiser access record and all associated entries
12
+ #: (deal_advertiser_access_ids: Array[untyped]) -> HTTP::Response
13
+ def delete_deal_advertiser_access(deal_advertiser_access_ids:)
14
+ request(:post, "/adsApi/v1/delete/dealAdvertiserAccesses", json: { "dealAdvertiserAccessIds" => deal_advertiser_access_ids }.compact)
15
+ end
16
+
17
+ # Retrieve a deal advertiser access record by ID
18
+ #: (deal_advertiser_access_ids: Array[untyped]) -> HTTP::Response
19
+ def retrieve_deal_advertiser_access(deal_advertiser_access_ids:)
20
+ request(:post, "/adsApi/v1/retrieve/dealAdvertiserAccesses", json: { "dealAdvertiserAccessIds" => deal_advertiser_access_ids }.compact)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AmazonAds
4
+ class DealAvailses < API
5
+ # Query deal avails by advertising deal ID. Returns avails records aggregated by selected attributes over the last 7 days, sorted by eligible avails descending.
6
+ #: (ad_product_filter: untyped, advertising_deal_id_filter: untyped, ?eligible_avails_targeting_filter: untyped?, ?group_by_attributes_filter: untyped?, ?max_results: Integer?, ?next_token: String?, ?sort: Array[untyped]?) -> HTTP::Response
7
+ def query_deal_avails(ad_product_filter:, advertising_deal_id_filter:, eligible_avails_targeting_filter: nil, group_by_attributes_filter: nil, max_results: nil, next_token: nil, sort: nil)
8
+ request(:post, "/adsApi/v1/query/dealAvailses", json: { "adProductFilter" => ad_product_filter, "advertisingDealIdFilter" => advertising_deal_id_filter, "eligibleAvailsTargetingFilter" => eligible_avails_targeting_filter, "groupByAttributesFilter" => group_by_attributes_filter, "maxResults" => max_results, "nextToken" => next_token, "sort" => sort }.compact)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AmazonAds
4
+ class DealPerformances < API
5
+ # Retrieve performance metrics for each specified deal.
6
+ # @rbs ad_product: String -- **AdProduct Enum:** | AdProduct | Description | | --- | --- | | `AMAZON_DSP` | Amazon Demand-Side Platform ad product. |
7
+ #: (advertising_deal_id: String, ?ad_product: String?, ?performance_end_date: String?, ?performance_start_date: String?, ?next_token: String?, ?max_results: Integer?) -> HTTP::Response
8
+ def list_deal_performance(advertising_deal_id:, ad_product: nil, performance_end_date: nil, performance_start_date: nil, next_token: nil, max_results: nil)
9
+ request(:get, "/adsApi/v1/dealPerformances", params: { "adProduct" => ad_product, "advertisingDealId" => advertising_deal_id, "performanceEndDate" => performance_end_date, "performanceStartDate" => performance_start_date, "nextToken" => next_token, "maxResults" => max_results }.compact)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AmazonAds
4
+ class DealPlanningMetricses < API
5
+ # Query deal planning metrics for specified deals, with optional metric range filters and sort.
6
+ #: (ad_product_filter: untyped, advertising_deal_id_filter: untyped, ?click_through_rate_filter: untyped?, ?currency_filter: untyped?, ?effective_cpm_filter: untyped?, ?max_results: Integer?, ?measured_rate_filter: untyped?, ?next_token: String?, ?sort: Array[untyped]?, ?video_completion_rate_filter: untyped?, ?view_rate_filter: untyped?, ?viewable_cpm_filter: untyped?) -> HTTP::Response
7
+ def query_deal_planning_metrics(ad_product_filter:, advertising_deal_id_filter:, click_through_rate_filter: nil, currency_filter: nil, effective_cpm_filter: nil, max_results: nil, measured_rate_filter: nil, next_token: nil, sort: nil, video_completion_rate_filter: nil, view_rate_filter: nil, viewable_cpm_filter: nil)
8
+ request(:post, "/adsApi/v1/query/dealPlanningMetricses", json: { "adProductFilter" => ad_product_filter, "advertisingDealIdFilter" => advertising_deal_id_filter, "clickThroughRateFilter" => click_through_rate_filter, "currencyFilter" => currency_filter, "effectiveCPMFilter" => effective_cpm_filter, "maxResults" => max_results, "measuredRateFilter" => measured_rate_filter, "nextToken" => next_token, "sort" => sort, "videoCompletionRateFilter" => video_completion_rate_filter, "viewRateFilter" => view_rate_filter, "viewableCPMFilter" => viewable_cpm_filter }.compact)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AmazonAds
4
+ class LabelObjectAssociations < API
5
+ # Query label-to-object associations with filters.
6
+ #: (label_object_type_filter: untyped, ?ad_product_filter: untyped?, ?label_id_filter: untyped?, ?label_object_id_filter: untyped?, ?max_results: Integer?, ?next_token: String?) -> HTTP::Response
7
+ def query_label_object_association(label_object_type_filter:, ad_product_filter: nil, label_id_filter: nil, label_object_id_filter: nil, max_results: nil, next_token: nil)
8
+ request(:post, "/adsApi/v1/query/labelObjectAssociations", json: { "adProductFilter" => ad_product_filter, "labelIdFilter" => label_id_filter, "labelObjectIdFilter" => label_object_id_filter, "labelObjectTypeFilter" => label_object_type_filter, "maxResults" => max_results, "nextToken" => next_token }.compact)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AmazonAds
4
+ class Labels < API
5
+ # Query labels with filters. Returns labels that have associations of the specified object type and are visible to the caller's entity.
6
+ #: (label_object_type_filter: untyped, ?ad_product_filter: untyped?, ?label_id_filter: untyped?, ?label_name_filter: untyped?, ?max_results: Integer?, ?next_token: String?) -> HTTP::Response
7
+ def query_label(label_object_type_filter:, ad_product_filter: nil, label_id_filter: nil, label_name_filter: nil, max_results: nil, next_token: nil)
8
+ request(:post, "/adsApi/v1/query/labels", json: { "adProductFilter" => ad_product_filter, "labelIdFilter" => label_id_filter, "labelNameFilter" => label_name_filter, "labelObjectTypeFilter" => label_object_type_filter, "maxResults" => max_results, "nextToken" => next_token }.compact)
9
+ end
10
+ end
11
+ end
@@ -10,7 +10,7 @@ module AmazonAds
10
10
  # @rbs notes: String -- Additional details associated with the subscription
11
11
  #: (client_request_token: String, data_set_id: String, ?destination: untyped?, ?destination_arn: String?, ?notes: String?) -> HTTP::Response
12
12
  def create_dsp_stream_subscription(client_request_token:, data_set_id:, destination: nil, destination_arn: nil, notes: nil)
13
- request(:post, "/dsp/streams/subscriptions", json: { "clientRequestToken" => client_request_token, "dataSetId" => data_set_id, "destination" => destination, "destinationArn" => destination_arn, "notes" => notes }.compact, headers: { "Content-Type" => "application/vnd.amazonmarketingstreamsubscriptions.v1+json" })
13
+ request(:post, "/dsp/streams/subscriptions", json: { "clientRequestToken" => client_request_token, "dataSetId" => data_set_id, "destination" => destination, "destinationArn" => destination_arn, "notes" => notes }.compact, headers: { "Content-Type" => "application/vnd.amazonmarketingstreamsubscriptions.v1+json", "Accept" => "application/vnd.amazonmarketingstreamsubscriptions.v1+json" })
14
14
  end
15
15
 
16
16
  # Create a new subscription Note: trailing slash in request uri is not allowed
@@ -20,7 +20,7 @@ module AmazonAds
20
20
  # @rbs notes: String -- Additional details associated with the subscription
21
21
  #: (client_request_token: String, data_set_id: String, ?destination: untyped?, ?destination_arn: String?, ?notes: String?) -> HTTP::Response
22
22
  def create_stream_subscription(client_request_token:, data_set_id:, destination: nil, destination_arn: nil, notes: nil)
23
- request(:post, "/streams/subscriptions", json: { "clientRequestToken" => client_request_token, "dataSetId" => data_set_id, "destination" => destination, "destinationArn" => destination_arn, "notes" => notes }.compact, headers: { "Content-Type" => "application/vnd.amazonmarketingstreamsubscriptions.v1+json" })
23
+ request(:post, "/streams/subscriptions", json: { "clientRequestToken" => client_request_token, "dataSetId" => data_set_id, "destination" => destination, "destinationArn" => destination_arn, "notes" => notes }.compact, headers: { "Content-Type" => "application/vnd.amazonmarketingstreamsubscriptions.v1+json", "Accept" => "application/vnd.amazonmarketingstreamsubscriptions.v1+json" })
24
24
  end
25
25
 
26
26
  # Fetch a specific subscription by Id Note: trailing slash in request uri is not allowed
@@ -58,7 +58,7 @@ module AmazonAds
58
58
  # @rbs notes: String -- Additional details associated with the subscription
59
59
  #: (String, ?notes: String?, ?status: untyped?) -> HTTP::Response
60
60
  def update_dsp_stream_subscription(subscription_id, notes: nil, status: nil)
61
- request(:put, "/dsp/streams/subscriptions/#{subscription_id}", json: { "notes" => notes, "status" => status }.compact, headers: { "Content-Type" => "application/vnd.amazonmarketingstreamsubscriptions.v1+json" })
61
+ request(:put, "/dsp/streams/subscriptions/#{subscription_id}", json: { "notes" => notes, "status" => status }.compact, headers: { "Content-Type" => "application/vnd.amazonmarketingstreamsubscriptions.v1+json", "Accept" => "application/vnd.amazonmarketingstreamsubscriptions.v1+json" })
62
62
  end
63
63
 
64
64
  # Update an existing subscription Note: trailing slash in request uri is not allowed
@@ -66,7 +66,7 @@ module AmazonAds
66
66
  # @rbs notes: String -- Additional details associated with the subscription
67
67
  #: (String, ?notes: String?, ?status: untyped?) -> HTTP::Response
68
68
  def update_stream_subscription(subscription_id, notes: nil, status: nil)
69
- request(:put, "/streams/subscriptions/#{subscription_id}", json: { "notes" => notes, "status" => status }.compact, headers: { "Content-Type" => "application/vnd.amazonmarketingstreamsubscriptions.v1+json" })
69
+ request(:put, "/streams/subscriptions/#{subscription_id}", json: { "notes" => notes, "status" => status }.compact, headers: { "Content-Type" => "application/vnd.amazonmarketingstreamsubscriptions.v1+json", "Accept" => "application/vnd.amazonmarketingstreamsubscriptions.v1+json" })
70
70
  end
71
71
  end
72
72
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AmazonAds
4
+ # Portfolios
5
+ class Portfolios < API
6
+ # @rbs portfolios: Array[untyped] -- An array of portfolio to create.
7
+ #: (portfolios: Array[untyped]) -> HTTP::Response
8
+ def create_portfolios(portfolios:)
9
+ request(:post, "/portfolios", json: { "portfolios" => portfolios }.compact, headers: { "Content-Type" => "application/vnd.spPortfolio.v3+json", "Accept" => "application/vnd.spPortfolio.v3+json" })
10
+ end
11
+
12
+ # @rbs include_extended_data_fields: bool -- whether to get a list of targetingClauses with extended data fields (creationDate, lastUpdateDate, servingStatus).
13
+ # @rbs next_token: String -- token value allowing to navigate to the next response page
14
+ #: (?include_extended_data_fields: bool?, ?name_filter: untyped?, ?next_token: String?, ?portfolio_id_filter: untyped?, ?state_filter: untyped?) -> HTTP::Response
15
+ def list_portfolios(include_extended_data_fields: nil, name_filter: nil, next_token: nil, portfolio_id_filter: nil, state_filter: nil)
16
+ request(:post, "/portfolios/list", json: { "includeExtendedDataFields" => include_extended_data_fields, "nameFilter" => name_filter, "nextToken" => next_token, "portfolioIdFilter" => portfolio_id_filter, "stateFilter" => state_filter }.compact, headers: { "Content-Type" => "application/vnd.spPortfolio.v3+json", "Accept" => "application/vnd.spPortfolio.v3+json" })
17
+ end
18
+
19
+ # Budget usage API for portfolios
20
+ # @rbs portfolio_ids: Array[untyped] -- A list of portfolio IDs.
21
+ #: (?portfolio_ids: Array[untyped]?) -> HTTP::Response
22
+ def portfolio_budget_usage(portfolio_ids: nil)
23
+ request(:post, "/portfolios/budget/usage", json: { "portfolioIds" => portfolio_ids }.compact, headers: { "Content-Type" => "application/vnd.portfoliobudgetusage.v1+json", "Accept" => "application/vnd.portfoliobudgetusage.v1+json" })
24
+ end
25
+
26
+ # @rbs portfolios: Array[untyped] -- An array of portfolio with updated values.
27
+ #: (portfolios: Array[untyped]) -> HTTP::Response
28
+ def update_portfolios(portfolios:)
29
+ request(:put, "/portfolios", json: { "portfolios" => portfolios }.compact, headers: { "Content-Type" => "application/vnd.spPortfolio.v3+json", "Accept" => "application/vnd.spPortfolio.v3+json" })
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AmazonAds
4
+ class Publishers < API
5
+ # Query publishers. A publisher is a business entity that operates the apps, sites, or video streams where ads are displayed. Use this API to search publishers by ID or name, for example to understand and compare where your ads run.
6
+ #: (ad_product_filter: untyped, ?max_results: Integer?, ?name_filter: untyped?, ?next_token: String?, ?publisher_id_filter: untyped?, ?publisher_owner_id_filter: untyped?, ?root_domain_filter: untyped?, ?sort: Array[untyped]?) -> HTTP::Response
7
+ def query_publisher(ad_product_filter:, max_results: nil, name_filter: nil, next_token: nil, publisher_id_filter: nil, publisher_owner_id_filter: nil, root_domain_filter: nil, sort: nil)
8
+ request(:post, "/adsApi/v1/query/publishers", json: { "adProductFilter" => ad_product_filter, "maxResults" => max_results, "nameFilter" => name_filter, "nextToken" => next_token, "publisherIdFilter" => publisher_id_filter, "publisherOwnerIdFilter" => publisher_owner_id_filter, "rootDomainFilter" => root_domain_filter, "sort" => sort }.compact)
9
+ end
10
+ end
11
+ end
@@ -2,6 +2,22 @@
2
2
 
3
3
  module AmazonAds
4
4
  class Recommendations < API
5
+ # List recommendations for a given advertiser.
6
+ # @rbs ad_product: String -- **AdProduct Enum:** | AdProduct | Description | | --- | --- | | `AMAZON_DSP` | Amazon Demand-Side Platform ad product. |
7
+ # @rbs language_locale_iso: String -- A combination of ISO-639 standard for language code and ISO-3166 for country code. **LanguageLocaleIso Enum:** | LanguageLocaleIso | Description | | --- | --- | | `ak-GH` | Akan (Ghana). | | `am-ET` | Amharic (Ethiopia). | | `an-ES` | Aragonese (Spain). | | `ar-AE` | Arabic (UAE). | | `as-IN` | Assamese (India). | | `av-RU` | Avaric (Russia). | | `ay-BO` | Aymara (Bolivia). | | `ba-RU` | Bashkir (Russia). | | `be-BY` | Belarusian (Belarus). | | `bg-BG` | Bulgarian (Bulgaria). | | `bh-IN` | Bihari (India). | | `bi-VU` | Bislama (Vanuatu). | | `bm-ML` | Bambara (Mali). | | `bo-CN` | Tibetan (China). | | `bs-BA` | Bosnian (Bosnia and Herzegovina). | | `ca-ES` | Catalan (Spain). | | `ce-RU` | Chechen (Russia). | | `ch-GU` | Chamorro (Guam). | | `de-DE` | German (Germany). | | `el-GR` | Greek (Greece). | | `en-AE` | English (UAE). | | `en-AU` | English (Australia). | | `en-CA` | English (Canada). | | `en-GB` | English (United Kingdom). | | `en-IN` | English (India). | | `en-SG` | English (Singapore). | | `en-US` | English (United States). | | `eo-INT` | Esperanto (International). | | `es-CO` | Spanish (Colombia). | | `es-ES` | Spanish (Spain). | | `es-MX` | Spanish (Mexico). | | `et-EE` | Estonian (Estonia). | | `eu-ES` | Basque (Spain). | | `fa-IR` | Persian (Iran). | | `fi-FI` | Finnish (Finland). | | `fj-FJ` | Fijian (Fiji). | | `fo-FO` | Faroese (Faroe Islands). | | `fr-CA` | French (Canada). | | `fr-FR` | French (France). | | `fy-NL` | Western Frisian (Netherlands). | | `ga-IE` | Irish (Ireland). | | `gd-GB` | Scottish Gaelic (United Kingdom). | | `gl-ES` | Galician (Spain). | | `gn-PY` | Guarani (Paraguay). | | `gu-IN` | Gujarati (India). | | `gv-IM` | Manx (Isle of Man). | | `ha-NG` | Hausa (Nigeria). | | `he-IL` | Hebrew (Israel). | | `hi-IN` | Hindi (India). | | `ho-PG` | Hiri Motu (Papua New Guinea). | | `hr-HR` | Croatian (Croatia). | | `ht-HT` | Haitian Creole (Haiti). | | `hu-HU` | Hungarian (Hungary). | | `hy-AM` | Armenian (Armenia). | | `hz-NA` | Herero (Namibia). | | `ia-INT` | Interlingua (International). | | `id-ID` | Indonesian (Indonesia). | | `ie-INT` | Interlingue (International). | | `ig-NG` | Igbo (Nigeria). | | `ii-CN` | Sichuan Yi (China). | | `ik-US` | Inupiaq (United States). | | `io-INT` | Ido (International). | | `is-IS` | Icelandic (Iceland). | | `it-IT` | Italian (Italy). | | `iu-CA` | Inuktitut (Canada). | | `ja-JP` | Japanese (Japan). | | `jv-ID` | Javanese (Indonesia). | | `ka-GE` | Georgian (Georgia). | | `kg-CD` | Kongo (Democratic Republic of the Congo). | | `ki-KE` | Kikuyu (Kenya). | | `kj-NA` | Kwanyama (Namibia). | | `kk-KZ` | Kazakh (Kazakhstan). | | `kl-GL` | Kalaallisut (Greenland). | | `km-KH` | Khmer (Cambodia). | | `kn-IN` | Kannada (India). | | `ko-KR` | Korean (South Korea). | | `kr-NG` | Kanuri (Nigeria). | | `ks-IN` | Kashmiri (India). | | `ku-TR` | Kurdish (Turkey). | | `kv-RU` | Komi (Russia). | | `kw-GB` | Cornish (United Kingdom). | | `ky-KG` | Kyrgyz (Kyrgyzstan). | | `la-VA` | Latin (Vatican City). | | `lb-LU` | Luxembourgish (Luxembourg). | | `lg-UG` | Ganda (Uganda). | | `li-NL` | Limburgish (Netherlands). | | `ln-CD` | Lingala (Democratic Republic of the Congo). | | `lo-LA` | Lao (Laos). | | `lt-LT` | Lithuanian (Lithuania). | | `lu-CD` | Luba-Katanga (Democratic Republic of the Congo). | | `lv-LV` | Latvian (Latvia). | | `mg-MG` | Malagasy (Madagascar). | | `mh-MH` | Marshallese (Marshall Islands). | | `mi-NZ` | Māori (New Zealand). | | `mk-MK` | Macedonian (North Macedonia). | | `ml-IN` | Malayalam (India). | | `mn-MN` | Mongolian (Mongolia). | | `mr-IN` | Marathi (India). | | `ms-MY` | Malay (Malaysia). | | `mt-MT` | Maltese (Malta). | | `my-MM` | Burmese (Myanmar). | | `na-NR` | Nauru (Nauru). | | `nb-NO` | Norwegian Bokmål (Norway). | | `nd-ZW` | North Ndebele (Zimbabwe). | | `ne-NP` | Nepali (Nepal). | | `ng-NA` | Ndonga (Namibia). | | `nl-NL` | Dutch (Netherlands). | | `nn-NO` | Norwegian Nynorsk (Norway). | | `no-NO` | Norwegian (Norway). | | `nr-ZA` | South Ndebele (South Africa). | | `nv-US` | Navajo (United States). | | `ny-MW` | Chichewa (Malawi). | | `oc-FR` | Occitan (France). | | `oj-CA` | Ojibwa (Canada). | | `om-ET` | Oromo (Ethiopia). | | `or-IN` | Oriya (India). | | `os-RU` | Ossetian (Russia). | | `pa-IN` | Punjabi (India). | | `pi-IN` | Pali (India). | | `pl-PL` | Polish (Poland). | | `ps-AF` | Pashto (Afghanistan). | | `pt-BR` | Portuguese (Brazil). | | `pt-PT` | Portuguese (Portugal). | | `qu-PE` | Quechua (Peru). | | `rm-CH` | Romansh (Switzerland). | | `rn-BI` | Kirundi (Burundi). | | `ro-RO` | Romanian (Romania). | | `ru-RU` | Russian (Russia). | | `rw-RW` | Kinyarwanda (Rwanda). | | `sa-IN` | Sanskrit (India). | | `sc-IT` | Sardinian (Italy). | | `sd-PK` | Sindhi (Pakistan). | | `se-NO` | Northern Sami (Norway). | | `sg-CF` | Sango (Central African Republic). | | `si-LK` | Sinhala (Sri Lanka). | | `sk-SK` | Slovak (Slovakia). | | `sl-SI` | Slovenian (Slovenia). | | `sm-WS` | Samoan (Samoa). | | `sn-ZW` | Shona (Zimbabwe). | | `so-SO` | Somali (Somalia). | | `sq-AL` | Albanian (Albania). | | `sr-RS` | Serbian (Serbia). | | `ss-SZ` | Swati (Eswatini). | | `st-LS` | Southern Sotho (Lesotho). | | `su-ID` | Sundanese (Indonesia). | | `sv-SE` | Swedish (Sweden). | | `sw-TZ` | Swahili (Tanzania). | | `ta-IN` | Tamil (India). | | `te-IN` | Telugu (India). | | `tg-TJ` | Tajik (Tajikistan). | | `th-TH` | Thai (Thailand). | | `ti-ET` | Tigrinya (Ethiopia). | | `tk-TM` | Turkmen (Turkmenistan). | | `tl-PH` | Tagalog (Philippines). | | `tn-BW` | Tswana (Botswana). | | `to-TO` | Tonga (Tonga). | | `tr-TR` | Turkish (Turkey). | | `ts-ZA` | Tsonga (South Africa). | | `tt-RU` | Tatar (Russia). | | `tw-GH` | Twi (Ghana). | | `ty-PF` | Tahitian (French Polynesia). | | `ug-CN` | Uyghur (China). | | `uk-UA` | Ukrainian (Ukraine). | | `ur-PK` | Urdu (Pakistan). | | `uz-UZ` | Uzbek (Uzbekistan). | | `ve-ZA` | Venda (South Africa). | | `vi-VN` | Vietnamese (Vietnam). | | `vo-INT` | Volapük (International). | | `wa-BE` | Walloon (Belgium). | | `wo-SN` | Wolof (Senegal). | | `xh-ZA` | Xhosa (South Africa). | | `yi-IL` | Yiddish (Israel). | | `yo-NG` | Yoruba (Nigeria). | | `za-CN` | Zhuang (China). | | `zh-CN` | Chinese (China). | | `zh-TW` | Chinese (Taiwan). | | `zu-ZA` | Zulu (South Africa). |
8
+ # @rbs marketplace: String -- A list of country codes representing Amazon marketplaces
9
+ # @rbs recommendation_type_enum: String -- The unique identifier of the recommendation type. Used to classify and group similar recommendations (e.g. 'BRANDED_KEYWORD'). **RecommendationTypeEnum Enum:** | RecommendationTypeEnum | Description | | --- | --- | | `AUTOMATIC_GLOBAL_ADS_ENROLLMENT` | Surfaces an advertiser's automatic global ads enrollment status and trial performance. No additional type details are required when querying. |
10
+ #: (?ad_product: String?, ?language_locale_iso: String?, ?marketplace: String?, ?recommendation_type_enum: String?, ?next_token: String?, ?max_results: Integer?) -> HTTP::Response
11
+ def list_recommendation(ad_product: nil, language_locale_iso: nil, marketplace: nil, recommendation_type_enum: nil, next_token: nil, max_results: nil)
12
+ request(:get, "/adsApi/v1/recommendations", params: { "adProduct" => ad_product, "languageLocaleIso" => language_locale_iso, "marketplace" => marketplace, "recommendationTypeEnum" => recommendation_type_enum, "nextToken" => next_token, "maxResults" => max_results }.compact)
13
+ end
14
+
15
+ # Fetch full recommendations for a given advertiser and product.
16
+ #: (access_requested_accounts: Array[untyped], ?ad_product_filter: untyped?, ?language_filter: untyped?, ?marketplaces_filter: untyped?, ?max_results: Integer?, ?next_token: String?, ?recommendation_type_details_filter: untyped?, ?recommendation_type_filter: untyped?) -> HTTP::Response
17
+ def query_recommendation(access_requested_accounts:, ad_product_filter: nil, language_filter: nil, marketplaces_filter: nil, max_results: nil, next_token: nil, recommendation_type_details_filter: nil, recommendation_type_filter: nil)
18
+ request(:post, "/adsApi/v1/query/recommendations", json: { "accessRequestedAccounts" => access_requested_accounts, "adProductFilter" => ad_product_filter, "languageFilter" => language_filter, "marketplacesFilter" => marketplaces_filter, "maxResults" => max_results, "nextToken" => next_token, "recommendationTypeDetailsFilter" => recommendation_type_details_filter, "recommendationTypeFilter" => recommendation_type_filter }.compact)
19
+ end
20
+
5
21
  # Create recommendations
6
22
  #: (?recommendations: Array[untyped]?) -> HTTP::Response
7
23
  def sb_create_recommendation(recommendations: nil)
@@ -3,13 +3,15 @@
3
3
  module AmazonAds
4
4
  # Offline Report
5
5
  class Reporting < API
6
+ include AmazonAds::Helpers::Reporting
7
+
6
8
  # Creates a report request
7
9
  # @rbs end_date: String -- YYYY-MM-DD format. The maximum lookback window supported depends on the selection of reportTypeId. Most report types support `95 days` as lookback window.
8
10
  # @rbs name: String -- The name of the report.
9
11
  # @rbs start_date: String -- YYYY-MM-DD format. The maximum lookback window supported depends on the selection of reportTypeId. Most report types support `95 days` as lookback window.
10
12
  #: (configuration: untyped, end_date: String, start_date: String, ?name: String?) -> HTTP::Response
11
13
  def create_async_report(configuration:, end_date:, start_date:, name: nil)
12
- request(:post, "/reporting/reports", json: { "configuration" => configuration, "endDate" => end_date, "name" => name, "startDate" => start_date }.compact, headers: { "Content-Type" => "application/vnd.createasyncreportrequest.v3+json" })
14
+ request(:post, "/reporting/reports", json: { "configuration" => configuration, "endDate" => end_date, "name" => name, "startDate" => start_date }.compact, headers: { "Content-Type" => "application/vnd.createasyncreportrequest.v3+json", "Accept" => "application/vnd.createasyncreportrequest.v3+json" })
13
15
  end
14
16
 
15
17
  # Deletes a report by id
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AmazonAds
4
+ class Reports < API
5
+ # Create a report
6
+ #: (access_requested_accounts: Array[untyped], reports: Array[untyped]) -> HTTP::Response
7
+ def ads_apiv1_create_report(access_requested_accounts:, reports:)
8
+ request(:post, "/adsApi/v1/create/reports", json: { "accessRequestedAccounts" => access_requested_accounts, "reports" => reports }.compact)
9
+ end
10
+
11
+ # Delete a report by ID
12
+ #: (report_ids: Array[untyped]) -> HTTP::Response
13
+ def ads_apiv1_delete_report(report_ids:)
14
+ request(:post, "/adsApi/v1/delete/reports", json: { "reportIds" => report_ids }.compact)
15
+ end
16
+
17
+ # Retrieve a report by ID
18
+ #: (report_ids: Array[untyped]) -> HTTP::Response
19
+ def ads_apiv1_retrieve_report(report_ids:)
20
+ request(:post, "/adsApi/v1/retrieve/reports", json: { "reportIds" => report_ids }.compact)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AmazonAds
4
+ class Sellers < API
5
+ # Query sellers. A seller is a business entity that has the rights to sell a publisher's advertising inventory and holds accounts with suppliers that send that inventory to Amazon DSP. Use this API to search sellers by ID or name, for example to identify a seller when creating a deal or commitment.
6
+ #: (ad_product_filter: untyped, ?max_results: Integer?, ?name_filter: untyped?, ?next_token: String?, ?seller_id_filter: untyped?, ?seller_parent_id_filter: untyped?, ?sort: Array[untyped]?) -> HTTP::Response
7
+ def query_seller(ad_product_filter:, max_results: nil, name_filter: nil, next_token: nil, seller_id_filter: nil, seller_parent_id_filter: nil, sort: nil)
8
+ request(:post, "/adsApi/v1/query/sellers", json: { "adProductFilter" => ad_product_filter, "maxResults" => max_results, "nameFilter" => name_filter, "nextToken" => next_token, "sellerIdFilter" => seller_id_filter, "sellerParentIdFilter" => seller_parent_id_filter, "sort" => sort }.compact)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AmazonAds
4
+ class StreamSubscriptions < API
5
+ # Create a new subscription\nNote: trailing slash in request uri is not allowed
6
+ #: (access_requested_accounts: Array[untyped], stream_subscriptions: Array[untyped]) -> HTTP::Response
7
+ def ads_apiv1_create_stream_subscription(access_requested_accounts:, stream_subscriptions:)
8
+ request(:post, "/adsApi/v1/create/streamSubscriptions", json: { "accessRequestedAccounts" => access_requested_accounts, "streamSubscriptions" => stream_subscriptions }.compact)
9
+ end
10
+
11
+ # Archive an existing subscription Note: trailing slash in request uri is not allowed
12
+ #: (access_requested_accounts: Array[untyped], stream_subscription_ids: Array[untyped]) -> HTTP::Response
13
+ def ads_apiv1_delete_stream_subscription(access_requested_accounts:, stream_subscription_ids:)
14
+ request(:post, "/adsApi/v1/delete/streamSubscriptions", json: { "accessRequestedAccounts" => access_requested_accounts, "streamSubscriptionIds" => stream_subscription_ids }.compact)
15
+ end
16
+
17
+ # Query subscriptions Note: trailing slash in request uri is not allowed
18
+ #: (access_requested_accounts: Array[untyped], ?max_results: Integer?, ?next_token: String?) -> HTTP::Response
19
+ def ads_apiv1_query_stream_subscription(access_requested_accounts:, max_results: nil, next_token: nil)
20
+ request(:post, "/adsApi/v1/query/streamSubscriptions", json: { "accessRequestedAccounts" => access_requested_accounts, "maxResults" => max_results, "nextToken" => next_token }.compact)
21
+ end
22
+
23
+ # Fetch a specific subscription by Id Note: trailing slash in request uri is not allowed
24
+ #: (access_requested_accounts: Array[untyped], stream_subscription_ids: Array[untyped]) -> HTTP::Response
25
+ def ads_apiv1_retrieve_stream_subscription(access_requested_accounts:, stream_subscription_ids:)
26
+ request(:post, "/adsApi/v1/retrieve/streamSubscriptions", json: { "accessRequestedAccounts" => access_requested_accounts, "streamSubscriptionIds" => stream_subscription_ids }.compact)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AmazonAds
4
+ class Suppliers < API
5
+ # Query suppliers. A supplier is a business entity that sends advertising inventory to Amazon DSP, either through direct publisher relationships or as an intermediary such as a supply-side platform (SSP). Use this API to search suppliers by ID or name, or to find the suppliers that can serve a given inventory type or delivery channel in the open auction.
6
+ #: (ad_product_filter: untyped, ?integration_type_filter: untyped?, ?max_results: Integer?, ?next_token: String?, ?open_auction_delivery_channels_filter: untyped?, ?open_auction_device_types_filter: untyped?, ?open_auction_inventory_types_filter: untyped?, ?sort: Array[untyped]?, ?state_filter: untyped?, ?supplier_id_filter: untyped?, ?supplier_name_filter: untyped?, ?type_filter: untyped?) -> HTTP::Response
7
+ def query_supplier(ad_product_filter:, integration_type_filter: nil, max_results: nil, next_token: nil, open_auction_delivery_channels_filter: nil, open_auction_device_types_filter: nil, open_auction_inventory_types_filter: nil, sort: nil, state_filter: nil, supplier_id_filter: nil, supplier_name_filter: nil, type_filter: nil)
8
+ request(:post, "/adsApi/v1/query/suppliers", json: { "adProductFilter" => ad_product_filter, "integrationTypeFilter" => integration_type_filter, "maxResults" => max_results, "nextToken" => next_token, "openAuctionDeliveryChannelsFilter" => open_auction_delivery_channels_filter, "openAuctionDeviceTypesFilter" => open_auction_device_types_filter, "openAuctionInventoryTypesFilter" => open_auction_inventory_types_filter, "sort" => sort, "stateFilter" => state_filter, "supplierIdFilter" => supplier_id_filter, "supplierNameFilter" => supplier_name_filter, "typeFilter" => type_filter }.compact)
9
+ end
10
+ end
11
+ end
@@ -15,9 +15,9 @@ module AmazonAds
15
15
  end
16
16
 
17
17
  # List target
18
- #: (ad_product_filter: untyped, ?ad_group_id_filter: untyped?, ?campaign_id_filter: untyped?, ?inventory_source_id_filter: untyped?, ?inventory_source_type_filter: untyped?, ?keyword_filter: untyped?, ?marketplace_scope_filter: untyped?, ?match_type_filter: untyped?, ?max_results: Integer?, ?native_language_locale_filter: untyped?, ?negative_filter: untyped?, ?next_token: String?, ?product_id_filter: untyped?, ?state_filter: untyped?, ?target_id_filter: untyped?, ?target_type_filter: untyped?) -> HTTP::Response
19
- def query_target(ad_product_filter:, ad_group_id_filter: nil, campaign_id_filter: nil, inventory_source_id_filter: nil, inventory_source_type_filter: nil, keyword_filter: nil, marketplace_scope_filter: nil, match_type_filter: nil, max_results: nil, native_language_locale_filter: nil, negative_filter: nil, next_token: nil, product_id_filter: nil, state_filter: nil, target_id_filter: nil, target_type_filter: nil)
20
- request(:post, "/adsApi/v1/query/targets", json: { "adGroupIdFilter" => ad_group_id_filter, "adProductFilter" => ad_product_filter, "campaignIdFilter" => campaign_id_filter, "inventorySourceIdFilter" => inventory_source_id_filter, "inventorySourceTypeFilter" => inventory_source_type_filter, "keywordFilter" => keyword_filter, "marketplaceScopeFilter" => marketplace_scope_filter, "matchTypeFilter" => match_type_filter, "maxResults" => max_results, "nativeLanguageLocaleFilter" => native_language_locale_filter, "negativeFilter" => negative_filter, "nextToken" => next_token, "productIdFilter" => product_id_filter, "stateFilter" => state_filter, "targetIdFilter" => target_id_filter, "targetTypeFilter" => target_type_filter }.compact)
18
+ #: (ad_product_filter: untyped, ?ad_group_id_filter: untyped?, ?campaign_id_filter: untyped?, ?inventory_source_id_filter: untyped?, ?inventory_source_type_filter: untyped?, ?keyword_filter: untyped?, ?marketplace_scope_filter: untyped?, ?match_type_filter: untyped?, ?max_results: Integer?, ?native_language_locale_filter: untyped?, ?negative_filter: untyped?, ?next_token: String?, ?product_id_filter: untyped?, ?retailer_id_filter: untyped?, ?retailer_scope_filter: untyped?, ?state_filter: untyped?, ?target_id_filter: untyped?, ?target_type_filter: untyped?) -> HTTP::Response
19
+ def query_target(ad_product_filter:, ad_group_id_filter: nil, campaign_id_filter: nil, inventory_source_id_filter: nil, inventory_source_type_filter: nil, keyword_filter: nil, marketplace_scope_filter: nil, match_type_filter: nil, max_results: nil, native_language_locale_filter: nil, negative_filter: nil, next_token: nil, product_id_filter: nil, retailer_id_filter: nil, retailer_scope_filter: nil, state_filter: nil, target_id_filter: nil, target_type_filter: nil)
20
+ request(:post, "/adsApi/v1/query/targets", json: { "adGroupIdFilter" => ad_group_id_filter, "adProductFilter" => ad_product_filter, "campaignIdFilter" => campaign_id_filter, "inventorySourceIdFilter" => inventory_source_id_filter, "inventorySourceTypeFilter" => inventory_source_type_filter, "keywordFilter" => keyword_filter, "marketplaceScopeFilter" => marketplace_scope_filter, "matchTypeFilter" => match_type_filter, "maxResults" => max_results, "nativeLanguageLocaleFilter" => native_language_locale_filter, "negativeFilter" => negative_filter, "nextToken" => next_token, "productIdFilter" => product_id_filter, "retailerIdFilter" => retailer_id_filter, "retailerScopeFilter" => retailer_scope_filter, "stateFilter" => state_filter, "targetIdFilter" => target_id_filter, "targetTypeFilter" => target_type_filter }.compact)
21
21
  end
22
22
 
23
23
  # Update target
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "http"
4
+ require "json"
4
5
 
5
6
  module AmazonAds
6
7
  # Raised when the API or LWA responds with a 4xx or 5xx
@@ -8,15 +9,34 @@ module AmazonAds
8
9
  # The failed response
9
10
  attr_reader :response #: HTTP::Response?
10
11
 
12
+ # Amazon's error code, if the response carries one
13
+ attr_reader :code #: String?
14
+
15
+ # Returns the subclass in Errors matching the response's error code,
16
+ # falling back to Error when the code is unknown or missing
17
+ #
11
18
  #: (HTTP::Response) -> Error
12
19
  def self.build(response)
13
20
  response.flush # memoize the body while the connection is still readable
14
- new(response.status.to_s, response)
21
+ code = parse_code(response)
22
+ klass = (code && Errors::CODES[code]) || Error
23
+ klass.new(response.status.to_s, response, code: code)
24
+ end
25
+
26
+ #: (HTTP::Response) -> String?
27
+ def self.parse_code(response)
28
+ body = JSON.parse(response.body.to_s)
29
+ code = body["code"] if body.is_a?(Hash)
30
+ code if code.is_a?(String)
31
+ rescue JSON::ParserError
32
+ nil
15
33
  end
34
+ private_class_method :parse_code
16
35
 
17
- #: (?String?, ?HTTP::Response?) -> void
18
- def initialize(msg = nil, response = nil)
36
+ #: (?String?, ?HTTP::Response?, ?code: String?) -> void
37
+ def initialize(msg = nil, response = nil, code: nil)
19
38
  @response = response
39
+ @code = code
20
40
  super(msg)
21
41
  end
22
42
 
@@ -25,16 +45,16 @@ module AmazonAds
25
45
  response&.status&.code
26
46
  end
27
47
 
28
- # Supports pattern matching on status
48
+ # Supports pattern matching on status and code
29
49
  #
30
50
  # case error
31
- # in status: 429 then backoff
51
+ # in code: "TOO_MANY_REQUESTS" then backoff
32
52
  # in status: 500..599 then retry
33
53
  # end
34
54
  #
35
55
  #: (Array[Symbol]?) -> Hash[Symbol, untyped]
36
56
  def deconstruct_keys(keys)
37
- hash = { status: status }
57
+ hash = { status: status, code: code }
38
58
  keys ? hash.slice(*keys) : hash
39
59
  end
40
60
  end
@@ -0,0 +1,286 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AmazonAds
4
+ # Errors for the codes Amazon Ads documents in its ErrorCode enum
5
+ module Errors
6
+ # The request does not have access to the manager account provided in the registration request.
7
+ class AccessDeniedForManagerAccount < Error; end
8
+
9
+ # An advertiser account already exists with this display name.
10
+ class AccountAlreadyExistsForAccountName < Error; end
11
+
12
+ # An advertiser account already exists for this selling account.
13
+ class AccountAlreadyExistsForSellingAccount < Error; end
14
+
15
+ # An advertiser account already exists for the selected vendor.
16
+ class AccountAlreadyExistsForVendor < Error; end
17
+
18
+ # The request is not supported.
19
+ class ActionNotSupported < Error; end
20
+
21
+ # Too many live resources. Remove resources and try again.
22
+ class ActiveResourceLimitExceeded < Error; end
23
+
24
+ # Business name provided is too long.
25
+ class AddressBusinessNameTooLong < Error; end
26
+
27
+ # The state provided in business address is invalid.
28
+ class AddressInvalidState < Error; end
29
+
30
+ # New resources cannot be created within an archived parent.
31
+ class ArchivedParentCannotCreate < Error; end
32
+
33
+ # Resources within an archived parent cannot be edited.
34
+ class ArchivedParentCannotEdit < Error; end
35
+
36
+ # Archived resources cannot be edited.
37
+ class ArchivedResourceCannotEdit < Error; end
38
+
39
+ # The provided asset is still being processed.
40
+ class AssetNotReady < Error; end
41
+
42
+ # Autocreated entities cannot be edited. To complete this action, create the resource manually.
43
+ class AutocreatedEntityCannotEdit < Error; end
44
+
45
+ # The request is not valid considering the documented schema.
46
+ class BadRequest < Error; end
47
+
48
+ # Operation could not be completed due to a conflict. Please retry your request.
49
+ class Conflict < Error; end
50
+
51
+ # The request is too large. Consider splitting it into multiple requests.
52
+ class ContentTooLarge < Error; end
53
+
54
+ # Update the date to be in the future.
55
+ class DateCannotBeInPast < Error; end
56
+
57
+ # Update the date.
58
+ class DateCannotBeNull < Error; end
59
+
60
+ # Update the date to be further in the future.
61
+ class DateTooSoon < Error; end
62
+
63
+ # Multiple resources share the non-unique field values. Remove the non-unique field value.
64
+ class DuplicateFieldValueFound < Error; end
65
+
66
+ # Multiple resources share the same ID. Remove the duplicate ID.
67
+ class DuplicateResourceIdFound < Error; end
68
+
69
+ # Update the length to be within the required range.
70
+ class DurationTooShort < Error; end
71
+
72
+ # Feature has been discontinued.
73
+ class FeatureDiscontinued < Error; end
74
+
75
+ # The requested feature is not available.
76
+ class FeatureNotAvailable < Error; end
77
+
78
+ # Update the value to be within the required range.
79
+ class FieldSizeIsAboveMaximumLimit < Error; end
80
+
81
+ # Update the value to be within the required range.
82
+ class FieldSizeIsBelowMinimumLimit < Error; end
83
+
84
+ # Update the value to be within the required range.
85
+ class FieldSizeIsOutOfRange < Error; end
86
+
87
+ # Field value cannot be edited.
88
+ class FieldValueCannotEdit < Error; end
89
+
90
+ # Update the request with the required information for this resource.
91
+ class FieldValueContainsBlocklistedWords < Error; end
92
+
93
+ # Remove the invalid characters and try again.
94
+ class FieldValueContainsInvalidCharacters < Error; end
95
+
96
+ # Update the value to be within the required range.
97
+ class FieldValueIsAboveMaximumLimit < Error; end
98
+
99
+ # Update the value to be within the required range.
100
+ class FieldValueIsBelowMinimumLimit < Error; end
101
+
102
+ # Update the request with the required information for this resource.
103
+ class FieldValueIsEmpty < Error; end
104
+
105
+ # Update the request with the required information for this resource.
106
+ class FieldValueIsInvalid < Error; end
107
+
108
+ # Update the request with the required information for this resource.
109
+ class FieldValueIsNull < Error; end
110
+
111
+ # Update the value to be within the required range.
112
+ class FieldValueIsOutOfRange < Error; end
113
+
114
+ # Mismatch among resource field values.
115
+ class FieldValueMismatch < Error; end
116
+
117
+ # Update the request with the required information for this resource.
118
+ class FieldValueMustBeEmptyOrNull < Error; end
119
+
120
+ # Resource specified in the field value not found. Try again with valid value.
121
+ class FieldValueNotFound < Error; end
122
+
123
+ # Resource field value conflicts with existing resource. Try again with an unique field value.
124
+ class FieldValueNotUnique < Error; end
125
+
126
+ # The caller is not authorized to make the given request.
127
+ class Forbidden < Error; end
128
+
129
+ # The campaign is associated with a global campaign. Portfolio association cannot be updated on a child campaign. Please perform operation on the global campaign.
130
+ class GlobalAttributeUpdateRestrictedPortfolio < Error; end
131
+
132
+ # The campaign is associated with a global campaign. The state on child campaign cannot be set to archived. Please perform operation on global campaign.
133
+ class GlobalAttributeUpdateRestrictedState < Error; end
134
+
135
+ # The campaign is associated with a global campaign. Only one ad group can be created under this campaign.
136
+ class GlobalCampaignSingleAdgroupLimit < Error; end
137
+
138
+ # The server encountered an unexpected condition that prevented it from fulfilling the request.
139
+ class InternalError < Error; end
140
+
141
+ # The request has invalid input parameters.
142
+ class InvalidInput < Error; end
143
+
144
+ # The state provided in business address is invalid.
145
+ class InvalidStateOrRegion < Error; end
146
+
147
+ # The website url provided in business detail is invalid
148
+ class InvalidWebsiteUrl < Error; end
149
+
150
+ # The zip code provided in business address is invalid.
151
+ class InvalidZipCode < Error; end
152
+
153
+ # Address line 1 is missing in business address.
154
+ class MissingAddressLineOne < Error; end
155
+
156
+ # Business name is missing from business detail.
157
+ class MissingBusinessName < Error; end
158
+
159
+ # City is missing in business address.
160
+ class MissingCity < Error; end
161
+
162
+ # Country is missing in business address.
163
+ class MissingCountryCode < Error; end
164
+
165
+ # Phone number is missing from business detail.
166
+ class MissingPhoneNumber < Error; end
167
+
168
+ # State is missing in business address.
169
+ class MissingState < Error; end
170
+
171
+ # Website url is missing from business detail.
172
+ class MissingWebsiteUrl < Error; end
173
+
174
+ # Zip code is missing in business address.
175
+ class MissingZipCode < Error; end
176
+
177
+ # The requested resource does not exist.
178
+ class NotFound < Error; end
179
+
180
+ # Payment failed.
181
+ class PaymentIssue < Error; end
182
+
183
+ # Product is not eligible for advertising. Try again with a valid product.
184
+ class ProductIneligible < Error; end
185
+
186
+ # Resource does not belong to the specified parent. Try again with a valid parent ID.
187
+ class ResourceDoesNotBelongToParent < Error; end
188
+
189
+ # Resource ID not found. Try again with valid ID.
190
+ class ResourceIdNotFound < Error; end
191
+
192
+ # Update the request with the required information for this resource.
193
+ class ResourceIsEmpty < Error; end
194
+
195
+ # Resource is in terminal state.
196
+ class ResourceIsInTerminalState < Error; end
197
+
198
+ # Update the request with the required information for this resource.
199
+ class ResourceIsNull < Error; end
200
+
201
+ # There have been too many requests, please slow down your call rate.
202
+ class TooManyRequests < Error; end
203
+
204
+ # Too many resources. Remove resources and try again.
205
+ class TotalResourceLimitExceeded < Error; end
206
+
207
+ # The request lacks the necessary credentials.
208
+ class Unauthorized < Error; end
209
+
210
+ # Marketplace not supported. Try again with a supported marketplace.
211
+ class UnsupportedMarketplace < Error; end
212
+
213
+ # Maps Amazon's error codes to their classes
214
+ CODES = { #: Hash[String, singleton(Error)]
215
+ "ACCESS_DENIED_FOR_MANAGER_ACCOUNT" => AccessDeniedForManagerAccount,
216
+ "ACCOUNT_ALREADY_EXISTS_FOR_ACCOUNT_NAME" => AccountAlreadyExistsForAccountName,
217
+ "ACCOUNT_ALREADY_EXISTS_FOR_SELLING_ACCOUNT" => AccountAlreadyExistsForSellingAccount,
218
+ "ACCOUNT_ALREADY_EXISTS_FOR_VENDOR" => AccountAlreadyExistsForVendor,
219
+ "ACTION_NOT_SUPPORTED" => ActionNotSupported,
220
+ "ACTIVE_RESOURCE_LIMIT_EXCEEDED" => ActiveResourceLimitExceeded,
221
+ "ADDRESS_BUSINESS_NAME_TOO_LONG" => AddressBusinessNameTooLong,
222
+ "ADDRESS_INVALID_STATE" => AddressInvalidState,
223
+ "ARCHIVED_PARENT_CANNOT_CREATE" => ArchivedParentCannotCreate,
224
+ "ARCHIVED_PARENT_CANNOT_EDIT" => ArchivedParentCannotEdit,
225
+ "ARCHIVED_RESOURCE_CANNOT_EDIT" => ArchivedResourceCannotEdit,
226
+ "ASSET_NOT_READY" => AssetNotReady,
227
+ "AUTOCREATED_ENTITY_CANNOT_EDIT" => AutocreatedEntityCannotEdit,
228
+ "BAD_REQUEST" => BadRequest,
229
+ "CONFLICT" => Conflict,
230
+ "CONTENT_TOO_LARGE" => ContentTooLarge,
231
+ "DATE_CANNOT_BE_IN_PAST" => DateCannotBeInPast,
232
+ "DATE_CANNOT_BE_NULL" => DateCannotBeNull,
233
+ "DATE_TOO_SOON" => DateTooSoon,
234
+ "DUPLICATE_FIELD_VALUE_FOUND" => DuplicateFieldValueFound,
235
+ "DUPLICATE_RESOURCE_ID_FOUND" => DuplicateResourceIdFound,
236
+ "DURATION_TOO_SHORT" => DurationTooShort,
237
+ "FEATURE_DISCONTINUED" => FeatureDiscontinued,
238
+ "FEATURE_NOT_AVAILABLE" => FeatureNotAvailable,
239
+ "FIELD_SIZE_IS_ABOVE_MAXIMUM_LIMIT" => FieldSizeIsAboveMaximumLimit,
240
+ "FIELD_SIZE_IS_BELOW_MINIMUM_LIMIT" => FieldSizeIsBelowMinimumLimit,
241
+ "FIELD_SIZE_IS_OUT_OF_RANGE" => FieldSizeIsOutOfRange,
242
+ "FIELD_VALUE_CANNOT_EDIT" => FieldValueCannotEdit,
243
+ "FIELD_VALUE_CONTAINS_BLOCKLISTED_WORDS" => FieldValueContainsBlocklistedWords,
244
+ "FIELD_VALUE_CONTAINS_INVALID_CHARACTERS" => FieldValueContainsInvalidCharacters,
245
+ "FIELD_VALUE_IS_ABOVE_MAXIMUM_LIMIT" => FieldValueIsAboveMaximumLimit,
246
+ "FIELD_VALUE_IS_BELOW_MINIMUM_LIMIT" => FieldValueIsBelowMinimumLimit,
247
+ "FIELD_VALUE_IS_EMPTY" => FieldValueIsEmpty,
248
+ "FIELD_VALUE_IS_INVALID" => FieldValueIsInvalid,
249
+ "FIELD_VALUE_IS_NULL" => FieldValueIsNull,
250
+ "FIELD_VALUE_IS_OUT_OF_RANGE" => FieldValueIsOutOfRange,
251
+ "FIELD_VALUE_MISMATCH" => FieldValueMismatch,
252
+ "FIELD_VALUE_MUST_BE_EMPTY_OR_NULL" => FieldValueMustBeEmptyOrNull,
253
+ "FIELD_VALUE_NOT_FOUND" => FieldValueNotFound,
254
+ "FIELD_VALUE_NOT_UNIQUE" => FieldValueNotUnique,
255
+ "FORBIDDEN" => Forbidden,
256
+ "GLOBAL_ATTRIBUTE_UPDATE_RESTRICTED_PORTFOLIO" => GlobalAttributeUpdateRestrictedPortfolio,
257
+ "GLOBAL_ATTRIBUTE_UPDATE_RESTRICTED_STATE" => GlobalAttributeUpdateRestrictedState,
258
+ "GLOBAL_CAMPAIGN_SINGLE_ADGROUP_LIMIT" => GlobalCampaignSingleAdgroupLimit,
259
+ "INTERNAL_ERROR" => InternalError,
260
+ "INVALID_INPUT" => InvalidInput,
261
+ "INVALID_STATE_OR_REGION" => InvalidStateOrRegion,
262
+ "INVALID_WEBSITE_URL" => InvalidWebsiteUrl,
263
+ "INVALID_ZIP_CODE" => InvalidZipCode,
264
+ "MISSING_ADDRESS_LINE_ONE" => MissingAddressLineOne,
265
+ "MISSING_BUSINESS_NAME" => MissingBusinessName,
266
+ "MISSING_CITY" => MissingCity,
267
+ "MISSING_COUNTRY_CODE" => MissingCountryCode,
268
+ "MISSING_PHONE_NUMBER" => MissingPhoneNumber,
269
+ "MISSING_STATE" => MissingState,
270
+ "MISSING_WEBSITE_URL" => MissingWebsiteUrl,
271
+ "MISSING_ZIP_CODE" => MissingZipCode,
272
+ "NOT_FOUND" => NotFound,
273
+ "PAYMENT_ISSUE" => PaymentIssue,
274
+ "PRODUCT_INELIGIBLE" => ProductIneligible,
275
+ "RESOURCE_DOES_NOT_BELONG_TO_PARENT" => ResourceDoesNotBelongToParent,
276
+ "RESOURCE_ID_NOT_FOUND" => ResourceIdNotFound,
277
+ "RESOURCE_IS_EMPTY" => ResourceIsEmpty,
278
+ "RESOURCE_IS_IN_TERMINAL_STATE" => ResourceIsInTerminalState,
279
+ "RESOURCE_IS_NULL" => ResourceIsNull,
280
+ "TOO_MANY_REQUESTS" => TooManyRequests,
281
+ "TOTAL_RESOURCE_LIMIT_EXCEEDED" => TotalResourceLimitExceeded,
282
+ "UNAUTHORIZED" => Unauthorized,
283
+ "UNSUPPORTED_MARKETPLACE" => UnsupportedMarketplace,
284
+ }.freeze
285
+ end
286
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "http"
4
+ require "stringio"
5
+ require "zlib"
6
+
7
+ module AmazonAds
8
+ module Helpers
9
+ # Convenience methods for the Reporting API
10
+ module Reporting
11
+ # Downloads a report by report ID or presigned download URL
12
+ #
13
+ # @param report_id_or_url [String] The report identifier or download URL
14
+ # @return [HTTP::Response] The response containing decompressed report content
15
+ #: (String) -> HTTP::Response
16
+ def download_report(report_id_or_url)
17
+ url = if report_id_or_url.start_with?("http")
18
+ report_id_or_url
19
+ else
20
+ # @type var client: AmazonAds::Reporting
21
+ client = self
22
+ client.get_async_report(report_id_or_url).parse.fetch("url")
23
+ end
24
+
25
+ download_report_from_url(url)
26
+ end
27
+
28
+ private
29
+
30
+ #: (String) -> HTTP::Response
31
+ def download_report_from_url(url)
32
+ response = HTTP.use(:auto_inflate).get(url)
33
+ body = response.body.to_s
34
+ if body.b.start_with?("\x1F\x8B".b)
35
+ body = Zlib::GzipReader.new(StringIO.new(body)).read
36
+ end
37
+
38
+ headers = response.headers.to_h
39
+ headers["Content-Type"] ||= "application/json"
40
+
41
+ HTTP::Response.new(
42
+ status: response.code,
43
+ version: response.version,
44
+ headers: headers,
45
+ body: body,
46
+ request: response.request,
47
+ )
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AmazonAds
4
- VERSION = "0.5.0"
4
+ VERSION = "0.7.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amazon-ads
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hakan Ensari
@@ -73,22 +73,35 @@ files:
73
73
  - lib/amazon_ads/apis/brand_store_pages.rb
74
74
  - lib/amazon_ads/apis/brand_stores.rb
75
75
  - lib/amazon_ads/apis/branded_keywords_pricings.rb
76
+ - lib/amazon_ads/apis/buyer_seats.rb
76
77
  - lib/amazon_ads/apis/campaign_forecasts.rb
77
78
  - lib/amazon_ads/apis/campaigns.rb
78
79
  - lib/amazon_ads/apis/commitment_spends.rb
79
80
  - lib/amazon_ads/apis/commitments.rb
81
+ - lib/amazon_ads/apis/deal_advertiser_access_entries.rb
82
+ - lib/amazon_ads/apis/deal_advertiser_accesses.rb
83
+ - lib/amazon_ads/apis/deal_availses.rb
84
+ - lib/amazon_ads/apis/deal_performances.rb
85
+ - lib/amazon_ads/apis/deal_planning_metricses.rb
80
86
  - lib/amazon_ads/apis/deal_preferences.rb
81
87
  - lib/amazon_ads/apis/geo_locations.rb
82
88
  - lib/amazon_ads/apis/keyword_reservation_validations.rb
89
+ - lib/amazon_ads/apis/label_object_associations.rb
90
+ - lib/amazon_ads/apis/labels.rb
83
91
  - lib/amazon_ads/apis/location_indexes.rb
84
92
  - lib/amazon_ads/apis/manager_accounts.rb
85
93
  - lib/amazon_ads/apis/marketing_stream.rb
94
+ - lib/amazon_ads/apis/portfolios.rb
86
95
  - lib/amazon_ads/apis/profiles.rb
96
+ - lib/amazon_ads/apis/publishers.rb
87
97
  - lib/amazon_ads/apis/recommendation_types.rb
88
98
  - lib/amazon_ads/apis/recommendations.rb
89
99
  - lib/amazon_ads/apis/reporting.rb
100
+ - lib/amazon_ads/apis/reports.rb
90
101
  - lib/amazon_ads/apis/reserved_target_pricings.rb
102
+ - lib/amazon_ads/apis/sellers.rb
91
103
  - lib/amazon_ads/apis/selling_accounts.rb
104
+ - lib/amazon_ads/apis/stream_subscriptions.rb
92
105
  - lib/amazon_ads/apis/supplier_ad_product_prices.rb
93
106
  - lib/amazon_ads/apis/supplier_ad_products.rb
94
107
  - lib/amazon_ads/apis/supplier_proposal_destinations.rb
@@ -99,8 +112,11 @@ files:
99
112
  - lib/amazon_ads/apis/supplier_proposed_deals.rb
100
113
  - lib/amazon_ads/apis/supplier_publishers.rb
101
114
  - lib/amazon_ads/apis/supplier_target_items.rb
115
+ - lib/amazon_ads/apis/suppliers.rb
102
116
  - lib/amazon_ads/apis/targets.rb
103
117
  - lib/amazon_ads/error.rb
118
+ - lib/amazon_ads/errors.rb
119
+ - lib/amazon_ads/helpers/reporting.rb
104
120
  - lib/amazon_ads/lwa.rb
105
121
  - lib/amazon_ads/version.rb
106
122
  homepage: https://github.com/lineofflight/amazon-ads-ruby
@@ -125,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
141
  - !ruby/object:Gem::Version
126
142
  version: '0'
127
143
  requirements: []
128
- rubygems_version: 4.0.16
144
+ rubygems_version: 4.0.20
129
145
  specification_version: 4
130
146
  summary: Amazon Ads API client for Ruby
131
147
  test_files: []