使用 Select 网址 API 轮播广告素材

使用 Select 网址 API 充分利用 Shared Storage,以确定用户在各个网站上看到的广告素材。

广告客户或内容生产者可能希望对广告系列应用不同的内容轮播策略,并轮播内容或广告素材以提高效果。Select 网址 API 可用于在不同的网站上运行不同的轮替策略,例如顺序轮替和平均分配轮替。

借助 Select 网址 API 广告素材轮替功能,您可以存储广告素材 ID、观看次数和用户互动等数据,以确定用户在不同网站上看到的广告素材。

如需详细了解底层 API 及其选择方式,请浏览“Select 网址”API 文档

尝试广告素材轮播

如需试用广告素材轮替功能,请确保已启用 Select 网址 API 和共享存储空间:

  • chrome://settings/content/siteData 中,选择 Allow sites to save data on your deviceDelete data sites have saved to your device when you close all windows
  • chrome://settings/adPrivacy/sites 中,选择 Site-suggested ads

试用我们的“共享存储空间”实时演示,查看本文档中代码示例的实时版本。

带有代码示例的演示

在此示例中:

  • creative-rotation.js 是用于定义要轮替的内容以及用于确定要选择和显示的下一个内容的任何数据(例如本例中的权重)的第三方脚本。发布商页面会执行此脚本。此脚本会调用共享存储空间 Worklet,以便根据存储空间中的可用数据和可供选择的网址列表确定要显示的内容。

  • creative-rotation-worklet.js 是第三方的共享存储工作流,用于查找轮替策略、计算下一步要发布的内容,并返回相应内容。

演示的运作方式

  1. 当用户访问发布商网页时,该网页会加载第三方的 creative-rotation.js 脚本。广告素材轮替脚本负责加载和运行共享存储工作流程。该脚本会向 worklet 调用提供可供选择的网址列表。
  2. 在 worklet 中,如果尚未初始化共享存储空间,则系统会使用初始广告素材轮替策略和广告素材编号来初始化存储空间。此演示中使用的初始轮替策略是顺序策略。
  3. 该 worklet 会从共享存储空间读取轮播模式,并返回下一个广告的索引。在顺序轮替模式下,它还会使用要用于下次调用的新值更新共享存储空间中的广告素材编号。该 worklet 会根据调用 selectURL 时使用的 resolveToConfig 值返回 FencedFrameConfig 或不透明 URN 对象。
  4. creative-rotation 脚本会在 Fenced Frame 或 iFrame 中显示所选广告。如需详细了解返回类型,请参阅“呈现广告”文档
  5. 当用户更改旋转模式时,共享存储空间 Worklet 会更新存储在共享存储空间中的广告素材旋转模式值。
  6. 重新加载发布商页面时,系统会重复第 1-4 步,以便根据所选轮替策略选择要观看的下一个广告

代码示例

以下是 creative-rotation.jscreative-rotation-worklet.js 的代码示例。

creative-rotation.js

const contentProducerUrl = 'https://your-server.example';

// Ad config with the URL of the ad, a probability weight for rotation, and the clickthrough rate.
const DEMO_AD_CONFIG = [
  {
    url: `${contentProducerUrl}/ads/ad-1.html`,
    weight: 0.7,
  },
  {
    url: `${contentProducerUrl}/ads/ad-2.html`,
    weight: 0.2,
  },
  {
    url: `${contentProducerUrl}/ads/ad-3.html`,
    weight: 0.1,
  },
];

async function setRotationMode(rotationMode) {
  // Load the worklet module
  const creativeRotationWorklet = await window.sharedStorage.createWorklet(
    `${contentProducerUrl}/url-selection/creative-rotation-worklet.js`,
    { dataOrigin: 'script-origin' }
  );

  await creativeRotationWorklet.run('set-rotation-mode', {
    data: { rotationMode }
  });
  console.log(`creative rotation mode set to ${rotationMode}`);
}

async function injectAd() {
  // Load the worklet module
  const creativeRotationWorklet = await window.sharedStorage.createWorklet(
    `${contentProducerUrl}/url-selection/creative-rotation-worklet.js`,
    { dataOrigin: 'script-origin' }
  );

  const urls = DEMO_AD_CONFIG.map(({ url }) => ({ url }));

  // Resolve the selectURL call to a fenced frame config only when it exists on the page
  const resolveToConfig = typeof window.FencedFrameConfig !== 'undefined';

  // Run the URL selection operation to determine the next ad that should be rendered
  const selectedUrl = await creativeRotationWorklet.selectURL('creative-rotation', urls, {
    data: DEMO_AD_CONFIG,
    resolveToConfig
  });

  const adSlot = document.getElementById('ad-slot');

  if (resolveToConfig && selectedUrl instanceof FencedFrameConfig) {
    adSlot.config = selectedUrl;
  } else {
    adSlot.src = selectedUrl;
  }
}

