Skip to content
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: zMaticoo #3349

Merged
merged 25 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
36eecb7
add zmaticoo prebid adapter 1.0
Dec 13, 2023
46927d7
add zmaticoo prebid adapter 1.0
Dec 13, 2023
bee679f
for Yeahmobi adapter add bidExt video duration
Dec 14, 2023
005bd14
add aliasOf for zMaticoo adapter
Dec 22, 2023
490db00
change the zmaticoo.yaml to zmaticoo_ssp.yaml
Dec 22, 2023
1423f1b
change the zmaticoo.yaml,zmaticoo is new adapter.
Dec 28, 2023
7961562
Merge branch 'prebid:master' into master
lxj15398019970 Dec 29, 2023
cbadd47
feat:change some code by reviewer commment
Dec 29, 2023
105a432
feat:change some code by reviewer commment
Dec 29, 2023
e8a5840
feat:change some code by reviewer commment
Dec 29, 2023
9288101
feat:change some code by reviewer commment
Dec 29, 2023
1be4737
feat:change test code
Dec 29, 2023
1a4f330
feat:remove yeahmobi code change
Jan 2, 2024
863126c
feat:adapters.NewBidderResponseWithBidsCapacity(len(internalRequest.I…
Jan 2, 2024
99bd586
feat:remove invalid code
Jan 4, 2024
ffc56c9
feat:remove invalid code
Jan 4, 2024
778ba7e
feat:remove about yeahmobi code
Jan 4, 2024
2faafd5
feat:change getZmaticooExt code
Jan 9, 2024
699a416
feat: add empty_imp_ext_bidder test json
Jan 10, 2024
5cbf496
feat: add empty_imp_ext_bidder test json
Jan 10, 2024
b002d76
feat: add empty_imp_ext_bidder test json
Jan 10, 2024
3448c3a
feat: add empty_imp_ext_bidder test json
Jan 11, 2024
2873dad
feat: add empty_imp_ext_bidder test json
Jan 11, 2024
d23bab2
feat: change code for transform function
Jan 17, 2024
adc564c
feat: rename function getZmaticooExt to validateZmaticooExt
Jan 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions adapters/yeahmobi/yeahmobi.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,16 +154,32 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest

bidResponse := adapters.NewBidderResponseWithBidsCapacity(1)

var errs []error
for _, sb := range bidResp.SeatBid {
for i := range sb.Bid {
var mediaType = getBidType(sb.Bid[i].ImpID, internalRequest.Imp)
bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
Bid: &sb.Bid[i],
BidType: mediaType,
})
bid := sb.Bid[i]
var mediaType = getBidType(bid.ImpID, internalRequest.Imp)
typedBid := &adapters.TypedBid{
Bid: &bid,
BidType: mediaType,
BidVideo: &openrtb_ext.ExtBidPrebidVideo{},
}
if bid.Ext != nil {
var bidExt *yeahmobiBidExt
err := json.Unmarshal(bid.Ext, &bidExt)
if err != nil {
errs = append(errs, err)
} else if bidExt != nil {
if bidExt.VideoCreativeInfo != nil && bidExt.VideoCreativeInfo.Duration != nil {
typedBid.BidVideo.Duration = *bidExt.VideoCreativeInfo.Duration
}
}
}

bidResponse.Bids = append(bidResponse.Bids, typedBid)
}
}
return bidResponse, nil
return bidResponse, errs

}

Expand All @@ -187,3 +203,10 @@ func getBidType(impId string, imps []openrtb2.Imp) openrtb_ext.BidType {
}
return bidType
}

lxj15398019970 marked this conversation as resolved.
Show resolved Hide resolved
type yeahmobiBidExt struct {
VideoCreativeInfo *yeahmobiBidExtVideo `json:"video,omitempty"`
}
type yeahmobiBidExtVideo struct {
Duration *int `json:"duration,omitempty"`
}
lxj15398019970 marked this conversation as resolved.
Show resolved Hide resolved
48 changes: 48 additions & 0 deletions adapters/zmaticoo/params_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package zmaticoo

import (
"encoding/json"
"testing"

"github.com/prebid/prebid-server/v2/openrtb_ext"
)

