Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 35 additions & 10 deletions adapters/taboola/taboola.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co
}

func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {

var requests []*adapters.RequestData

taboolaRequests, errs := createTaboolaRequests(request)
Expand Down Expand Up @@ -121,7 +120,7 @@ func (a *adapter) buildRequest(request *openrtb2.BidRequest) (*adapters.RequestD
DISPLAY_ENDPOINT_PREFIX = "display"
)

//set MediaType based on first imp
// set MediaType based on first imp
var mediaType string
if request.Imp[0].Banner != nil {
mediaType = DISPLAY_ENDPOINT_PREFIX
Expand Down Expand Up @@ -163,6 +162,17 @@ func createTaboolaRequests(request *openrtb2.BidRequest) (taboolaRequests []*ope
var errs []error

var taboolaExt openrtb_ext.ImpExtTaboola

// user ID extraction logic - checking user.ext.eids for source="taboola.com"
if userID, err := findTaboolaUserId(modifiedRequest.User); err == nil && userID != "" {
if modifiedRequest.User == nil {
modifiedRequest.User = &openrtb2.User{}
}
modifiedRequest.User.BuyerUID = userID
} else if err != nil {
errs = append(errs, err)
}

for i := 0; i < len(modifiedRequest.Imp); i++ {
imp := modifiedRequest.Imp[i]

Expand All @@ -180,7 +190,6 @@ func createTaboolaRequests(request *openrtb2.BidRequest) (taboolaRequests []*ope
if len(taboolaExt.TagID) < 1 {
tagId = taboolaExt.TagId
}

imp.TagID = tagId
modifiedRequest.Imp[i] = imp

Expand All @@ -200,13 +209,11 @@ func createTaboolaRequests(request *openrtb2.BidRequest) (taboolaRequests []*ope
} else if modifiedRequest.Imp[i].Native != nil {
nativeImp = append(nativeImp, modifiedRequest.Imp[i])
}

}

publisher := &openrtb2.Publisher{
ID: taboolaExt.PublisherId,
}

if modifiedRequest.Site == nil {
newSite := &openrtb2.Site{
ID: taboolaExt.PublisherId,
Expand All @@ -227,7 +234,6 @@ func createTaboolaRequests(request *openrtb2.BidRequest) (taboolaRequests []*ope
if taboolaExt.BCat != nil {
modifiedRequest.BCat = taboolaExt.BCat
}

if taboolaExt.BAdv != nil {
modifiedRequest.BAdv = taboolaExt.BAdv
}
Expand All @@ -243,21 +249,18 @@ func createTaboolaRequests(request *openrtb2.BidRequest) (taboolaRequests []*ope

taboolaRequests = append(taboolaRequests, overrideBidRequestImp(&modifiedRequest, nativeImp))
taboolaRequests = append(taboolaRequests, overrideBidRequestImp(&modifiedRequest, bannerImp))

return taboolaRequests, errs
}

func makeRequestExt(pageType string) (json.RawMessage, error) {
requestExt := &RequestExt{
PageType: pageType,
}

requestExtJson, err := json.Marshal(requestExt)
if err != nil {
return nil, fmt.Errorf("could not marshal %s, err: %s", requestExt, err)
}
return requestExtJson, nil

}

func getMediaType(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) {
Expand All @@ -270,7 +273,6 @@ func getMediaType(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error
}
}
}

return "", &errortypes.BadInput{
Message: fmt.Sprintf("Failed to find banner/native impression \"%s\" ", impID),
}
Expand Down Expand Up @@ -299,3 +301,26 @@ func resolveMacros(bid *openrtb2.Bid) {
bid.AdM = strings.Replace(bid.AdM, "${AUCTION_PRICE}", price, -1)
}
}

// findTaboolaUserId attempts to read user.ext.eids (openrtb2.EID) and locate the one with source="taboola.com".
// If found, returns the ID. If user is nil, or no eids, or no taboola.com found, returns empty string.
func findTaboolaUserId(user *openrtb2.User) (string, error) {
if user == nil || user.Ext == nil {
return "", nil
}

var userExt struct {
Eids []openrtb2.EID `json:"eids,omitempty"`
}

if err := json.Unmarshal(user.Ext, &userExt); err != nil {
return "", fmt.Errorf("error parsing user.ext eids: %v", err)
}

for _, eid := range userExt.Eids {
if strings.EqualFold(eid.Source, "taboola.com") && len(eid.UIDs) > 0 {
return eid.UIDs[0].ID, nil
}
}
return "", nil
}
119 changes: 110 additions & 9 deletions adapters/taboola/taboola_test.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,135 @@
package taboola

import (
"encoding/json"
"testing"

"github.com/prebid/openrtb/v20/openrtb2"
"github.com/prebid/prebid-server/v2/adapters/adapterstest"
"github.com/prebid/prebid-server/v2/config"
"github.com/prebid/prebid-server/v2/openrtb_ext"
"github.com/stretchr/testify/assert"
)

func TestJsonSamples(t *testing.T) {
bidder, buildErr := Builder(openrtb_ext.BidderTaboola, config.Adapter{
Endpoint: "http://{{.MediaType}}.whatever.com/{{.GvlID}}/{{.PublisherID}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 12, DataCenter: "2"})

bidder, buildErr := Builder(
openrtb_ext.BidderTaboola,
config.Adapter{
Endpoint: "http://{{.MediaType}}.whatever.com/{{.GvlID}}/{{.PublisherID}}",
},
config.Server{ExternalUrl: "http://hosturl.com", GvlID: 12, DataCenter: "2"},
)
if buildErr != nil {
t.Fatalf("Builder returned unexpected error %v", buildErr)
}

adapterstest.RunJSONBidderTest(t, "taboolatest", bidder)
}

// TestEmptyExternalUrl checks if gvlID remains empty when GvlID=0
func TestEmptyExternalUrl(t *testing.T) {
bidder, buildErr := Builder(openrtb_ext.BidderTaboola, config.Adapter{
Endpoint: "http://whatever.com"}, config.Server{})

bidder, buildErr := Builder(
openrtb_ext.BidderTaboola,
config.Adapter{Endpoint: "http://whatever.com"},
config.Server{},
)
if buildErr != nil {
t.Fatalf("Builder returned unexpected error %v", buildErr)
}

bidderTaboola := bidder.(*adapter)
assert.Equal(t, "", bidderTaboola.gvlID, "Expected empty gvlID when GvlID=0")
}

// TestNoEids ensures that if user.ext has no taboola.com eids, we don't set BuyerUID.
func TestNoEids(t *testing.T) {
bidder, buildErr := Builder(
openrtb_ext.BidderTaboola,
config.Adapter{Endpoint: "http://whatever.com"},
config.Server{},
)
assert.NoError(t, buildErr)
w, h := int64(300), int64(250)

// Minimal request with no user or user.ext
req := &openrtb2.BidRequest{
Imp: []openrtb2.Imp{
{
ID: "imp1",
Banner: &openrtb2.Banner{W: &w, H: &h},
Ext: json.RawMessage(`{"bidder":{"tagid": "example-tag"}}`),
},
},
// No user at all -> no eids
}

// MakeRequests
requests, errs := bidder.MakeRequests(req, nil)
assert.Empty(t, errs, "Expected no errors")
assert.NotEmpty(t, requests, "Should produce at least one request")

// Parse the request body to confirm BuyerUID is not set
for _, r := range requests {
var parsed openrtb2.BidRequest
err := json.Unmarshal(r.Body, &parsed)
assert.NoError(t, err)

assert.Equal(t, "", bidderTaboola.gvlID)
if parsed.User != nil {
assert.Empty(t, parsed.User.BuyerUID, "Expected BuyerUID to remain empty when no taboola.com eids present")
}
}
}

// TestWithTaboolaEid ensures that if user.ext.eids includes source=taboola.com,
// we set user.BuyerUID to that ID.
func TestWithTaboolaEid(t *testing.T) {
bidder, buildErr := Builder(
openrtb_ext.BidderTaboola,
config.Adapter{Endpoint: "http://whatever.com"},
config.Server{},
)
assert.NoError(t, buildErr)

// Create user.ext that has an eid with source="taboola.com"
eidsJSON := `{
"eids": [
{
"source": "taboola.com",
"uids": [{"id": "taboola-user-123"}]
},
{
"source": "other.com",
"uids": [{"id": "not-used"}]
}
]
}`
userExt := json.RawMessage(eidsJSON)
w, h := int64(300), int64(250)
req := &openrtb2.BidRequest{
Imp: []openrtb2.Imp{
{
ID: "imp1",
Banner: &openrtb2.Banner{W: &w, H: &h},
Ext: json.RawMessage(`{"bidder":{"tagid": "example-tag"}}`),
},
},
User: &openrtb2.User{
Ext: userExt,
},
}

// MakeRequests
requests, errs := bidder.MakeRequests(req, nil)
assert.Empty(t, errs, "Expected no errors with valid eids")
assert.NotEmpty(t, requests, "Should produce at least one request")

// Check that user.BuyerUID was set to "taboola-user-123"
for _, r := range requests {
var parsed openrtb2.BidRequest
err := json.Unmarshal(r.Body, &parsed)
assert.NoError(t, err)

if parsed.User != nil {
assert.Equal(t, "taboola-user-123", parsed.User.BuyerUID,
"Expected BuyerUID to be set from taboola.com eids ID")
}
}
}