injectAd();

creative-rotation-worklet.js

class SelectURLOperation {
  async run(urls, data) {
    // Initially set the storage to sequential mode for the demo
    await SelectURLOperation.seedStorage();

    // Read the rotation mode from Shared Storage
    const rotationMode = await sharedStorage.get('creative-rotation-mode');

    // Generate a random number to be used for rotation
    const randomNumber = Math.random();

    let index;

    switch (rotationMode) {
      /**
       * Sequential rotation
       * - Rotates the creatives in order
       * - Example: A -> B -> C -> A ...
       */
      case 'sequential':
        const currentIndex = await sharedStorage.get('creative-rotation-index');
        index = parseInt(currentIndex, 10);
        const nextIndex = (index + 1) % urls.length;

        console.log(`index = ${index} / next index = ${nextIndex}`);

        await sharedStorage.set('creative-rotation-index', nextIndex.toString());
        break;

      /**
       * Evenly-distributed rotation
       * - Rotates the creatives with equal probability
       * - Example: A=33% / B=33% / C=33%
       */
      case 'even-distribution':
        index = Math.floor(randomNumber * urls.length);
        break;

      /**
       * Weighted rotation
       * - Rotates the creatives with weighted probability
       * - Example: A=70% / B=20% / C=10%
       */
      case 'weighted-distribution':
        console.log('data = ', JSON.stringify(data));
        // Find the first URL where the cumnulative sum of the weights
        // exceed the random number. The array is sorted by the weight
        // in descending order.
        let weightSum = 0;
        const { url } = data
          .sort((a, b) => b.weight - a.weight)
          .find(({ weight }) => {
            weightSum += weight;
            return weightSum > randomNumber;
          });

        index = urls.indexOf(url);
        break;

      default:
        index = 0;
    }

    console.log(JSON.stringify({ index, randomNumber, rotationMode }));
    return index;
  }

  // Set the mode to sequential and set the starting index to 0.
  static async seedStorage() {
    await sharedStorage.set('creative-rotation-mode', 'sequential', {
      ignoreIfPresent: true,
    });

    await sharedStorage.set('creative-rotation-index', 0, {
      ignoreIfPresent: true,
    });
  }
}

class SetRotationModeOperation {
  async run({ rotationMode }) {
    await sharedStorage.set('creative-rotation-mode', rotationMode);
  }
}

// Register the operation as 'creative-rotation'
register('creative-rotation', SelectURLOperation);
register('set-rotation-mode', SetRotationModeOperation);

