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

feat: add helpers to run banner auctions #19

Merged
merged 8 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.topsort.analytics.banners

import com.topsort.analytics.model.auctions.Device

/**
* Class that handles different type of Banner configurations
*/
sealed class BannerConfig private constructor() {

/**
* Banner configuration for landing page banners
*
* @property slotId id of the banner slot
* @property ids ids of the entities that are competing for the banner
* @property device target device for the banner
* @property geoTargeting optional location for geo-targeted banners
*/
data class LandingPage(
val slotId: String,
val ids: List<String>,
val device: Device = Device.mobile,
val geoTargeting: String? = null
) : BannerConfig()

/**
* Banner configuration for single category banners
*
* @property slotId id of the banner slot
* @property category category for the banner
* @property device target device for the banner
* @property geoTargeting optional location for geo-targeted banners
*/
data class CategorySingle(
val slotId: String,
val category: String,
val device: Device = Device.mobile,
val geoTargeting: String? = null
) : BannerConfig()

/**
* Banner config for multiple category banners
*
* @property slotId id of the banner slot
* @property categories list of categories for the competing banners
* @property device target device for the banner
* @property geoTargeting optional location for geo-targeted banners
*/
data class CategoryMultiple(
val slotId: String,
val categories: List<String>,
val device: Device = Device.mobile,
val geoTargeting: String? = null,
) : BannerConfig()

/**
* Banner configuration for category disjunctions banners
*
* @property slotId id of the banner slot
* @property disjunctions category disjunctions for the competing banners
* @property device target device for the banner
* @property geoTargeting optional location for geo-targeted banners
*/
data class CategoryDisjunctions(
val slotId: String,
val disjunctions: List<List<String>>,
val device: Device = Device.mobile,
val geoTargeting: String? = null,
) : BannerConfig()

/**
* Banner configuration for keyword banners
*
* @property slotId id of the banner slot
* @property keyword keyword for the competing banners
* @property device target device for the banner
* @property geoTargeting optional location for geo-targeted banners
*/
data class Keyword(
val slotId: String,
val keyword: String,
val device: Device = Device.mobile,
val geoTargeting: String? = null,
) : BannerConfig()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.topsort.analytics.banners

import com.topsort.analytics.model.auctions.EntityType

/**
* Response for a single slot banner auction
*
* @property id id of the winning entity
* @property type type of the winning entity
* @property url url of the banner to show
* @property resolvedBidId id for tracking the auction result on events
*/
data class BannerResponse(
val id: String,
val type: EntityType,
val url: String,
val resolvedBidId: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.topsort.analytics.banners

import com.topsort.analytics.model.auctions.Auction
import com.topsort.analytics.model.auctions.AuctionRequest
import com.topsort.analytics.service.TopsortAuctionsHttpService

/**
* Run a banner auction with a single slot
*
* @param config the banner configuration that specifies which kind of banner auction to run
* @return A BannerResponse if the auction successfully returned a winner or null if not.
*/
fun runBannerAuction(config: BannerConfig): BannerResponse? {
val auction = buildBannerAuction(config)
val request = AuctionRequest(listOf(auction))
val response = TopsortAuctionsHttpService.runAuctions(request)
if ((response?.results?.isNotEmpty() == true)) {
if (response.results[0].winners.isNotEmpty()) {
val winner = response.results[0].winners[0]
return BannerResponse(
id = winner.id,
url = winner.asset!!.url,
type = winner.type,
resolvedBidId = winner.resolvedBidId
)
}
}
return null
}

/**
* Builds a low-level Auction object to be run with TopsortAuctionHttpService.
*
* Generally, you shouldn't be calling this function yourself and you should use runBannerAuction instead.
*
* @param config the banner configuration that specifies which kind of banner auction to run
* @return an Auction object
*/
fun buildBannerAuction(config: BannerConfig): Auction {
when (config) {
is BannerConfig.LandingPage -> {
return Auction.Factory.buildBannerAuctionLandingPage(
1,
config.slotId,
config.ids,
config.device,
config.geoTargeting
)
}

is BannerConfig.CategorySingle -> {
return Auction.Factory.buildBannerAuctionCategorySingle(
1,
config.slotId,
config.category,
config.device,
config.geoTargeting
)
}

is BannerConfig.CategoryMultiple -> {
return Auction.Factory.buildBannerAuctionCategoryMultiple(
1,
config.slotId,
config.categories,
config.device,
config.geoTargeting
)
}

is BannerConfig.CategoryDisjunctions -> {
return Auction.Factory.buildBannerAuctionCategoryDisjunctions(
1, config.slotId, config.disjunctions, config.device, config.geoTargeting
)
}

is BannerConfig.Keyword -> {
return Auction.Factory.buildBannerAuctionKeywords(
1,
config.slotId,
config.keyword,
config.device,
config.geoTargeting
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
package com.topsort.analytics.model.auctions

data class Auction private constructor (
data class Auction private constructor(
val type: String,
val slots: Int,
val products: Products? = null,
val category: Category? = null,
val searchQuery: String? = null,
val geoTargeting: GeoTargeting? = null,
val slotId: String? = null,
val device: String? = null,
val device: Device? = null,
) {

object Factory{
object Factory {

@JvmOverloads
fun buildSponsoredListingAuctionProductIds(
slots : Int,
slots: Int,
ids: List<String>,
geoTargeting: String? = null,
) : Auction {
): Auction {
return Auction(
type = "listings",
slots = slots,
Expand All @@ -29,10 +29,10 @@ data class Auction private constructor (

@JvmOverloads
fun buildSponsoredListingAuctionCategorySingle(
slots : Int,
slots: Int,
category: String,
geoTargeting: String? = null,
) : Auction {
): Auction {
return Auction(
type = "listings",
slots = slots,
Expand All @@ -43,10 +43,10 @@ data class Auction private constructor (

@JvmOverloads
fun buildSponsoredListingAuctionCategoryMultiple(
slots : Int,
slots: Int,
categories: List<String>,
geoTargeting: String? = null,
) : Auction {
): Auction {
return Auction(
type = "listings",
slots = slots,
Expand All @@ -57,10 +57,10 @@ data class Auction private constructor (

@JvmOverloads
fun buildSponsoredListingAuctionCategoryDisjunctions(
slots : Int,
slots: Int,
disjunctions: List<List<String>>,
geoTargeting: String? = null,
) : Auction {
): Auction {
return Auction(
type = "listings",
slots = slots,
Expand All @@ -71,10 +71,10 @@ data class Auction private constructor (

@JvmOverloads
fun buildSponsoredListingAuctionKeyword(
slots : Int,
slots: Int,
keyword: String,
geoTargeting: String? = null,
) : Auction {
): Auction {
return Auction(
type = "listings",
slots = slots,
Expand All @@ -85,12 +85,12 @@ data class Auction private constructor (

@JvmOverloads
fun buildBannerAuctionLandingPage(
slots : Int,
slotId : String,
slots: Int,
slotId: String,
ids: List<String>,
device: String? = null,
device: Device = Device.mobile,
geoTargeting: String? = null,
) : Auction {
): Auction {
return Auction(
type = "banners",
slots = slots,
Expand All @@ -103,12 +103,12 @@ data class Auction private constructor (

@JvmOverloads
fun buildBannerAuctionCategorySingle(
slots : Int,
slotId : String,
slots: Int,
slotId: String,
category: String,
device: String? = null,
device: Device = Device.mobile,
geoTargeting: String? = null,
) : Auction {
): Auction {
return Auction(
type = "banners",
slots = slots,
Expand All @@ -121,12 +121,12 @@ data class Auction private constructor (

@JvmOverloads
fun buildBannerAuctionCategoryMultiple(
slots : Int,
slotId : String,
slots: Int,
slotId: String,
categories: List<String>,
device: String? = null,
device: Device = Device.mobile,
geoTargeting: String? = null,
) : Auction {
): Auction {
return Auction(
type = "banners",
slots = slots,
Expand All @@ -139,12 +139,12 @@ data class Auction private constructor (

@JvmOverloads
fun buildBannerAuctionCategoryDisjunctions(
slots : Int,
slotId : String,
slots: Int,
slotId: String,
disjunctions: List<List<String>>,
device: String? = null,
device: Device = Device.mobile,
geoTargeting: String? = null,
) : Auction {
): Auction {
return Auction(
type = "banners",
slots = slots,
Expand All @@ -157,12 +157,12 @@ data class Auction private constructor (

@JvmOverloads
fun buildBannerAuctionKeywords(
slots : Int,
slotId : String,
slots: Int,
slotId: String,
keyword: String,
device: String? = null,
device: Device = Device.mobile,
geoTargeting: String? = null,
) : Auction {
): Auction {
return Auction(
type = "banners",
slots = slots,
Expand All @@ -174,7 +174,7 @@ data class Auction private constructor (
}
}

data class Products (
data class Products(
val ids: List<String>,
)

Expand Down
Loading