Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test: implement sponsored display targeting operation #531

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e51ba85
feat: implement create sd targeting method
nguyentoanit Aug 22, 2020
66792b3
test: adds Polly recordings [skip ci]
Aug 22, 2020
164a6dc
test: create T00020 sd campaign tactic
nguyentoanit Aug 22, 2020
4eb71c5
test: adds Polly recordings [skip ci]
Aug 22, 2020
7e97ad5
test: try to create sd campaign T00001 and T00030 tactic
nguyentoanit Aug 22, 2020
164dfb9
test: adds Polly recordings [skip ci]
Aug 22, 2020
8a5b26f
test: remove create unavailable sd campaign tactic
nguyentoanit Aug 22, 2020
92caed2
test: re-create sd ad group
nguyentoanit Aug 22, 2020
27cb34e
test: adds Polly recordings [skip ci]
Aug 22, 2020
1632dac
test: re-create sd targeting
nguyentoanit Aug 22, 2020
e772347
test: adds Polly recordings [skip ci]
Aug 22, 2020
438a0a7
feat: send campaign id when create sd targeting
nguyentoanit Aug 23, 2020
ac9e31c
test: adds Polly recordings [skip ci]
Aug 23, 2020
fef2412
Revert "feat: send campaign id when create sd targeting"
nguyentoanit Aug 23, 2020
5de944d
test: skip create sd targeting test
nguyentoanit Aug 23, 2020
0d0c318
feat: implement get, list, update and archive sd targeting
nguyentoanit Aug 23, 2020
1aff153
Merge branch 'feat/498-implement-sd-targeting-operation' of github.co…
nguyentoanit Aug 23, 2020
1c63ed2
test: re-record create sd targeting
nguyentoanit Aug 23, 2020
e62ef9a
test: remove create sd targeting recordings
nguyentoanit Aug 23, 2020
7fa159a
test: adds Polly recordings [skip ci]
Aug 23, 2020
9668b61
test: try to create sd targeting with other expression
nguyentoanit Aug 23, 2020
a69eeea
test: adds Polly recordings [skip ci]
Aug 23, 2020
36337d2
feat: adds ForbiddenError class
moltar Aug 29, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/amazon-advertising.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { SponsoredProductsSuggestedKeywordsOperation } from './operations/keywor
import { PortfolioOperation } from './operations/portfolios/portfolio-operation'
import { SponsoredProductsProductAdsOperation } from './operations/product-ads/sponsored-products-product-ads-operation'
import { SponsoredBrandsProductTargetingOperation } from './operations/product-targeting/sponsored-brands-product-targeting-operation'
import { SponsoredDisplayTargetingOperation } from './operations/product-targeting/sponsored-display-targeting-operation'
import { SponsoredProductsProductTargetingOperation } from './operations/product-targeting/sponsored-products-product-targeting-operation'
import { ProfileOperation } from './operations/profiles/profile-operation'
import { SponsoredBrandsBidRecommendationsOperation } from './operations/recommendations/sponsored-brands-bid-recommendations-operation'
Expand Down Expand Up @@ -130,6 +131,11 @@ export class AmazonAdvertising {
return this.operationProvider.create(SponsoredBrandsProductTargetingOperation)
}

@LazyGetter()
get sponsoredDisplayTargeting() {
return this.operationProvider.create(SponsoredDisplayTargetingOperation)
}

