Skip to content

Commit ad16182

Browse files
Openwrap_Release_5th_Aug_2025
Openwrap_Release_5th_Aug_2025
2 parents 0942eb7 + 766c2c3 commit ad16182

22 files changed

+2185
-85
lines changed

analytics/pubmatic/helper.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/prebid/prebid-server/v3/analytics"
1515
"github.com/prebid/prebid-server/v3/analytics/pubmatic/mhttp"
1616
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/models"
17+
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/sdk/sdkutils"
1718
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/wakanda"
1819
)
1920

@@ -82,11 +83,11 @@ var send = func(rCtx *models.RequestCtx, url string, headers http.Header, mhc mh
8283

8384
// RestoreBidResponse restores the original bid response for AppLovinMax from the signal data
8485
func RestoreBidResponse(rctx *models.RequestCtx, ao analytics.AuctionObject) error {
85-
if rctx.Endpoint != models.EndpointAppLovinMax && rctx.Endpoint != models.EndpointGoogleSDK {
86+
if !sdkutils.IsSdkIntegration(rctx.Endpoint) {
8687
return nil
8788
}
8889

89-
if rctx.AppLovinMax.Reject || rctx.GoogleSDK.Reject {
90+
if rctx.AppLovinMax.Reject || rctx.GoogleSDK.Reject || rctx.UnityLevelPlay.Reject {
9091
return nil
9192
}
9293

@@ -121,6 +122,12 @@ func RestoreBidResponse(rctx *models.RequestCtx, ao analytics.AuctionObject) err
121122
}
122123
}
123124

125+
if rctx.Endpoint == models.EndpointUnityLevelPlay {
126+
if err := json.Unmarshal([]byte(ao.Response.SeatBid[0].Bid[0].AdM), orignalResponse); err != nil {
127+
return err
128+
}
129+
}
130+
124131
*ao.Response = *orignalResponse
125132
return nil
126133
}

analytics/pubmatic/record.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ func (wlog *WloggerRecord) logIntegrationType(endpoint string) {
187187
switch endpoint {
188188
case models.EndpointAMP:
189189
wlog.IntegrationType = models.TypeAmp
190-
case models.EndpointV25, models.EndpointAppLovinMax, models.EndpointGoogleSDK:
190+
case models.EndpointV25, models.EndpointAppLovinMax, models.EndpointGoogleSDK, models.EndpointUnityLevelPlay:
191191
wlog.IntegrationType = models.TypeSDK
192192
case models.EndpointVAST:
193193
wlog.IntegrationType = models.TypeTag

endpoints/openrtb2/auction_ow.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/prebid/prebid-server/v3/analytics/pubmatic"
1616
"github.com/prebid/prebid-server/v3/metrics"
1717
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/models"
18+
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/sdk/sdkutils"
1819
"github.com/prebid/prebid-server/v3/openrtb_ext"
1920
)
2021

@@ -59,26 +60,26 @@ func UpdateResponseExtOW(w http.ResponseWriter, bidResponse *openrtb2.BidRespons
5960

6061
//Send owlogger in response only in case of debug mode
6162
if rCtx.Debug && !rCtx.LoggerDisabled {
62-
var orignalMaxBidResponse *openrtb2.BidResponse
63-
if rCtx.Endpoint == models.EndpointAppLovinMax || rCtx.Endpoint == models.EndpointGoogleSDK {
64-
orignalMaxBidResponse = new(openrtb2.BidResponse)
65-
*orignalMaxBidResponse = *bidResponse
63+
var originalBidResponse *openrtb2.BidResponse
64+
if sdkutils.IsSdkIntegration(rCtx.Endpoint) {
65+
originalBidResponse = new(openrtb2.BidResponse)
66+
*originalBidResponse = *bidResponse
6667
pubmatic.RestoreBidResponse(rCtx, ao)
6768
}
6869

6970
owlogger, _ := pubmatic.GetLogAuctionObjectAsURL(ao, rCtx, false, true)
70-
if rCtx.Endpoint == models.EndpointAppLovinMax || rCtx.Endpoint == models.EndpointGoogleSDK {
71-
*bidResponse = *orignalMaxBidResponse
71+
if sdkutils.IsSdkIntegration(rCtx.Endpoint) {
72+
*bidResponse = *originalBidResponse
7273
}
7374
if len(bidResponse.Ext) == 0 {
7475
bidResponse.Ext = []byte("{}")
7576
}
7677
if updatedExt, err := jsonparser.Set([]byte(bidResponse.Ext), []byte(strconv.Quote(owlogger)), "owlogger"); err == nil {
7778
bidResponse.Ext = updatedExt
7879
}
79-
} else if rCtx.Endpoint == models.EndpointAppLovinMax {
80+
} else if rCtx.Endpoint == models.EndpointAppLovinMax || rCtx.Endpoint == models.EndpointUnityLevelPlay {
8081
bidResponse.Ext = nil
81-
if rCtx.AppLovinMax.Reject {
82+
if rCtx.AppLovinMax.Reject || rCtx.UnityLevelPlay.Reject {
8283
w.WriteHeader(http.StatusNoContent)
8384
}
8485
}

modules/pubmatic/openwrap/allprocessedbidresponsehook.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/prebid/prebid-server/v3/exchange/entities"
99
"github.com/prebid/prebid-server/v3/hooks/hookstage"
1010
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/models"
11+
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/sdk/unitylevelplay"
1112
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/utils"
1213
"github.com/prebid/prebid-server/v3/openrtb_ext"
1314
)
@@ -44,6 +45,7 @@ func (m OpenWrap) handleAllProcessedBidResponsesHook(
4445

4546
result.ChangeSet.AddMutation(func(apbrp hookstage.AllProcessedBidResponsesPayload) (hookstage.AllProcessedBidResponsesPayload, error) {
4647
updateBidIds(apbrp.Responses)
48+
unitylevelplay.UpdateBidWithTestPrice(rCtx, apbrp.Responses)
4749
return apbrp, nil
4850
}, hookstage.MutationUpdate, "update-bid-id")
4951

modules/pubmatic/openwrap/applovinmax.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,10 @@ func updateApp(signalApp *openrtb2.App, maxRequest *openrtb2.BidRequest) {
146146
if signalApp.Domain != "" {
147147
maxRequest.App.Domain = signalApp.Domain
148148
}
149-
maxRequest.App.StoreURL = signalApp.StoreURL
149+
150+
if len(maxRequest.App.StoreURL) == 0 {
151+
maxRequest.App.StoreURL = signalApp.StoreURL
152+
}
150153
}
151154

152155
func updateRegs(signalRegs *openrtb2.Regs, maxRequest *openrtb2.BidRequest) {

modules/pubmatic/openwrap/applovinmax_test.go

Lines changed: 10 additions & 2 deletions
Large diffs are not rendered by default.

modules/pubmatic/openwrap/auctionresponsehook.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/models/nbr"
1818
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/parser"
1919
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/sdk/googlesdk"
20+
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/sdk/unitylevelplay"
2021
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/tracker"
2122
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/utils"
2223
"github.com/prebid/prebid-server/v3/openrtb_ext"
@@ -373,6 +374,7 @@ func (m OpenWrap) handleAuctionResponseHook(
373374

374375
rctx.AppLovinMax = updateAppLovinMaxResponse(rctx, payload.BidResponse)
375376
rctx.GoogleSDK.Reject = googlesdk.SetGoogleSDKResponseReject(rctx, payload.BidResponse)
377+
rctx.UnityLevelPlay.Reject = unitylevelplay.SetUnityLevelPlayResponseReject(rctx, payload.BidResponse)
376378

377379
if rctx.Endpoint == models.EndpointWebS2S {
378380
result.ChangeSet.AddMutation(func(ap hookstage.AuctionResponsePayload) (hookstage.AuctionResponsePayload, error) {
@@ -415,8 +417,10 @@ func (m OpenWrap) handleAuctionResponseHook(
415417
ap.BidResponse.Ext = responseExtjson
416418

417419
ap.BidResponse = googlesdk.ApplyGoogleSDKResponse(rctx, ap.BidResponse)
420+
418421
resetBidIdtoOriginal(ap.BidResponse)
419422

423+
ap.BidResponse = unitylevelplay.ApplyUnityLevelPlayResponse(rctx, ap.BidResponse)
420424
if rctx.Endpoint == models.EndpointAppLovinMax {
421425
ap.BidResponse = applyAppLovinMaxResponse(rctx, ap.BidResponse)
422426
}

modules/pubmatic/openwrap/beforevalidationhook.go

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/models/nbr"
3131
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/ortb"
3232
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/sdk/googlesdk"
33+
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/sdk/sdkutils"
3334
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/utils"
3435
"github.com/prebid/prebid-server/v3/openrtb_ext"
3536
"github.com/prebid/prebid-server/v3/util/ptrutil"
@@ -590,19 +591,21 @@ func (m OpenWrap) handleBeforeValidationHook(
590591
adserverURL = impExt.Wrapper.AdServerURL
591592
}
592593

593-
if rCtx.Endpoint == models.EndpointAppLovinMax {
594+
if rCtx.Endpoint == models.EndpointAppLovinMax || rCtx.Endpoint == models.EndpointUnityLevelPlay {
594595
if len(impExt.GpId) == 0 {
595596
impExt.GpId = imp.TagID
596597
}
597598
}
598599

599-
if rCtx.Endpoint == models.EndpointAppLovinMax || rCtx.Endpoint == models.EndpointGoogleSDK {
600-
if payload.BidRequest.App != nil && payload.BidRequest.App.StoreURL == "" {
601-
var isValidAppStoreUrl bool
602-
if rCtx.AppStoreUrl, isValidAppStoreUrl = getProfileAppStoreUrl(rCtx); isValidAppStoreUrl {
603-
m.updateSkadnSourceapp(rCtx, payload.BidRequest, impExt)
604-
}
605-
rCtx.PageURL = rCtx.AppStoreUrl
600+
if sdkutils.IsSdkIntegration(rCtx.Endpoint) {
601+
appStoreUrl, isValidAppStoreUrl := getProfileAppStoreUrl(rCtx)
602+
if !isValidAppStoreUrl && payload.BidRequest.App != nil && payload.BidRequest.App.StoreURL != "" {
603+
appStoreUrl = payload.BidRequest.App.StoreURL
604+
}
605+
rCtx.AppStoreUrl = appStoreUrl
606+
rCtx.PageURL = appStoreUrl
607+
if appStoreUrl != "" {
608+
m.updateSkadnSourceapp(rCtx, payload.BidRequest, impExt)
606609
}
607610
}
608611

@@ -758,14 +761,13 @@ func (m *OpenWrap) applyProfileChanges(rctx models.RequestCtx, bidRequest *openr
758761
bidRequest.Test = 1
759762
}
760763

761-
if rctx.Endpoint == models.EndpointAppLovinMax {
762-
if rctx.AppStoreUrl != "" {
763-
bidRequest.App.StoreURL = rctx.AppStoreUrl
764-
}
764+
if sdkutils.IsSdkIntegration(rctx.Endpoint) && rctx.AppStoreUrl != "" {
765+
bidRequest.App.StoreURL = rctx.AppStoreUrl
765766
}
766767

767-
if rctx.Endpoint == models.EndpointGoogleSDK && bidRequest.App != nil && bidRequest.App.StoreURL == "" && rctx.AppStoreUrl != "" {
768-
bidRequest.App.StoreURL = rctx.AppStoreUrl
768+
// Remove app.ext.token
769+
if rctx.Endpoint == models.EndpointUnityLevelPlay {
770+
bidRequest.App.Ext = jsonparser.Delete(bidRequest.App.Ext, "token")
769771
}
770772

771773
googleSSUFeatureEnabled := models.GetVersionLevelPropertyFromPartnerConfig(rctx.PartnerConfigMap, models.GoogleSSUFeatureEnabledKey) == models.Enabled

modules/pubmatic/openwrap/entrypointhook.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import (
1919
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/models"
2020
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/models/nbr"
2121
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/sdk/googlesdk"
22+
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/sdk/sdkutils"
23+
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/sdk/unitylevelplay"
2224
"github.com/prebid/prebid-server/v3/modules/pubmatic/openwrap/wakanda"
2325
"github.com/prebid/prebid-server/v3/openrtb_ext"
2426
"github.com/prebid/prebid-server/v3/usersync"
@@ -99,6 +101,17 @@ func (m OpenWrap) handleEntrypointHook(
99101
}, hookstage.MutationUpdate, "update-google-sdk-request")
100102
}
101103

104+
if endpoint == models.EndpointUnityLevelPlay {
105+
rCtx.MetricsEngine = m.metricEngine
106+
// Update fields from signal
107+
ulp := unitylevelplay.NewLevelPlay(m.metricEngine)
108+
payload.Body = ulp.ModifyRequestWithUnityLevelPlayParams(payload.Body)
109+
result.ChangeSet.AddMutation(func(ep hookstage.EntrypointPayload) (hookstage.EntrypointPayload, error) {
110+
ep.Body = payload.Body
111+
return ep, nil
112+
}, hookstage.MutationUpdate, "update-unity-level-play-request")
113+
}
114+
102115
// init default for all modules
103116
result.Reject = true
104117

@@ -152,7 +165,7 @@ func (m OpenWrap) handleEntrypointHook(
152165
WakandaDebug: &wakanda.Debug{
153166
Config: m.cfg.Wakanda,
154167
},
155-
SendBurl: endpoint == models.EndpointAppLovinMax || endpoint == models.EndpointGoogleSDK || getSendBurl(payload.Body),
168+
SendBurl: getSendBurl(payload.Body, endpoint),
156169
ImpCountingMethodEnabledBidders: make(map[string]struct{}),
157170
}
158171

@@ -245,6 +258,8 @@ func GetEndpoint(path, source string, agent string) string {
245258
return models.EndpointAppLovinMax
246259
case models.GoogleSDKAgent:
247260
return models.EndpointGoogleSDK
261+
case models.UnityLevelPlayAgent:
262+
return models.EndpointUnityLevelPlay
248263
}
249264
return models.EndpointV25
250265
default:
@@ -268,7 +283,11 @@ func GetEndpoint(path, source string, agent string) string {
268283
return ""
269284
}
270285

271-
func getSendBurl(request []byte) bool {
286+
func getSendBurl(request []byte, endpoint string) bool {
287+
if sdkutils.IsSdkIntegration(endpoint) {
288+
return true
289+
}
290+
272291
//ignore error, default is false
273292
sendBurl, _ := jsonparser.GetBoolean(request, "ext", "prebid", "bidderparams", "pubmatic", "sendburl")
274293
return sendBurl

modules/pubmatic/openwrap/entrypointhook_test.go

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -911,48 +911,76 @@ func TestGetEndpoint(t *testing.T) {
911911
}
912912
}
913913

914-
func Test_getSendBurl(t *testing.T) {
914+
func TestGetSendBurl(t *testing.T) {
915915
type args struct {
916-
request []byte
916+
request []byte
917+
endpoint string
917918
}
918919
tests := []struct {
919920
name string
920921
args args
921922
want bool
922923
}{
923-
924924
{
925-
name: "request with sendburl true",
925+
name: "AppLovinMax endpoint should always return true",
926+
args: args{
927+
request: []byte(`{}`),
928+
endpoint: models.EndpointAppLovinMax,
929+
},
930+
want: true,
931+
},
932+
{
933+
name: "GoogleSDK endpoint should always return true",
934+
args: args{
935+
request: []byte(`{}`),
936+
endpoint: models.EndpointGoogleSDK,
937+
},
938+
want: true,
939+
},
940+
{
941+
name: "UnityLevelPlay endpoint should always return true",
926942
args: args{
927-
request: []byte(`{"ext":{"prebid":{"bidderparams":{"pubmatic":{"sendburl":true,"wrapper":{"profileid":14052,"sumry_disable":1,"clientconfig":1}}}}}}`),
943+
request: []byte(`{}`),
944+
endpoint: models.EndpointUnityLevelPlay,
928945
},
929946
want: true,
930947
},
931948
{
932-
name: "appLovinMax request with sendburl false",
949+
name: "request with sendburl true for other endpoint",
933950
args: args{
934-
request: []byte(`{"ext":{"prebid":{"bidderparams":{"pubmatic":{"sendburl":false,"wrapper":{"profileid":14052,"sumry_disable":1,"clientconfig":1}}}}}}`),
951+
request: []byte(`{"ext":{"prebid":{"bidderparams":{"pubmatic":{"sendburl":true,"wrapper":{"profileid":14052,"sumry_disable":1,"clientconfig":1}}}}}}`),
952+
endpoint: models.EndpointWebS2S,
953+
},
954+
want: true,
955+
},
956+
{
957+
name: "request with sendburl false for other endpoint",
958+
args: args{
959+
request: []byte(`{"ext":{"prebid":{"bidderparams":{"pubmatic":{"sendburl":false,"wrapper":{"profileid":14052,"sumry_disable":1,"clientconfig":1}}}}}}`),
960+
endpoint: models.EndpointWebS2S,
935961
},
936962
want: false,
937963
},
938964
{
939-
name: "appLovinMax request with no sendburl key",
965+
name: "request with no sendburl key for other endpoint",
940966
args: args{
941-
request: []byte(`{"ext":{"prebid":{"bidderparams":{"pubmatic":{"wrapper":{"profileid":14052,"sumry_disable":1,"clientconfig":1}}}}}}`),
967+
request: []byte(`{"ext":{"prebid":{"bidderparams":{"pubmatic":{"wrapper":{"profileid":14052,"sumry_disable":1,"clientconfig":1}}}}}}`),
968+
endpoint: models.EndpointWebS2S,
942969
},
943970
want: false,
944971
},
945972
{
946-
name: "no ext object in request",
973+
name: "no ext object in request for other endpoint",
947974
args: args{
948-
request: []byte(``),
975+
request: []byte(``),
976+
endpoint: models.EndpointWebS2S,
949977
},
950978
want: false,
951979
},
952980
}
953981
for _, tt := range tests {
954982
t.Run(tt.name, func(t *testing.T) {
955-
got := getSendBurl(tt.args.request)
983+
got := getSendBurl(tt.args.request, tt.args.endpoint)
956984
assert.Equal(t, tt.want, got)
957985
})
958986
}

0 commit comments

Comments
 (0)