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

HuaweiAds: Increase fill rate for native ads #3279

Merged
merged 5 commits into from
Nov 20, 2023
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
87 changes: 63 additions & 24 deletions adapters/huaweiads/huaweiads.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"encoding/json"
"errors"
"fmt"
"math"
"net/http"
"net/url"
"regexp"
Expand Down Expand Up @@ -533,11 +534,27 @@ func getNativeFormat(adslot30 *adslot30, openRTBImp *openrtb2.Imp) error {
return err
}

//popular size for native ads
popularSizes := []map[string]int64{{"w": 225, "h": 150}, {"w": 300, "h": 250}, {"w": 320, "h": 250}, {"w": 640, "h": 360}, {"w": 720, "h": 1280}, {"w": 1080, "h": 170}, {"w": 1080, "h": 430}, {"w": 1080, "h": 432}, {"w": 1080, "h": 504}, {"w": 1080, "h": 607}, {"w": 1080, "h": 1620}, {"w": 1200, "h": 627}, {"w": 1280, "h": 720}, {"w": 1312, "h": 768}, {"w": 1920, "h": 1080}}

// only compute the main image number, type = native1.ImageAssetTypeMain
var numMainImage = 0
var numVideo = 0
var width int64
var height int64
var formats = make([]format, 0)
var numFormat = 0
var detailedCreativeTypeList = make([]string, 0, 2)

