Skip to content
This repository has been archived by the owner on Dec 22, 2022. It is now read-only.

Commit

Permalink
nanointeractive adapter (prebid#1213)
Browse files Browse the repository at this point in the history
* nanointeractive adapter

* nanointeractive adapter, changes after review

* nanointeractive adapter

* nanointeractive adapter, changes after review

* formatting
  • Loading branch information
rade-popovic authored Apr 2, 2020
1 parent 1871929 commit d655d80
Show file tree
Hide file tree
Showing 21 changed files with 940 additions and 15 deletions.
172 changes: 172 additions & 0 deletions adapters/nanointeractive/nanointeractive.go
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,
}
}
10 changes: 10 additions & 0 deletions adapters/nanointeractive/nanointeractive_test.go
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"))
}
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"
}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"pid": "58bfec94eb0a1916fa380163"
}
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"
}
]
}
Loading

0 comments on commit d655d80

Please sign in to comment.