Skip to content

Commit

Permalink
Native extension (#148)
Browse files Browse the repository at this point in the history
* Adds objects to encode a Native ad request as part of an extension to the Native object
  • Loading branch information
renam authored Dec 8, 2023
1 parent 100cb58 commit 560d5fe
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 2 deletions.
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[versions]
android = "8.0.2"
android = "8.1.2"
android-buildtools = "33.0.2"
dokka = "1.8.10"
kotest = "5.5.5"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.adsbynimbus.openrtb.enumerations

public object DataType {
public const val SPONSORED: Byte = 1
public const val DESC: Byte = 2
public const val RATING: Byte = 3
public const val LIKES: Byte = 4
public const val DOWNLOADS: Byte = 5
public const val PRICE: Byte = 6
public const val SALEPRICE: Byte = 7
public const val PHONE: Byte = 8
public const val ADDRESS: Byte = 9
public const val DESC2: Byte = 10
public const val DISPLAYURL: Byte = 11
public const val CTATEXT: Byte = 12
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.adsbynimbus.openrtb.enumerations

public object ImageType {
public const val ICON: Byte = 1

public const val MAIN: Byte = 3
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.adsbynimbus.openrtb.enumerations

public object NativeAdContext {
public const val CONTENT: Byte = 1 // Content-centric context such as newsfeed, article, image gallery, video gallery, or similar.
public const val SOCIAL: Byte = 2 // Social-centric context such as social network feed, email, chat, or similar.
public const val PRODUCT: Byte = 3 // Product context such as product listings, details, recommendations, reviews, or similar.
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.adsbynimbus.openrtb.enumerations

public object NativeAdContextSubType {
public val GENERALORMIXED: Byte = 10 // General or mixed content
public val ARTICLE: Byte = 11 // Primarily article content (which of course could include images, etc as part of the article)
public val VIDEO: Byte = 12// Primarily video content
public val AUDIO: Byte = 13 // Primarily audio content
public val IMAGE: Byte = 14 // Primarily image content
public val USERGENERATED: Byte = 15 // User-generated content - forums, comments, etc
public val SOCIAL: Byte = 20 // General social content such as a general social network
public val EMAIL: Byte = 21 // Primarily email content
public val CHAT: Byte = 22 // Primarily chat/IM content
public val SALES: Byte = 30 // Content focused on selling products, whether digital or physical
public val APPSTORE: Byte = 31 // Application store/marketplace
public val PRODUCTREVIEWS: Byte = 32 // Product reviews site primarily (which may sell product secondarily)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.adsbynimbus.openrtb.enumerations

public object TitleLength {
public const val SHORT: Int = 25

public const val MEDIUM: Int = 90

public const val LONG: Int = 140
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.adsbynimbus.openrtb.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlin.jvm.JvmField

/**
* This object represents a native asset object, which is the main container
* for each asset requested or supported by Exchange on behalf of the rendering client.
*
* [OpenRTB Native Ads 1.2](https://www.iab.com/wp-content/uploads/2018/03/OpenRTB-Native-Ads-Specification-Final-1.2.pdf)
*/
@Serializable
public class Asset (
@JvmField @SerialName("id") public var id: Int,
@JvmField @SerialName("required") public var required: Byte,
@JvmField @SerialName("ext") public var ext: Map<String, String>? = null,
@JvmField @SerialName("title") public var title: TitleObject? = null,
@JvmField @SerialName("img") public var img: ImageObject? = null,
@JvmField @SerialName("video") public var video: VideoObject? = null,
@JvmField @SerialName("data") public var data: DataObject? = null,
){
@Serializable
public class TitleObject(
@JvmField @SerialName("len") public var length: Int
)
@Serializable
public class ImageObject(
@JvmField @SerialName("type") public var type: Byte,
@JvmField @SerialName("w") public var w: Int? = null,
@JvmField @SerialName("h") public var h: Int? = null,
@JvmField @SerialName("hmin") public var hmin: Int? = null,
@JvmField @SerialName("wmin") public var wmin: Int? = null,
)
@Serializable
public class VideoObject(
@JvmField @SerialName("mimes") public var mimes: Array<String>? = null,
@JvmField @SerialName("minduration") public var minduration: Int = 0,
@JvmField @SerialName("maxduration") public var maxduration: Int = 60,
@JvmField @SerialName("protocols") public var protocols: ByteArray? = null,
)
@Serializable
public class DataObject(
@JvmField @SerialName("type") public var type: Byte,
@JvmField @SerialName("len") public var len: Int,
)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.adsbynimbus.openrtb.request

import com.adsbynimbus.openrtb.enumerations.NativeAdContext
import com.adsbynimbus.openrtb.enumerations.NativeAdContextSubType
import com.adsbynimbus.openrtb.enumerations.PlacementType
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlin.jvm.JvmField
Expand Down Expand Up @@ -37,4 +40,19 @@ public class Native(
@JvmField @SerialName("ver") public var ver: String? = null,
@JvmField @SerialName("api") public var api: ByteArray? = null,
@JvmField @SerialName("battr") public var battr: ByteArray? = null,
@JvmField @SerialName("ext") public var ext: Extension? = null
)

@Serializable
public class Extension(
@JvmField @SerialName("nimbus_native") public var nimbusNative : NimbusNative? = null
)

@Serializable
public class NimbusNative(
@JvmField @SerialName("ver") public var ver: String = "1.2",
@JvmField @SerialName("plcmttype") public var plcmttype: Byte?,
@JvmField @SerialName("context") public var context: Byte?,
@JvmField @SerialName("contextsubtype") public var contextsubtype: Byte?,
@JvmField @SerialName("assets") public var assets: List<Asset>,
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package com.adsbynimbus.openrtb.request

import com.adsbynimbus.openrtb.enumerations.ImageType
import com.adsbynimbus.openrtb.enumerations.TitleLength
import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.collections.shouldContainInOrder
import io.kotest.matchers.collections.shouldHaveSize
import io.kotest.matchers.collections.shouldNotContainInOrder
import io.kotest.matchers.maps.shouldContain
import io.kotest.matchers.maps.shouldNotBeEmpty
import io.kotest.matchers.nulls.shouldNotBeNull
Expand Down Expand Up @@ -61,7 +65,41 @@ const val testJson = """
"native":{
"bidfloor":1,
"request":"{\"assets\":[{\"id\":1,\"img\":{\"hmin\":250,\"type\":3,\"wmin\":300,\"mimes\":[\"image/jpeg\",\"image/png\",\"image/gif\"]},\"title\":{\"len\":140},\"data\":{\"type\":2,\"len\":140},\"required\":1}],\"plcmttype\":1,\"plcmtcnt\":1,\"required\":1,\"ver\":\"1.1\"}",
"ver":"1.1"
"ver":"1.1",
"ext": {
"nimbus_native": {
"ver": "1.2",
"plcmttype": 1,
"context": 1,
"contextsubtype": 11,
"assets": [
{
"id": 1,
"required": 1,
"title": {
"len": 140
}
},
{
"id": 2,
"img": {
"h": 250,
"type": 3,
"w": 300
},
"required": 1
},
{
"data": {
"len": 140,
"type": 2
},
"id": 3,
"required": 1
}
]
}
}
},
"instl":1,
"bidfloor":1,
Expand Down Expand Up @@ -215,4 +253,13 @@ class DeserializationTest : StringSpec({
eid2.ext.shouldContain("rtiPartner", "TDID")
}
}

"BidResponse fromJson deserialized native extension" {
request.imp[0].native?.ext?.nimbusNative?.run {
assets shouldHaveSize 3
context shouldBe 1
contextsubtype shouldBe 11
plcmttype shouldBe 1
}
}
})

0 comments on commit 560d5fe

Please sign in to comment.