//number of the requested image size
for _, asset := range nativePayload.Assets {
if numFormat > 1 {
break
}
if asset.Img != nil {
if asset.Img.Type == native1.ImageAssetTypeMain {
numFormat++
}
}
}
onkarvhanumante marked this conversation as resolved.
Show resolved Hide resolved
for _, asset := range nativePayload.Assets {
// Only one of the {title,img,video,data} objects should be present in each object.
if asset.Video != nil {
Expand All @@ -548,34 +565,52 @@ func getNativeFormat(adslot30 *adslot30, openRTBImp *openrtb2.Imp) error {
if asset.Img != nil {
if asset.Img.Type == native1.ImageAssetTypeMain {
numMainImage++
if asset.Img.H != 0 && asset.Img.W != 0 {
width = asset.Img.W
height = asset.Img.H
} else if asset.Img.WMin != 0 && asset.Img.HMin != 0 {
width = asset.Img.WMin
height = asset.Img.HMin
if numFormat > 1 && asset.Img.H != 0 && asset.Img.W != 0 && asset.Img.WMin != 0 && asset.Img.HMin != 0 {
formats = append(formats, format{asset.Img.W, asset.Img.H})
}
if numFormat == 1 && asset.Img.H != 0 && asset.Img.W != 0 && asset.Img.WMin != 0 && asset.Img.HMin != 0 {
result := filterPopularSizes(popularSizes, asset.Img.W, asset.Img.H, "ratio")
for i := 0; i < len(result); i++ {
formats = append(formats, format{result[i]["w"], result[i]["h"]})
}
}
Comment on lines +571 to +576
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should add json framework test to cover above code path

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @onkarvhanumante , thanks for all feedbacks and review 🙌 It's updated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @ahmetfaruk59

could you link jsontest where numFormatcount is 1 and asset.Img.W is 0 and asset.Img.H is 0

If jsontest is not available then should add one for above scenario

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @onkarvhanumante . actually nativeThreeImageIncludeIcon test file covers this scenario but i added a new test file only this case in last commit. thanks again for your feedback 🙌

if numFormat == 1 && asset.Img.H == 0 && asset.Img.W == 0 && asset.Img.WMin != 0 && asset.Img.HMin != 0 {
result := filterPopularSizes(popularSizes, asset.Img.W, asset.Img.H, "range")
for i := 0; i < len(result); i++ {
formats = append(formats, format{result[i]["w"], result[i]["h"]})
}
}
}
continue
}
adslot30.Format = formats
}
adslot30.W = width
adslot30.H = height

var detailedCreativeTypeList = make([]string, 0, 2)
if numVideo >= 1 {
detailedCreativeTypeList = append(detailedCreativeTypeList, "903")
} else if numMainImage > 1 {
detailedCreativeTypeList = append(detailedCreativeTypeList, "904")
} else if numMainImage == 1 {
detailedCreativeTypeList = append(detailedCreativeTypeList, "901")
} else {
detailedCreativeTypeList = append(detailedCreativeTypeList, "913", "914")
}
detailedCreativeTypeList = append(detailedCreativeTypeList, "901", "905")
adslot30.DetailedCreativeTypeList = detailedCreativeTypeList
return nil
}

// filter popular size by range or ratio to append format array
func filterPopularSizes(sizes []map[string]int64, width int64, height int64, byWhat string) []map[string]int64 {

filtered := []map[string]int64{}
for _, size := range sizes {
w := size["w"]
h := size["h"]

if byWhat == "ratio" {
ratio := float64(width) / float64(height)
diff := math.Abs(float64(w)/float64(h) - ratio)
if diff <= 0.3 {
filtered = append(filtered, size)
}
}
if byWhat == "range" && w > width && h > height {
filtered = append(filtered, size)
}
}
return filtered
}

// roll ad need TotalDuration
func getVideoFormat(adslot30 *adslot30, adtype int32, openRTBImp *openrtb2.Imp) error {
adslot30.W = openRTBImp.Video.W
Expand Down Expand Up @@ -960,10 +995,14 @@ func checkRespStatusCode(response *adapters.ResponseData) error {
}

func checkHuaweiAdsResponseRetcode(response huaweiAdsResponse) error {
if response.Retcode == 200 || response.Retcode == 204 || response.Retcode == 206 {
if response.Retcode == 200 || response.Retcode == 206 {
return nil
}

if response.Retcode == 204 {
return &errortypes.BadInput{
Message: fmt.Sprintf("HuaweiAdsResponse retcode: %d , reason: The request packet is correct, but no advertisement was found for this request.", response.Retcode),
}
}
if (response.Retcode < 600 && response.Retcode >= 400) || (response.Retcode < 300 && response.Retcode > 200) {
return &errortypes.BadInput{
Message: fmt.Sprintf("HuaweiAdsResponse retcode: %d , reason: %s", response.Retcode, response.Reason),
Expand Down
114 changes: 67 additions & 47 deletions adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{
"id": "test-imp-id",
"native": {
"request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":100,\"title\":{\"len\":90},\"required\":1},{\"id\":101,\"img\":{\"type\":3,\"wmin\":200,\"hmin\":200},\"required\":1},{\"id\":107,\"video\":{\"mimes\":[\"mp4\"],\"minduration\":100,\"maxduration\":100,\"protocols\":[1,2]},\"required\":1},{\"id\":105,\"data\":{\"type\":2,\"len\":90},\"required\":1}],\"ver\":\"1.2\"}",
"request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":100,\"title\":{\"len\":90},\"required\":1},{\"id\":101,\"img\":{\"type\":3,\"w\":200,\"h\":300,\"wmin\":300,\"hmin\":200},\"required\":1},{\"id\":102,\"img\":{\"type\":3,\"w\":400,\"h\":500,\"wmin\":400,\"hmin\":500},\"required\":1},{\"id\":103,\"img\":{\"type\":3,\"w\":300,\"h\":250,\"wmin\":300,\"hmin\":250},\"required\":1},{\"id\":105,\"data\":{\"type\":2,\"len\":90},\"required\":1}],\"ver\":\"1.2\"}",
"ver": "1.2"
},
"ext": {
Expand All @@ -21,15 +21,14 @@
}
],
"app": {
"bundle": "com.huawei.browser",
"bundle": "com.huawei.p11",
"name": "Huawei Browser",
"ver": "9.1.0.301"
},
"device": {
"ua": "useragent",
"h": 1920,
"language": "zh",
"geoCountry": "CH",
"language": "en",
"model": "COL-TEST",
"os": "android",
"osv": "10.0.0",
Expand All @@ -39,12 +38,10 @@
"ip": "152.193.6.74",
"pxratio": 23.01,
"geo": {
"country": ""
"country": "ARG"
}
},
"user": {
"id": "db089de9-a62e-4861-a881-0ff15e052516",
"buyeruid": "v4_bidder_token",
"ext": {
"data": {
"gaid": [
Expand Down Expand Up @@ -83,31 +80,44 @@
"body": {
"app": {
"lang": "en",
"country": "ZA",
"country": "AR",
"name": "Huawei Browser",
"pkgname": "com.huawei.browser",
"pkgname": "com.example.pkgname2",
"version": "9.1.0.301"
},
"multislot": [
{
"adtype": 3,
"slotid": "u42ohmaufh",
"detailedCreativeTypeList": [
"903"
"901",
"905"
],
"h": 200,
"w": 200,
"format": [
{
"w": 200,
"h": 300
},
{
"w": 400,
"h": 500
},
{
"w": 300,
"h": 250
}
],
"test": 1
}
],
"device": {
"height": 1920,
"language": "zh",
"language": "en",
"oaid": "oaid",
"os": "android",
"type": 4,
"ip": "152.193.6.74",
"localeCountry": "ZA",
"localeCountry": "AR",
"pxratio": 23.01,
"model": "COL-TEST",
"width": 1080,
Expand All @@ -116,7 +126,7 @@
"useragent": "useragent",
"version": "10.0.0",
"maker": "huawei",
"belongCountry": "ZA"
"belongCountry": "AR"
},
"geo": {
},
Expand Down Expand Up @@ -146,7 +156,7 @@
"metaData": {
"adSign": "2",
"apkInfo": {
"appIcon": "https://pps-icon.png",
"appIcon": "https://icon.png",
"appName": "%E6%89%8B%E6%9C%BA%E6%B7%98%E5%AE%9D",
"fileSize": 118902470,
"packageName": "com.demo.package",
Expand All @@ -171,7 +181,16 @@
"height": 160,
"imageType": "img",
"sha256": "042479eccbda9a8d7d3aa3da73c42486854407835623a30ffff875cb578242d0",
"url": "https://pps-icon.png",
"url": "https://icon1.png",
"width": 160
},
{
"checkSha256Flag": 1,
"fileSize": 10797,
"height": 320,
"imageType": "img",
"sha256": "042479eccbda9a8d7d3aa3da73c42486854407835623a30ffff875cb578242d0",
"url": "https://icon2.png",
"width": 160
}
],
Expand All @@ -191,49 +210,51 @@
"sha256": "8baa56fdb2702b9fb044d95b328936160cd245764375cdb25a4ab504f4ae2e19",
"url": "http://image2.jpg",
"width": 400
},
{
"checkSha256Flag": 0,
"height": 300,
"imageType": "img",
"sha256": "8baa56fdb2702b9fb044d95b328936160cd245764375cdb25a4ab504f4ae2e19",
"url": "http://image3.jpg",
"width": 400
}
],
"label": "%E6%89%8B%E6%9C%BA%E6%B7%98%E5%AE%9D",
"landingPageType": "3",
"marketAppId": "C101219405",
"title": "%2Ftest%2F",
"description": "this is a test ad",
"videoInfo": {
"autoPlayAreaRatio": 100,
"autoStopPlayAreaRatio": 10,
"checkSha256Flag": 1,
"sha256": "aa08c8ffce82bbcd37cabefd6c8972b407de48f0b4e332e06d4cc18d25377d77",
"timeBeforeVideoAutoPlay": 50,
"videoAutoPlayOnWifi": "y",
"videoAutoPlayWithSound": "n",
"videoDownloadUrl": "https://video.mp4",
"videoDuration": 6038,
"videoFileSize": 949951,
"videoPlayMode": 2,
"videoRatio": 0.5625,
"width": 600,
"height": 500
}
"description": "this is a test ad"
},
"monitor": [
{
"eventType": "vastError",
"eventType": "click",
"url": [
"http://test/vastError"
"http://test/click"
]
},
{
"eventType": "click",
"eventType": "imp",
"url": [
"http://test/click",
"http://test/dspclick"
"http://test/imp"
]
},
{
"eventType": "imp",
"eventType": "download",
"url": [
"http://test/download"
]
},
{
"eventType": "install",
"url": [
"http://test/install"
]
},
{
"eventType": "downloadstart",
"url": [
"http://test/imp",
"http://test/dspimp"
"http://test/downloadstart"
]
},
{
Expand All @@ -251,8 +272,7 @@
{
"eventType": "playEnd",
"url": [
"http://test/playEnd1",
"http://test/playEnd2"
"http://test/playEnd"
]
},
{
Expand Down Expand Up @@ -312,12 +332,12 @@
"huaweiads"
],
"crid": "58022259",
"adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":100,\"title\":{\"text\":\"/test/\",\"len\":6}},{\"id\":101,\"img\":{\"type\":3,\"url\":\"http://image1.jpg\",\"w\":400,\"h\":350}},{\"id\":107,\"video\":{\"vasttag\":\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?><VAST version=\\\"3.0\\\"><Ad id=\\\"58022259\\\"><InLine><AdSystem>HuaweiAds</AdSystem><AdTitle>/test/</AdTitle><Error><![CDATA[http://test/vastError&et=[ERRORCODE]]]></Error><Impression><![CDATA[http://test/imp]]></Impression><Impression><![CDATA[http://test/dspimp]]></Impression><Creatives><Creative adId=\\\"58022259\\\" id=\\\"58022259\\\"><Linear><Duration>00:00:06.038</Duration><TrackingEvents><Tracking event=\\\"skip\\\"><![CDATA[http://test/userclose]]></Tracking><Tracking event=\\\"closeLinear\\\"><![CDATA[http://test/userclose]]></Tracking><Tracking event=\\\"start\\\"><![CDATA[http://test/playStart]]></Tracking><Tracking event=\\\"complete\\\"><![CDATA[http://test/playEnd1]]></Tracking><Tracking event=\\\"complete\\\"><![CDATA[http://test/playEnd2]]></Tracking><Tracking event=\\\"resume\\\"><![CDATA[http://test/playResume]]></Tracking><Tracking event=\\\"pause\\\"><![CDATA[http://test/playPause]]></Tracking></TrackingEvents><VideoClicks><ClickThrough><![CDATA[https://ads.huawei.com/usermgtportal/home/index.html#/]]></ClickThrough><ClickTracking><![CDATA[http://test/click]]></ClickTracking><ClickTracking><![CDATA[http://test/dspclick]]></ClickTracking></VideoClicks><MediaFiles><MediaFile delivery=\\\"progressive\\\" type=\\\"video/mp4\\\" width=\\\"600\\\" height=\\\"500\\\" scalable=\\\"true\\\" maintainAspectRatio=\\\"true\\\"> <![CDATA[https://video.mp4]]></MediaFile></MediaFiles></Linear></Creative></Creatives></InLine></Ad></VAST>\"}},{\"id\":105,\"data\":{\"label\":\"desc\",\"value\":\"this is a test ad\"}}],\"link\":{\"url\":\"https://ads.huawei.com/usermgtportal/home/index.html#/\",\"clicktrackers\":[\"http://test/click\",\"http://test/dspclick\"]},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"http://test/imp\"},{\"event\":1,\"method\":1,\"url\":\"http://test/dspimp\"}]}",
"adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":100,\"title\":{\"text\":\"/test/\",\"len\":6}},{\"id\":101,\"img\":{\"type\":3,\"url\":\"http://image1.jpg\",\"w\":400,\"h\":350}},{\"id\":102,\"img\":{\"type\":3,\"url\":\"http://image2.jpg\",\"w\":400,\"h\":300}},{\"id\":103,\"img\":{\"type\":3,\"url\":\"http://image3.jpg\",\"w\":400,\"h\":300}},{\"id\":105,\"data\":{\"label\":\"desc\",\"value\":\"this is a test ad\"}}],\"link\":{\"url\":\"https://ads.huawei.com/usermgtportal/home/index.html#/\",\"clicktrackers\":[\"http://test/click\"]},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"http://test/imp\"}]}",
"id": "test-imp-id",
"impid": "test-imp-id",
"price": 2.8,
"h": 500,
"w": 600
"h": 350,
"w": 400
},
"type": "native"
}
Expand Down
Loading
Loading