func TestValidParams(t *testing.T) {
validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
if err != nil {
t.Fatalf("Failed to fetch the json-schemas. %v", err)
}

for _, validParam := range validParams {
if err := validator.Validate(openrtb_ext.BidderZmaticoo, json.RawMessage(validParam)); err != nil {
t.Errorf("Schema rejected zmaticoo params: %s", validParam)
}
}
}

// TestInvalidParams makes sure that the zmaticoo schema rejects all the imp.ext fields we don't support.
func TestInvalidParams(t *testing.T) {
validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
if err != nil {
t.Fatalf("Failed to fetch the json-schemas. %v", err)
}

for _, invalidParam := range invalidParams {
if err := validator.Validate(openrtb_ext.BidderZmaticoo, json.RawMessage(invalidParam)); err == nil {
t.Errorf("Schema allowed unexpected params: %s", invalidParam)
}
}
}

var validParams = []string{
`{"pubId": "11233", "zoneId": "sin"}`,
`{"pubId": "11244", "zoneId": "iad"}`,
}

var invalidParams = []string{
`{"pubId": "11233"}`,
`{"zoneId": "aaa"}`,
`{"pubId": 123, "zoneId": "sin"}`,
`{"pubId": "", "zoneId": "iad"}`,
`{"pubId": "11233", "zoneId": ""}`,
}
189 changes: 189 additions & 0 deletions adapters/zmaticoo/zmaticoo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
package zmaticoo

import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"text/template"

"github.com/prebid/openrtb/v19/openrtb2"
"github.com/prebid/prebid-server/v2/adapters"
"github.com/prebid/prebid-server/v2/config"
"github.com/prebid/prebid-server/v2/errortypes"
"github.com/prebid/prebid-server/v2/macros"
"github.com/prebid/prebid-server/v2/openrtb_ext"
)

type adapter struct {
EndpointTemplate *template.Template
}

// Builder builds a new instance of the zmaticoo adapter for the given bidder with the given config.
func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
template, err := template.New("endpointTemplate").Parse(config.Endpoint)
if err != nil {
return nil, fmt.Errorf("unable to parse endpoint url template: %v", err)
}

bidder := &adapter{
EndpointTemplate: template,
lxj15398019970 marked this conversation as resolved.
Show resolved Hide resolved
}
return bidder, nil
}

func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
var adapterRequests []*adapters.RequestData

adapterRequest, errs := a.makeRequest(request)
if errs == nil {
adapterRequests = append(adapterRequests, adapterRequest)
}

return adapterRequests, errs
}

func (a *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, []error) {
var errs []error

zmaticooExt, errs := getZmaticooExt(request)

lxj15398019970 marked this conversation as resolved.
Show resolved Hide resolved
if zmaticooExt == nil {
return nil, errs
}
endPoint, err := a.getEndpoint(zmaticooExt)
if err != nil {
return nil, append(errs, err)
}
lxj15398019970 marked this conversation as resolved.
Show resolved Hide resolved
transform(request)
reqBody, err := json.Marshal(request)

lxj15398019970 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, append(errs, err)
}

headers := http.Header{}
headers.Add("Content-Type", "application/json;charset=utf-8")

return &adapters.RequestData{
Method: "POST",
Uri: endPoint,
Body: reqBody,
Headers: headers,
}, errs
}

func transform(request *openrtb2.BidRequest) {
for i, imp := range request.Imp {
if imp.Native != nil {
var nativeRequest map[string]interface{}
nativeCopyRequest := make(map[string]interface{})
err := json.Unmarshal([]byte(request.Imp[i].Native.Request), &nativeRequest)
//just ignore the bad native request
lxj15398019970 marked this conversation as resolved.
Show resolved Hide resolved
if err == nil {
_, exists := nativeRequest["native"]
if exists {
continue
}

nativeCopyRequest["native"] = nativeRequest
nativeReqByte, err := json.Marshal(nativeCopyRequest)
//just ignore the bad native request
lxj15398019970 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
continue
}

nativeCopy := *request.Imp[i].Native
nativeCopy.Request = string(nativeReqByte)
request.Imp[i].Native = &nativeCopy
}
}
}
}

