This repository has been archived by the owner on Dec 22, 2022. It is now read-only.
forked from prebid/prebid-server
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
nanointeractive adapter (prebid#1213)
* nanointeractive adapter * nanointeractive adapter, changes after review * nanointeractive adapter * nanointeractive adapter, changes after review * formatting
- Loading branch information
1 parent
98b7150
commit 1dccdd7
Showing
21 changed files
with
940 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
package nanointeractive | ||
|
||
import ( | ||
"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 NanoInteractiveAdapter struct { | ||
endpoint string | ||
} | ||
|
||
func (a *NanoInteractiveAdapter) Name() string { | ||
return "Nano" | ||
} | ||
|
||
func (a *NanoInteractiveAdapter) SkipNoCookies() bool { | ||
return false | ||
} | ||
|
||
func (a *NanoInteractiveAdapter) MakeRequests(bidRequest *openrtb.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { | ||
|
||
var errs []error | ||
var validImps []openrtb.Imp | ||
|
||
var adapterRequests []*adapters.RequestData | ||
var referer string = "" | ||
|
||
for i := 0; i < len(bidRequest.Imp); i++ { | ||
|
||
ref, err := checkImp(&bidRequest.Imp[i]) | ||
|
||
// If the parsing is failed, remove imp and add the error. | ||
if err != nil { | ||
errs = append(errs, err) | ||
continue | ||
} | ||
if referer == "" && ref != "" { | ||
referer = ref | ||
} | ||
validImps = append(validImps, bidRequest.Imp[i]) | ||
} | ||
|
||
if len(validImps) == 0 { | ||
errs = append(errs, fmt.Errorf("no impressions in the bid request")) | ||
return nil, errs | ||
} | ||
|
||
// set referer origin | ||
if referer != "" { | ||
if bidRequest.Site == nil { | ||
bidRequest.Site = &openrtb.Site{} | ||
} | ||
bidRequest.Site.Ref = referer | ||
} | ||
|
||
bidRequest.Imp = validImps | ||
|
||
reqJSON, err := json.Marshal(bidRequest) | ||
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") | ||
headers.Add("x-openrtb-version", "2.5") | ||
if bidRequest.Device != nil { | ||
headers.Add("User-Agent", bidRequest.Device.UA) | ||
headers.Add("X-Forwarded-For", bidRequest.Device.IP) | ||
} | ||
if bidRequest.Site != nil { | ||
headers.Add("Referer", bidRequest.Site.Page) | ||
} | ||
|
||
// set user's cookie | ||
if bidRequest.User != nil && bidRequest.User.BuyerUID != "" { | ||
headers.Add("Cookie", "Nano="+bidRequest.User.BuyerUID) | ||
} | ||
|
||
adapterRequests = append(adapterRequests, &adapters.RequestData{ | ||
Method: "POST", | ||
Uri: a.endpoint, | ||
Body: reqJSON, | ||
Headers: headers, | ||
}) | ||
|
||
return adapterRequests, errs | ||
} | ||
|
||
func (a *NanoInteractiveAdapter) MakeBids( | ||
internalRequest *openrtb.BidRequest, | ||
externalRequest *adapters.RequestData, | ||
response *adapters.ResponseData) (*adapters.BidderResponse, []error) { | ||
|
||
if response.StatusCode == http.StatusNoContent { | ||
return nil, nil | ||
} else if response.StatusCode == http.StatusBadRequest { | ||
return nil, []error{adapters.BadInput("Invalid request.")} | ||
} else if response.StatusCode != http.StatusOK { | ||
return nil, []error{&errortypes.BadServerResponse{ | ||
Message: fmt.Sprintf("unexpected HTTP status %d.", response.StatusCode), | ||
}} | ||
} | ||
|
||
var openRtbBidResponse openrtb.BidResponse | ||
|
||
if err := json.Unmarshal(response.Body, &openRtbBidResponse); err != nil { | ||
return nil, []error{&errortypes.BadServerResponse{ | ||
Message: fmt.Sprintf("bad server body response"), | ||
}} | ||
} | ||
|
||
bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(openRtbBidResponse.SeatBid[0].Bid)) | ||
bidResponse.Currency = openRtbBidResponse.Cur | ||
|
||
sb := openRtbBidResponse.SeatBid[0] | ||
for i := 0; i < len(sb.Bid); i++ { | ||
if !(sb.Bid[i].Price > 0) { | ||
continue | ||
} | ||
bid := sb.Bid[i] | ||
bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ | ||
Bid: &bid, | ||
BidType: openrtb_ext.BidTypeBanner, | ||
}) | ||
} | ||
return bidResponse, nil | ||
} | ||
|
||
func checkImp(imp *openrtb.Imp) (string, error) { | ||
// We support only banner impression | ||
if imp.Banner == nil { | ||
return "", fmt.Errorf("invalid MediaType. NanoInteractive only supports Banner type. ImpID=%s", imp.ID) | ||
} | ||
|
||
var bidderExt adapters.ExtImpBidder | ||
if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { | ||
return "", fmt.Errorf("ext not provided; ImpID=%s", imp.ID) | ||
} | ||
|
||
var nanoExt openrtb_ext.ExtImpNanoInteractive | ||
if err := json.Unmarshal(bidderExt.Bidder, &nanoExt); err != nil { | ||
return "", fmt.Errorf("ext.bidder not provided; ImpID=%s", imp.ID) | ||
} | ||
if nanoExt.Pid == "" { | ||
return "", fmt.Errorf("pid is empty; ImpID=%s", imp.ID) | ||
} | ||
|
||
if nanoExt.Ref != "" { | ||
return string(nanoExt.Ref), nil | ||
} | ||
|
||
return "", nil | ||
} | ||
|
||
func NewNanoIneractiveBidder(endpoint string) *NanoInteractiveAdapter { | ||
return &NanoInteractiveAdapter{ | ||
endpoint: endpoint, | ||
} | ||
} | ||
|
||
func NewNanoInteractiveAdapter(uri string) *NanoInteractiveAdapter { | ||
return &NanoInteractiveAdapter{ | ||
endpoint: uri, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package nanointeractive | ||
|
||
import ( | ||
"github.com/prebid/prebid-server/adapters/adapterstest" | ||
"testing" | ||
) | ||
|
||
func TestJsonSamples(t *testing.T) { | ||
adapterstest.RunJSONBidderTest(t, "nanointeractivetest", NewNanoIneractiveBidder("https://ad.audiencemanager.de/hbs")) | ||
} |
90 changes: 90 additions & 0 deletions
90
adapters/nanointeractive/nanointeractivetest/exemplary/simple-banner.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
{ | ||
"mockBidRequest": { | ||
"id": "test-request-id", | ||
"imp": [ | ||
{ | ||
"id": "test-imp-id", | ||
"banner": { | ||
"format": [{"w": 300, "h": 250}] | ||
}, | ||
"ext": { | ||
"bidder": { | ||
"pid": "58bfec94eb0a1916fa380163" | ||
} | ||
} | ||
} | ||
] | ||
}, | ||
|
||
"httpCalls": [ | ||
{ | ||
"expectedRequest": { | ||
"uri": "https://ad.audiencemanager.de/hbs", | ||
"body": { | ||
"id": "test-request-id", | ||
"imp": [ | ||
{ | ||
"id": "test-imp-id", | ||
"banner": { | ||
"format": [{ "w": 300,"h": 250} | ||
] | ||
}, | ||
"ext": { | ||
"bidder": { | ||
"pid": "58bfec94eb0a1916fa380163" | ||
} | ||
} | ||
} | ||
] | ||
} | ||
}, | ||
"mockResponse": { | ||
"status": 200, | ||
"body": { | ||
"id": "test-request-id", | ||
"seatbid": [ | ||
{ | ||
"seat": "nanointeractive", | ||
"bid": [{ | ||
"id": "1", | ||
"impid": "test-imp-id", | ||
"price": 0.4580126, | ||
"adm": "<a href=\"https://www.nanointeractive.com\" target=\"_blank\"><img width=\"300\" height=\"250\" src=\"https://cdn.audiencemanager.de/images/d941c4456b1bc2320db0a15334f86527.png\"/></a>", | ||
"adid": "test_ad_id", | ||
"adomain": ["audiencemanager.de"], | ||
"cid": "test_cid", | ||
"crid": "test_banner_crid", | ||
"h": 250, | ||
"w": 300 | ||
}] | ||
} | ||
], | ||
"bidid": "5a7789eg2662b524d8d7264a96", | ||
"cur": "EUR" | ||
} | ||
} | ||
} | ||
], | ||
|
||
"expectedBids": [ | ||
{ | ||
"bid": { | ||
"id": "1", | ||
"impid": "test-imp-id", | ||
"price": 0.4580126, | ||
"adm": "<a href=\"https://www.nanointeractive.com\" target=\"_blank\"><img width=\"300\" height=\"250\" src=\"https://cdn.audiencemanager.de/images/d941c4456b1bc2320db0a15334f86527.png\"/></a>", | ||
"adid": "test_ad_id", | ||
"adomain": ["yahoo.com"], | ||
"cid": "test_cid", | ||
"crid": "test_banner_crid", | ||
"h": 250, | ||
"w": 300 | ||
}, | ||
"ext": { | ||
"prebid": { | ||
"type": "banner" | ||
} | ||
} | ||
} | ||
] | ||
} |
3 changes: 3 additions & 0 deletions
3
adapters/nanointeractive/nanointeractivetest/params/race/banner.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"pid": "58bfec94eb0a1916fa380163" | ||
} |
63 changes: 63 additions & 0 deletions
63
adapters/nanointeractive/nanointeractivetest/supplemental/bad_response.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
{ | ||
"mockBidRequest": { | ||
"id": "test-request-id", | ||
"imp": [ | ||
{ | ||
"id": "test-imp-id", | ||
"banner": { | ||
"format": [ | ||
{ | ||
"w": 300, | ||
"h": 250 | ||
} | ||
] | ||
}, | ||
"ext": { | ||
"bidder": { | ||
"pid": "213" | ||
} | ||
} | ||
} | ||
] | ||
}, | ||
|
||
"httpCalls": [ | ||
{ | ||
"expectedRequest": { | ||
"uri": "https://ad.audiencemanager.de/hbs", | ||
"body": { | ||
"id": "test-request-id", | ||
"imp": [ | ||
{ | ||
"id": "test-imp-id", | ||
"banner": { | ||
"format": [ | ||
{ | ||
"w": 300, | ||
"h": 250 | ||
} | ||
] | ||
}, | ||
"ext": { | ||
"bidder": { | ||
"pid": "213" | ||
} | ||
} | ||
} | ||
] | ||
} | ||
}, | ||
"mockResponse": { | ||
"status": 200, | ||
"body": "{\"id\"data.lost" | ||
} | ||
} | ||
], | ||
|
||
"expectedMakeBidsErrors": [ | ||
{ | ||
"value": "bad server body response", | ||
"comparison": "literal" | ||
} | ||
] | ||
} |
Oops, something went wrong.