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

Support bidder-specific device data #4147

Open
paulborile opened this issue Jan 13, 2025 · 9 comments
Open

Support bidder-specific device data #4147

paulborile opened this issue Jan 13, 2025 · 9 comments

Comments

@paulborile
Copy link

We observed that when Prebid.js calls a Prebid Server (PBS), some bidder-specific global data (which appears in .ext.prebid.bidderconfig[<bidder>].config.ortb2.device when passed to PBS) is not forwarded to the bidders (it does not appear in the Bidder Request hook). Specifically, the device data added by, for example, the Prebid.js WURFL RTD module in ortb2.device is lost during transit in PBS.

@paulborile
Copy link
Author

The same happens on pbs Java

@bretg
Copy link
Contributor

bretg commented Jan 24, 2025

@paulborile - please provide an ORTB example.

ext.prebid.bidderconfig.BIDDER.config.ortb2.device should get added to the ORTB seen by BIDDER as simply "device"

@bretg bretg moved this from Triage to Clarify Request in Prebid Server Prioritization Jan 24, 2025
@paulborile
Copy link
Author

paulborile commented Jan 24, 2025

Input request coming from prebid.js + wurfl rtd : some Bidder-Specific global FPD is set

{
    "imp": [
        {
            "ext": {
                "prebid": {
                    "bidder": {
                        "pubmatic": {
                            "publisherId": "156276",
                            "adSlot": "pubmatic_test"
                        },
                        "appnexus": {
                            "placement_id": 13144370
                        },
                        "eplanning": {
                            "ci": "18f66",
                            "t": 1
                        }
                    },
                    "adunitcode": "test-div-1"
                }
            },
            "id": "test-div-1",
            "banner": {
                "topframe": 1,
                "format": [
                    {
                        "w": 300,
                        "h": 250
                    },
                    {
                        "w": 300,
                        "h": 600
                    }
                ]
            },
            "secure": 1
        }
    ],
    "site": {
        "domain": "staging-prebid-js-poc.scientiamobile.com",
        "publisher": {
            "domain": "scientiamobile.com",
            "id": "1"
        },
        "page": "https://staging-prebid-js-poc.scientiamobile.com/static/html/pbs_wurfl.html"
    },
    "device": {
        "w": 635,
        "h": 882,
        "dnt": 0,
        "ua": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36",
        "language": "en",
        "ext": {
            "vpw": 980,
            "vph": 1362
        },
        "sua": {
            "source": 2,
            "platform": {
                "brand": "Android",
                "version": [
                    "6",
                    "0"
                ]
            },
            "browsers": [
                {
                    "brand": "Not A(Brand",
                    "version": [
                        "8",
                        "0",
                        "0",
                        "0"
                    ]
                },
                {
                    "brand": "Chromium",
                    "version": [
                        "132",
                        "0",
                        "6834",
                        "110"
                    ]
                },
                {
                    "brand": "Google Chrome",
                    "version": [
                        "132",
                        "0",
                        "6834",
                        "110"
                    ]
                }
            ],
            "mobile": 1,
            "model": "Nexus 5",
            "architecture": ""
        }
    },
    "ext": {
        "prebid": {
            "auctiontimestamp": 1737731924490,
            "targeting": {
                "includewinners": true,
                "includebidderkeys": false
            },
            "bidderconfig": [
                {
                    "bidders": [
                        "pubmatic"
                    ],
                    "config": {
                        "ortb2": {
                            "device": {
                                "ext": {
                                    "wurfl": {
                                        "is_mobile": true,
                                        "complete_device_name": "Google Nexus 5",
                                        "form_factor": "Feature Phone",
                                        "model_name": "Nexus 5",
                                        "brand_name": "Google"
                                    }
                                },
                                "make": "Google",
                                "model": "Nexus 5"
                            }
                        }
                    }
                },
                {
                    "bidders": [
                        "appnexus"
                    ],
                    "config": {
                        "ortb2": {
                            "device": {
                                "ext": {
                                    "wurfl": {
                                        "advertised_browser": "Chrome Mobile",
                                        "advertised_browser_version": "132.0.0.0",
                                        "advertised_device_os": "Android",
                                        "advertised_device_os_version": "6.0",
                                        "ajax_support_javascript": true,
                                        "brand_name": "Google",
                                        "complete_device_name": "Google Nexus 5",
                                        "density_class": "3.0",
                                        "form_factor": "Feature Phone",
                                        "is_app_webview": false,
                                        "is_connected_tv": false,
                                        "is_full_desktop": false,
                                        "is_mobile": true,
                                        "is_ott": false,
                                        "is_phone": true,
                                        "is_robot": false,
                                        "is_smartphone": false,
                                        "is_smarttv": false,
                                        "is_tablet": false,
                                        "manufacturer_name": "LG",
                                        "marketing_name": "",
                                        "max_image_height": 640,
                                        "max_image_width": 360,
                                        "model_name": "Nexus 5",
                                        "physical_screen_height": 110,
                                        "physical_screen_width": 62,
                                        "pixel_density": 443,
                                        "pointing_method": "touchscreen",
                                        "resolution_height": 1920,
                                        "resolution_width": 1080
                                    }
                                },
                                "make": "Google",
                                "model": "Nexus 5",
                                "devicetype": 1,
                                "os": "Android",
                                "osv": "6.0",
                                "hwv": "Nexus 5",
                                "ppi": 443,
                                "pxratio": "3.0",
                                "js": true
                            }
                        }
                    }
                },
                {
                    "bidders": [
                        "eplanning"
                    ],
                    "config": {
                        "ortb2": {
                            "device": {
                                "ext": {
                                    "wurfl": {
                                        "advertised_browser": "Chrome Mobile",
                                        "advertised_browser_version": "132.0.0.0",
                                        "advertised_device_os": "Android",
                                        "advertised_device_os_version": "6.0",
                                        "ajax_support_javascript": true,
                                        "brand_name": "Google",
                                        "complete_device_name": "Google Nexus 5",
                                        "density_class": "3.0",
                                        "form_factor": "Feature Phone",
                                        "is_app_webview": false,
                                        "is_connected_tv": false,
                                        "is_full_desktop": false,
                                        "is_mobile": true,
                                        "is_ott": false,
                                        "is_phone": true,
                                        "is_robot": false,
                                        "is_smartphone": false,
                                        "is_smarttv": false,
                                        "is_tablet": false,
                                        "manufacturer_name": "LG",
                                        "marketing_name": "",
                                        "max_image_height": 640,
                                        "max_image_width": 360,
                                        "model_name": "Nexus 5",
                                        "physical_screen_height": 110,
                                        "physical_screen_width": 62,
                                        "pixel_density": 443,
                                        "pointing_method": "touchscreen",
                                        "resolution_height": 1920,
                                        "resolution_width": 1080
                                    }
                                },
                                "make": "Google",
                                "model": "Nexus 5",
                                "devicetype": 1,
                                "os": "Android",
                                "osv": "6.0",
                                "hwv": "Nexus 5",
                                "ppi": 443,
                                "pxratio": "3.0",
                                "js": true
                            }
                        }
                    }
                },
                {
                    "bidders": [
                        "0test"
                    ],
                    "config": {
                        "ortb2": {
                            "device": {
                                "ext": {
                                    "wurfl": {
                                        "is_mobile": true,
                                        "complete_device_name": "Google Nexus 5",
                                        "form_factor": "Feature Phone",
                                        "model_name": "Nexus 5",
                                        "brand_name": "Google"
                                    }
                                },
                                "make": "Google",
                                "model": "Nexus 5"
                            }
                        }
                    }
                }
            ],
            "channel": {
                "name": "pbjs",
                "version": "v9.22.0"
            },
            "createtids": false
        },
        "tmaxmax": 3000
    },
    "id": "0a63b9b8-31c6-4eaf-9f78-cfeb06ddcbcb",
    "test": 0,
    "tmax": 1000
}

