diff --git a/adapters/mgid/README.md b/adapters/mgid/README.md new file mode 100644 index 00000000000..32c06fd83be --- /dev/null +++ b/adapters/mgid/README.md @@ -0,0 +1 @@ +Please contact if you would like to build and deploy Prebid server and use it with Mgid. diff --git a/adapters/mgid/mgid.go b/adapters/mgid/mgid.go new file mode 100644 index 00000000000..ed63ebb9f27 --- /dev/null +++ b/adapters/mgid/mgid.go @@ -0,0 +1,169 @@ +package mgid + +import ( + "bytes" + "encoding/json" + "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" +) + +type MgidAdapter struct { + endpoint string +} + +type ReqExt struct { + PlacementId string `json:"placementId"` + AccountId string `json:"accountId"` +} + +type RespBidExt struct { + CreativeType openrtb_ext.BidType `json:"crtype"` +} + +func (a *MgidAdapter) MakeRequests(request *openrtb.BidRequest) (adapterRequests []*adapters.RequestData, errs []error) { + + adapterReq, errs := a.makeRequest(request) + if adapterReq != nil && len(errs) == 0 { + adapterRequests = append(adapterRequests, adapterReq) + } + + return +} + +func (a *MgidAdapter) makeRequest(request *openrtb.BidRequest) (*adapters.RequestData, []error) { + var errs []error + + path, err := preprocess(request) + if err != nil { + errs = append(errs, err) + return nil, errs + } + + // Last Step + reqJSON, err := json.Marshal(request) + if err != nil { + errs = append(errs, err) + return nil, errs + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + + return &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint + path, + Body: reqJSON, + Headers: headers, + }, errs +} + +// Mutate the request to get it ready to send to yieldmo. +func preprocess(request *openrtb.BidRequest) (path string, err error) { + if request.TMax == 0 { + request.TMax = 200 + } + for i := 0; i < len(request.Imp); i++ { + var imp = request.Imp[i] + var bidderExt adapters.ExtImpBidder + + if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + return "", &errortypes.BadInput{ + Message: err.Error(), + } + } + + var mgidExt openrtb_ext.ExtImpMgid + + if err := json.Unmarshal(bidderExt.Bidder, &mgidExt); err != nil { + return "", &errortypes.BadInput{ + Message: err.Error(), + } + } + + if path == "" { + path = mgidExt.AccountId + } + request.Imp[i].TagID = mgidExt.PlacementId + + cur := "" + if mgidExt.Currency != "" && mgidExt.Currency != "USD" { + cur = mgidExt.Currency + } + if cur == "" && mgidExt.Cur != "" && mgidExt.Cur != "USD" { + cur = mgidExt.Cur + } + bidfloor := mgidExt.BidFloor + if bidfloor <= 0 { + bidfloor = mgidExt.BidFloor2 + } + if bidfloor > 0 { + request.Imp[i].BidFloor = bidfloor + } + if cur != "" { + request.Imp[i].BidFloorCur = cur + } + } + if path == "" { + return "", &errortypes.BadInput{ + Message: "accountId is not set", + } + } + + return +} + +func (a *MgidAdapter) MakeBids(bidReq *openrtb.BidRequest, unused *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if response.StatusCode == http.StatusNoContent { + return nil, nil + } + + if response.StatusCode == http.StatusBadRequest { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), + }} + } + + if response.StatusCode != http.StatusOK { + return nil, []error{&errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), + }} + } + + var bidResp openrtb.BidResponse + + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(1) + + bidResponse.Currency = bidResp.Cur + + for _, sb := range bidResp.SeatBid { + for i := range sb.Bid { + bidType := openrtb_ext.BidTypeBanner + if len(sb.Bid[i].Ext) > 0 && bytes.Contains(sb.Bid[i].Ext, []byte("crtype")) { + ext := RespBidExt{} + if err := json.Unmarshal(sb.Bid[i].Ext, &ext); err == nil && len(ext.CreativeType) > 0 { + bidType = ext.CreativeType + } + } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &sb.Bid[i], + BidType: bidType, + }) + } + } + return bidResponse, nil +} + +func NewMgidBidder(endpoint string) *MgidAdapter { + return &MgidAdapter{ + endpoint: endpoint, + } +} diff --git a/adapters/mgid/mgid_test.go b/adapters/mgid/mgid_test.go new file mode 100644 index 00000000000..e7c5b9d904f --- /dev/null +++ b/adapters/mgid/mgid_test.go @@ -0,0 +1,10 @@ +package mgid + +import ( + "github.com/prebid/prebid-server/adapters/adapterstest" + "testing" +) + +func TestJsonSamples(t *testing.T) { + adapterstest.RunJSONBidderTest(t, "mgidtest", NewMgidBidder("https://prebid.mgid.com/prebid/")) +} diff --git a/adapters/mgid/mgidtest/exemplary/simple-banner.json b/adapters/mgid/mgidtest/exemplary/simple-banner.json new file mode 100644 index 00000000000..3e227ada92f --- /dev/null +++ b/adapters/mgid/mgidtest/exemplary/simple-banner.json @@ -0,0 +1,135 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "accountId": "123", + "placementId": "456" + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/awesome/site" + }, + "user": { + "buyeruid": "test_reader_id" + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"] + }, + "uri": "https://prebid.mgid.com/prebid/123", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "tagid": "456", + "ext": { + "bidder": { + "accountId": "123", + "placementId": "456" + } + } + } + ], + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/awesome/site" + }, + "tmax": 200, + "user": { + "buyeruid": "test_reader_id" + }, + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "dnt": 0, + "language": "en" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 3.5, + "nurl": "nurl", + "adm": "some-test-ad", + "w": 300, + "h": 250 + } + ] + } + ] + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 3.5, + "adm": "some-test-ad", + "nurl": "nurl", + "w": 300, + "h": 250 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/mgid/mgidtest/exemplary/simple-banner_no_device.json b/adapters/mgid/mgidtest/exemplary/simple-banner_no_device.json new file mode 100644 index 00000000000..58a58b77369 --- /dev/null +++ b/adapters/mgid/mgidtest/exemplary/simple-banner_no_device.json @@ -0,0 +1,129 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "accountId": "123", + "placementId": "456", + "bidfloor": 1.1, + "cur": "GBP" + } + } + } + ], + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/awesome/site" + }, + "user": { + "buyeruid": "test_reader_id" + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"] + }, + "uri": "https://prebid.mgid.com/prebid/123", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "bidfloor": 1.1, + "bidfloorcur": "GBP", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "tagid": "456", + "ext": { + "bidder": { + "accountId": "123", + "placementId": "456", + "bidfloor": 1.1, + "cur": "GBP" + } + } + } + ], + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/awesome/site" + }, + "tmax": 200, + "user": { + "buyeruid": "test_reader_id" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 3.5, + "nurl": "nurl", + "adm": "some-test-ad", + "w": 300, + "h": 250 + } + ] + } + ] + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 3.5, + "adm": "some-test-ad", + "nurl": "nurl", + "w": 300, + "h": 250 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/mgid/mgidtest/exemplary/simple-banner_no_device_no_site.json b/adapters/mgid/mgidtest/exemplary/simple-banner_no_device_no_site.json new file mode 100644 index 00000000000..74cafd63691 --- /dev/null +++ b/adapters/mgid/mgidtest/exemplary/simple-banner_no_device_no_site.json @@ -0,0 +1,121 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "accountId": "123", + "placementId": "456", + "bidFloor": 1.1, + "currency": "GBP" + } + } + } + ], + "user": { + "buyeruid": "test_reader_id" + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"] + }, + "uri": "https://prebid.mgid.com/prebid/123", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "bidfloor": 1.1, + "bidfloorcur": "GBP", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "tagid": "456", + "ext": { + "bidder": { + "accountId": "123", + "placementId": "456", + "bidFloor": 1.1, + "currency": "GBP" + } + } + } + ], + "tmax": 200, + "user": { + "buyeruid": "test_reader_id" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 3.5, + "nurl": "nurl", + "adm": "some-test-ad", + "w": 300, + "h": 250 + } + ] + } + ] + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 3.5, + "adm": "some-test-ad", + "nurl": "nurl", + "w": 300, + "h": 250 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/mgid/mgidtest/exemplary/simple-banner_with_crtype.json b/adapters/mgid/mgidtest/exemplary/simple-banner_with_crtype.json new file mode 100644 index 00000000000..87888149119 --- /dev/null +++ b/adapters/mgid/mgidtest/exemplary/simple-banner_with_crtype.json @@ -0,0 +1,141 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "accountId": "123", + "placementId": "456" + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/awesome/site" + }, + "user": { + "buyeruid": "test_reader_id" + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"] + }, + "uri": "https://prebid.mgid.com/prebid/123", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "tagid": "456", + "ext": { + "bidder": { + "accountId": "123", + "placementId": "456" + } + } + } + ], + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/awesome/site" + }, + "tmax": 200, + "user": { + "buyeruid": "test_reader_id" + }, + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "dnt": 0, + "language": "en" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 3.5, + "nurl": "nurl", + "adm": "some-test-ad", + "w": 300, + "h": 250, + "ext" : { + "crtype": "banner" + } + } + ] + } + ] + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 3.5, + "adm": "some-test-ad", + "nurl": "nurl", + "w": 300, + "h": 250, + "ext" : { + "crtype": "banner" + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/mgid/mgidtest/supplemental/noaccountid.json b/adapters/mgid/mgidtest/supplemental/noaccountid.json new file mode 100644 index 00000000000..2c031c4d70c --- /dev/null +++ b/adapters/mgid/mgidtest/supplemental/noaccountid.json @@ -0,0 +1,29 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "123" + } + } + } + ], + "site": { + "id": "fake-site-id" + } + }, + "expectedMakeRequestsErrors" : [ + "accountId is not set" + ] +} diff --git a/adapters/mgid/mgidtest/supplemental/status_204.json b/adapters/mgid/mgidtest/supplemental/status_204.json new file mode 100644 index 00000000000..6c133e5b924 --- /dev/null +++ b/adapters/mgid/mgidtest/supplemental/status_204.json @@ -0,0 +1,68 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "321", + "accountId": "123" + } + } + } + ], + "site": { + "domain": "fake-site-domain" + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://prebid.mgid.com/prebid/123", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "321", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "321", + "accountId": "123" + } + } + } + ], + "site": { + "domain": "fake-site-domain" + }, + "tmax": 200 + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + + "expectedBidResponses": [] +} diff --git a/adapters/mgid/mgidtest/supplemental/status_not200.json b/adapters/mgid/mgidtest/supplemental/status_not200.json new file mode 100644 index 00000000000..4572076ffab --- /dev/null +++ b/adapters/mgid/mgidtest/supplemental/status_not200.json @@ -0,0 +1,70 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "321", + "accountId": "123" + } + } + } + ], + "site": { + "domain": "fake-site-domain" + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://prebid.mgid.com/prebid/123", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "321", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "321", + "accountId": "123" + } + } + } + ], + "site": { + "domain": "fake-site-domain" + }, + "tmax": 200 + } + }, + "mockResponse": { + "status": 404, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [ + "Unexpected status code: 404. Run with request.debug = 1 for more info" + ], + "expectedBidResponses": [] +} diff --git a/adapters/mgid/mgidtest/supplemental/video.json b/adapters/mgid/mgidtest/supplemental/video.json new file mode 100644 index 00000000000..129dbe173b8 --- /dev/null +++ b/adapters/mgid/mgidtest/supplemental/video.json @@ -0,0 +1,57 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext":{ + "bidder":{ + "accountId": "123", + "placementId": "456" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://prebid.mgid.com/prebid/123", + "body": { + "tmax" : 200, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "456", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "accountId": "123", + "placementId": "456" + } + } + } + ] + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/mgid/usersync.go b/adapters/mgid/usersync.go new file mode 100644 index 00000000000..fbdb95f01fc --- /dev/null +++ b/adapters/mgid/usersync.go @@ -0,0 +1,12 @@ +package mgid + +import ( + "text/template" + + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/usersync" +) + +func NewMgidSyncer(temp *template.Template) usersync.Usersyncer { + return adapters.NewSyncer("mgid", 358, temp, adapters.SyncTypeRedirect) +} diff --git a/adapters/mgid/usersync_test.go b/adapters/mgid/usersync_test.go new file mode 100644 index 00000000000..7bb4d1e043b --- /dev/null +++ b/adapters/mgid/usersync_test.go @@ -0,0 +1,18 @@ +package mgid + +import ( + "github.com/stretchr/testify/assert" + "testing" + "text/template" +) + +func TestMgidSyncer(t *testing.T) { + temp := template.Must(template.New("sync-template").Parse("https://cm.mgid.com/m?cdsp=363893&adu=https%3A//external.com%2Fsetuid%3Fbidder%3Dmgid%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7Bmuidn%7D")) + syncer := NewMgidSyncer(temp) + syncInfo, err := syncer.GetUsersyncInfo("0", "") + assert.NoError(t, err) + assert.Equal(t, "https://cm.mgid.com/m?cdsp=363893&adu=https%3A//external.com%2Fsetuid%3Fbidder%3Dmgid%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%7Bmuidn%7D", syncInfo.URL) + assert.Equal(t, "redirect", syncInfo.Type) + assert.EqualValues(t, 358, syncer.GDPRVendorID()) + assert.Equal(t, false, syncInfo.SupportCORS) +} diff --git a/config/config.go b/config/config.go index dc50c8a062c..d81db5d84de 100644 --- a/config/config.go +++ b/config/config.go @@ -435,6 +435,7 @@ func (cfg *Configuration) setDerivedDefaults() { setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderSonobi, "https://sync.go.sonobi.com/us.gif?loc="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dsonobi%26consent_string%3D{{.GDPR}}%26gdpr%3D{{.GDPRConsent}}%26uid%3D%5BUID%5D") setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderYieldmo, "https://ads.yieldmo.com/pbsync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirectUri="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dyieldmo%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID") setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderGamoshi, "https://rtb.gamoshi.io/pix/0000/scm?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&rurl="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dgamoshi%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5Bgusr%5D") + setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderMgid, "https://cm.mgid.com/m?cdsp=363893&adu="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dmgid%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7Bmuidn%7D") } @@ -590,6 +591,7 @@ func SetupViper(v *viper.Viper, filename string) { v.SetDefault("adapters.sonobi.endpoint", "https://apex.go.sonobi.com/prebid?partnerid=71d9d3d8af") v.SetDefault("adapters.yieldmo.endpoint", "http://ads.yieldmo.com/exchange/prebid-server") v.SetDefault("adapters.gamoshi.endpoint", "https://rtb.gamoshi.io") + v.SetDefault("adapters.mgid.endpoint", "https://prebid.mgid.com/prebid/") v.SetDefault("max_request_size", 1024*256) v.SetDefault("analytics.file.filename", "") diff --git a/exchange/adapter_map.go b/exchange/adapter_map.go index 61d3cf16b42..2e7efeb2b75 100644 --- a/exchange/adapter_map.go +++ b/exchange/adapter_map.go @@ -23,6 +23,7 @@ import ( "github.com/prebid/prebid-server/adapters/improvedigital" "github.com/prebid/prebid-server/adapters/ix" "github.com/prebid/prebid-server/adapters/lifestreet" + "github.com/prebid/prebid-server/adapters/mgid" "github.com/prebid/prebid-server/adapters/openx" "github.com/prebid/prebid-server/adapters/pubmatic" "github.com/prebid/prebid-server/adapters/pulsepoint" @@ -67,6 +68,7 @@ func newAdapterMap(client *http.Client, cfg *config.Configuration, infos adapter openrtb_ext.BidderSonobi: sonobi.NewSonobiBidder(client, cfg.Adapters[string(openrtb_ext.BidderSonobi)].Endpoint), openrtb_ext.BidderYieldmo: yieldmo.NewYieldmoBidder(cfg.Adapters[string(openrtb_ext.BidderYieldmo)].Endpoint), openrtb_ext.BidderGamoshi: gamoshi.NewGamoshiBidder(cfg.Adapters[string(openrtb_ext.BidderGamoshi)].Endpoint), + openrtb_ext.BidderMgid: mgid.NewMgidBidder(cfg.Adapters[string(openrtb_ext.BidderMgid)].Endpoint), openrtb_ext.BidderImprovedigital: improvedigital.NewImprovedigitalBidder(cfg.Adapters[string(openrtb_ext.BidderImprovedigital)].Endpoint), } diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 6f8bcffa7f7..69bd6e44110 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -37,6 +37,7 @@ const ( BidderImprovedigital BidderName = "improvedigital" BidderIx BidderName = "ix" BidderLifestreet BidderName = "lifestreet" + BidderMgid BidderName = "mgid" BidderOpenx BidderName = "openx" BidderPubmatic BidderName = "pubmatic" BidderPulsepoint BidderName = "pulsepoint" @@ -68,6 +69,7 @@ var BidderMap = map[string]BidderName{ "ix": BidderIx, "lifestreet": BidderLifestreet, "openx": BidderOpenx, + "mgid": BidderMgid, "pubmatic": BidderPubmatic, "pulsepoint": BidderPulsepoint, "rhythmone": BidderRhythmone, diff --git a/openrtb_ext/imp_mgid.go b/openrtb_ext/imp_mgid.go new file mode 100644 index 00000000000..3cf4530e1de --- /dev/null +++ b/openrtb_ext/imp_mgid.go @@ -0,0 +1,11 @@ +package openrtb_ext + +// ExtImpMgid defines the contract for bidrequest.imp[i].ext.mgid +type ExtImpMgid struct { + AccountId string `json:"accountId"` + PlacementId string `json:"placementId"` + Cur string `json:"cur"` + Currency string `json:"currency"` + BidFloor float64 `json:"bidfloor"` + BidFloor2 float64 `json:"bidFloor"` +} diff --git a/static/bidder-info/mgid.yaml b/static/bidder-info/mgid.yaml new file mode 100644 index 00000000000..f8ba6db60b1 --- /dev/null +++ b/static/bidder-info/mgid.yaml @@ -0,0 +1,11 @@ +maintainer: + email: "prebid@mgid.com" +capabilities: + app: + mediaTypes: + - banner + - native + site: + mediaTypes: + - banner + - native diff --git a/static/bidder-params/mgid.json b/static/bidder-params/mgid.json new file mode 100644 index 00000000000..45f6df83b5d --- /dev/null +++ b/static/bidder-params/mgid.json @@ -0,0 +1,34 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Mgid Adapter Params", + "description": "A schema which validates params accepted by the Mgid adapter", + + "type": "object", + "properties": { + "accountId": { + "type": "string", + "description": "Internal Mgid account ID" + }, + "placementId": { + "type": "string", + "description": "Internal Mgid Placement ID" + }, + "cur": { + "type": "string", + "description": "optional bidfloor currency" + }, + "currency": { + "type": "string", + "description": "optional bidfloor currency" + }, + "bidfloor": { + "type": "number", + "description": "optional minimum acceptable bid, in CPM, USD by default" + }, + "bidFloor": { + "type": "number", + "description": "optional minimum acceptable bid, in CPM, USD by default" + } + }, + "required": ["accountId","placementId"] +} diff --git a/usersync/usersyncers/syncer.go b/usersync/usersyncers/syncer.go index a0a69e7fb7e..e2dee24f6c0 100644 --- a/usersync/usersyncers/syncer.go +++ b/usersync/usersyncers/syncer.go @@ -22,6 +22,7 @@ import ( "github.com/prebid/prebid-server/adapters/improvedigital" "github.com/prebid/prebid-server/adapters/ix" "github.com/prebid/prebid-server/adapters/lifestreet" + "github.com/prebid/prebid-server/adapters/mgid" "github.com/prebid/prebid-server/adapters/openx" "github.com/prebid/prebid-server/adapters/pubmatic" "github.com/prebid/prebid-server/adapters/pulsepoint" @@ -68,6 +69,7 @@ func NewSyncerMap(cfg *config.Configuration) map[openrtb_ext.BidderName]usersync insertIntoMap(cfg, syncers, openrtb_ext.BidderSonobi, sonobi.NewSonobiSyncer) insertIntoMap(cfg, syncers, openrtb_ext.BidderYieldmo, yieldmo.NewYieldmoSyncer) insertIntoMap(cfg, syncers, openrtb_ext.BidderGamoshi, gamoshi.NewGamoshiSyncer) + insertIntoMap(cfg, syncers, openrtb_ext.BidderMgid, mgid.NewMgidSyncer) return syncers } diff --git a/usersync/usersyncers/syncer_test.go b/usersync/usersyncers/syncer_test.go index bb42b8622ac..c754839365e 100644 --- a/usersync/usersyncers/syncer_test.go +++ b/usersync/usersyncers/syncer_test.go @@ -29,6 +29,7 @@ func TestNewSyncerMap(t *testing.T) { string(openrtb_ext.BidderImprovedigital): syncConfig, string(openrtb_ext.BidderIx): syncConfig, string(openrtb_ext.BidderLifestreet): syncConfig, + string(openrtb_ext.BidderMgid): syncConfig, string(openrtb_ext.BidderOpenx): syncConfig, string(openrtb_ext.BidderPubmatic): syncConfig, string(openrtb_ext.BidderPulsepoint): syncConfig,