@LazyGetter()
get sponsoredProductsProductTargeting() {
return this.operationProvider.create(SponsoredProductsProductTargetingOperation)
Expand Down
4 changes: 4 additions & 0 deletions src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ export class ResourceNotFoundError extends GenericError {}

export class NotAcceptableError extends GenericError {}

export class ForbiddenError extends GenericError {}

export function apiErrorFactory(err: ErrorObject, headers: Headers): GenericError {
switch (err.code) {
case 'UNAUTHORIZED':
Expand All @@ -84,6 +86,8 @@ export function apiErrorFactory(err: ErrorObject, headers: Headers): GenericErro
return new ResourceNotFoundError(err, headers)
case '400':
return new BadRequestError(err, headers)
case '403':
return new ForbiddenError(err, headers)
case '406':
return new NotAcceptableError(err, headers)
case '422':
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export * from './operations/keywords/sponsored-products-suggested-keywords-opera
export * from './operations/portfolios/portfolio-operation'
export * from './operations/product-ads/sponsored-products-product-ads-operation'
export * from './operations/product-targeting/sponsored-brands-product-targeting-operation'
export * from './operations/product-targeting/sponsored-display-targeting-operation'
export * from './operations/product-targeting/sponsored-products-product-targeting-operation'
export * from './operations/profiles/profile-operation'
export * from './operations/recommendations/sponsored-brands-bid-recommendations-operation'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { Operation } from '../operation'
import { Decode, DecodeArray } from '../../decorators'
import { AmazonAdTypeURIPrefix } from '../amazon-ad-type-uri-prefix'

import {
TargetingClauseResponse,
CreateSponsoredDisplayTargetingClausesParams,
TargetId,
SponsoredDisplayTargetingClause,
SponsoredDisplayTargetingClauseExtended,
UpdateSponsoredDisplayTargetingClausesParams,
ListTargetingClausesParams,
} from './types'

export class SponsoredDisplayTargetingOperation extends Operation {
protected resource = `${this.version}/${AmazonAdTypeURIPrefix.SponsoredDisplay}/targets`

/**
* Gets a targeting clause specified by identifier.
*
* @param targetId -
* @returns
*/
@Decode(SponsoredDisplayTargetingClause)
public getTargetingClause(targetId: TargetId) {
return this.client.get<SponsoredDisplayTargetingClause>(`${this.resource}/${targetId}`)
}

/**
* Gets extended information for a targeting clause.
*
* @param targetId -
* @returns
*/
@Decode(SponsoredDisplayTargetingClauseExtended)
public getTargetingClauseExtended(targetId: TargetId) {
return this.client.get<SponsoredDisplayTargetingClauseExtended>(
`${this.resource}/extended/${targetId}`,
)
}

/**
* Creates one or more targeting clauses.
*
* @param params -
* @returns
*/
@DecodeArray(TargetingClauseResponse)
public createTargetingClauses(params: CreateSponsoredDisplayTargetingClausesParams[]) {
return this.client.post<TargetingClauseResponse[]>(this.resource, params)
}

/**
* Update one or more targeting clauses.
*
* @param params -
* @returns
*/
@DecodeArray(TargetingClauseResponse)
public updateTargetingClauses(params: UpdateSponsoredDisplayTargetingClausesParams[]) {
return this.client.put<TargetingClauseResponse[]>(this.resource, params)
}

/**
* Gets a list of targeting clauses.
*
* @param params -
* @returns
*/
@DecodeArray(SponsoredDisplayTargetingClause)
public listTargetingClauses(params?: ListTargetingClausesParams) {
return this.client.get<SponsoredDisplayTargetingClause[]>(
this.paramsFilterTransformer(this.resource, params),
)
}

/**
* Gets a list of targeting clause objects with extended fields.
*
* @param params -
* @returns
*/
@DecodeArray(SponsoredDisplayTargetingClauseExtended)
public listTargetingClausesExtended(params?: ListTargetingClausesParams) {
return this.client.get<SponsoredDisplayTargetingClauseExtended[]>(
this.paramsFilterTransformer(`${this.resource}/extended`, params),
)
}

/**
* Set the status of targeting clauses to archived.
* Equivalent to using the updateTargetingClauses operation to set the state property of a targeting clause to archived.
*
* @param targetId -
* @returns
*/
@Decode(TargetingClauseResponse)
public archiveTargetingClause(targetId: TargetId) {
return this.client.delete<TargetingClauseResponse>(`${this.resource}/${targetId}`)
}
}
151 changes: 151 additions & 0 deletions src/operations/product-targeting/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1081,3 +1081,154 @@ export const SponsoredBrandsBatchGetNegativeTargetsResponse = t.strict({
export type SponsoredBrandsBatchGetNegativeTargetsResponse = t.TypeOf<
typeof SponsoredBrandsBatchGetNegativeTargetsResponse
>

// Sponsored Display Types

export const SponsoredDisplayTargetingPredicateType = t.union([
t.literal('asinSameAs'),
t.literal('asinCategorySameAs'),
t.literal('asinBrandSameAs'),
t.literal('asinPriceBetween'),
t.literal('asinPriceGreaterThan'),
t.literal('asinPriceLessThan'),
t.literal('asinReviewRatingLessThan'),
t.literal('asinReviewRatingGreaterThan'),
t.literal('asinReviewRatingBetween'),
t.literal('similarProduct'),
t.literal('exactProduct'),
t.literal('asinIsPrimeShippingEligible'),
t.literal('asinAgeRangeSameAs'),
t.literal('asinGenreSameAs'),
t.literal('lookback'),
t.literal('negative'),
])
export type SponsoredDisplayTargetingPredicateType = t.TypeOf<
typeof SponsoredDisplayTargetingPredicateType
>

export const SponsoredDisplayTargetingPredicate = t.strict({
type: SponsoredDisplayTargetingPredicateType,

/**
* The value to be targeted.
*/
value: t.string,
})
export type SponsoredDisplayTargetingPredicate = t.TypeOf<typeof SponsoredDisplayTargetingPredicate>

export const SponsoredDisplayTargetingPredicateLegacy = t.strict({
type: SponsoredDisplayTargetingPredicateType,

/**
* The value to be targeted.
*/
value: t.string,

/**
* The type of event that the value applies to. Only available for similarProduct and exactProduct currently.
*/
eventType: t.literal('views'),
})
export type SponsoredDisplayTargetingPredicateLegacy = t.TypeOf<
typeof SponsoredDisplayTargetingPredicateLegacy
>

export const SponsoredDisplayTargetingPredicateNested = t.strict({
type: t.literal('views'),

value: t.array(SponsoredDisplayTargetingPredicate),
})
export type SponsoredDisplayTargetingPredicateNested = t.TypeOf<
typeof SponsoredDisplayTargetingPredicateNested
>

export const SponsoredDisplayTargetingExpression = t.union([
SponsoredDisplayTargetingPredicate,
SponsoredDisplayTargetingPredicateLegacy,
SponsoredDisplayTargetingPredicateNested,
])
export type SponsoredDisplayTargetingExpression = t.TypeOf<
typeof SponsoredDisplayTargetingExpression
>

export const CreateSponsoredDisplayTargetingClausesParams = t.strict({
/**
* The ID of the ad group to which this target belongs.
*/
adGroupId: AdGroupId,

/**
* Advertiser-specified state of the target
*/
state: TargetingClauseState,

/**
* The type of expression.
* Tactic T00020 ad groups only allow manual targeting.
*/
expressionType: ExpressionType,

/**
* The bid will override the adGroup bid if specified. Bid is not allowed in negative targeting clauses.
*/
bid: t.number,

/**
* The targeting expression to match against.
*/
expression: t.array(SponsoredDisplayTargetingExpression),
})
export type CreateSponsoredDisplayTargetingClausesParams = t.TypeOf<
typeof CreateSponsoredDisplayTargetingClausesParams
>

export const UpdateSponsoredDisplayTargetingClausesParams = t.intersection([
t.strict({
targetId: TargetId,
}),
t.partial({
/**
* The bid will override the adGroup bid if specified. Bid is not allowed in negative targeting clauses.
*/
bid: t.number,

/**
* Advertiser-specified state of the target
*/
state: TargetingClauseState,
}),
])
export type UpdateSponsoredDisplayTargetingClausesParams = t.TypeOf<
typeof UpdateSponsoredDisplayTargetingClausesParams
>

export const SponsoredDisplayTargetingClause = t.intersection([
CreateSponsoredDisplayTargetingClausesParams,
t.strict({
targetId: TargetId,
}),
])
export type SponsoredDisplayTargetingClause = t.TypeOf<typeof SponsoredDisplayTargetingClause>

export const SponsoredDisplayTargetingClauseExtended = t.intersection([
SponsoredDisplayTargetingClause,
t.strict({
/**
* The date the ad group was created as epoch time in milliseconds.
*/
creationDate: DateFromNumber,

/**
* The date the ad group was last updated as epoch time in milliseconds.
*/
lastUpdatedDate: DateFromNumber,

/**
* The computed status, accounting for out of budget, policy violations, etc. See developer notes for more information.
*/
servingStatus: TargetingClauseServingStatus,
}),
])
export type SponsoredDisplayTargetingClauseExtended = t.TypeOf<
typeof SponsoredDisplayTargetingClauseExtended
>
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@
"url": "https://advertising-api-test.amazon.com/v2/sp/adGroups"
},
"response": {
"bodySize": 47,
"bodySize": 48,
"content": {
"mimeType": "application/json",
"size": 47,
"size": 48,
"text": [
{
"adGroupId": 83691965128172,
"adGroupId": 257081908560802,
"code": "SUCCESS"
}
]
Expand All @@ -98,7 +98,7 @@
},
{
"name": "date",
"value": "Sun, 16 Aug 2020 15:31:22 GMT"
"value": "Sat, 22 Aug 2020 10:34:20 GMT"
},
{
"name": "content-type",
Expand All @@ -114,7 +114,7 @@
},
{
"name": "x-amz-request-id",
"value": "GGAFQ77G4ZTQPE1SZKX7"
"value": "R6KGFJ3BW61GJ0MS5HKX"
},
{
"name": "vary",
Expand All @@ -127,16 +127,16 @@
"status": 207,
"statusText": "Multi-Status"
},
"startedDateTime": "2020-08-16T15:31:22.703Z",
"time": 203,
"startedDateTime": "2020-08-22T10:34:20.757Z",
"time": 156,
"timings": {
"blocked": -1,
"connect": -1,
"dns": -1,
"receive": 0,
"send": 0,
"ssl": -1,
"wait": 203
"wait": 156
}
}
],
Expand Down
Loading