(0test being our test Adapter)

The following data is from MakeRequest of pubmatic adapter ( https://docs.prebid.org/prebid-server/developers/add-new-bidder-go.html#makerequests )

(*openrtb2.BidRequest)(0xc000bcfe00)({
 ID: (string) (len=36) "0a63b9b8-31c6-4eaf-9f78-cfeb06ddcbcb",
 Imp: ([]openrtb2.Imp) (len=1 cap=1) {
  (openrtb2.Imp) {
   ID: (string) (len=10) "test-div-1",
   Metric: ([]openrtb2.Metric) <nil>,
   Banner: (*openrtb2.Banner)(0xc0002ddd00)({
    Format: ([]openrtb2.Format) (len=2 cap=2) {
     (openrtb2.Format) {
      W: (int64) 300,
      H: (int64) 250,
      WRatio: (int64) 0,
      HRatio: (int64) 0,
      WMin: (int64) 0,
      Ext: (json.RawMessage) <nil>
     },
     (openrtb2.Format) {
      W: (int64) 300,
      H: (int64) 600,
      WRatio: (int64) 0,
      HRatio: (int64) 0,
      WMin: (int64) 0,
      Ext: (json.RawMessage) <nil>
     }
    },
    W: (*int64)(<nil>),
    H: (*int64)(<nil>),
    WMax: (int64) 0,
    HMax: (int64) 0,
    WMin: (int64) 0,
    HMin: (int64) 0,
    BType: ([]openrtb2.BannerAdType) <nil>,
    BAttr: ([]adcom1.CreativeAttribute) <nil>,
    Pos: (*adcom1.PlacementPosition)(<nil>),
    MIMEs: ([]string) <nil>,
    TopFrame: (int8) 1,
    ExpDir: ([]adcom1.ExpandableDirection) <nil>,
    API: ([]adcom1.APIFramework) <nil>,
    ID: (string) "",
    Vcm: (*int8)(<nil>),
    Ext: (json.RawMessage) <nil>
   }),
   Video: (*openrtb2.Video)(<nil>),
   Audio: (*openrtb2.Audio)(<nil>),
   Native: (*openrtb2.Native)(<nil>),
   PMP: (*openrtb2.PMP)(<nil>),
   DisplayManager: (string) "",
   DisplayManagerVer: (string) "",
   Instl: (int8) 0,
   TagID: (string) "",
   BidFloor: (float64) 0,
   BidFloorCur: (string) "",
   ClickBrowser: (*int8)(<nil>),
   Secure: (*int8)(0xc000779ad6)(1),
   IframeBuster: ([]string) <nil>,
   Rwdd: (int8) 0,
   SSAI: (openrtb2.AdInsertion) 0,
   Exp: (int64) 0,
   Qty: (*openrtb2.Qty)(<nil>),
   DT: (float64) 0,
   Refresh: (*openrtb2.Refresh)(<nil>),
   Ext: (json.RawMessage) (len=105 cap=105) {
    00000000  7b 22 62 69 64 64 65 72  22 3a 7b 22 70 75 62 6c  |{"bidder":{"publ|
    00000010  69 73 68 65 72 49 64 22  3a 22 31 35 36 32 37 36  |isherId":"156276|
    00000020  22 2c 22 61 64 53 6c 6f  74 22 3a 22 70 75 62 6d  |","adSlot":"pubm|
    00000030  61 74 69 63 5f 74 65 73  74 22 7d 2c 22 74 69 64  |atic_test"},"tid|
    00000040  22 3a 22 39 64 35 33 65  66 66 36 2d 31 34 37 62  |":"9d53eff6-147b|
    00000050  2d 34 37 37 31 2d 62 30  36 31 2d 66 38 32 63 30  |-4771-b061-f82c0|
    00000060  63 38 32 37 35 30 61 22  7d                       |c82750a"}|
   }
  }
 },
 Site: (*openrtb2.Site)(0xc0007d3c20)({
  ID: (string) "",
  Name: (string) "",
  Domain: (string) (len=40) "staging-prebid-js-poc.scientiamobile.com",
  CatTax: (adcom1.CategoryTaxonomy) 0,
  Cat: ([]string) <nil>,
  SectionCat: ([]string) <nil>,
  PageCat: ([]string) <nil>,
  Page: (string) (len=75) "https://staging-prebid-js-poc.scientiamobile.com/static/html/pbs_wurfl.html",
  Ref: (string) "",
  Search: (string) "",
  Mobile: (*int8)(<nil>),
  PrivacyPolicy: (*int8)(<nil>),
  Publisher: (*openrtb2.Publisher)(0xc00023ebd0)({
   ID: (string) (len=1) "1",
   Name: (string) "",
   CatTax: (adcom1.CategoryTaxonomy) 0,
   Cat: ([]string) <nil>,
   Domain: (string) (len=18) "scientiamobile.com",
   Ext: (json.RawMessage) <nil>
  }),
  Content: (*openrtb2.Content)(<nil>),
  Keywords: (string) "",
  KwArray: ([]string) <nil>,
  InventoryPartnerDomain: (string) "",
  Ext: (json.RawMessage) <nil>
 }),
 App: (*openrtb2.App)(<nil>),
 DOOH: (*openrtb2.DOOH)(<nil>),
 Device: (*openrtb2.Device)(0xc000604c40)({
  Geo: (*openrtb2.Geo)(<nil>),
  DNT: (*int8)(0xc0009ef9eb)(0),
  Lmt: (*int8)(<nil>),
  UA: (string) (len=131) "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36",
  SUA: (*openrtb2.UserAgent)(0xc000a69e00)({
   Browsers: ([]openrtb2.BrandVersion) (len=3 cap=3) {
    (openrtb2.BrandVersion) {
     Brand: (string) (len=11) "Not A(Brand",
     Version: ([]string) (len=4 cap=4) {
      (string) (len=1) "8",
      (string) (len=1) "0",
      (string) (len=1) "0",
      (string) (len=1) "0"
     },
     Ext: (json.RawMessage) <nil>
    },
    (openrtb2.BrandVersion) {
     Brand: (string) (len=8) "Chromium",
     Version: ([]string) (len=4 cap=4) {
      (string) (len=3) "132",
      (string) (len=1) "0",
      (string) (len=4) "6834",
      (string) (len=3) "110"
     },
     Ext: (json.RawMessage) <nil>
    },
    (openrtb2.BrandVersion) {
     Brand: (string) (len=13) "Google Chrome",
     Version: ([]string) (len=4 cap=4) {
      (string) (len=3) "132",
      (string) (len=1) "0",
      (string) (len=4) "6834",
      (string) (len=3) "110"
     },
     Ext: (json.RawMessage) <nil>
    }
   },
   Platform: (*openrtb2.BrandVersion)(0xc0009e0d00)({
    Brand: (string) (len=7) "Android",
    Version: ([]string) (len=2 cap=2) {
     (string) (len=1) "6",
     (string) (len=1) "0"
    },
    Ext: (json.RawMessage) <nil>
   }),
   Mobile: (*int8)(0xc0009ef9ec)(1),
   Architecture: (string) "",
   Bitness: (string) "",
   Model: (string) (len=7) "Nexus 5",
   Source: (adcom1.UserAgentSource) 2,
   Ext: (json.RawMessage) <nil>
  }),
  IP: (string) "",
  IPv6: (string) "",
  DeviceType: (adcom1.DeviceType) 0,
  Make: (string) "",
  Model: (string) "",
  OS: (string) "",
  OSV: (string) "",
  HWV: (string) "",
  H: (int64) 882,
  W: (int64) 635,
  PPI: (int64) 0,
  PxRatio: (float64) 0,
  JS: (*int8)(<nil>),
  GeoFetch: (*int8)(<nil>),
  FlashVer: (string) "",
  Language: (string) (len=2) "en",
  LangB: (string) "",
  Carrier: (string) "",
  MCCMNC: (string) "",
  ConnectionType: (*adcom1.ConnectionType)(<nil>),
  IFA: (string) "",
  DIDSHA1: (string) "",
  DIDMD5: (string) "",
  DPIDSHA1: (string) "",
  DPIDMD5: (string) "",
  MACSHA1: (string) "",
  MACMD5: (string) "",
  Ext: (json.RawMessage) (len=56 cap=64) {
   00000000  7b 20 20 20 20 20 20 20  20 20 20 20 20 22 76 70  |{            "vp|
   00000010  77 22 3a 20 39 38 30 2c  20 20 20 20 20 20 20 20  |w": 980,        |
   00000020  20 20 20 20 22 76 70 68  22 3a 20 31 33 36 32 20  |    "vph": 1362 |
   00000030  20 20 20 20 20 20 20 7d                           |       }|
  }
 }),
 User: (*openrtb2.User)(<nil>),
 Test: (int8) 0,
 AT: (int64) 1,
 TMax: (int64) 1000,
 WSeat: ([]string) <nil>,
 BSeat: ([]string) <nil>,
 AllImps: (int8) 0,
 Cur: ([]string) <nil>,
 WLang: ([]string) <nil>,
 WLangB: ([]string) <nil>,
 ACat: ([]string) <nil>,
 BCat: ([]string) <nil>,
 CatTax: (adcom1.CategoryTaxonomy) 0,
 BAdv: ([]string) <nil>,
 BApp: ([]string) <nil>,
 Source: (*openrtb2.Source)(0xc0009f05a0)({
  FD: (*int8)(<nil>),
  TID: (string) (len=36) "9bcd7279-d616-4229-a37a-1e4c52fef7cc",
  PChain: (string) "",
  SChain: (*openrtb2.SupplyChain)(<nil>),
  Ext: (json.RawMessage) <nil>
 }),
 Regs: (*openrtb2.Regs)(<nil>),
 Ext: (json.RawMessage) (len=148 cap=148) {
  00000000  7b 22 70 72 65 62 69 64  22 3a 7b 22 63 68 61 6e  |{"prebid":{"chan|
  00000010  6e 65 6c 22 3a 7b 22 6e  61 6d 65 22 3a 22 70 62  |nel":{"name":"pb|
  00000020  6a 73 22 2c 22 76 65 72  73 69 6f 6e 22 3a 22 76  |js","version":"v|
  00000030  39 2e 32 32 2e 30 22 7d  2c 22 73 65 72 76 65 72  |9.22.0"},"server|
  00000040  22 3a 7b 22 65 78 74 65  72 6e 61 6c 75 72 6c 22  |":{"externalurl"|
  00000050  3a 22 68 74 74 70 3a 2f  2f 6c 6f 63 61 6c 68 6f  |:"http://localho|
  00000060  73 74 3a 38 30 30 30 22  2c 22 67 76 6c 69 64 22  |st:8000","gvlid"|
  00000070  3a 30 2c 22 64 61 74 61  63 65 6e 74 65 72 22 3a  |:0,"datacenter":|
  00000080  22 22 7d 7d 2c 22 74 6d  61 78 6d 61 78 22 3a 33  |""}},"tmaxmax":3|
  00000090  30 30 30 7d                                       |000}|
 }
})

While device.make and device.model had values in input request bidder-specific global fpd, here they are empty :

  Make: (string) "",
  Model: (string) "",

(In a similar way for the other device fields devicetype, os, osv, hwv, ppi, pxratio and js which are filled by prebid.js wurfl rtd)
Is this the intended behavior for pbs i.e. stripping down every bidder request to standard fpd regardless of input Bidder-Specific global fpd ?
Is there a way to enable this via data permission or does this needs to be modified at the server level ?
(tested with pbs 3.7.0 and default configuration)

@bretg
Copy link
Contributor

bretg commented Jan 24, 2025

Actually, I do seem to recall that bidderconfig only supports merging ORTB for site, app, and user top-level objects.

What's the use case for bidder-specific device data? This would be an enhancement request that's not going to be high priority.

@paulborile
Copy link
Author

When a publisher uses prebid.js with WURFL RTD for device detection, bid requests routed through PBS lose the device enrichment provided by WURFL RTD. Bid requests sent directly to bidders retain this enrichment.

@bretg
Copy link
Contributor

bretg commented Jan 24, 2025

The question is "why is it bidder-specific"?

i.e. why can't the device enhancement be global to all bidders?

pbjs.setConfig({
   ortb2: {
      device: {
         ... data ...

@paulborile
Copy link
Author

Our current business model involves sending different sets of information to specific bidders (similar to enabling device enrichment for specific publishers).

To address the issue with bidder-specific data in Prebid Server, we are thinking at a new configuration option in the Prebid.js-WURFL RTD module: "Add device data to global ortb object (set true for Prebid Server)" [true/false].

When enabled, this option will ensure that device data is added to ortb2Fragments.global instead of ortb2Fragments.[bidder].data, specifically for use with Prebid Server.

@bretg bretg changed the title bidderconfig device data not forwarded to bidders Support bidder-specific device data Jan 28, 2025
@bretg
Copy link
Contributor

bretg commented Jan 28, 2025

Very well, I've updated the title to reflect this is an enhancement request. I'm limiting it to just 'device' and not the entire ORTB object at this point. Will bring it up in a future PMC meeting where perhaps we'll decide to throw the doors wide open.

@bretg
Copy link
Contributor

bretg commented Jan 29, 2025

Discussed in committee. Agreed to add device as a top-level object supported in bidderconfig with the same behavior: merge into the main request with bidderconfig.ortb2.device fields taking precedence.

@bretg bretg moved this from Clarify Request to Ready for Dev in Prebid Server Prioritization Jan 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Ready for Dev
Development

No branches or pull requests

2 participants