Skip to content

Commit

Permalink
HuaweiAds: Increase fill rate for native ads (#3279)
Browse files Browse the repository at this point in the history
co-authored by @ahmetfaruk59
  • Loading branch information
ahmetfaruk59 authored Nov 20, 2023
1 parent f5f1e07 commit 515b937
Show file tree
Hide file tree
Showing 8 changed files with 951 additions and 86 deletions.
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++
}
}
}
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"]})
}
}
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

0 comments on commit 515b937

Please sign in to comment.