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

Add mapping of user.ext.eids[] for LiveIntent in Rubicon bidder #1089

Merged
merged 8 commits into from
Dec 11, 2019
66 changes: 64 additions & 2 deletions adapters/rubicon/rubicon.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,16 @@ var rubiSizeMap = map[rubiSize]int{
{w: 640, h: 320}: 156,
}

// defines the contract for bidrequest.user.ext.eids[i].ext
type rubiconUserExtEidExt struct {
Segments []string `json:"segments,omitempty"`
}

// defines the contract for bidrequest.user.ext.eids[i].uids[j].ext
type rubiconUserExtEidUidExt struct {
RtiPartner string `json:"rtiPartner,omitempty"`
}

//MAS algorithm
func findPrimary(alt []int) (int, []int) {
min, pos, primary := 0, 0, 0
Expand Down Expand Up @@ -649,19 +659,71 @@ func (a *RubiconAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *adap
// set user.ext.tpid
if len(userExt.Eids) > 0 {
tpIds := make([]rubiconExtUserTpID, 0)

var segments []string
for _, eid := range userExt.Eids {
if eid.Source == "adserver.org" {
uids := eid.Uids
if len(uids) > 0 {
uid := uids[0]
if uid.Ext != nil && uid.Ext.RtiPartner == "TDID" {
tpIds = append(tpIds, rubiconExtUserTpID{Source: "tdid", UID: uid.ID})

if uid.Ext != nil {
var eidUidExt rubiconUserExtEidUidExt
if err := json.Unmarshal(uid.Ext, &eidUidExt); err != nil {
errs = append(errs, &errortypes.BadInput{
Message: err.Error(),
})
continue
}

if eidUidExt.RtiPartner == "TDID" {
tpIds = append(tpIds, rubiconExtUserTpID{Source: "tdid", UID: uid.ID})
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Please consider moving this if block and it's else block into their own functions for better readability and easier unit testing. For example, in case where source is liveintent.com, tpId.UID is set to uids[0].ID but that's not covered in the unit test and with a unit test trying to test the entire OpenRTB request, it is hard to incorporate all the different test cases. Breaking it into smaller functions will help with better test coverage.

} else if eid.Source == "liveintent.com" {
uids := eid.Uids
if len(uids) > 0 {
uidId := uids[0].ID
if uidId != "" {
tpIds = append(tpIds, rubiconExtUserTpID{Source: "liveintent.com", UID: uidId})
}

if eid.Ext != nil {
var eidExt rubiconUserExtEidExt
if err := json.Unmarshal(eid.Ext, &eidExt); err != nil {
errs = append(errs, &errortypes.BadInput{
Message: err.Error(),
})
continue
}
segments = eidExt.Segments
}
}
}
}

if len(tpIds) > 0 {
userExtRP.TpID = tpIds

if segments != nil {
userExtRPTarget := make(map[string]interface{})
if err := json.Unmarshal(userExtRP.RP.Target, &userExtRPTarget); err != nil {
rpanchyk marked this conversation as resolved.
Show resolved Hide resolved
errs = append(errs, &errortypes.BadInput{
Message: err.Error(),
})
continue
}

userExtRPTarget["LIseg"] = segments

target, err = json.Marshal(&userExtRPTarget)
if err != nil {
errs = append(errs, err)
continue
}
userExtRP.RP.Target = target
}
}
}
}
Expand Down
32 changes: 28 additions & 4 deletions adapters/rubicon/rubicon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,8 @@ func TestOpenRTBRequest(t *testing.T) {
"keyv": 1,
"pref": 0
},
"eids": [{
"eids": [
{
"source": "adserver.org",
"uids": [{
"id": "3d50a262-bd8e-4be3-90b8-246291523907",
Expand All @@ -1048,7 +1049,17 @@ func TestOpenRTBRequest(t *testing.T) {
{
"source": "pubcid",
"id": "2402fc76-7b39-4f0e-bfc2-060ef7693648"
}]
},
{
"source": "liveintent.com",
"uids": [{
"id": "T7JiRRvsRAmh88"
}],
"ext": {
"segments": ["999","888"]
}
}
]
}`),
},
Ext: json.RawMessage(`{"prebid": {}}`),
Expand Down Expand Up @@ -1136,12 +1147,25 @@ func TestOpenRTBRequest(t *testing.T) {
if userExt.DigiTrust.ID != "some-digitrust-id" || userExt.DigiTrust.KeyV != 1 || userExt.DigiTrust.Pref != 0 {
t.Fatal("DigiTrust values are not as expected!")
}
if userExt.Eids == nil || len(userExt.Eids) != 2 {
if userExt.Eids == nil || len(userExt.Eids) != 3 {
t.Fatal("Eids values are not as expected!")
}
if userExt.TpID == nil || len(userExt.TpID) != 1 {
if userExt.TpID == nil || len(userExt.TpID) != 2 {
t.Fatal("TpID values are not as expected!")
}
if userExt.TpID[0].Source != "tdid" {
t.Fatal("TpID source value is not as expected!")
}
if userExt.TpID[1].Source != "liveintent.com" {
t.Fatal("TpID source value is not as expected!")
}
userExtRPTarget := make(map[string]interface{})
if err := json.Unmarshal(userExt.RP.Target, &userExtRPTarget); err != nil {
t.Fatal("Error unmarshalling request.user.ext.rp.target object.")
}
if _, ok := userExtRPTarget["LIseg"]; !ok {
t.Fatal("request.user.ext.rp.target value is not as expected!")
}
} else {
t.Fatalf("User.Ext object should not be nil since it contains a valid digitrust object.")
}
Expand Down
12 changes: 5 additions & 7 deletions openrtb_ext/user.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package openrtb_ext

import "encoding/json"

// ExtUser defines the contract for bidrequest.user.ext
type ExtUser struct {
// Consent is a GDPR consent string. See "Advised Extensions" of
Expand Down Expand Up @@ -36,15 +38,11 @@ type ExtUserEid struct {
Source string `json:"source"`
ID string `json:"id,omitempty"`
Uids []ExtUserEidUid `json:"uids,omitempty"`
Ext json.RawMessage `json:"ext,omitempty"`
}

// ExtUserEidUid defines the contract for bidrequest.user.ext.eids[i].uids[j]
type ExtUserEidUid struct {
ID string `json:"id"`
Ext *ExtUserEidUidExt `json:"ext,omitempty"`
}

// ExtUserEidUidExt defines the contract for bidrequest.user.ext.eids[i].uids[j].ext
type ExtUserEidUidExt struct {
RtiPartner string `json:"rtiPartner,omitempty"`
ID string `json:"id"`
Ext json.RawMessage `json:"ext,omitempty"`
}