From 9bd87535d1c04ce32d4eb200ebe5fcdf169b3b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20Lindstr=C3=B6m?= Date: Thu, 19 Feb 2026 14:17:46 +0100 Subject: [PATCH] relevantBidAdapter: add useSourceBidderCode option Add opt-in useSourceBidderCode bidder param that passes the upstream bidder's seat through in bid responses. This allows alternate bidder codes to work when relevantdigital is used as a server-side adapter. --- adapters/relevantdigital/relevantdigital.go | 21 +++ .../supplemental/useSourceBidderCode.json | 131 ++++++++++++++ .../useSourceBidderCodeDisabled.json | 129 ++++++++++++++ ...rceBidderCodeDisabledMultipleSeatBids.json | 157 +++++++++++++++++ .../useSourceBidderCodeMultipleSeatBids.json | 160 ++++++++++++++++++ openrtb_ext/imp_relevantdigital.go | 9 +- static/bidder-params/relevantdigital.json | 4 + 7 files changed, 607 insertions(+), 4 deletions(-) create mode 100644 adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCode.json create mode 100644 adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeDisabled.json create mode 100644 adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeDisabledMultipleSeatBids.json create mode 100644 adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeMultipleSeatBids.json diff --git a/adapters/relevantdigital/relevantdigital.go b/adapters/relevantdigital/relevantdigital.go index 702dca6b271..d002733b359 100644 --- a/adapters/relevantdigital/relevantdigital.go +++ b/adapters/relevantdigital/relevantdigital.go @@ -114,6 +114,11 @@ func setTMax(prebidBidRequest *openrtb2.BidRequest, pbsBufferMs int) { func createBidRequest(prebidBidRequest *openrtb2.BidRequest, params []*openrtb_ext.ExtRelevantDigital) ([]byte, error) { bidRequestCopy := *prebidBidRequest + // Copy Imp slice so patchBidImpExt only mutates this outgoing request. + // MakeBids receives the same request and needs the original Imp[].Ext + // to read useSourceBidderCode from bidder params. + bidRequestCopy.Imp = make([]openrtb2.Imp, len(prebidBidRequest.Imp)) + copy(bidRequestCopy.Imp, prebidBidRequest.Imp) err := patchBidRequestExt(&bidRequestCopy, params[0].AccountId) if err != nil { @@ -292,6 +297,17 @@ func isSupportedMediaType(bidType openrtb_ext.BidType) error { return fmt.Errorf("bid type not supported %s", bidType) } +func useSourceBidderCode(request *openrtb2.BidRequest) bool { + if request == nil || len(request.Imp) == 0 { + return false + } + impExt, err := getImpressionExt(&request.Imp[0]) + if err != nil { + return false + } + return impExt.UseSourceBidderCode +} + func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { if adapters.IsResponseStatusCodeNoContent(responseData) { return nil, nil @@ -306,6 +322,8 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R return nil, []error{err} } + passSourceSeat := useSourceBidderCode(request) + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(response.SeatBid)) bidResponse.Currency = response.Cur var errs []error @@ -324,6 +342,9 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R Bid: &seatBid.Bid[i], BidType: bidType, } + if passSourceSeat { + b.Seat = openrtb_ext.BidderName(seatBid.Seat) + } bidResponse.Bids = append(bidResponse.Bids, b) } } diff --git a/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCode.json b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCode.json new file mode 100644 index 00000000000..1b8e105dfe8 --- /dev/null +++ b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCode.json @@ -0,0 +1,131 @@ +{ + "mockBidRequest": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "accountId": "620523ae7f4bbe1691bbb815", + "pbsHost": "fakeHost", + "placementId": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817", + "useSourceBidderCode": true + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakeHost.relevant-digital.com/openrtb2/auction", + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817" + } + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + }, + "ext": { + "prebid": { + "debug": false, + "storedrequest": { + "id": "620523ae7f4bbe1691bbb815" + } + }, + "relevant": { + "adapterType": "server", + "count": 1 + } + }, + "tmax": 750 + }, + "impIDs": ["div-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "seatbid": [ + { + "seat": "pubmatic", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "div-1", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 300, + "h": 250, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "div-1", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner", + "seat": "pubmatic" + } + ] + } + ] +} diff --git a/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeDisabled.json b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeDisabled.json new file mode 100644 index 00000000000..a8ab5a81c0a --- /dev/null +++ b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeDisabled.json @@ -0,0 +1,129 @@ +{ + "mockBidRequest": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "accountId": "620523ae7f4bbe1691bbb815", + "pbsHost": "fakeHost", + "placementId": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817" + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakeHost.relevant-digital.com/openrtb2/auction", + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817" + } + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + }, + "ext": { + "prebid": { + "debug": false, + "storedrequest": { + "id": "620523ae7f4bbe1691bbb815" + } + }, + "relevant": { + "adapterType": "server", + "count": 1 + } + }, + "tmax": 750 + }, + "impIDs": ["div-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "seatbid": [ + { + "seat": "pubmatic", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "div-1", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 300, + "h": 250, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "div-1", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeDisabledMultipleSeatBids.json b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeDisabledMultipleSeatBids.json new file mode 100644 index 00000000000..8040c2e0399 --- /dev/null +++ b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeDisabledMultipleSeatBids.json @@ -0,0 +1,157 @@ +{ + "mockBidRequest": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "accountId": "620523ae7f4bbe1691bbb815", + "pbsHost": "fakeHost", + "placementId": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817" + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakeHost.relevant-digital.com/openrtb2/auction", + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817" + } + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + }, + "ext": { + "prebid": { + "debug": false, + "storedrequest": { + "id": "620523ae7f4bbe1691bbb815" + } + }, + "relevant": { + "adapterType": "server", + "count": 1 + } + }, + "tmax": 750 + }, + "impIDs": ["div-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "seatbid": [ + { + "seat": "pubmatic", + "bid": [ + { + "id": "bid-1", + "impid": "div-1", + "price": 0.5, + "adm": "pubmatic-ad", + "crid": "crid_1", + "w": 300, + "h": 250, + "mtype": 1 + } + ] + }, + { + "seat": "appnexus", + "bid": [ + { + "id": "bid-2", + "impid": "div-1", + "price": 0.8, + "adm": "appnexus-ad", + "crid": "crid_2", + "w": 300, + "h": 250, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-1", + "impid": "div-1", + "price": 0.5, + "adm": "pubmatic-ad", + "crid": "crid_1", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "bid-2", + "impid": "div-1", + "price": 0.8, + "adm": "appnexus-ad", + "crid": "crid_2", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeMultipleSeatBids.json b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeMultipleSeatBids.json new file mode 100644 index 00000000000..1a0b8e2aaca --- /dev/null +++ b/adapters/relevantdigital/relevantdigitaltest/supplemental/useSourceBidderCodeMultipleSeatBids.json @@ -0,0 +1,160 @@ +{ + "mockBidRequest": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "accountId": "620523ae7f4bbe1691bbb815", + "pbsHost": "fakeHost", + "placementId": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817", + "useSourceBidderCode": true + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakeHost.relevant-digital.com/openrtb2/auction", + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "imp": [ + { + "id": "div-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "prebid": { + "storedrequest": { + "id": "620525862d7518bfd4bbb81e_620523b5d1dbed6b0fbbb817" + } + } + } + } + ], + "site": { + "domain": "somedomain.com", + "page": "https://somedomain.com" + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + }, + "ext": { + "prebid": { + "debug": false, + "storedrequest": { + "id": "620523ae7f4bbe1691bbb815" + } + }, + "relevant": { + "adapterType": "server", + "count": 1 + } + }, + "tmax": 750 + }, + "impIDs": ["div-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "3621f78b-abdf-4562-8eca-1c5e893387d0", + "seatbid": [ + { + "seat": "pubmatic", + "bid": [ + { + "id": "bid-1", + "impid": "div-1", + "price": 0.5, + "adm": "pubmatic-ad", + "crid": "crid_1", + "w": 300, + "h": 250, + "mtype": 1 + } + ] + }, + { + "seat": "appnexus", + "bid": [ + { + "id": "bid-2", + "impid": "div-1", + "price": 0.8, + "adm": "appnexus-ad", + "crid": "crid_2", + "w": 300, + "h": 250, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-1", + "impid": "div-1", + "price": 0.5, + "adm": "pubmatic-ad", + "crid": "crid_1", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner", + "seat": "pubmatic" + }, + { + "bid": { + "id": "bid-2", + "impid": "div-1", + "price": 0.8, + "adm": "appnexus-ad", + "crid": "crid_2", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner", + "seat": "appnexus" + } + ] + } + ] +} diff --git a/openrtb_ext/imp_relevantdigital.go b/openrtb_ext/imp_relevantdigital.go index ec250557c2b..89277c17216 100644 --- a/openrtb_ext/imp_relevantdigital.go +++ b/openrtb_ext/imp_relevantdigital.go @@ -1,8 +1,9 @@ package openrtb_ext type ExtRelevantDigital struct { - AccountId string `json:"accountId"` - PlacementId string `json:"placementId"` - Host string `json:"pbsHost"` - PbsBufferMs int `json:"pbsBufferMs"` + AccountId string `json:"accountId"` + PlacementId string `json:"placementId"` + Host string `json:"pbsHost"` + PbsBufferMs int `json:"pbsBufferMs"` + UseSourceBidderCode bool `json:"useSourceBidderCode,omitempty"` } diff --git a/static/bidder-params/relevantdigital.json b/static/bidder-params/relevantdigital.json index 5f88d85fe58..a3c1ad027d7 100644 --- a/static/bidder-params/relevantdigital.json +++ b/static/bidder-params/relevantdigital.json @@ -19,6 +19,10 @@ "pbsBufferMs": { "type": "number", "description": "TMax buffer, default is 250" + }, + "useSourceBidderCode": { + "type": "boolean", + "description": "Use the bidder code of the actual server-side bidder in bid responses" } }, "required": [