Skip to content

Commit

Permalink
Adds Avocet adapter (#1354)
Browse files Browse the repository at this point in the history
  • Loading branch information
scritchley authored Jun 18, 2020
1 parent d1c8129 commit 6eed873
Show file tree
Hide file tree
Showing 15 changed files with 738 additions and 0 deletions.
124 changes: 124 additions & 0 deletions adapters/avocet/avocet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package avocet

import (
"encoding/json"
"fmt"
"net/http"

"github.com/mxmCherry/openrtb"
"github.com/prebid/prebid-server/adapters"
"github.com/prebid/prebid-server/errortypes"
"github.com/prebid/prebid-server/openrtb_ext"
)

// AvocetAdapter implements a adapters.Bidder compatible with the Avocet advertising platform.
type AvocetAdapter struct {
// Endpoint is a http endpoint to use when making requests to the Avocet advertising platform.
Endpoint string
}

func (a *AvocetAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
if len(request.Imp) == 0 {
return nil, nil
}

headers := http.Header{}
headers.Add("Content-Type", "application/json;charset=utf-8")
headers.Add("Accept", "application/json")
body, err := json.Marshal(request)
if err != nil {
return nil, []error{&errortypes.FailedToRequestBids{
Message: err.Error(),
}}
}
reqData := &adapters.RequestData{
Method: http.MethodPost,
Uri: a.Endpoint,
Body: body,
Headers: headers,
}
return []*adapters.RequestData{reqData}, nil
}

type avocetBidExt struct {
Avocet avocetBidExtension `json:"avocet"`
}

type avocetBidExtension struct {
Duration int `json:"duration"`
DealPriority int `json:"deal_priority"`
}

func (a *AvocetAdapter) MakeBids(internalRequest *openrtb.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {

if response.StatusCode == http.StatusNoContent {
return nil, nil
}

if response.StatusCode != http.StatusOK {
var errStr string
if len(response.Body) > 0 {
errStr = string(response.Body)
} else {
errStr = "no response body"
}
return nil, []error{&errortypes.BadServerResponse{
Message: fmt.Sprintf("received status code: %v error: %s", response.StatusCode, errStr),
}}
}

var br openrtb.BidResponse
err := json.Unmarshal(response.Body, &br)
if err != nil {
return nil, []error{&errortypes.BadServerResponse{
Message: err.Error(),
}}
}
var errs []error

bidResponse := adapters.NewBidderResponseWithBidsCapacity(5)
for i := range br.SeatBid {
for j := range br.SeatBid[i].Bid {
var ext avocetBidExt
if len(br.SeatBid[i].Bid[j].Ext) > 0 {
err := json.Unmarshal(br.SeatBid[i].Bid[j].Ext, &ext)
if err != nil {
errs = append(errs, err)
continue
}
}
tbid := &adapters.TypedBid{
Bid: &br.SeatBid[i].Bid[j],
DealPriority: ext.Avocet.DealPriority,
}
tbid.BidType = getBidType(br.SeatBid[i].Bid[j], ext)
if tbid.BidType == openrtb_ext.BidTypeVideo {
tbid.BidVideo = &openrtb_ext.ExtBidPrebidVideo{
Duration: ext.Avocet.Duration,
}
}
bidResponse.Bids = append(bidResponse.Bids, tbid)
}
}
return bidResponse, nil
}

// getBidType returns the openrtb_ext.BidType for the provided bid.
func getBidType(bid openrtb.Bid, ext avocetBidExt) openrtb_ext.BidType {
if ext.Avocet.Duration != 0 {
return openrtb_ext.BidTypeVideo
}
switch bid.API {
case openrtb.APIFrameworkVPAID10, openrtb.APIFrameworkVPAID20:
return openrtb_ext.BidTypeVideo
default:
return openrtb_ext.BidTypeBanner
}
}

// NewAvocetAdapter returns a new AvocetAdapter using the provided endpoint.
func NewAvocetAdapter(endpoint string) *AvocetAdapter {
return &AvocetAdapter{
Endpoint: endpoint,
}
}
106 changes: 106 additions & 0 deletions adapters/avocet/avocet/exemplary/banner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
{
"mockBidRequest": {
"id": "test-request-id",
"imp": [
{
"id": "test-imp-id",
"banner": {
"format": [
{
"w": 300,
"h": 250
},
{
"w": 300,
"h": 600
}
]
},
"ext": {
"bidder": {
"placement": "5ea9601ac865f911007f1b6a"
}
}
}
]
},

"httpCalls": [
{
"expectedRequest": {
"uri": "https://bid.staging.avct.cloud/ortb/bid/5e722ee9bd6df11d063a8013",
"body": {
"id": "test-request-id",
"imp": [
{
"id": "test-imp-id",
"banner": {
"format": [
{
"w": 300,
"h": 250
},
{
"w": 300,
"h": 600
}
]
},
"ext": {
"bidder": {
"placement": "5ea9601ac865f911007f1b6a"
}
}
}
]
}
},
"mockResponse": {
"status": 200,
"body": {
"bidid": "dd87f80c-16a0-43c8-a673-b94b3ea4d417",
"id": "test-request-id",
"seatbid": [
{
"bid": [
{
"adm": "<iframe src=\"http://ads.staging.avct.cloud/sv?pp=${AUCTION_PRICE}&uuid=0df2c449-6d85-4179-b5d5-37f2f91caa24&ty=h&crid=5b51e49634f2021f127ff7c9&tacid=5b51e4ed89654741306813a8&aid=749d36d7-c993-455f-aefd-ffd8a7e3ccf_0&accid=5b51dd1634f2021f127ff7c0&brid=5b51e20f34f2021f127ff7c4&ioid=5b51e22089654741306813a1&caid=5b51e2d689654741306813a4&it=1&iobsid=496e8cff35b2c0110029534d&ext_aid=749d36d7-c993-455f-aefd-ffd8a7e3ccf_0&bp=15.64434783&bt=1591874537316649768&h=250&w=300&vpr=0&vdp=0&domain=example.com&gco=54510b3b816269000061a0f7&stid=542d2c1615e3c013de53a6e2&glat=0&glong=0&bip4=3232238090&ext_siid=5ea89200c865f911007f1b0e&ext_pid=1&ext_sid=5ea84df8c865f911007f1ade&ext_plid=5ea9601ac865f911007f1b6a&optv=latest:latest&invsrc=5e722ee9bd6df11d063a8013&ug=0d&ca=0&biid=requestd-54644474bf-l7gx4|eu-central-1-staging&reg=eu-central-1&ck=1_5d99a849\" height=\"250\" width=\"300\" marginwidth=0 marginheight=0 hspace=0 vspace=0 frameborder=0 scrolling=\"no\"></iframe>",
"adomain": ["avocet.io"],
"cid": "5b51e2d689654741306813a4",
"crid": "5b51e49634f2021f127ff7c9",
"h": 250,
"id": "bc708396-9202-437b-b726-08b9864cb8b8",
"impid": "test-imp-id",
"iurl": "https://cdn.staging.avocet.io/snapshots/5b51dd1634f2021f127ff7c0/5b51e49634f2021f127ff7c9.jpeg",
"language": "en",
"price": 15.64434783,
"w": 300
}
],
"seat": "TEST_SEAT_ID"
}
]
}
}
}
],

"expectedBids": [
{
"bid": {
"adm": "<iframe src=\"http://ads.staging.avct.cloud/sv?pp=${AUCTION_PRICE}&uuid=0df2c449-6d85-4179-b5d5-37f2f91caa24&ty=h&crid=5b51e49634f2021f127ff7c9&tacid=5b51e4ed89654741306813a8&aid=749d36d7-c993-455f-aefd-ffd8a7e3ccf_0&accid=5b51dd1634f2021f127ff7c0&brid=5b51e20f34f2021f127ff7c4&ioid=5b51e22089654741306813a1&caid=5b51e2d689654741306813a4&it=1&iobsid=496e8cff35b2c0110029534d&ext_aid=749d36d7-c993-455f-aefd-ffd8a7e3ccf_0&bp=15.64434783&bt=1591874537316649768&h=250&w=300&vpr=0&vdp=0&domain=example.com&gco=54510b3b816269000061a0f7&stid=542d2c1615e3c013de53a6e2&glat=0&glong=0&bip4=3232238090&ext_siid=5ea89200c865f911007f1b0e&ext_pid=1&ext_sid=5ea84df8c865f911007f1ade&ext_plid=5ea9601ac865f911007f1b6a&optv=latest:latest&invsrc=5e722ee9bd6df11d063a8013&ug=0d&ca=0&biid=requestd-54644474bf-l7gx4|eu-central-1-staging&reg=eu-central-1&ck=1_5d99a849\" height=\"250\" width=\"300\" marginwidth=0 marginheight=0 hspace=0 vspace=0 frameborder=0 scrolling=\"no\"></iframe>",
"adomain": ["avocet.io"],
"cid": "5b51e2d689654741306813a4",
"crid": "5b51e49634f2021f127ff7c9",
"h": 250,
"id": "bc708396-9202-437b-b726-08b9864cb8b8",
"impid": "test-imp-id",
"iurl": "https://cdn.staging.avocet.io/snapshots/5b51dd1634f2021f127ff7c0/5b51e49634f2021f127ff7c9.jpeg",
"language": "en",
"price": 15.64434783,
"w": 300
},
"type": "banner"
}
]
}
104 changes: 104 additions & 0 deletions adapters/avocet/avocet/exemplary/video.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
{
"mockBidRequest": {
"id": "test-request-id",
"imp": [
{
"id": "test-imp-id",
"video": {
"mimes": ["video/mp4"],
"protocols": [2, 5],
"w": 1920,
"h": 1080
},
"ext": {
"bidder": {
"placement": "5ea9601ac865f911007f1b6a"
}
}
}
]
},

"httpCalls": [
{
"expectedRequest": {
"uri": "https://bid.staging.avct.cloud/ortb/bid/5e722ee9bd6df11d063a8013",
"body": {
"id": "test-request-id",
"imp": [
{
"id": "test-imp-id",
"video": {
"mimes": ["video/mp4"],
"protocols": [2, 5],
"w": 1920,
"h": 1080
},
"ext": {
"bidder": {
"placement": "5ea9601ac865f911007f1b6a"
}
}
}
]
}
},
"mockResponse": {
"status": 200,
"body": {
"bidid": "a0eec3aa-f9f6-42fb-9aa4-f1b5656d4f42",
"id": "749d36d7-c993-455f-aefd-ffd8a7e3ccf",
"seatbid": [
{
"bid": [
{
"adm": "<VAST version=\"3.0\"><Ad id=\"5ec530e32d57fe1100f17d87\"><Wrapper><AdSystem>Avocet</AdSystem><VASTAdTagURI><![CDATA[http://ads.staging.avct.cloud/vast?x=1&uuid=0df2c449-6d85-4179-b5d5-37f2f91caa24&ty=h&crid=5ec530e32d57fe1100f17d87&tacid=5ec531d32d57fe1100f17d89&aid=749d36d7-c993-455f-aefd-ffd8a7e3ccf_0&accid=5b51dd1634f2021f127ff7c0&brid=5b51e20f34f2021f127ff7c4&ioid=5b51e22089654741306813a1&caid=5b51e2d689654741306813a4&it=2&iobsid=496e8cff35b2c0110029534d&ext_aid=749d36d7-c993-455f-aefd-ffd8a7e3ccf_0&bp=15.64434783&bt=1591875033134290518&h=396&w=600&vpr=0&vdp=0&domain=example.com&gco=54510b3b816269000061a0f7&stid=542d2c1615e3c013de53a6e2&glat=0&glong=0&bip4=3232238090&ext_siid=5ea89200c865f911007f1b0e&ext_pid=1&ext_sid=5ea84df8c865f911007f1ade&ext_plid=5ea9601ac865f911007f1b6a&optv=latest:latest&invsrc=5e722ee9bd6df11d063a8013&ug=0d&ca=0&biid=requestd-54644474bf-l7gx4|eu-central-1-staging&reg=eu-central-1&pixel=1&ck=1_c343bf14]]></VASTAdTagURI><Impression><![CDATA[http://ads.staging.avct.cloud/sv?pp=${AUCTION_PRICE}&uuid=0df2c449-6d85-4179-b5d5-37f2f91caa24&ty=h&crid=5ec530e32d57fe1100f17d87&tacid=5ec531d32d57fe1100f17d89&aid=749d36d7-c993-455f-aefd-ffd8a7e3ccf_0&accid=5b51dd1634f2021f127ff7c0&brid=5b51e20f34f2021f127ff7c4&ioid=5b51e22089654741306813a1&caid=5b51e2d689654741306813a4&it=2&iobsid=496e8cff35b2c0110029534d&ext_aid=749d36d7-c993-455f-aefd-ffd8a7e3ccf_0&bp=15.64434783&bt=1591875033134290518&h=396&w=600&vpr=0&vdp=0&domain=example.com&gco=54510b3b816269000061a0f7&stid=542d2c1615e3c013de53a6e2&glat=0&glong=0&bip4=3232238090&ext_siid=5ea89200c865f911007f1b0e&ext_pid=1&ext_sid=5ea84df8c865f911007f1ade&ext_plid=5ea9601ac865f911007f1b6a&optv=latest:latest&invsrc=5e722ee9bd6df11d063a8013&ug=0d&ca=0&biid=requestd-54644474bf-l7gx4|eu-central-1-staging&reg=eu-central-1&pixel=1&ck=1_c343bf14]]></Impression><Creatives><Creative AdId=\"5ec530e32d57fe1100f17d87\"><Linear><TrackingEvents></TrackingEvents><VideoClicks></VideoClicks></Linear></Creative></Creatives></Wrapper></Ad></VAST>",
"adomain": ["avocet.io"],
"cid": "5b51e2d689654741306813a4",
"crid": "5ec530e32d57fe1100f17d87",
"h": 396,
"id": "3d4c2d45-5a8c-43b8-9e15-4f48ac45204f",
"impid": "dfp-ad--top-above-nav",
"iurl": "https://cdn.staging.avocet.io/snapshots/5b51dd1634f2021f127ff7c0/5ec530e32d57fe1100f17d87.jpeg",
"language": "en",
"price": 15.64434783,
"w": 600,
"ext": {
"avocet": {
"duration": 30
}
}
}
],
"seat": "TEST_SEAT_ID"
}
]
}
}
}
],

"expectedBids": [
{
"bid": {
"adm": "<VAST version=\"3.0\"><Ad id=\"5ec530e32d57fe1100f17d87\"><Wrapper><AdSystem>Avocet</AdSystem><VASTAdTagURI><![CDATA[http://ads.staging.avct.cloud/vast?x=1&uuid=0df2c449-6d85-4179-b5d5-37f2f91caa24&ty=h&crid=5ec530e32d57fe1100f17d87&tacid=5ec531d32d57fe1100f17d89&aid=749d36d7-c993-455f-aefd-ffd8a7e3ccf_0&accid=5b51dd1634f2021f127ff7c0&brid=5b51e20f34f2021f127ff7c4&ioid=5b51e22089654741306813a1&caid=5b51e2d689654741306813a4&it=2&iobsid=496e8cff35b2c0110029534d&ext_aid=749d36d7-c993-455f-aefd-ffd8a7e3ccf_0&bp=15.64434783&bt=1591875033134290518&h=396&w=600&vpr=0&vdp=0&domain=example.com&gco=54510b3b816269000061a0f7&stid=542d2c1615e3c013de53a6e2&glat=0&glong=0&bip4=3232238090&ext_siid=5ea89200c865f911007f1b0e&ext_pid=1&ext_sid=5ea84df8c865f911007f1ade&ext_plid=5ea9601ac865f911007f1b6a&optv=latest:latest&invsrc=5e722ee9bd6df11d063a8013&ug=0d&ca=0&biid=requestd-54644474bf-l7gx4|eu-central-1-staging&reg=eu-central-1&pixel=1&ck=1_c343bf14]]></VASTAdTagURI><Impression><![CDATA[http://ads.staging.avct.cloud/sv?pp=${AUCTION_PRICE}&uuid=0df2c449-6d85-4179-b5d5-37f2f91caa24&ty=h&crid=5ec530e32d57fe1100f17d87&tacid=5ec531d32d57fe1100f17d89&aid=749d36d7-c993-455f-aefd-ffd8a7e3ccf_0&accid=5b51dd1634f2021f127ff7c0&brid=5b51e20f34f2021f127ff7c4&ioid=5b51e22089654741306813a1&caid=5b51e2d689654741306813a4&it=2&iobsid=496e8cff35b2c0110029534d&ext_aid=749d36d7-c993-455f-aefd-ffd8a7e3ccf_0&bp=15.64434783&bt=1591875033134290518&h=396&w=600&vpr=0&vdp=0&domain=example.com&gco=54510b3b816269000061a0f7&stid=542d2c1615e3c013de53a6e2&glat=0&glong=0&bip4=3232238090&ext_siid=5ea89200c865f911007f1b0e&ext_pid=1&ext_sid=5ea84df8c865f911007f1ade&ext_plid=5ea9601ac865f911007f1b6a&optv=latest:latest&invsrc=5e722ee9bd6df11d063a8013&ug=0d&ca=0&biid=requestd-54644474bf-l7gx4|eu-central-1-staging&reg=eu-central-1&pixel=1&ck=1_c343bf14]]></Impression><Creatives><Creative AdId=\"5ec530e32d57fe1100f17d87\"><Linear><TrackingEvents></TrackingEvents><VideoClicks></VideoClicks></Linear></Creative></Creatives></Wrapper></Ad></VAST>",
"adomain": ["avocet.io"],
"cid": "5b51e2d689654741306813a4",
"crid": "5ec530e32d57fe1100f17d87",
"h": 396,
"id": "3d4c2d45-5a8c-43b8-9e15-4f48ac45204f",
"impid": "dfp-ad--top-above-nav",
"iurl": "https://cdn.staging.avocet.io/snapshots/5b51dd1634f2021f127ff7c0/5ec530e32d57fe1100f17d87.jpeg",
"language": "en",
"price": 15.64434783,
"w": 600,
"ext": {
"avocet": {
"duration": 30
}
}
},
"type": "video"
}
]
}
Loading

0 comments on commit 6eed873

Please sign in to comment.