出价和竞价 (B&A) 服务是一组面向广告买方和卖方的服务,可在可信执行环境 (TEE) 中运行,以促成 Protected Audience (PA) 竞价。本开发者指南介绍了买方如何与 Chrome 的 B&A PA 竞价进行集成。
概览
若要通过 B&A 服务参与 Protected Audience 竞价,买方会更新兴趣群体 (IG),以优化载荷,从而缩短竞价延迟时间。
买方要求执行以下载荷优化任务:
joinAdInterestGroup()任务generateBid()任务
B&A 的兴趣群组
以下是应用了载荷优化的 B&A PA 竞价的兴趣组配置示例:
navigator.joinAdInterestGroup({
name: 'example-ig',
owner: 'https://dsp.example',
// An ID is mapped to each render URL
ads: [
{
renderURL: 'https://dsp.example/ad.html',
adRenderId: '12345678' // 12 characters max,
buyerReportingId: 'brid123', // Optional
buyerAndSellerReportingId: 'bsrid123', // Optional
selectableBuyerAndSellerReportingId: ['sbsrid123', 'sbsrid456'], // Optional
},
],
adComponents: [
{
renderURL: 'https://dsp.example/ad-component.html',
adRenderId: 'abcdefgh'
},
],
// Flags are set to omit data in the B&A auction payload
auctionServerRequestFlags: ['omit-ads', 'omit-user-bidding-signals'],
// Data not included in the B&A auction payload can be fetched as trusted signals
// The following is an example of how the keys could look, but the actual
// implementation is up to the ad tech
trustedBiddingSignalsKeys: [
'exampleUserBiddingSignalsKey',
'exampleAdRenderIdKey',
'exampleAdMetadataKey',
'exampleAdReportingIdKey',
],
// Optionally, interest groups can be prioritized
priority: 0.0,
});
B&A 配置与设备端兴趣群体配置之间的区别如下:
| 字段 | B&A IG | 设备端 IG | 包含在 B&A 竞价载荷中 |
auctionServerRequestFlags |
已使用 | 未使用 | 否 |
userBiddingSignals |
不推荐 | 已使用 | 如果设置了 omit-user-bidding-signals 标志,则为否 |
ads 和 adComponents 中的 adRenderId |
已使用 | 未使用 | 如果设置了 omit-ads 标志,则 ads 中的 adRenderId 仅在载荷的 browserSignals.prevWins 中可用。adComponents 中定义的 adRenderId 未包含在载荷中。如果未设置 |
ads 和 adComponents 中的 renderURL |
已使用 | 已使用 | 否 |
ads 和 adComponents 中的 metadata |
未使用 | 已使用 | 否 |
ads 中的报告 ID |
已使用 | 已使用 | 否 |
- 通过
auctionServerRequestFlags字段,您可以设置标志来告知浏览器在 B&A 竞价载荷中省略某些数据。 - 可以在兴趣组中定义
userBiddingSignals值,但建议使用omit-user-bidding-signals标志将其省略。可以使用 K/V 服务提供省略的信号。 adRenderId字段与关联的renderURL一起设置,但只有adRenderId会成为 B&A 竞价载荷的一部分。在竞价期间,稍后从generateBid()返回的渲染网址必须与 IG 中定义的渲染网址一致。- 报告 ID 在 B&A IG 中定义,但不包含在 B&A 竞价载荷中。在竞价期间稍后从
generateBid()返回的报告 ID 必须与 IG 中定义的呈现网址一致。 ad.metadata和报告 ID 不包含在 B&A 竞价载荷中,而是通过可信的键值对服务使用情况提供这些数据。
请注意,ads 中的 renderURL 和报告 ID 仍会在兴趣组配置中定义,但不会包含在竞价请求载荷中,因为浏览器会检查出价服务的 generateBid() 函数返回的渲染网址和报告 ID 是否与兴趣组中定义的值一致。
joinAdInterestGroup() 项任务
需要为 joinAdInterestGroup() 调用执行以下任务。
设置服务器请求标志
joinAdInterestGroup() 配置的 auctionServerRequestFlags 字段接受以下标志:
| 标志 | 说明 |
omit-user-bidding-signals |
omit-user-bidding-signals 标志会省略竞价载荷中的 userBiddingSignals 对象。
如果未设置此标志,则在竞价服务的 |
omit-ads |
omit-ads 标志会告知浏览器在竞价载荷中省略 ads 和 adComponents 对象。
如果未设置该标志,则 强烈建议买家选择 |
通过在 trustedBiddingSignals 中提供相关信息来处理省略的数据。这些标志可以单独使用,无需一起使用。
用法示例:
navigator.joinAdInterestGroup({
auctionServerRequestFlags: ['omit-user-bidding-signals', 'omit-ads'],
});
设置广告呈现 ID
为了减小 B&A 竞价载荷的大小,系统会省略兴趣组的 ads 和 adComponents 对象,因此在出价服务中运行的 generateBid() 函数内无法使用这些对象。
为了处理广告信息缺失的情况,买方会维护与兴趣群体配置中每个广告相关联的标识符(adRenderId 和 adComponentRenderId)。标识符必须是长度不超过 12 个字节的 DOMString。如果标识符采用 Base64 编码,其长度必须不超过 12 字节。
包含广告呈现 ID 的兴趣组示例:
navigator.joinAdInterestGroup({
ads: [
{
renderURL: 'https://dsp.example/ad.html',
adRenderId: '12345678' // 12 characters max
},
],
adComponents: [
{
renderURL: 'https://dsp.example/ad-component.html',
adComponentRenderId: 'abcdefgh'
},
],
});
与广告相关联的 adRenderId 将于 generateBid() 在 prevWins.browserSignals 中提供。
虽然 renderURL 未包含在请求载荷中,但从 generateBid() 返回的渲染网址必须与在兴趣组配置中定义的渲染网址一致。广告技术平台可以在 trustedBiddingSignals 中发回广告元数据和其他信息,以便在 generateBid() 执行期间为出价生成广告呈现网址和广告组件呈现网址。
设置兴趣群体优先级
Chrome 允许买方优先处理兴趣群体。如果达到卖家设置的每个买方载荷大小限制,则在为卖家生成 B&A 竞价载荷时,系统会使用兴趣组优先级值来舍弃单个买方的较低优先级兴趣组。对于在不同买家之间选择兴趣群体,浏览器会根据序列化载荷的大小做出决定。默认情况下,每个买家的规模都相同。请注意,实际的优先级设置是在 B&A 服务器上进行的,而不是在生成请求载荷时进行的。
优先级是在竞价时使用买方的优先级向量 (priorityVector) 和卖方的优先级信号 (prioritySignals) 计算出来的。买方有权替换卖方的优先级信号。
| 属性 | 说明 |
| 优先级向量 | 买方通过 K/V 服务的 priorityVector 键的值提供向量 |
| 优先信号 | 卖方通过设置竞价配置的 priority_signals 来提供信号 |
| 优先级信号替换 | 买方在竞价配置的 PerBuyerConfig 的 priority_signals_overrides 字段中提供替换项。 |
在竞价期间,浏览器会计算 priorityVector 和 prioritySignals 中匹配键的稀疏点积,以确定优先级。在下图中,优先级由 (4 * 2) + (3 * -1) 计算得出,简化为 8 + -3,因此此兴趣群组在竞价时的优先级为 5。
此外,B&A 中还可使用其他信号来确定优先顺序:
| 信号 | 说明 |
deviceSignals.one |
该值始终为 1,可用于向点积添加常量。 |
deviceSignals.ageInMinutes |
该值以分钟为单位描述了兴趣群组的年龄(自最近一次加入兴趣群组以来经过的时间),是一个介于 0 到 43,200 之间的整数。 |
deviceSignals.ageInMinutesMax60 |
该值与 ageInMinutes 信号描述的相同,但上限为 60。如果群组存在时间超过 1 小时,则返回 60。 |
deviceSignals.ageInHoursMax24 |
该值以小时为单位描述兴趣群组的存续时间,最长为 24 小时。如果群组存在时间超过一天,则返回 24。 |
deviceSignals.ageInDaysMax30 |
该值以天为单位描述了兴趣群组的年龄,最长为 30 天。如果群组存在时间超过 30 天,则返回 30。 |
如需了解详情,请访问 GitHub 上的说明。
设置可信出价信号
由于 B&A 竞价载荷中会省略一些数据,因此您可以使用键值对服务将省略的数据作为可信的出价信号提供给 generateBid() 函数。
以下省略的数据可由 K/V 服务提供:
userBiddingSignals(如果买方使用)- 与每个广告相关联的
metadata - 与每个广告相关联的
adRenderId - 报告 ID
一种可行的方法是在可信出价信号键中添加唯一标识符,然后将关联的数据发送到您的服务器,以便将其加载到键/值服务中。不过,实际实现取决于广告技术,并且 API 不具有规范性。
以下示例介绍了一种可实现的方法:
const ad1RenderURL = 'https://dsp.example/ad-1.html';
const ad2RenderURL = 'https://dsp.example/ad-2.html';
const ad1RenderId = 'render-id-1';
const ad2RenderId = 'render-id-2';
const ad1ReportingId = 'reporting-id-1';
const ad2ReportingId = 'reporting-id-2';
// Generate a unique identifier
const id = crypto.randomUUID();
// Define the keys with the unique ID
const trustedSignalsKeyForIG = `interest-group-${id}`
// Set the keys in the interest group
navigator.joinAdInterestGroup({
// …
ads: [
{
renderURL: ad1RenderURL,
adRenderId: ad1RenderId,
buyerReportingId: ad1ReportingId
},
{
renderURL: ad2RenderURL,
adRenderId: ad2RenderId,
buyerReportingId: ad2ReportingId
},
],
trustedBiddingSignalsKeys: [
trustedSignalsKeyForIG
]
});
// Send the associated data to your server to be loaded into the Key/Value Service
fetch('https://dsp.example/kv/load', {
method: 'POST',
body: JSON.stringify({
id,
[trustedSignalsKeyForIG]: {
userBiddingSignals: {
favoriteColor: 'blue'
},
ads: [
{
renderURL: ad1RenderURL,
adRenderId: ad1RenderId,
buyerReportingId: ad1ReportingId,
metadata: {
color: 'red'
}
},
{
renderURL: ad2RenderURL,
adRenderId: ad2RenderId,
buyerReportingId: ad2ReportingId,
metadata: {
color: 'blue'
}
},
]
}
})
});
在此示例中,为 IG 定义了一个唯一标识符,该标识符会成为可信信号密钥的一部分。IG 的键及其关联的值会发送到您的服务器,以加载到键值对服务中。在竞价的后续阶段,浏览器会提取可信信号,并在买方的 generateBid() 函数中提供这些信号。
根据需要从 K/V 返回兴趣组更新信号
可信信号的 updateIfOlderThanMs 键用于在比通常的每日间隔更早的时间更新兴趣群体。如果兴趣组在超过为 updateIfOlderThanMs 键返回的毫秒值的时间段内未加入或更新,则会通过 updateURL 机制更新该兴趣组。请注意,Chrome 更新兴趣群组的频率不会超过每 10 分钟一次。
如果 B&A 竞价返回的胜出广告与浏览器中存储的兴趣组中定义的广告不匹配,则浏览器将使竞价失败。updateIfOlderThanMs 机制有助于确保浏览器和 B&A 竞价就兴趣群体中的广告集达成一致。
如需了解详情,请参阅说明。
generateBid() 项任务
需要为 generateBid() 调用执行以下任务。
读取浏览器信号
传递到 B&A generateBid() 调用的 browserSignals 对象如下所示:
{
topWindowHostname: 'advertiser.example',
seller: 'https://ssp.example',
topLevelSeller: 'https://ssp-top.example',
joinCount: 5,
bidCount: 24,
recency: 1684134092,
// prevWins is [timeInSeconds, adRenderId]
prevWins: [
[9342, 'render-id-1'],
[1314521, 'render-id-2']
],
// Compiled WebAssembly code
wasmHelper: WebAssembly.Module
// Data-Version value from K/V response, if available
dataVersion: 1,
}
browserSignals 中提供以下经过修改或新增的属性:
| 属性 | 说明 |
prevWins |
prevWins 是一个包含时间和广告元组的数组。相应广告自上次在过去 30 天内赢得竞价以来经过的时间(以秒为单位)。它已修改为提供 |
wasmHelper |
从 biddingWasmHelperURL 提供的代码的已编译对象。 |
dataVersion |
受信任的服务器可以选择性地包含一个数字 Data-Version 响应标头,该标头可在 generateBid() 中使用。如需了解详情,请参阅 GitHub 上的说明。 |
从 generateBid() 返回渲染网址
由于 B&A 竞价载荷中省略了 ads 对象,因此必须重新创建从 generateBid() 返回的渲染网址。呈现网址的重新创建方式由您的实现决定,并且返回的网址必须与兴趣组中定义的呈现网址相匹配。
一种可行的方法是维护一个基本网址,并使用来自 interestGroup 和 trustedBiddingSignals 的信息填充模板。
在此示例中,我们将根据颜色和商品定义 4 个广告:
await navigator.joinAdInterestGroup({
ads: [
{ renderURL: 'https://dsp.example/red-shirt-ad.html', adRenderId: 'arid1'},
{ renderURL: 'https://dsp.example/blue-shirt-ad.html', adRenderId: 'arid2'},
{ renderURL: 'https://dsp.example/red-pants-ad.html', adRenderId: 'arid3'},
{ renderURL: 'https://dsp.example/blue-pants-ad.html', adRenderId: 'arid4'},
],
trustedBiddingSignalKeys: [
'userBiddingSignals-someUniqueId',
// ...and more
]
})
然后,我们会发送用户喜爱的颜色和商品信息,以加载到键/值服务中:
fetch('https://dsp.example/kv/load', {
body: JSON.stringify({
'userBiddingSignals-someUniqueId': {
favoriteColor: 'blue',
favoriteProduct: 'shirt'
}
})
})
稍后,当竞价开始时,可信出价信号会在 generateBid() 中提供,并且该信息可用于重建网址:
function generateBid(..., trustedBiddingSignals, browserSignals) {
const { userBiddingSignals } = trustedBiddingSignals
const { favoriteColor, favoriteProduct } = userBiddingSignals
return {
bid: 1,
render: `https://dsp.example/${favoriteColor}-${favoriteProduct}-ad.html`
}
}
从 generateBid() 返回报告 ID
由于报告 ID 不包含在 B&A 竞价载荷中,因此 generateBid() 可以通过可信出价信号获取该 ID。确定要使用哪个报告 ID 后,系统会从 generateBid() 返回所选的报告 ID。返回的 ID 必须与兴趣组中定义的 ID 一致。
在此示例中,系统选择了广告 1,并从 generateBid() 返回了其关联的呈现 ID:
generateBid(..., trustedBiddingSignals, …) {
const { ad1ReportingId, ad2reportingId } = trustedBiddingSignals;
// ...
return {
bid: 1,
render: 'https://dsp.example/ad-1.html'
buyerReportingId: ad1reportingId
}
}
返回的报告 ID 通过 buyerReportingSignals 在 reportWin() 中提供:
reportWin(..., buyerReportingSignals) {
const { buyerReportingId } = buyerReportingSignals;
}
如果未从 generateBid() 返回 buyerReportingId,则 interestGroupName 值可在 buyerReportingSignals 中找到,而不是在 buyerReportingId 中找到。
如需了解详情,请参阅报告 ID 指南。
后续步骤
您可以参考以下资源
了解详情
- 详细了解 Chrome 中的 B&A 竞价配置
- 按照端到端本地测试 Codelab 的说明,通过 B&A 实验 Protected Audience。
有疑问?
- 如果您对出价和竞价服务有疑问,请在 B&A 服务代码库中提交问题。