带有屏幕截图的演示

  1. 如需使用 Select 网址 API 和共享存储空间访问广告素材轮替功能,请访问 https://shared-storage-demo.web.app/。选择“广告素材轮播”演示。

  2. 选择以“发布商 A”的身份探索演示。系统会将您重定向到 https://shared-storage-demo-publisher-a.web.app/creative-rotation。该页面会根据存储在共享存储空间中(通过 Select 网址 API 访问)的广告素材轮替数据加载编号内容。广告素材轮播的演示模式包括依序轮播、均匀分布和加权分布。该 worklet 会执行逻辑来选择要在 iframe 中显示的内容。下图显示了发布商页面。 一张屏幕截图,显示了发布商 A 的页面内容 https://shared-storage-demo-publisher-a.web.app/creative-rotation,其中包含一个包含数字 1 图片的 iframe,以及用于选择广告素材轮替策略(顺序、平均分配和加权分配)的控件。还有一个文本区域,其中介绍了不同的广告素材轮替策略,以及指向 iframe 和 Worklet 逻辑的链接。

    屏幕截图:显示了“发布商 A”页面,其中包含数字 1 的图片和用于选择广告素材轮替策略的控件。

  3. 如需查看共享存储空间中存储的内容,请在 Chrome 开发者工具中前往“应用”->“共享存储空间”。系统会为共享存储空间创建两个条目。https://shared-storage-demo-publisher-a.web.app 源有可用的空存储空间。这将包含特定于该来源的存储空间,在我们的演示中将保持空白,因为发布商无需写入共享存储空间。请注意,当您稍后出于演示目的访问该页面时,系统会为发布商 B 创建类似的存储空间。一张屏幕截图,显示了 Chrome DevTools,特别是“Application”(应用)部分,突出显示了“Shared Storage”(共享存储空间)条目,并显示了“Publisher A”(发布商 A)https://shared-storage-demo-publisher-a.web.app 的来源的空存储空间

    Chrome 开发者工具会显示发布商 A 的“共享存储空间”为空。

  4. 系统将为 https://shared-storage-demo-content-producer.web.app 源创建另一个共享存储空间条目。这是发布商页面上嵌入的第三方 iframe 的存储空间。此存储空间将用于在两个可用发布商之间共享数据,以协调广告素材选择。此共享存储空间将用于保存两个键值对,以保存有关所展示广告素材和轮替策略的信息。演示中使用的第一个键是 creative-rotation-index,其值为顺序模式下的当前广告素材编号。第二个键是 creative-rotation-mode,用于指定所使用的旋转策略。一张屏幕截图,显示了 Chrome 开发者工具,具体而言是来源 https://shared-storage-demo-content-producer.web.app 的共享存储空间。存储空间不为空,显示了已保存的两个键值对。第一个键是 creative-rotation-index,值为 1。第二个保存的键是 creative-rotation-mode,值为“sequential”

    一张屏幕截图,显示了 Chrome 开发者工具共享存储空间,其中包含两个键值对:creative-rotation-index: 1 和 creative-rotation-mode: "sequential"。

  5. 在依序模式下刷新页面将导致显示顺序 1、2、3、1、… 中的下一个广告素材。在依序模式下,键值 creative-rotation-index 的值将根据所显示广告素材的索引而变化。一张屏幕截图,显示了“发布商 A”网页以及显示“Shared Storage”(共享存储空间)部分的 DevTools。页面上的广告素材标记为 2,同时键值 creative-rotation-index 的值也突出显示为 2,与所显示广告素材的索引相符。当前的 creative-rotation-mode 显示为 sequential。

    一张屏幕截图,显示了发布商 A 的网页和 DevTools。显示的广告素材是 2,creative-rotation-mode 为 sequential,creative-rotation-index 为 2。

  6. 使用控件按钮更改广告素材轮播模式后,系统会将键值 creative-rotation-mode 的值更新为相应的策略。该值将由 worklet 代码用于选择要在 iframe 中显示的下一个广告素材。请注意,对于顺序以外的轮替模式,为 creative-rotation-index 保存的值不会发生变化。一张屏幕截图,显示了“发布商 A”网页以及显示“Shared Storage”(共享存储空间)部分的 DevTools。网页上的广告素材显示为 1。同时突出显示 creative-rotation-mode 已设置为加权分布,并突出显示用于将轮播模式设置为加权分布的相应控件。虽然显示的广告素材是 1,但 creative-rotation-index 的值为 2,因为对于除“依序”以外的轮播模式,系统不会使用或更新该索引。

    一张屏幕截图,显示了发布商 A 的网页和 DevTools。所显示的广告素材是 1,creative-rotation-mode 是加权分布,creative-rotation-index 是 2(未使用)。

  7. 前往“发布商 B”的页面:https://shared-storage-demo-publisher-b.web.app/creative-rotation。在顺序模式下,访问“发布商 A”的网址时,系统应显示顺序中的下一个广告素材。检查内容生产者的共享存储空间后,您会发现“发布商 A”和“发布商 B”共用同一存储空间,并使用其中的设置来选择要显示的下一个广告素材和要使用的轮替策略。 一张屏幕截图,显示了“发布商 B”网页,以及显示来源 https://shared-storage-demo-content-producer.web.app 的“Shared Storage”部分的 DevTools。页面上的广告素材显示为 3。而突出显示的 creative-rotation 索引为 3,creative-rotation-mode 为 sequential。

    发布商 B 的网页和开发者工具。共享存储空间广告素材为 3,creative-rotation 索引为 3,creative-rotation-mode 为 sequential。

  8. “发布商 B”的共享存储空间为空,与“发布商 A”的共享存储空间类似。  屏幕截图:显示 Chrome 开发者工具(具体为“应用”部分),突出显示了“Shared Storage”条目,并显示了“Publisher B”https://shared-storage-demo-publisher-b.web.app 的来源的空存储空间。

    Chrome 开发者工具,显示发布商 B 来源的 Shared Storage 为空。

    使用场景

    本部分介绍了 Select 网址 API 的所有可用用例。我们会根据收到的反馈和发现的新测试用例,不断添加示例。

    • 轮替广告素材:存储广告素材 ID 和用户互动等数据,以确定用户在不同网站上看到的广告素材。
    • 按频次选择广告素材:使用观看次数数据确定用户在不同网站上看到的广告素材。
    • 运行 A/B 测试:您可以将用户分配到实验组,然后将该组存储在 Shared Storage 中以供跨网站访问。
    • 为已知客户量身定制体验:根据用户的注册状态或其他用户状态分享自定义内容和号召性用语。

Engage and share feedback

Note that the Select URL API proposal is under active discussion and development and subject to change.

We're eager to hear your thoughts on the Select URL API.