-
Notifications
You must be signed in to change notification settings - Fork 769
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New Adapter: FeedAd #4104
New Adapter: FeedAd #4104
Changes from all commits
0b0bf7b
67f84c8
29a94e9
842aee5
56414de
8a62f12
f41630f
3c9cd9e
8e1dcfe
4092931
acb6af1
770ffd8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package feedad | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/prebid/openrtb/v20/openrtb2" | ||
"github.com/prebid/prebid-server/v3/adapters" | ||
"github.com/prebid/prebid-server/v3/config" | ||
"github.com/prebid/prebid-server/v3/openrtb_ext" | ||
"github.com/prebid/prebid-server/v3/util/jsonutil" | ||
) | ||
|
||
const feedAdAdapterVersion = "1.0.0" | ||
|
||
func getHeaders(request *openrtb2.BidRequest) http.Header { | ||
headers := http.Header{} | ||
headers.Add("Accept", "application/json") | ||
headers.Add("Content-Type", "application/json;charset=utf-8") | ||
headers.Add("X-FA-PBS-Adapter-Version", feedAdAdapterVersion) | ||
headers.Add("X-Openrtb-Version", "2.5") | ||
|
||
if request.Device != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please create a new There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ |
||
if len(request.Device.IPv6) > 0 { | ||
headers.Add("X-Forwarded-For", request.Device.IPv6) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please either modify your There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ |
||
} | ||
|
||
if len(request.Device.IP) > 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Under this logic, if a request comes with both
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For us, this doesn't really matter. Can this really happen that both fields are filled anyway? Anyway, I don't see a real issue here to be honest. |
||
headers.Add("X-Forwarded-For", request.Device.IP) | ||
} | ||
} | ||
|
||
return headers | ||
} | ||
|
||
type adapter struct { | ||
endpoint string | ||
} | ||
|
||
func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { | ||
if adapters.IsResponseStatusCodeNoContent(responseData) { | ||
return nil, nil | ||
} | ||
|
||
if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { | ||
return nil, []error{err} | ||
} | ||
|
||
var response openrtb2.BidResponse | ||
err := jsonutil.Unmarshal(responseData.Body, &response) | ||
if err != nil { | ||
return nil, []error{err} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a supplemental JSON test case where the response is malformed. This can be done by simply setting the mock response body to a string instead of a JSON object. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ |
||
} | ||
|
||
bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(internalRequest.Imp)) | ||
bidResponse.Currency = response.Cur | ||
|
||
for _, seatBid := range response.SeatBid { | ||
for i := range seatBid.Bid { | ||
bidResponse.Bids = append( | ||
bidResponse.Bids, | ||
&adapters.TypedBid{ | ||
Bid: &seatBid.Bid[i], | ||
BidType: openrtb_ext.BidTypeBanner, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we expect all of the bids to be banners? Is there a possibility now or in the future that we get Video, Native or Audio? If so, should we grab the type from the response instead of hard-coding the banner value?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, we only support banners right now. capabilities:
app:
mediaTypes:
- banner
site:
mediaTypes:
- banner |
||
}, | ||
) | ||
} | ||
} | ||
|
||
return bidResponse, nil | ||
} | ||
|
||
func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { | ||
requestBody, err := jsonutil.Marshal(request) | ||
if err != nil { | ||
return nil, []error{err} | ||
} | ||
|
||
requestData := &adapters.RequestData{ | ||
Method: http.MethodPost, | ||
Uri: a.endpoint, | ||
Body: requestBody, | ||
Headers: getHeaders(request), | ||
ImpIDs: openrtb_ext.GetImpIDs(request.Imp), | ||
} | ||
return []*adapters.RequestData{requestData}, nil | ||
} | ||
|
||
func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { | ||
bidder := &adapter{ | ||
endpoint: config.Endpoint, | ||
} | ||
return bidder, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package feedad | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/prebid/prebid-server/v3/adapters/adapterstest" | ||
"github.com/prebid/prebid-server/v3/config" | ||
"github.com/prebid/prebid-server/v3/openrtb_ext" | ||
) | ||
|
||
func TestJsonSamples(t *testing.T) { | ||
bidder, buildErr := Builder( | ||
openrtb_ext.BidderFeedAd, | ||
config.Adapter{ | ||
Endpoint: "https://example.com/1/prebid/requests", | ||
}, | ||
config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}, | ||
) | ||
|
||
if buildErr != nil { | ||
t.Fatalf("Builder returned unexpected error: %v", buildErr) | ||
} | ||
|
||
adapterstest.RunJSONBidderTest(t, "feedadtest", bidder) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
{ | ||
"mockBidRequest": { | ||
"id": "some-request-id", | ||
"device": { | ||
"ua": "test-user-agent", | ||
"ip": "123.123.123.123", | ||
"language": "en", | ||
"dnt": 0 | ||
}, | ||
"tmax": 1000, | ||
"user": { | ||
"buyeruid": "awesome-user" | ||
}, | ||
"app": { | ||
"publisher": { | ||
"id": "123456789" | ||
}, | ||
"cat": [ | ||
"IAB22-1" | ||
], | ||
"bundle": "com.app.awesome", | ||
"name": "Awesome App", | ||
"domain": "awesomeapp.com", | ||
"id": "123456789" | ||
}, | ||
"imp": [ | ||
{ | ||
"id": "1", | ||
"tagid": "ogTAGID", | ||
"banner": { | ||
"w": 320, | ||
"h": 50 | ||
}, | ||
"ext": { | ||
"bidder": { | ||
"clientToken": "some-client-token", | ||
"placementId": "some-placement-id" | ||
} | ||
} | ||
} | ||
] | ||
}, | ||
"httpCalls": [ | ||
{ | ||
"expectedRequest": { | ||
"headers": { | ||
"Accept": [ | ||
"application/json" | ||
], | ||
"Content-Type": [ | ||
"application/json;charset=utf-8" | ||
], | ||
"X-Fa-Pbs-Adapter-Version": [ | ||
"1.0.0" | ||
], | ||
"X-Forwarded-For": [ | ||
"123.123.123.123" | ||
], | ||
"X-Openrtb-Version": [ | ||
"2.5" | ||
] | ||
}, | ||
"uri": "https://example.com/1/prebid/requests", | ||
"body": { | ||
"id": "some-request-id", | ||
"device": { | ||
"ua": "test-user-agent", | ||
"ip": "123.123.123.123", | ||
"language": "en", | ||
"dnt": 0 | ||
}, | ||
"imp": [ | ||
{ | ||
"id": "1", | ||
"banner": { | ||
"w": 320, | ||
"h": 50 | ||
}, | ||
"ext": { | ||
"bidder": { | ||
"clientToken": "some-client-token", | ||
"placementId": "some-placement-id" | ||
} | ||
}, | ||
"tagid": "ogTAGID" | ||
} | ||
], | ||
"app": { | ||
"id": "123456789", | ||
"name": "Awesome App", | ||
"bundle": "com.app.awesome", | ||
"domain": "awesomeapp.com", | ||
"cat": [ | ||
"IAB22-1" | ||
], | ||
"publisher": { | ||
"id": "123456789" | ||
} | ||
}, | ||
"user": { | ||
"buyeruid": "awesome-user" | ||
}, | ||
"tmax": 1000 | ||
}, | ||
"impIDs": [ | ||
"1" | ||
] | ||
}, | ||
"mockResponse": { | ||
"status": 200, | ||
"body": { | ||
"id": "awesome-resp-id", | ||
"seatbid": [ | ||
{ | ||
"bid": [ | ||
{ | ||
"id": "a3ae1b4e2fc24a4fb45540082e98e161", | ||
"impid": "1", | ||
"price": 3.5, | ||
"adm": "awesome-markup", | ||
"adomain": [ | ||
"awesome.com" | ||
], | ||
"crid": "20", | ||
"w": 320, | ||
"h": 50, | ||
"mtype": 1 | ||
} | ||
], | ||
"type": "banner", | ||
"seat": "escalax" | ||
} | ||
], | ||
"cur": "USD" | ||
} | ||
} | ||
} | ||
], | ||
"expectedBidResponses": [ | ||
{ | ||
"bids": [ | ||
{ | ||
"bid": { | ||
"id": "a3ae1b4e2fc24a4fb45540082e98e161", | ||
"impid": "1", | ||
"price": 3.5, | ||
"adm": "awesome-markup", | ||
"adomain": [ | ||
"awesome.com" | ||
], | ||
"crid": "20", | ||
"w": 320, | ||
"h": 50, | ||
"mtype": 1 | ||
}, | ||
"type": "banner" | ||
} | ||
] | ||
} | ||
] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you able to support OpenRTB 2.6 instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m afraid, we don’t have support for oRTB 2.6, yet, but it’s on our roadmap for next year.
Can we please start with oRTB 2.5 for now?