New Adapter: targetVideo#4593
Conversation
|
|
||
| func Builder(bidderName openrtb_ext.BidderName, cfg config.Adapter, server config.Server) (adapters.Bidder, error) { | ||
|
|
||
| bidder := &TargetVideoAdapter{ |
There was a problem hiding this comment.
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.
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==
| geoscope: | ||
| - global | ||
| maintainer: | ||
| email: "contact@target-video.com" |
There was a problem hiding this comment.
We sent an email to this address. Please respond with "received" to verify this inbox is reachable.
There was a problem hiding this comment.
email is changed, I've used group email, I didn't know that response is going to be needed.
There was a problem hiding this comment.
New email address "contact@target-video.com" confirmed received.
| - global | ||
| maintainer: | ||
| email: "contact@target-video.com" | ||
| gvlVendorID: 786 |
There was a problem hiding this comment.
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.
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.
People usually accidentally set is as string and I just wanted to cover that situation.
| } | ||
|
|
||
| if len(bidResp.SeatBid[0].Bid) == 0 { | ||
| return nil, nil |
There was a problem hiding this comment.
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.
Please remove the site object since this is an app request.
| 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.
All of this can be simplified by doing the following:
- Change the type of
openrtb_ext/imp_targetvideo.goPlacementIdfrominttojsonutil.StringIntdefined ingithub.com/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
| 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.
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}}" |
|
@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 |
| 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.
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
| for i := range sb.Bid { | ||
| bid := sb.Bid[i] | ||
|
|
||
| mediaType := openrtb_ext.BidTypeVideo |
There was a problem hiding this comment.
Nitpick: we don't need mediaType variable here, we can directly assign video. Also remove empty lines.
| } | ||
|
|
||
| func Builder(bidderName openrtb_ext.BidderName, cfg config.Adapter, server config.Server) (adapters.Bidder, error) { | ||
|
|
There was a problem hiding this comment.
Nitpick: Remove blank line
Code coverage summaryNote:
targetVideoRefer here for heat map coverage report |
|
@pm-nikhil-vaidya done. |
Code coverage summaryNote:
targetVideoRefer here for heat map coverage report |
|
@bsardo @pm-nikhil-vaidya |
Code coverage summaryNote:
targetVideoRefer here for heat map coverage report |
Code coverage summaryNote:
targetVideoRefer here for heat map coverage report |
|
@linux019 can we maybe push for the 2nd reviewer here to get this live? Do you maybe know, when the next release is planned? |
|
@pedjoni8 can you resolve conflicts? |
Code coverage summaryNote:
targetVideoRefer here for heat map coverage report |
done |
Code coverage summaryNote:
targetVideoRefer here for heat map coverage report |
Code coverage summaryNote:
targetVideoRefer here for heat map coverage report |
|
@Taxel any news here? Would be great if we could get the second approval. |
| geoscope: | ||
| - global | ||
| maintainer: | ||
| email: "contact@target-video.com" |
There was a problem hiding this comment.
New email address "contact@target-video.com" confirmed received.
Code coverage summaryNote:
targetVideoRefer here for heat map coverage report |
|
@Taxel I think i covered it all. |
Code coverage summaryNote:
targetVideoRefer here for heat map coverage report |

Docs PR.
Adding targetVideo prebid server adapter...