diff --git a/adapters/dmx/dmx.go b/adapters/dmx/dmx.go new file mode 100644 index 00000000000..6b4f698d4b1 --- /dev/null +++ b/adapters/dmx/dmx.go @@ -0,0 +1,296 @@ +package dmx + +import ( + "encoding/json" + "errors" + "fmt" + "github.com/mxmCherry/openrtb" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/openrtb_ext" + "net/http" + "net/url" + "strings" +) + +type DmxAdapter struct { + endpoint string +} + +func NewDmxBidder(endpoint string) *DmxAdapter { + return &DmxAdapter{endpoint: endpoint} +} + +type dmxExt struct { + Bidder dmxParams `json:"bidder"` +} + +type dmxParams struct { + TagId string `json:"tagid,omitempty"` + DmxId string `json:"dmxid,omitempty"` + MemberId string `json:"memberid,omitempty"` + PublisherId string `json:"publisher_id,omitempty"` + SellerId string `json:"seller_id,omitempty"` +} + +func UserSellerOrPubId(str1, str2 string) string { + if str1 != "" { + return str1 + } + return str2 +} + +func (adapter *DmxAdapter) MakeRequests(request *openrtb.BidRequest, req *adapters.ExtraRequestInfo) (reqsBidder []*adapters.RequestData, errs []error) { + var imps []openrtb.Imp + var rootExtInfo dmxExt + var publisherId string + var sellerId string + var userExt openrtb_ext.ExtUser + var anyHasId = false + var reqCopy openrtb.BidRequest = *request + var dmxReq *openrtb.BidRequest = &reqCopy + + if request.User == nil { + if request.App == nil { + return nil, []error{errors.New("No user id or app id found. Could not send request to DMX.")} + } + } + + if len(request.Imp) >= 1 { + err := json.Unmarshal(request.Imp[0].Ext, &rootExtInfo) + if err != nil { + errs = append(errs, err) + } else { + publisherId = UserSellerOrPubId(rootExtInfo.Bidder.PublisherId, rootExtInfo.Bidder.MemberId) + sellerId = rootExtInfo.Bidder.SellerId + } + } + + if request.App != nil { + appCopy := *request.App + appPublisherCopy := *request.App.Publisher + dmxReq.App = &appCopy + dmxReq.App.Publisher = &appPublisherCopy + if dmxReq.App.ID != "" { + anyHasId = true + } + } else { + dmxReq.App = nil + } + + if request.Site != nil { + siteCopy := *request.Site + sitePublisherCopy := *request.Site.Publisher + dmxReq.Site = &siteCopy + dmxReq.Site.Publisher = &sitePublisherCopy + if dmxReq.Site.Publisher != nil { + dmxReq.Site.Publisher.ID = publisherId + } else { + dmxReq.Site.Publisher = &openrtb.Publisher{ID: publisherId} + } + } else { + dmxReq.Site = nil + } + + if request.User != nil { + userCopy := *request.User + dmxReq.User = &userCopy + } else { + dmxReq.User = nil + } + + if dmxReq.User != nil { + if dmxReq.User.ID != "" { + anyHasId = true + } + if dmxReq.User.Ext != nil { + if err := json.Unmarshal(dmxReq.User.Ext, &userExt); err == nil { + if len(userExt.Eids) > 0 || (userExt.DigiTrust != nil && userExt.DigiTrust.ID != "") { + anyHasId = true + } + } + } + } + + if anyHasId == false { + return nil, []error{errors.New("This request contained no identifier")} + } + + for _, inst := range dmxReq.Imp { + var banner *openrtb.Banner + var video *openrtb.Video + var ins openrtb.Imp + var params dmxExt + const intVal int8 = 1 + source := (*json.RawMessage)(&inst.Ext) + if err := json.Unmarshal(*source, ¶ms); err != nil { + errs = append(errs, err) + } + if isDmxParams(params.Bidder) { + if inst.Banner != nil { + if len(inst.Banner.Format) != 0 { + banner = inst.Banner + if params.Bidder.PublisherId != "" || params.Bidder.MemberId != "" { + imps = fetchParams(params, inst, ins, imps, banner, nil, intVal) + } else { + return nil, []error{errors.New("Missing Params for auction to be send")} + } + } + } + + if inst.Video != nil { + video = inst.Video + if params.Bidder.PublisherId != "" || params.Bidder.MemberId != "" { + imps = fetchParams(params, inst, ins, imps, nil, video, intVal) + } else { + return nil, []error{errors.New("Missing Params for auction to be send")} + } + } + } + + } + + dmxReq.Imp = imps + + oJson, err := json.Marshal(dmxReq) + + if err != nil { + errs = append(errs, err) + return nil, errs + } + + headers := http.Header{} + headers.Add("Content-Type", "Application/json;charset=utf-8") + reqBidder := &adapters.RequestData{ + Method: "POST", + Uri: adapter.endpoint + addParams(sellerId), //adapter.endpoint, + Body: oJson, + Headers: headers, + } + reqsBidder = append(reqsBidder, reqBidder) + return +} + +func (adapter *DmxAdapter) MakeBids(request *openrtb.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + var errs []error + + if http.StatusNoContent == response.StatusCode { + return nil, nil + } + + if http.StatusBadRequest == response.StatusCode { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Unexpected status code 400"), + }} + } + + if http.StatusOK != response.StatusCode { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Unexpected response no status code"), + }} + } + + var bidResp openrtb.BidResponse + + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(5) + + for _, sb := range bidResp.SeatBid { + for i := range sb.Bid { + bidType, err := getMediaTypeForImp(sb.Bid[i].ImpID, request.Imp) + if err != nil { + errs = append(errs, err) + } else { + b := &adapters.TypedBid{ + Bid: &sb.Bid[i], + BidType: bidType, + } + if b.BidType == openrtb_ext.BidTypeVideo { + b.Bid.AdM = videoImpInsertion(b.Bid) + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + } + return bidResponse, errs + +} + +func fetchParams(params dmxExt, inst openrtb.Imp, ins openrtb.Imp, imps []openrtb.Imp, banner *openrtb.Banner, video *openrtb.Video, intVal int8) []openrtb.Imp { + if params.Bidder.TagId != "" { + ins = openrtb.Imp{ + ID: inst.ID, + TagID: params.Bidder.TagId, + Ext: inst.Ext, + Secure: &intVal, + } + } + + if params.Bidder.DmxId != "" { + ins = openrtb.Imp{ + ID: inst.ID, + TagID: params.Bidder.DmxId, + Ext: inst.Ext, + Secure: &intVal, + } + } + if banner != nil { + ins.Banner = banner + } + + if video != nil { + ins.Video = video + } + + if ins.TagID == "" { + return imps + } + imps = append(imps, ins) + return imps +} + +func addParams(str string) string { + if str != "" { + return "?sellerid=" + url.QueryEscape(str) + } + return "" +} + +func getMediaTypeForImp(impID string, imps []openrtb.Imp) (openrtb_ext.BidType, error) { + mediaType := openrtb_ext.BidTypeBanner + for _, imp := range imps { + if imp.ID == impID { + if imp.Banner == nil && imp.Video != nil { + mediaType = openrtb_ext.BidTypeVideo + } + return mediaType, nil + } + } + + // This shouldnt happen. Lets handle it just incase by returning an error. + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to find impression \"%s\" ", impID), + } +} + +func videoImpInsertion(bid *openrtb.Bid) string { + adm := bid.AdM + nurl := bid.NURL + search := "" + imp := "" + wrapped_nurl := fmt.Sprintf(imp, nurl) + results := strings.Replace(adm, search, wrapped_nurl, 1) + return results +} + +func isDmxParams(t interface{}) bool { + switch t.(type) { + case dmxParams: + return true + default: + return false + } +} diff --git a/adapters/dmx/dmx_test.go b/adapters/dmx/dmx_test.go new file mode 100644 index 00000000000..e9f195eb61d --- /dev/null +++ b/adapters/dmx/dmx_test.go @@ -0,0 +1,782 @@ +package dmx + +import ( + "encoding/json" + "github.com/mxmCherry/openrtb" + "github.com/prebid/prebid-server/adapters" + "strings" + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" +) + +var ( + bidRequest string +) + +func TestFetchParams(t *testing.T) { + var w, h int = 300, 250 + + var width, height uint64 = uint64(w), uint64(h) + var arrImp []openrtb.Imp + var imps = fetchParams( + dmxExt{Bidder: dmxParams{ + TagId: "222", + PublisherId: "5555", + }}, + openrtb.Imp{ID: "32"}, + openrtb.Imp{ID: "32"}, + arrImp, + &openrtb.Banner{W: &width, H: &height, Format: []openrtb.Format{ + {W: 300, H: 250}, + }}, + nil, + 1) + var imps2 = fetchParams( + dmxExt{Bidder: dmxParams{ + DmxId: "222", + MemberId: "5555", + }}, + openrtb.Imp{ID: "32"}, + openrtb.Imp{ID: "32"}, + arrImp, + &openrtb.Banner{W: &width, H: &height, Format: []openrtb.Format{ + {W: 300, H: 250}, + }}, + nil, + 1) + if len(imps) == 0 { + t.Errorf("should increment the length by one") + } + + if len(imps2) == 0 { + t.Errorf("should increment the length by one") + } + +} +func TestJsonSamples(t *testing.T) { + adapterstest.RunJSONBidderTest(t, "dmxtest", new(DmxAdapter)) +} + +func TestMakeRequestsOtherPlacement(t *testing.T) { + var w, h int = 300, 250 + + var width, height uint64 = uint64(w), uint64(h) + + adapter := NewDmxBidder("https://dmx.districtm.io/b/v2") + imp1 := openrtb.Imp{ + ID: "imp1", + Ext: json.RawMessage("{\"bidder\":{\"dmxid\": \"1007\", \"memberid\": \"123456\", \"seller_id\":\"1008\"}}"), + Banner: &openrtb.Banner{ + W: &width, + H: &height, + Format: []openrtb.Format{ + {W: 300, H: 250}, + }, + }} + + inputRequest := openrtb.BidRequest{ + User: &openrtb.User{ID: "bscakucbkasucbkasunscancasuin"}, + Imp: []openrtb.Imp{imp1}, + Site: &openrtb.Site{ + Publisher: &openrtb.Publisher{ + ID: "10007", + }, + }, + ID: "1234", + } + + actualAdapterRequests, err := adapter.MakeRequests(&inputRequest, &adapters.ExtraRequestInfo{}) + + if actualAdapterRequests == nil { + t.Errorf("request should be nil") + } + if len(err) != 0 { + t.Errorf("We should have no error") + } + +} + +func TestMakeRequestsInvalid(t *testing.T) { + var w, h int = 300, 250 + + var width, height uint64 = uint64(w), uint64(h) + + adapter := NewDmxBidder("https://dmx.districtm.io/b/v2") + imp1 := openrtb.Imp{ + ID: "imp1", + Ext: json.RawMessage("{\"dmxid\": \"1007\", \"memberid\": \"123456\", \"seller_id\":\"1008\"}"), + Banner: &openrtb.Banner{ + W: &width, + H: &height, + Format: []openrtb.Format{ + {W: 300, H: 250}, + }, + }} + + inputRequest := openrtb.BidRequest{ + Imp: []openrtb.Imp{imp1}, + Site: &openrtb.Site{ + Publisher: &openrtb.Publisher{ + ID: "10007", + }, + }, + ID: "1234", + } + + actualAdapterRequests, err := adapter.MakeRequests(&inputRequest, &adapters.ExtraRequestInfo{}) + + if len(actualAdapterRequests) != 0 { + t.Errorf("request should be nil") + } + if len(err) == 0 { + t.Errorf("We should have no error") + } + +} + +func TestMakeRequestNoSite(t *testing.T) { + var w, h int = 300, 250 + + var width, height uint64 = uint64(w), uint64(h) + + adapter := NewDmxBidder("https://dmx.districtm.io/b/v2") + imp1 := openrtb.Imp{ + ID: "imp1", + Ext: json.RawMessage("{\"bidder\":{\"dmxid\": \"1007\", \"memberid\": \"123456\", \"seller_id\":\"1008\"}}"), + Banner: &openrtb.Banner{ + W: &width, + H: &height, + Format: []openrtb.Format{ + {W: 300, H: 250}, + }, + }} + + inputRequest := openrtb.BidRequest{ + Imp: []openrtb.Imp{imp1}, + App: &openrtb.App{ID: "cansanuabnua", Publisher: &openrtb.Publisher{ID: "whatever"}}, + ID: "1234", + } + + actualAdapterRequests, _ := adapter.MakeRequests(&inputRequest, &adapters.ExtraRequestInfo{}) + + if len(actualAdapterRequests) != 1 { + t.Errorf("openrtb type should be an Array when it's an App") + } + var the_body openrtb.BidRequest + if err := json.Unmarshal(actualAdapterRequests[0].Body, &the_body); err != nil { + t.Errorf("failed to read bid request") + } + + if the_body.App == nil { + t.Errorf("app property should be populated") + } + + if the_body.App.Publisher.ID == "" { + t.Errorf("Missing publisher ID must be in") + } +} + +func TestMakeRequestsApp(t *testing.T) { + var w, h int = 300, 250 + + var width, height uint64 = uint64(w), uint64(h) + + adapter := NewDmxBidder("https://dmx.districtm.io/b/v2") + imp1 := openrtb.Imp{ + ID: "imp1", + Ext: json.RawMessage("{\"bidder\":{\"dmxid\": \"1007\", \"memberid\": \"123456\", \"seller_id\":\"1008\"}}"), + Banner: &openrtb.Banner{ + W: &width, + H: &height, + Format: []openrtb.Format{ + {W: 300, H: 250}, + }, + }} + + inputRequest := openrtb.BidRequest{ + Imp: []openrtb.Imp{imp1}, + Site: &openrtb.Site{ + Publisher: &openrtb.Publisher{ + ID: "10007", + }, + }, + App: &openrtb.App{ID: "cansanuabnua", Publisher: &openrtb.Publisher{ID: "whatever"}}, + ID: "1234", + } + + actualAdapterRequests, _ := adapter.MakeRequests(&inputRequest, &adapters.ExtraRequestInfo{}) + + if len(actualAdapterRequests) != 1 { + t.Errorf("openrtb type should be an Array when it's an App") + } + var the_body openrtb.BidRequest + if err := json.Unmarshal(actualAdapterRequests[0].Body, &the_body); err != nil { + t.Errorf("failed to read bid request") + } + + if the_body.App == nil { + t.Errorf("app property should be populated") + } + +} + +func TestMakeRequestsNoUser(t *testing.T) { + var w, h int = 300, 250 + + var width, height uint64 = uint64(w), uint64(h) + + adapter := NewDmxBidder("https://dmx.districtm.io/b/v2") + imp1 := openrtb.Imp{ + ID: "imp1", + Ext: json.RawMessage("{\"bidder\":{\"dmxid\": \"1007\", \"memberid\": \"123456\", \"seller_id\":\"1008\"}}"), + Banner: &openrtb.Banner{ + W: &width, + H: &height, + Format: []openrtb.Format{ + {W: 300, H: 250}, + }, + }} + + inputRequest := openrtb.BidRequest{ + Imp: []openrtb.Imp{imp1}, + Site: &openrtb.Site{ + Publisher: &openrtb.Publisher{ + ID: "10007", + }, + }, + ID: "1234", + } + + actualAdapterRequests, _ := adapter.MakeRequests(&inputRequest, &adapters.ExtraRequestInfo{}) + + if actualAdapterRequests != nil { + t.Errorf("openrtb type should be empty") + } + +} + +func TestMakeRequests(t *testing.T) { + //server := httptest.NewServer(http.HandlerFunc(DummyDmxServer)) + var w, h int = 300, 250 + + var width, height uint64 = uint64(w), uint64(h) + + adapter := NewDmxBidder("https://dmx.districtm.io/b/v2") + imp1 := openrtb.Imp{ + ID: "imp1", + Ext: json.RawMessage("{\"bidder\":{\"dmxid\": \"1007\", \"memberid\": \"123456\", \"seller_id\":\"1008\"}}"), + Banner: &openrtb.Banner{ + W: &width, + H: &height, + Format: []openrtb.Format{ + {W: 300, H: 250}, + }, + }} + imp2 := openrtb.Imp{ + ID: "imp2", + Ext: json.RawMessage("{\"bidder\":{\"dmxid\": \"1007\", \"memberid\": \"123456\", \"seller_id\":\"1008\"}}"), + Banner: &openrtb.Banner{ + W: &width, + H: &height, + Format: []openrtb.Format{ + {W: 300, H: 250}, + }, + }} + imp3 := openrtb.Imp{ + ID: "imp3", + Ext: json.RawMessage("{\"bidder\":{\"dmxid\": \"1007\", \"memberid\": \"123456\", \"seller_id\":\"1008\"}}"), + Banner: &openrtb.Banner{ + W: &width, + H: &height, + Format: []openrtb.Format{ + {W: 300, H: 250}, + }, + }} + + inputRequest := openrtb.BidRequest{ + Imp: []openrtb.Imp{imp1, imp2, imp3}, + Site: &openrtb.Site{ + Publisher: &openrtb.Publisher{ + ID: "10007", + }, + }, + User: &openrtb.User{ID: "districtmID"}, + ID: "1234", + } + + actualAdapterRequests, _ := adapter.MakeRequests(&inputRequest, &adapters.ExtraRequestInfo{}) + + if len(actualAdapterRequests) != 1 { + t.Errorf("should have 1 request") + } + var the_body openrtb.BidRequest + if err := json.Unmarshal(actualAdapterRequests[0].Body, &the_body); err != nil { + t.Errorf("failed to read bid request") + } + + if len(the_body.Imp) != 3 { + t.Errorf("must have 3 bids") + } + +} + +func TestMakeBidVideo(t *testing.T) { + var w, h int = 640, 480 + + var width, height uint64 = uint64(w), uint64(h) + + adapter := NewDmxBidder("https://dmx.districtm.io/b/v2") + imp1 := openrtb.Imp{ + ID: "imp1", + Ext: json.RawMessage("{\"bidder\":{\"dmxid\": \"1007\", \"memberid\": \"123456\", \"seller_id\":\"1008\"}}"), + Video: &openrtb.Video{ + W: width, + H: height, + MIMEs: []string{"video/mp4"}, + }} + + inputRequest := openrtb.BidRequest{ + Imp: []openrtb.Imp{imp1}, + Site: &openrtb.Site{ + Publisher: &openrtb.Publisher{ + ID: "10007", + }, + }, + User: &openrtb.User{ID: "districtmID"}, + ID: "1234", + } + + actualAdapterRequests, _ := adapter.MakeRequests(&inputRequest, &adapters.ExtraRequestInfo{}) + + if len(actualAdapterRequests) != 1 { + t.Errorf("should have 1 request") + } + var the_body openrtb.BidRequest + if err := json.Unmarshal(actualAdapterRequests[0].Body, &the_body); err != nil { + t.Errorf("failed to read bid request") + } + + if len(the_body.Imp) != 1 { + t.Errorf("must have 1 bids") + } +} + +func TestMakeBidsNoContent(t *testing.T) { + var w, h int = 300, 250 + + var width, height uint64 = uint64(w), uint64(h) + + adapter := NewDmxBidder("https://dmx.districtm.io/b/v2") + imp1 := openrtb.Imp{ + ID: "imp1", + Ext: json.RawMessage("{\"bidder\":{\"dmxid\": \"1007\", \"memberid\": \"123456\", \"seller_id\":\"1008\"}}"), + Banner: &openrtb.Banner{ + W: &width, + H: &height, + Format: []openrtb.Format{ + {W: 300, H: 250}, + }, + }} + + inputRequest := openrtb.BidRequest{ + Imp: []openrtb.Imp{imp1}, + Site: &openrtb.Site{ + Publisher: &openrtb.Publisher{ + ID: "10007", + }, + }, + User: &openrtb.User{ID: "districtmID"}, + ID: "1234", + } + + actualAdapterRequests, _ := adapter.MakeRequests(&inputRequest, &adapters.ExtraRequestInfo{}) + + _, err204 := adapter.MakeBids(&inputRequest, actualAdapterRequests[0], &adapters.ResponseData{StatusCode: 204}) + + if err204 != nil { + t.Errorf("Was expecting nil") + } + + _, err400 := adapter.MakeBids(&inputRequest, actualAdapterRequests[0], &adapters.ResponseData{StatusCode: 400}) + + if err400 == nil { + t.Errorf("Was expecting error") + } + + _, err500 := adapter.MakeBids(&inputRequest, actualAdapterRequests[0], &adapters.ResponseData{StatusCode: 500}) + + if err500 == nil { + t.Errorf("Was expecting error") + } + + bidResponse := &adapters.ResponseData{ + StatusCode: 200, + Body: []byte(`{ + "id": "JdSgvXjee0UZ", + "seatbid": [ + { + "bid": [ + { + "id": "16-40dbf1ef_0gKywr9JnzPAW4bE-1", + "impid": "imp1", + "price": 2.3456, + "adm": "", + "nurl": "dmxnotificationurlhere", + "adomain": [ + "brand.com", + "advertiser.net" + ], + "cid": "12345", + "crid": "232303", + "cat": [ + "IAB20-3" + ], + "attr": [ + 2 + ], + "w": 300, + "h": 600, + "language": "en" + } + ], + "seat": "10001" + } + ], + "cur": "USD" +}`), + } + + bidResponseNoMatch := &adapters.ResponseData{ + StatusCode: 200, + Body: []byte(`{ + "id": "JdSgvXjee0UZ", + "seatbid": [ + { + "bid": [ + { + "id": "16-40dbf1ef_0gKywr9JnzPAW4bE-1", + "impid": "djvnsvns", + "price": 2.3456, + "adm": "", + "nurl": "dmxnotificationurlhere", + "adomain": [ + "brand.com", + "advertiser.net" + ], + "cid": "12345", + "crid": "232303", + "cat": [ + "IAB20-3" + ], + "attr": [ + 2 + ], + "w": 300, + "h": 600, + "language": "en" + } + ], + "seat": "10001" + } + ], + "cur": "USD" +}`), + } + + bids, _ := adapter.MakeBids(&inputRequest, actualAdapterRequests[0], bidResponse) + if bids == nil { + t.Errorf("ads not parse") + } + bidsNoMatching, _ := adapter.MakeBids(&inputRequest, actualAdapterRequests[0], bidResponseNoMatch) + if bidsNoMatching == nil { + t.Errorf("ads not parse") + } + +} +func TestUserExtEmptyObject(t *testing.T) { + var w, h int = 300, 250 + + var width, height uint64 = uint64(w), uint64(h) + + adapter := NewDmxBidder("https://dmx.districtm.io/b/v2") + imp1 := openrtb.Imp{ + ID: "imp1", + Ext: json.RawMessage("{\"bidder\":{\"dmxid\": \"1007\", \"memberid\": \"123456\", \"seller_id\":\"1008\"}}"), + Banner: &openrtb.Banner{ + W: &width, + H: &height, + Format: []openrtb.Format{ + {W: 300, H: 250}, + }, + }} + + inputRequest := openrtb.BidRequest{ + Imp: []openrtb.Imp{imp1, imp1, imp1}, + Site: &openrtb.Site{ + Publisher: &openrtb.Publisher{ + ID: "10007", + }, + }, + User: &openrtb.User{Ext: json.RawMessage(`{}`)}, + ID: "1234", + } + + actualAdapterRequests, _ := adapter.MakeRequests(&inputRequest, &adapters.ExtraRequestInfo{}) + if len(actualAdapterRequests) != 0 { + t.Errorf("should have 0 request") + } +} +func TestUserEidsOnly(t *testing.T) { + var w, h int = 300, 250 + + var width, height uint64 = uint64(w), uint64(h) + + adapter := NewDmxBidder("https://dmx.districtm.io/b/v2") + imp1 := openrtb.Imp{ + ID: "imp1", + Ext: json.RawMessage("{\"bidder\":{\"dmxid\": \"1007\", \"memberid\": \"123456\", \"seller_id\":\"1008\"}}"), + Banner: &openrtb.Banner{ + W: &width, + H: &height, + Format: []openrtb.Format{ + {W: 300, H: 250}, + }, + }} + + inputRequest := openrtb.BidRequest{ + Imp: []openrtb.Imp{imp1, imp1, imp1}, + Site: &openrtb.Site{ + Publisher: &openrtb.Publisher{ + ID: "10007", + }, + }, + User: &openrtb.User{Ext: json.RawMessage(`{"eids": [{ + "source": "adserver.org", + "uids": [{ + "id": "111111111111", + "ext": { + "rtiPartner": "TDID" + } + }] + },{ + "source": "netid.de", + "uids": [{ + "id": "11111111" + }] + }] + }`)}, + ID: "1234", + } + + actualAdapterRequests, _ := adapter.MakeRequests(&inputRequest, &adapters.ExtraRequestInfo{}) + if len(actualAdapterRequests) != 1 { + t.Errorf("should have 1 request") + } +} + +func TestUserDigitrustOnly(t *testing.T) { + var w, h int = 300, 250 + + var width, height uint64 = uint64(w), uint64(h) + + adapter := NewDmxBidder("https://dmx.districtm.io/b/v2") + imp1 := openrtb.Imp{ + ID: "imp1", + Ext: json.RawMessage("{\"bidder\":{\"dmxid\": \"1007\", \"memberid\": \"123456\", \"seller_id\":\"1008\"}}"), + Banner: &openrtb.Banner{ + W: &width, + H: &height, + Format: []openrtb.Format{ + {W: 300, H: 250}, + }, + }} + + inputRequest := openrtb.BidRequest{ + Imp: []openrtb.Imp{imp1, imp1, imp1}, + Site: &openrtb.Site{ + Publisher: &openrtb.Publisher{ + ID: "10007", + }, + }, + User: &openrtb.User{Ext: json.RawMessage(`{ + "digitrust": { + "id": "11111111111", + "keyv": 4 + }}`)}, + ID: "1234", + } + + actualAdapterRequests, _ := adapter.MakeRequests(&inputRequest, &adapters.ExtraRequestInfo{}) + if len(actualAdapterRequests) != 1 { + t.Errorf("should have 1 request") + } +} + +func TestUsersEids(t *testing.T) { + var w, h int = 300, 250 + + var width, height uint64 = uint64(w), uint64(h) + + adapter := NewDmxBidder("https://dmx.districtm.io/b/v2") + imp1 := openrtb.Imp{ + ID: "imp1", + Ext: json.RawMessage("{\"bidder\":{\"dmxid\": \"1007\", \"memberid\": \"123456\", \"seller_id\":\"1008\"}}"), + Banner: &openrtb.Banner{ + W: &width, + H: &height, + Format: []openrtb.Format{ + {W: 300, H: 250}, + }, + }} + + inputRequest := openrtb.BidRequest{ + Imp: []openrtb.Imp{imp1, imp1, imp1}, + Site: &openrtb.Site{ + Publisher: &openrtb.Publisher{ + ID: "10007", + }, + }, + User: &openrtb.User{ID: "districtmID", Ext: json.RawMessage(`{"eids": [{ + "source": "adserver.org", + "uids": [{ + "id": "111111111111", + "ext": { + "rtiPartner": "TDID" + } + }] + },{ + "source": "pubcid.org", + "uids": [{ + "id":"11111111" + }] + }, + { + "source": "id5-sync.com", + "uids": [{ + "id": "ID5-12345" + }] + }, + { + "source": "parrable.com", + "uids": [{ + "id": "01.1563917337.test-eid" + }] + },{ + "source": "identityLink", + "uids": [{ + "id": "11111111" + }] + },{ + "source": "criteo", + "uids": [{ + "id": "11111111" + }] + },{ + "source": "britepool.com", + "uids": [{ + "id": "11111111" + }] + },{ + "source": "liveintent.com", + "uids": [{ + "id": "11111111" + }] + },{ + "source": "netid.de", + "uids": [{ + "id": "11111111" + }] + }], + "digitrust": { + "id": "11111111111", + "keyv": 4 + }}`)}, + ID: "1234", + } + + actualAdapterRequests, _ := adapter.MakeRequests(&inputRequest, &adapters.ExtraRequestInfo{}) + if len(actualAdapterRequests) != 1 { + t.Errorf("should have 1 request") + } + var the_body openrtb.BidRequest + if err := json.Unmarshal(actualAdapterRequests[0].Body, &the_body); err != nil { + t.Errorf("failed to read bid request") + } + + if len(the_body.Imp) != 3 { + t.Errorf("must have 3 bids") + } +} +func TestVideoImpInsertion(t *testing.T) { + var bidResp openrtb.BidResponse + var bid openrtb.Bid + payload := []byte(`{ + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "video1", + "impid": "video1", + "price": 5.01, + "nurl": "https://demo.arripiblik.com/359585167267151", + "adm": "BidSwitch", + "crid": "76575664756", + "dealid": "dmx-deal-hp-24", + "w": 640, + "h": 480, + "ext": { + "prebid": { + "type": "video" + } + } + }, + { + "id": "some-impression-id", + "impid": "some-impression-id", + "price": 5.01, + "adm": "", + "crid": "1346943998", + "dealid": "dmx-deal-hp-24", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + { + "id": "some-impression-id2", + "impid": "some-impression-id2", + "price": 5.01, + "adm": "", + "crid": "1424798162", + "dealid": "dmx-deal-hp-24", + "w": 728, + "h": 90, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "dmx" + } + ] +}`) + + err := json.Unmarshal(payload, &bidResp) + if err != nil { + t.Errorf("Payload is invalid") + } + bid = openrtb.Bid(bidResp.SeatBid[0].Bid[0]) + data := videoImpInsertion(&bid) + find := strings.Index(data, "demo.arripiblik.com") + if find == -1 { + t.Errorf("String was not found") + } + +} diff --git a/adapters/dmx/dmxtest/exemplary/simple-app.json b/adapters/dmx/dmxtest/exemplary/simple-app.json new file mode 100644 index 00000000000..a2d57163f3c --- /dev/null +++ b/adapters/dmx/dmxtest/exemplary/simple-app.json @@ -0,0 +1,138 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app":{ + "bundle":"302324249", + "id":"ed6207cefff74c14878963566683c070", + "name":"Skout - iOS Match Buy", + "publisher":{ + "id":"10400" + }, + "storeurl":"https://itunes.apple.com/app/id302324249" + }, + "imp": [ + { + + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250, + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "dmxid": "123454", + "publisher_id": "10400" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "", + "body": { + "id": "test-request-id", + "app":{ + "bundle":"302324249", + "id":"ed6207cefff74c14878963566683c070", + "name":"Skout - iOS Match Buy", + "publisher":{ + "id":"10400" + }, + "storeurl":"https://itunes.apple.com/app/id302324249" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "123454", + "secure": 1, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisher_id": "10400", + "dmxid": "123454" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 1.75, + "adid": "29681110", + "adm": "
banner-ads
", + "adomain": ["dmx.districtm.io"], + "iurl": "https://dmx.districtm.io/b/v2", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300 + }] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 1.75, + "adm": "
banner-ads
", + "adid": "29681110", + "adomain": ["dmx.districtm.io"], + "iurl": "https://dmx.districtm.io/b/v2", + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250 + + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/dmx/dmxtest/exemplary/simple-banner.json b/adapters/dmx/dmxtest/exemplary/simple-banner.json new file mode 100644 index 00000000000..03ea6246ee4 --- /dev/null +++ b/adapters/dmx/dmxtest/exemplary/simple-banner.json @@ -0,0 +1,126 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "id": "fhacacnasicnaic" + }, + "imp": [ + { + + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250, + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "dmxid": "123454", + "publisher_id": "10400" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "", + "body": { + "id": "test-request-id", + "user": { + "id": "fhacacnasicnaic" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "123454", + "secure": 1, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisher_id": "10400", + "dmxid": "123454" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 1.75, + "adid": "29681110", + "adm": "
banner-ads
", + "adomain": ["dmx.districtm.io"], + "iurl": "https://dmx.districtm.io/b/v2", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300 + }] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 1.75, + "adm": "
banner-ads
", + "adid": "29681110", + "adomain": ["dmx.districtm.io"], + "iurl": "https://dmx.districtm.io/b/v2", + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250 + + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/dmx/dmxtest/exemplary/simple-video.json b/adapters/dmx/dmxtest/exemplary/simple-video.json new file mode 100644 index 00000000000..b4c53188119 --- /dev/null +++ b/adapters/dmx/dmxtest/exemplary/simple-video.json @@ -0,0 +1,112 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "id": "whateveryouwant" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "tagid": "12345", + "publisher_id": "10400" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "", + "body": { + "id": "test-request-id", + "user": { + "id": "whateveryouwant" + }, + "imp": [ + { + "ext": { + "bidder": { + "tagid": "12345", + "publisher_id": "10400" + } + }, + "id": "test-imp-id", + "tagid": "12345", + "secure": 1, + "video": { + "mimes": ["video/mp4"], + "minduration": 15, + "maxduration": 30, + "protocols": [2, 3, 5, 6, 7, 8], + "w": 940, + "h": 560 + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 1.90, + "adid": "29681110", + "adm": "ads", + "adomain": ["dmx.districtm.io"], + "iurl": "https://dmx.districtm.io/b/v2", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300 + }] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 1.90, + "adm": "ads", + "adid": "29681110", + "adomain": ["dmx.districtm.io"], + "iurl": "https://dmx.districtm.io/b/v2", + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/dmx/dmxtest/params/race/banner.json b/adapters/dmx/dmxtest/params/race/banner.json new file mode 100644 index 00000000000..1c0adff78ac --- /dev/null +++ b/adapters/dmx/dmxtest/params/race/banner.json @@ -0,0 +1,4 @@ +{ + "tagid": "25251", + "publisher_id": "100152" +} \ No newline at end of file diff --git a/adapters/dmx/dmxtest/params/race/video.json b/adapters/dmx/dmxtest/params/race/video.json new file mode 100644 index 00000000000..3bbd83bd3b0 --- /dev/null +++ b/adapters/dmx/dmxtest/params/race/video.json @@ -0,0 +1,4 @@ +{ + "tagid": "25255", + "publisher_id": "100151" +} \ No newline at end of file diff --git a/adapters/dmx/usersync.go b/adapters/dmx/usersync.go new file mode 100644 index 00000000000..98e56234fa6 --- /dev/null +++ b/adapters/dmx/usersync.go @@ -0,0 +1,12 @@ +package dmx + +import ( + "text/template" + + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/usersync" +) + +func NewDmxSyncer(temp *template.Template) usersync.Usersyncer { + return adapters.NewSyncer("dmx", 144, temp, adapters.SyncTypeRedirect) +} diff --git a/adapters/dmx/usersync_test.go b/adapters/dmx/usersync_test.go new file mode 100644 index 00000000000..e4e3c7d8e55 --- /dev/null +++ b/adapters/dmx/usersync_test.go @@ -0,0 +1,20 @@ +package dmx + +import ( + "github.com/prebid/prebid-server/privacy" + "testing" + "text/template" + + "github.com/stretchr/testify/assert" +) + +func TestDmxSyncer(t *testing.T) { + temp := template.Must(template.New("sync-template").Parse("https://dmx.districtm.io/s/v1/img/s/10007")) + syncer := NewDmxSyncer(temp) + syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{}) + assert.NoError(t, err) + assert.Equal(t, "https://dmx.districtm.io/s/v1/img/s/10007", syncInfo.URL) + assert.Equal(t, "redirect", syncInfo.Type) + assert.EqualValues(t, 144, syncer.GDPRVendorID()) + assert.Equal(t, false, syncInfo.SupportCORS) +} diff --git a/config/config.go b/config/config.go index 9652ae141f5..e93aed46eab 100755 --- a/config/config.go +++ b/config/config.go @@ -534,6 +534,7 @@ func (cfg *Configuration) setDerivedDefaults() { setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderConversant, "https://prebid-match.dotomi.com/match/bounce/current?version=1&networkId=72582&rurl="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dconversant%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D") setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderCpmstar, "https://server.cpmstar.com/usersync.aspx?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dcpmstar%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID") setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderDatablocks, "https://sync.v5prebid.datablocks.net/s2ssync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Ddatablocks%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7Buid%7D") + setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderDmx, "https://dmx.districtm.io/s/v1/img/s/10007?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Ddatablocks%26gdpr%3D%24%7Bgdpr%7D%26gdpr_consent%3D%24%7Bgdpr_consent%7D%26uid%3D%24%7Buid%7D") setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderEmxDigital, "https://cs.emxdgt.com/um?ssp=pbs&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Demx_digital%26uid%3D%24UID") setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderEngageBDR, "https://match.bnmla.com/usersync/s2s_sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dengagebdr%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUUID%7D") setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderEPlanning, "https://ads.us.e-planning.net/uspd/1/?du="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Deplanning%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID") @@ -711,9 +712,10 @@ func SetupViper(v *viper.Viper, filename string) { // for them and specify all the parameters they need for them to work correctly. v.SetDefault("adapters.audiencenetwork.disabled", true) v.SetDefault("adapters.rubicon.disabled", true) - v.SetDefault("adapters.33across.endpoint", "http://ssc.33across.com/api/v1/hb") v.SetDefault("adapters.33across.partner_id", "") + v.SetDefault("adapters.dmx.endpoint", "https://dmx.districtm.io/b/v2") + v.SetDefault("adapters.adtelligent.endpoint", "http://hb.adtelligent.com/auction") v.SetDefault("adapters.adform.endpoint", "http://adx.adform.net/adx") v.SetDefault("adapters.adgeneration.endpoint", "https://d.socdm.com/adsv/v1") v.SetDefault("adapters.adhese.endpoint", "https://ads-{{.AccountID}}.adhese.com/json") diff --git a/exchange/adapter_map.go b/exchange/adapter_map.go index b69b5b50e13..390016117fb 100755 --- a/exchange/adapter_map.go +++ b/exchange/adapter_map.go @@ -29,6 +29,7 @@ import ( "github.com/prebid/prebid-server/adapters/conversant" "github.com/prebid/prebid-server/adapters/cpmstar" "github.com/prebid/prebid-server/adapters/datablocks" + "github.com/prebid/prebid-server/adapters/dmx" "github.com/prebid/prebid-server/adapters/emx_digital" "github.com/prebid/prebid-server/adapters/engagebdr" "github.com/prebid/prebid-server/adapters/eplanning" @@ -107,6 +108,7 @@ func newAdapterMap(client *http.Client, cfg *config.Configuration, infos adapter openrtb_ext.BidderConsumable: consumable.NewConsumableBidder(cfg.Adapters[string(openrtb_ext.BidderConsumable)].Endpoint), openrtb_ext.BidderCpmstar: cpmstar.NewCpmstarBidder(cfg.Adapters[string(openrtb_ext.BidderCpmstar)].Endpoint), openrtb_ext.BidderDatablocks: datablocks.NewDatablocksBidder(cfg.Adapters[string(openrtb_ext.BidderDatablocks)].Endpoint), + openrtb_ext.BidderDmx: dmx.NewDmxBidder(cfg.Adapters[string(openrtb_ext.BidderDmx)].Endpoint), openrtb_ext.BidderEmxDigital: emx_digital.NewEmxDigitalBidder(cfg.Adapters[string(openrtb_ext.BidderEmxDigital)].Endpoint), openrtb_ext.BidderEngageBDR: engagebdr.NewEngageBDRBidder(client, cfg.Adapters[string(openrtb_ext.BidderEngageBDR)].Endpoint), openrtb_ext.BidderEPlanning: eplanning.NewEPlanningBidder(client, cfg.Adapters[string(openrtb_ext.BidderEPlanning)].Endpoint), diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 8a53e4adcf2..b3ecddb06cd 100755 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -46,6 +46,7 @@ const ( BidderConversant BidderName = "conversant" BidderCpmstar BidderName = "cpmstar" BidderDatablocks BidderName = "datablocks" + BidderDmx BidderName = "dmx" BidderEmxDigital BidderName = "emx_digital" BidderEngageBDR BidderName = "engagebdr" BidderEPlanning BidderName = "eplanning" @@ -122,6 +123,7 @@ var BidderMap = map[string]BidderName{ "conversant": BidderConversant, "cpmstar": BidderCpmstar, "datablocks": BidderDatablocks, + "dmx": BidderDmx, "emx_digital": BidderEmxDigital, "engagebdr": BidderEngageBDR, "eplanning": BidderEPlanning, diff --git a/static/bidder-info/dmx.yaml b/static/bidder-info/dmx.yaml new file mode 100644 index 00000000000..d6e54178db4 --- /dev/null +++ b/static/bidder-info/dmx.yaml @@ -0,0 +1,11 @@ +maintainer: + email: "steve@districtm.net" +capabilities: + site: + mediaTypes: + - banner + - video + app: + mediaTypes: + - banner + - video diff --git a/static/bidder-params/dmx.json b/static/bidder-params/dmx.json new file mode 100644 index 00000000000..4c0df65e3d4 --- /dev/null +++ b/static/bidder-params/dmx.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "District M DMX Adapter Params", + "description": "A schema which validates params accepted by the DMX adapter", + "type": "object", + "properties": { + "memberid" : { + "type": "string", + "description": "Represent boost MemberId from districtm UI" + }, + "tagid": { + "type": "string", + "description": "Represent the placement ID, this value is optional" + }, + "bidfloor": { + "type": "string", + "description": "The minimum price acceptable for a bid" + } + }, + + "required": ["memberid"] +} \ No newline at end of file diff --git a/usersync/usersyncers/syncer.go b/usersync/usersyncers/syncer.go index 791a00de0a9..5dccf855add 100755 --- a/usersync/usersyncers/syncer.go +++ b/usersync/usersyncers/syncer.go @@ -24,6 +24,7 @@ import ( "github.com/prebid/prebid-server/adapters/conversant" "github.com/prebid/prebid-server/adapters/cpmstar" "github.com/prebid/prebid-server/adapters/datablocks" + "github.com/prebid/prebid-server/adapters/dmx" "github.com/prebid/prebid-server/adapters/emx_digital" "github.com/prebid/prebid-server/adapters/engagebdr" "github.com/prebid/prebid-server/adapters/eplanning" @@ -94,6 +95,7 @@ func NewSyncerMap(cfg *config.Configuration) map[openrtb_ext.BidderName]usersync insertIntoMap(cfg, syncers, openrtb_ext.BidderConversant, conversant.NewConversantSyncer) insertIntoMap(cfg, syncers, openrtb_ext.BidderCpmstar, cpmstar.NewCpmstarSyncer) insertIntoMap(cfg, syncers, openrtb_ext.BidderDatablocks, datablocks.NewDatablocksSyncer) + insertIntoMap(cfg, syncers, openrtb_ext.BidderDmx, dmx.NewDmxSyncer) insertIntoMap(cfg, syncers, openrtb_ext.BidderEmxDigital, emx_digital.NewEMXDigitalSyncer) insertIntoMap(cfg, syncers, openrtb_ext.BidderEngageBDR, engagebdr.NewEngageBDRSyncer) insertIntoMap(cfg, syncers, openrtb_ext.BidderEPlanning, eplanning.NewEPlanningSyncer) diff --git a/usersync/usersyncers/syncer_test.go b/usersync/usersyncers/syncer_test.go index 9aae284da2a..ddd067e8be7 100755 --- a/usersync/usersyncers/syncer_test.go +++ b/usersync/usersyncers/syncer_test.go @@ -32,6 +32,7 @@ func TestNewSyncerMap(t *testing.T) { string(openrtb_ext.BidderConversant): syncConfig, string(openrtb_ext.BidderCpmstar): syncConfig, string(openrtb_ext.BidderDatablocks): syncConfig, + string(openrtb_ext.BidderDmx): syncConfig, string(openrtb_ext.BidderEmxDigital): syncConfig, string(openrtb_ext.BidderEngageBDR): syncConfig, string(openrtb_ext.BidderEPlanning): syncConfig,