Skip to content
Open

. #22

Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
- [adcom1](adcom1/) - [AdCOM](https://iabtechlab.com/standards/openmedia/) [1.0](https://github.com/InteractiveAdvertisingBureau/AdCOM) (can lag behind because official spec is constantly updated without version bump, feel free to PR)
- [native1](native1/) - [OpenRTB Dynamic Native Ads API](https://iabtechlab.com/standards/openrtb-native/) [1.2](https://iabtechlab.com/wp-content/uploads/2016/07/OpenRTB-Native-Ads-Specification-Final-1.2.pdf)

**Requires Go 1.16+**
**Requires Go 1.25.5+**

This library uses [Go modules](https://golang.org/ref/mod) ([tl;dr](https://blog.golang.org/using-go-modules)) and requires Go [1.16](https://golang.org/doc/go1.16)+ for the ability to issue release retractions.
This library uses [Go modules](https://golang.org/ref/mod) ([tl;dr](https://blog.golang.org/using-go-modules)) and requires Go [1.25.5](https://golang.org/doc/go1.25.5)+ for the ability to issue release retractions.

# Using

Expand Down
6 changes: 6 additions & 0 deletions adcom1/api_framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ const (
APISIMID10 APIFramework = 8 // SIMID 1.0
APISIMID11 APIFramework = 9 // SIMID 1.1
)

var APIFrameworkORTBV26Only = map[APIFramework]bool{
APIOMID10: true,
APISIMID10: true,
APISIMID11: true,
}
4 changes: 4 additions & 0 deletions adcom1/connection_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ const (
Connection5G ConnectionType = 7 // 7 Cellular Network - 5G
)

var ConnectionTypeORTBV26Only = map[ConnectionType]bool{
Connection5G: true,
}

// Ptr returns pointer to own value.
func (c ConnectionType) Ptr() *ConnectionType {
return &c
Expand Down
4 changes: 4 additions & 0 deletions adcom1/creative_attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,7 @@ const (
AttrFlash CreativeAttribute = 17 // Adobe Flash
AttrResponsive CreativeAttribute = 18 // Responsive; Sizeless; Fluid (i.e., creatives that dynamically resize to environment)
)

var CreativeAttributeORTBV26Only = map[CreativeAttribute]bool{
AttrResponsive: true,
}
4 changes: 4 additions & 0 deletions adcom1/device_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ const (
DeviceSetTopBox DeviceType = 7 // Set Top Box
DeviceOOH DeviceType = 8 // OOH Device
)

var DeviveTypeORTBV26Only = map[DeviceType]bool{
DeviceOOH: true,
}
4 changes: 4 additions & 0 deletions adcom1/expandable_direction.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ const (
ExpandableFullScreen ExpandableDirection = 5 // Full Screen
ExpandableResize ExpandableDirection = 6 // Resize/Minimize (make smaller)
)

var ExpandableDirectionORTBV26Only = map[ExpandableDirection]bool{
ExpandableResize: true,
}
7 changes: 7 additions & 0 deletions adcom1/media_creative_subtype.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,10 @@ const (
CreativeVAST42 MediaCreativeSubtype = 13 // VAST 4.2
CreativeVAST42Wrapper MediaCreativeSubtype = 14 // VAST 4.2 Wrapper
)

var MediaCreativeSubtypeORTBV26Only = map[MediaCreativeSubtype]bool{
CreativeVAST41: true,
CreativeVAST41Wrapper: true,
CreativeVAST42: true,
CreativeVAST42Wrapper: true,
}
12 changes: 11 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
module github.com/prebid/openrtb/v20

go 1.16
go 1.25.5

require (
github.com/onsi/ginkgo v1.16.1
github.com/onsi/gomega v1.11.0
)

require (
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/nxadm/tail v1.4.8 // indirect
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb // indirect
golang.org/x/sys v0.0.0-20210112080510-489259a85091 // indirect
golang.org/x/text v0.3.3 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
4 changes: 2 additions & 2 deletions openrtb2/banner.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type Banner struct {
// Description:
// Exact width in device independent pixels (DIPS);
// recommended if no format objects are specified.
W *int64 `json:"w,omitempty"`
W *uint64 `json:"w,omitempty"`

// Attribute:
// h
Expand All @@ -43,7 +43,7 @@ type Banner struct {
// Description:
// Exact height in device independent pixels (DIPS);
// recommended if no format objects are specified.
H *int64 `json:"h,omitempty"`
H *uint64 `json:"h,omitempty"`

// Attribute:
// wmax
Expand Down
65 changes: 63 additions & 2 deletions openrtb2/bid.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ type Bid struct {
// Substitution macros (Section 4.4) may be included.
AdM string `json:"adm,omitempty"`

// AdMObj is used for the case when we receive not string-typed data in adm field
// In custom marshalers we cast object in string if it's possible
AdMObj interface{} `json:"-"`

// Attribute:
// adid
// Type:
Expand Down Expand Up @@ -274,15 +278,15 @@ type Bid struct {
// integer
// Description:
// Width of the creative in device independent pixels (DIPS).
W int64 `json:"w,omitempty"`
W uint64 `json:"w,omitempty"`

// Attribute:
// h
// Type:
// integer
// Description:
// Height of the creative in device independent pixels (DIPS).
H int64 `json:"h,omitempty"`
H uint64 `json:"h,omitempty"`

// Attribute:
// wratio
Expand Down Expand Up @@ -352,3 +356,60 @@ type Bid struct {
// Placeholder for bidder-specific extensions to OpenRTB
Ext json.RawMessage `json:"ext,omitempty"`
}

// Used to unmarshal not string AdM
// Receive as interface and try to marshal into string then
func (bid *Bid) UnmarshalJSON(data []byte) error {
type Alias Bid
aliasedBid := &struct {
*Alias
AdM interface{} `json:"adm,omitempty"`
}{
Alias: (*Alias)(bid),
}

err := json.Unmarshal(data, &aliasedBid)
if err != nil {
return err
}

receivedAdM := aliasedBid.AdM
_, ok := receivedAdM.(string)
if ok {
bid.AdM = receivedAdM.(string)
return nil
}

if aliasedBid.AdM != nil {
// do not marshal nil to prevent adm: null in response

marshaledAdM, err := JSONMarshal(receivedAdM)
if err != nil {
return err
}

bid.AdM = string(marshaledAdM)

return nil
}

return nil
}

// If we need to send not string AdM we fill AdMObj in advance and then marshal bid with aliased adm field
func (bid *Bid) MarshalJSON() ([]byte, error) {
if bid.AdMObj == nil {
return JSONMarshal(*bid)
}

type Alias Bid
aliasedBid := &struct {
*Alias
AdM interface{} `json:"adm"`
}{
Alias: (*Alias)(bid),
AdM: bid.AdMObj,
}

return JSONMarshal(aliasedBid)
}
1 change: 1 addition & 0 deletions openrtb2/bid_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
// Among these are the Site and App objects, which describe the type of published media in which the impression(s) appear.
// These objects are highly recommended, but only one applies to a given bid request depending on whether the media is browser-based web content or a non-browser application, respectively.
type BidRequest struct {
ORTBVersion string `json:"-"`

// Attribute:
// id
Expand Down
4 changes: 2 additions & 2 deletions openrtb2/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ type Format struct {
// integer
// Description:
// Width in device independent pixels (DIPS).
W int64 `json:"w,omitempty"`
W *uint64 `json:"w,omitempty"`

// Attribute:
// h
// Type:
// integer
// Description:
// Height in device independent pixels (DIPS).
H int64 `json:"h,omitempty"`
H *uint64 `json:"h,omitempty"`

// Attribute:
// wratio
Expand Down
30 changes: 30 additions & 0 deletions openrtb2/helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package openrtb2

import (
"bytes"
"encoding/json"
"strings"
"sync"
)

var bufferPool = &sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}

// JSONMarshal can marshal object without HTML-chars escaping
// https://stackoverflow.com/a/28596225/5160055
func JSONMarshal(t interface{}) ([]byte, error) {
buffer := bufferPool.Get().(*bytes.Buffer)
buffer.Reset()

encoder := json.NewEncoder(buffer)
encoder.SetEscapeHTML(false)
err := encoder.Encode(t)
str := strings.Trim(buffer.String(), "\n") // encoder.Encode always adds "\n" in the end but it may be changed any moment

bufferPool.Put(buffer)

return []byte(str), err
}
54 changes: 54 additions & 0 deletions openrtb2/native.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ type Native struct {
// Markup Request Object, section 4.1 of OpenRTB Native 1.1+.
Request string `json:"request"`

// RequestObj is used for the case when we receive not string-typed data in request field
// In custom marshalers we cast object in string if it's possible
RequestObj interface{} `json:"-"`

// Attribute:
// ver
// Type:
Expand Down Expand Up @@ -81,3 +85,53 @@ type Native struct {
// Placeholder for exchange-specific extensions to OpenRTB.
Ext json.RawMessage `json:"ext,omitempty"`
}

// Used to unmarshal not string Request
// Receive as interface and try to marshal into string then
func (native *Native) UnmarshalJSON(data []byte) error {
type Alias Native
aliasedNative := &struct {
*Alias
Request interface{} `json:"request"`
}{
Alias: (*Alias)(native),
}

err := json.Unmarshal(data, &aliasedNative)
if err != nil {
return err
}

receivedNativeRequest := aliasedNative.Request
_, ok := receivedNativeRequest.(string)
if ok {
native.Request = receivedNativeRequest.(string)
return nil
}

marshaledNativeRequest, err := JSONMarshal(receivedNativeRequest)
if err != nil {
return err
}

native.Request = string(marshaledNativeRequest)
return nil
}

// If we need to send not string Request we fill RequestObj in advance and then marshal bid with aliased request field
func (native *Native) MarshalJSON() ([]byte, error) {
if native.RequestObj == nil {
return JSONMarshal(*native)
}

type Alias Native
aliasedNative := &struct {
*Alias
Request interface{} `json:"request"`
}{
Alias: (*Alias)(native),
Request: native.RequestObj,
}

return JSONMarshal(aliasedNative)
}
5 changes: 5 additions & 0 deletions openrtb2/ptr.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@ func Int8Ptr(n int8) *int8 {
func Int64Ptr(n int64) *int64 {
return &n
}

// Int64Ptr returns pointer to passed argument.
func Uint64Ptr(n uint64) *uint64 {
return &n
}
4 changes: 2 additions & 2 deletions openrtb2/video.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,15 @@ type Video struct {
// integer; recommended
// Description:
// Width of the video player in device independent pixels (DIPS).
W *int64 `json:"w,omitempty"`
W uint64 `json:"w,omitempty"`

// Attribute:
// h
// Type:
// integer; recommended
// Description:
// Height of the video player in device independent pixels (DIPS).
H *int64 `json:"h,omitempty"`
H uint64 `json:"h,omitempty"`

// Attribute:
// podid
Expand Down
10 changes: 10 additions & 0 deletions openrtb3/no_bid_reason.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ const (
NoBidBlockedSupplyChainNode NoBidReason = 17 // Blocked SupplyChain Node
)

var NoBidReasonORTBV26Only = map[NoBidReason]bool{
NoBidAuthorizationUnavailable: true,
NoBidAuthorizationViolation: true,
NoBidAuthenticationUnavailable: true,
NoBidAuthenticationViolation: true,
NoBidInsufficientTime: true,
NoBidIncompleteSupplyChain: true,
NoBidBlockedSupplyChainNode: true,
}

// Ptr returns pointer to own value.
func (n NoBidReason) Ptr() *NoBidReason {
return &n
Expand Down