func getZmaticooExt(request *openrtb2.BidRequest) (*openrtb_ext.ExtImpZmaticoo, []error) {
var extImpZmaticoo openrtb_ext.ExtImpZmaticoo
var errs []error

for _, imp := range request.Imp {
var extBidder adapters.ExtImpBidder
err := json.Unmarshal(imp.Ext, &extBidder)
if err != nil {
errs = append(errs, err)
continue
}
err = json.Unmarshal(extBidder.Bidder, &extImpZmaticoo)
if err != nil {
errs = append(errs, err)
continue
}
break
}

return &extImpZmaticoo, errs

}

func (a *adapter) getEndpoint(ext *openrtb_ext.ExtImpZmaticoo) (string, error) {
return macros.ResolveMacros(a.EndpointTemplate, macros.EndpointTemplateParams{Host: "gw-" + url.QueryEscape(ext.ZoneId) + "-bid.zmaticoo.com"})
}

// MakeBids make the bids for the bid response.
func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *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.", response.StatusCode),
}}
}

if response.StatusCode != http.StatusOK {
return nil, []error{&errortypes.BadServerResponse{
Message: fmt.Sprintf("Unexpected status code: %d.", response.StatusCode),
}}
}
lxj15398019970 marked this conversation as resolved.
Show resolved Hide resolved

var bidResp openrtb2.BidResponse

lxj15398019970 marked this conversation as resolved.
Show resolved Hide resolved
if err := json.Unmarshal(response.Body, &bidResp); err != nil {
return nil, []error{err}
}

bidResponse := adapters.NewBidderResponseWithBidsCapacity(1)
lxj15398019970 marked this conversation as resolved.
Show resolved Hide resolved

for _, sb := range bidResp.SeatBid {
for i := range sb.Bid {
var mediaType = getBidType(sb.Bid[i].ImpID, internalRequest.Imp)
bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
Bid: &sb.Bid[i],
BidType: mediaType,
})
}
}
return bidResponse, nil

}

func getBidType(impId string, imps []openrtb2.Imp) openrtb_ext.BidType {
bidType := openrtb_ext.BidTypeBanner
for _, imp := range imps {
if imp.ID == impId {
if imp.Banner != nil {
break
}
if imp.Video != nil {
bidType = openrtb_ext.BidTypeVideo
break
}
if imp.Native != nil {
bidType = openrtb_ext.BidTypeNative
break
}

}
}
lxj15398019970 marked this conversation as resolved.
Show resolved Hide resolved
return bidType
}
28 changes: 28 additions & 0 deletions adapters/zmaticoo/zmaticoo_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package zmaticoo

import (
"testing"

"github.com/prebid/prebid-server/v2/adapters/adapterstest"
"github.com/prebid/prebid-server/v2/config"
"github.com/prebid/prebid-server/v2/openrtb_ext"
"github.com/stretchr/testify/assert"
)

func TestJsonSamples(t *testing.T) {
bidder, buildErr := Builder(openrtb_ext.BidderZmaticoo, config.Adapter{
Endpoint: "https://{{.Host}}/prebid/bid"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})

if buildErr != nil {
t.Fatalf("Builder returned unexpected error %v", buildErr)
}

adapterstest.RunJSONBidderTest(t, "zmaticootest", bidder)
}

func TestEndpointTemplateMalformed(t *testing.T) {
_, buildErr := Builder(openrtb_ext.BidderZmaticoo, config.Adapter{
Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})

assert.Error(t, buildErr)
}
58 changes: 58 additions & 0 deletions adapters/zmaticoo/zmaticootest/exemplary/no-bid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"mockBidRequest": {
"id": "test-request-id",
"imp": [
{
"id": "test-imp-id",
"banner": {
"format": [
{
"w": 300,
"h": 50
}
]
},
"ext": {
"bidder": {
"pubId": "fake-pub-id",
"zoneId": "sin"
}
}
}
]
},
"httpCalls": [
{
"expectedRequest": {
"uri": "https://gw-sin-bid.zmaticoo.com/prebid/bid",
"body": {
"id": "test-request-id",
"imp": [
{
"id": "test-imp-id",
"banner": {
"format": [
{
"w": 300,
"h": 50
}
]
},
"ext": {
"bidder": {
"pubId": "fake-pub-id",
"zoneId": "sin"
}
}
}
]
}
},
"mockResponse": {
"status": 204,
"body": {}
}
}
],
"expectedBidResponses": []
}
Loading
Loading