-
Notifications
You must be signed in to change notification settings - Fork 845
New Adapter: targetVideo #4593
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
base: master
Are you sure you want to change the base?
New Adapter: targetVideo #4593
Conversation
adapters/targetVideo/targetvideo.go
Outdated
|
|
||
| func Builder(bidderName openrtb_ext.BidderName, cfg config.Adapter, server config.Server) (adapters.Bidder, error) { | ||
|
|
||
| bidder := &TargetVideoAdapter{ |
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.
You can call this simply "adapter", the TargetVideoAdapter identification is already supplied by the package name. As you have it, referencing your adapter from outside the package would be TargetVideoAdapter.TargetVideoAdapter which looks a little redundant. See example below:
package foo
type adapter struct {
endpoint string
}
func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
return &adapter{endpoint: "https://www.foo.com"}, nil
}
Code coverage summaryNote:
targetVideoRefer here for heat map coverage report |
Code coverage summaryNote:
targetVideoRefer here for heat map coverage report |
Code coverage summaryNote:
targetVideoRefer here for heat map coverage report |
| @@ -0,0 +1,17 @@ | |||
| endpoint: "https://pbs.prebrid.tv/openrtb2/auction" | |||
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.
Verified the endpoint is reachable:
curl -i --location --request POST https://pbs.prebrid.tv/openrtb2/auction
HTTP/2 400
content-type: application/octet-stream
content-length: 44
date: Thu, 06 Nov 2025 14:49:46 GMT
x-prebid: pbs-go/3.27.0+
server: nginx
cache-control: no-cache, no-store, must-revalidate
expires: 0
pragma: no-cache
vary: Origin
x-cache: Error from cloudfront
via: 1.1 f300b5f0c0ff51593fb31953294424c0.cloudfront.net (CloudFront)
x-amz-cf-pop: PHL51-P1
x-amz-cf-id: gUjfF-zVTgLDW86lrZCpy-TZZ3UcIBJ3ZisCwSVIIZeVxDSATcGPSg==
static/bidder-info/targetVideo.yaml
Outdated
| geoscope: | ||
| - global | ||
| maintainer: | ||
| email: "[email protected]" |
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.
We sent an email to this address. Please respond with "received" to verify this inbox is reachable.
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.
email is changed, I've used group email, I didn't know that response is going to be needed.
| - global | ||
| maintainer: | ||
| email: "[email protected]" | ||
| gvlVendorID: 786 |
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.
Verified GVL ID:
curl https://vendor-list.consensu.org/v3/vendor-list.json | jq '.vendors."786"'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 802k 100 802k 0 0 3418k 0 --:--:-- --:--:-- --:--:-- 3429k
{
"id": 786,
"name": "TargetVideo GmbH",
"purposes": [
1,
7,
8,
10
],
"legIntPurposes": [],
"flexiblePurposes": [],
"specialPurposes": [],
"features": [],
"specialFeatures": [],
"cookieMaxAgeSeconds": null,
"usesCookies": false,
"cookieRefresh": false,
"urls": [
{
"langId": "en",
"privacy": "https://target-video.com/privacy-policy/"
}
],
"usesNonCookieAccess": true,
"dataRetention": {
"stdRetention": 365,
"purposes": {},
"specialPurposes": {}
},
"dataDeclaration": [
2,
8
],
"deviceStorageDisclosureUrl": "https://target-video.com/vendors-device-storage-and-operational-disclosures.json"
}
| "type": "object", | ||
| "properties": { | ||
| "placementId": { | ||
| "type": ["integer", "string"], |
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 see that you're supporting two different formats for this parameter. Just checking if this is necessary given that the pattern is all digits.
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.
People usually accidentally set is as string and I just wanted to cover that situation.
| `undefined`, | ||
| `{"placementId": "%9"}`, | ||
| `{"publisherId": "as9""}`, | ||
| `{"placementId": true}`, |
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.
Please add {"placementId": ""} to invalid params to ensure your regex is correct.
adapters/targetVideo/targetvideo.go
Outdated
| } | ||
|
|
||
| if len(bidResp.SeatBid[0].Bid) == 0 { | ||
| return nil, nil |
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.
If you choose to keep this conditional, please add a supplemental test case to cover.
| "site": { | ||
| "domain": "www.publisher.com", | ||
| "page": "http://www.publisher.com/some/path", | ||
| "ext": { | ||
| "amp": 0 | ||
| } | ||
| } |
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.
Please remove the site object since this is an app request.
adapters/targetVideo/targetvideo.go
Outdated
| var root map[string]json.RawMessage | ||
| if err := json.Unmarshal(request.Imp[i].Ext, &root); err != nil { | ||
| // If ext cannot be parsed, skip transformation for this imp | ||
| continue | ||
| } | ||
|
|
||
| // Try to extract placementId from ext.bidder.targetVideo (or targetvideo) | ||
| placementId := "" | ||
| if bRaw, ok := root["bidder"]; ok && len(bRaw) > 0 { | ||
| var bidder map[string]json.RawMessage | ||
| if err := json.Unmarshal(bRaw, &bidder); err == nil { | ||
| if placementIdRaw, ok := bidder["placementId"]; ok && len(placementIdRaw) > 0 { | ||
|
|
||
| var asStr string | ||
| var asInt int64 | ||
| if err := json.Unmarshal(placementIdRaw, &asStr); err == nil && asStr != "" { | ||
| placementId = asStr | ||
| } else if err := json.Unmarshal(placementIdRaw, &asInt); err == nil { | ||
| placementId = fmt.Sprintf("%d", asInt) | ||
| } | ||
|
|
||
| } | ||
| } | ||
| // Remove bidder node as required | ||
| delete(root, "bidder") | ||
| } | ||
|
|
||
| // If we obtained a placementId, set ext.prebid.storedrequest.id = placementId | ||
| if placementId != "" { | ||
| // Build prebid.storedrequest structure, preserving existing prebid if any | ||
| var prebid map[string]json.RawMessage | ||
| if pr, ok := root["prebid"]; ok && len(pr) > 0 { | ||
| _ = json.Unmarshal(pr, &prebid) | ||
| } | ||
| if prebid == nil { | ||
| prebid = make(map[string]json.RawMessage) | ||
| } | ||
| stored := map[string]string{"id": placementId} | ||
| storedRaw, _ := json.Marshal(stored) | ||
| prebid["storedrequest"] = storedRaw | ||
| prebidRaw, _ := json.Marshal(prebid) |
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.
All of this can be simplified by doing the following:
- Change the type of
openrtb_ext/imp_targetvideo.goPlacementIdfrominttojsonutil.StringIntdefined ingithub.1485827954.workers.dev/prebid/prebid-server/v3/util/jsonutil. This will handle converting a string to an int when unmarshaling theplacement_idparameter toopenrtb_ext.ExtImpTargetVideo. ThisStringInttype has a custom unmarshaler defined. - Declare the following types at the top of this file:
type impExtBidder struct {
TargetVideo openrtb_ext.ExtImpTargetVideo `json:"targetVideo"`
}
type impExtPrebid struct {
Prebid *openrtb_ext.ExtImpPrebid `json:"prebid,omitempty"`
}
- Replace all of this code with something like this:
var extBidder adapters.ExtImpBidder
if err := jsonutil.Unmarshal(imp.Ext, &extBidder); err != nil {
return nil, &errortypes.BadInput{Message: fmt.Sprintf("error parsing imp.ext, err: %s", err)}
}
var extImpTargetVideo openrtb_ext.ExtImpTargetVideo
if err := jsonutil.Unmarshal(extBidder.Bidder, &extImpTargetVideo); err != nil {
return nil, &errortypes.BadInput{Message: fmt.Sprintf("error parsing imp.ext.bidder, err: %s", err)}
}
var prebid *openrtb_ext.ExtImpPrebid
if extBidder.Prebid == nil {
prebid = &openrtb_ext.ExtImpPrebid{}
}
if prebid.StoredRequest == nil {
prebid.StoredRequest = &openrtb_ext.ExtStoredRequest{}
}
prebid.StoredRequest.ID = fmt.Sprintf("%d", extImpTargetVideo.PlacementId)
ext := impExtPrebid{
Prebid: prebid,
}
extRaw, err := jsonutil.Marshal(ext)
if err != nil {
return nil, &errortypes.BadInput{Message: fmt.Sprintf("error building imp.ext, err: %s", err)}
}
request.Imp[i].Ext = extRaw
adapters/targetVideo/targetvideo.go
Outdated
| if len(bidResp.SeatBid) == 0 { | ||
| return nil, nil | ||
| } | ||
|
|
||
| if len(bidResp.SeatBid[0].Bid) == 0 { | ||
| return nil, nil | ||
| } |
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.
You can delete these two checks because the for range on line 151 should gracefully handle the empty scenarios.
| redirect: | ||
| url: "https://pbs.prebrid.tv/user_sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redirect={{.RedirectURL}}" |
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.
|
@pedjoni8 I suggest addressing this comment first: #4593 (comment) |
Code coverage summaryNote:
targetVideoRefer here for heat map coverage report |
|
@bsardo Thank you for your help and suggestions. I think I covered everything. |
Code coverage summaryNote:
targetVideoRefer here for heat map coverage report |
adapters/targetVideo/targetvideo.go
Outdated
| if adapterReq, err := a.makeRequest(*request, request.Imp[i]); err == nil { | ||
| adapterRequests = append(adapterRequests, adapterReq) | ||
| } else { | ||
| errors = append(errors, err) | ||
| } |
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.
Nitpick:
Can be rewritten as
adapterReq, err := a.makeRequest(*request, request.Imp[i])
if err != nil {
errors = append(errors, err)
continue
}
adapterRequests = append(adapterRequests, adapterReq)Its more idiomatic way in golang
adapters/targetVideo/targetvideo.go
Outdated
| for i := range sb.Bid { | ||
| bid := sb.Bid[i] | ||
|
|
||
| mediaType := openrtb_ext.BidTypeVideo |
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.
Nitpick: we don't need mediaType variable here, we can directly assign video. Also remove empty lines.
adapters/targetVideo/targetvideo.go
Outdated
| } | ||
|
|
||
| func Builder(bidderName openrtb_ext.BidderName, cfg config.Adapter, server config.Server) (adapters.Bidder, error) { | ||
|
|
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.
Nitpick: Remove blank line
Code coverage summaryNote:
targetVideoRefer here for heat map coverage report |
|
@pm-nikhil-vaidya done. |

Docs PR.
Adding targetVideo prebid server adapter...