diff --git a/endpoints/openrtb2/ctv/util/util.go b/endpoints/openrtb2/ctv/util/util.go index 32cb8d29e27..d80c89300cf 100644 --- a/endpoints/openrtb2/ctv/util/util.go +++ b/endpoints/openrtb2/ctv/util/util.go @@ -8,6 +8,9 @@ import ( "strings" "time" + "github.com/PubMatic-OpenWrap/openrtb" + "github.com/buger/jsonparser" + "github.com/PubMatic-OpenWrap/prebid-server/endpoints/openrtb2/ctv/constant" "github.com/PubMatic-OpenWrap/prebid-server/endpoints/openrtb2/ctv/types" "github.com/PubMatic-OpenWrap/prebid-server/openrtb_ext" @@ -85,3 +88,12 @@ func TimeTrack(start time.Time, name string) { Logf("[TIMETRACK] %s took %s", name, elapsed) //eg: defer TimeTrack(time.Now(), "factorial") } + +// GetTargeting returns the value of targeting key associated with bidder +// it is expected that bid.Ext contains prebid.targeting map +// if value not present or any error occured empty value will be returned +// along with error. +func GetTargeting(key openrtb_ext.TargetingKey, bidder openrtb_ext.BidderName, bid openrtb.Bid) (string, error) { + bidderSpecificKey := key.BidderKey(openrtb_ext.BidderName(bidder), 20) + return jsonparser.GetString(bid.Ext, "prebid", "targeting", bidderSpecificKey) +} diff --git a/endpoints/openrtb2/ctv/util/util_test.go b/endpoints/openrtb2/ctv/util/util_test.go index fd1f8d1d68a..0f49b04f6bb 100644 --- a/endpoints/openrtb2/ctv/util/util_test.go +++ b/endpoints/openrtb2/ctv/util/util_test.go @@ -4,6 +4,8 @@ import ( "fmt" "testing" + "github.com/PubMatic-OpenWrap/prebid-server/openrtb_ext" + "github.com/PubMatic-OpenWrap/openrtb" "github.com/PubMatic-OpenWrap/prebid-server/endpoints/openrtb2/ctv/types" @@ -174,3 +176,31 @@ func TestSortByDealPriority(t *testing.T) { fmt.Println("") } } + +func TestGetTargeting(t *testing.T) { + var tests = []struct { + scenario string // Testcase scenario + targeting string + bidder string + key openrtb_ext.TargetingKey + expectValue string + expectError bool + }{ + {"no hb_bidder, expect error", "", "", openrtb_ext.HbCategoryDurationKey, "", true}, + {"hb_bidder present, no key present", `{"x" : "y"}`, "appnexus", openrtb_ext.HbCategoryDurationKey, "", true}, + {"hb_bidder present, required key present (of length 20)", `{"x" : "y", "hb_pb_cat_dur_appnex" : "5.00_sports_10s"}`, "appnexus", openrtb_ext.HbCategoryDurationKey, "5.00_sports_10s", false}, + } + + for _, test := range tests { + t.Run(test.scenario, func(t *testing.T) { + bid := new(openrtb.Bid) + bid.Ext = []byte(`{"prebid" : { "targeting" : ` + test.targeting + `}}`) + value, err := GetTargeting(test.key, openrtb_ext.BidderName(test.bidder), *bid) + if test.expectError { + assert.NotNil(t, err) + assert.Empty(t, value) + } + assert.Equal(t, test.expectValue, value) + }) + } +} diff --git a/endpoints/openrtb2/ctv_auction.go b/endpoints/openrtb2/ctv_auction.go index b1d95d09c7f..1a0528c5580 100644 --- a/endpoints/openrtb2/ctv_auction.go +++ b/endpoints/openrtb2/ctv_auction.go @@ -532,6 +532,18 @@ func (deps *ctvEndpointDeps) getBids(resp *openrtb.BidResponse) { continue } + value, err := util.GetTargeting(openrtb_ext.HbCategoryDurationKey, openrtb_ext.BidderName(seat.Seat), *bid) + if nil == err { + // ignore error + addTargetingKey(bid, openrtb_ext.HbCategoryDurationKey, value) + } + + value, err = util.GetTargeting(openrtb_ext.HbpbConstantKey, openrtb_ext.BidderName(seat.Seat), *bid) + if nil == err { + // ignore error + addTargetingKey(bid, openrtb_ext.HbpbConstantKey, value) + } + index := deps.impIndices[originalImpID] if len(deps.impData[index].Config) == 0 { //adding pure video bids @@ -852,3 +864,15 @@ func getAdPodBidExtension(adpod *types.AdPodBid) json.RawMessage { rawExt, _ := json.Marshal(bidExt) return rawExt } + +func addTargetingKey(bid *openrtb.Bid, key openrtb_ext.TargetingKey, value string) error { + if nil == bid { + return errors.New("Invalid bid") + } + + raw, err := jsonparser.Set(bid.Ext, []byte(strconv.Quote(value)), "prebid", "targeting", string(key)) + if nil == err { + bid.Ext = raw + } + return err +} diff --git a/endpoints/openrtb2/ctv_auction_test.go b/endpoints/openrtb2/ctv_auction_test.go new file mode 100644 index 00000000000..f5f8abc0999 --- /dev/null +++ b/endpoints/openrtb2/ctv_auction_test.go @@ -0,0 +1,35 @@ +package openrtb2 + +import ( + "encoding/json" + "testing" + + "github.com/PubMatic-OpenWrap/openrtb" + "github.com/PubMatic-OpenWrap/prebid-server/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestAddTargetingKeys(t *testing.T) { + var tests = []struct { + scenario string // Testcase scenario + key string + value string + bidExt string + expect map[string]string + }{ + {scenario: "key_not_exists", key: "hb_pb_cat_dur", value: "some_value", bidExt: `{"prebid":{"targeting":{}}}`, expect: map[string]string{"hb_pb_cat_dur": "some_value"}}, + {scenario: "key_already_exists", key: "hb_pb_cat_dur", value: "new_value", bidExt: `{"prebid":{"targeting":{"hb_pb_cat_dur":"old_value"}}}`, expect: map[string]string{"hb_pb_cat_dur": "new_value"}}, + } + for _, test := range tests { + t.Run(test.scenario, func(t *testing.T) { + bid := new(openrtb.Bid) + bid.Ext = []byte(test.bidExt) + key := openrtb_ext.TargetingKey(test.key) + assert.Nil(t, addTargetingKey(bid, key, test.value)) + extBid := openrtb_ext.ExtBid{} + json.Unmarshal(bid.Ext, &extBid) + assert.Equal(t, test.expect, extBid.Prebid.Targeting) + }) + } + assert.Equal(t, "Invalid bid", addTargetingKey(nil, openrtb_ext.HbCategoryDurationKey, "some value").Error()) +}