> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 数据源

> 使用数据源，通过 Liquid 语法实现个性化，在发送时将您的 API 中的实时数据拉取到 OneSignal 电子邮件消息中。

数据源让您在发送时**直接从您的 API 拉取实时数据到消息中**。这让您可以提供高度个性化的内容，而无需预先将数据加载到 OneSignal 中。

当您的数据经常变化时，请使用数据源，例如：

* 用户当前的奖励余额
* 最新订单状态
* 个性化产品推荐

其他个性化方法（如[标签](./add-user-data-tags)或[动态内容](./dynamic-content)）适用于静态数据。**数据源最适合实时、快速变化的值**。

<Note>
  数据源目前**仅适用于通过 Journeys 发送的电子邮件消息**。
  需要其他渠道？[填写这份简短调查](https://survey.survicate.com/954895d3e7ed1348/?p=anonymous)。
</Note>

***

## 数据源的工作原理

1. **创建数据源** – 配置 OneSignal 如何连接到您的 API。
2. **将数据源附加**到消息模板。
3. 使用 [Liquid 语法](./using-liquid-syntax)在消息中**插入响应字段**。
4. **在发送时**，OneSignal 为每个收件人进行 API 调用，解析响应，并将数据注入到您的消息中。

### 示例：显示奖励积分

假设您想向每个客户显示他们的奖励余额：

```liquid theme={null}
Hi {{ first_name }},

You have {{ data_feed.rewards.points }} points!
Your membership status is {{ data_feed.rewards.status_level }}.

Keep shopping to earn more points!
```

当 Sarah 收到这封电子邮件时，Liquid 变量将被替换为她实际的积分余额和会员状态。以下各节将逐步介绍如何设置此示例。

## 创建和使用数据源

### 1. 设置您的数据源配置

在侧边栏中导航至**数据 > 数据源**，查看现有数据源列表并创建新的数据源。

每个数据源必须具有：

* **名称**：描述性名称，如"客户奖励 API"，帮助您区分数据源。建议使用唯一名称，但不是必需的。
* **别名**：像 `rewards` 这样的简短标识符，用于 Liquid 语法（例如 `{{ data_feed.rewards.points }}`）。必须唯一，小写字母数字字符，不含空格或特殊字符。
* **方法**：OneSignal 联系您的 API 所使用的 HTTP 方法。通常为 `GET`，但也支持 `POST`。
* **URL**：您的 API 端点。支持 Liquid 语法，使 OneSignal 能够获取特定用户的数据。

例如，您的奖励端点可能接受用户的 `external_id`（存储在 OneSignal 中）作为 URL 参数：

```liquid theme={null}
https://acme.com/customers/user_id={{ external_id }}/rewards
```

* **标头**：您的 API 所需的键值对（例如身份验证令牌）。支持 Liquid 语法。
* **请求体**：可选的 JSON 请求体。支持 Liquid 语法，与 [Journey Webhooks](./journeys-webhook#personalization) 相同。

例如，您的 API 可能要求在请求体中传入用户 ID，而不是在 URL 中：

```json theme={null}
{
	"customer_id": "{{ subscription.external_id }}"
}
```

完整的数据源配置如下所示：

<Frame caption="数据源配置示例">
  <img src="https://mintcdn.com/onesignal/pJu1B0q7HE_EbGFK/images/dashboard/data-feed-configuration-example.png?fit=max&auto=format&n=pJu1B0q7HE_EbGFK&q=85&s=d000fa94b02ee58c15b089fa7f9ad834" alt="Data Feed configuration showing name, alias, method, URL, and headers" width="901" height="1142" data-path="images/dashboard/data-feed-configuration-example.png" />
</Frame>

<Tip>
  在投入生产之前测试您的数据源。数据源测试针对您的[测试订阅](./test-users)运行，因此请确认这些订阅具有能从您的 API 返回真实结果的属性。
</Tip>

最后，**激活**您的新数据源，使其准备好使用。

### 2. 将数据源附加到您的消息模板

将您的数据源附加到消息模板，让 OneSignal 知道要使用它。

1. 导航至**消息 > 模板**
2. 在消息部分，选择**个性化**按钮

<Frame caption="个性化按钮选项">
  <img src="https://mintcdn.com/onesignal/ciRrThfP6xMpI7GY/images/dashboard/data-feeds-personalization-button.png?fit=max&auto=format&n=ciRrThfP6xMpI7GY&q=85&s=a2b46a9c67cc0ce86c469c407d2afbac" alt="Personalization button in the message template editor" width="1940" height="614" data-path="images/dashboard/data-feeds-personalization-button.png" />
</Frame>

3. 打开**数据源**并选择您的数据源

<Frame caption="消息编辑器中的数据源部分">
  <img src="https://mintcdn.com/onesignal/ciRrThfP6xMpI7GY/images/dashboard/data-feeds-option.png?fit=max&auto=format&n=ciRrThfP6xMpI7GY&q=85&s=ca51e5f38a54b8550b3256ad76843947" alt="Data Feeds toggle and feed selector in the message composer" width="978" height="762" data-path="images/dashboard/data-feeds-option.png" />
</Frame>

4. 保存您的模板

### 3. 在消息中使用数据

使用 Liquid 语法在消息中的任何地方插入响应数据。继续奖励示例，对于 Sarah（其 `external_id` 为 `a1-b2c3`）的 API 响应可能如下所示：

```json theme={null}
{
	"external_id": "a1-b2c3",
	"points": 193,
	"status_level": "Gold"
}
```

要插入积分数量和状态级别，使用点表示法引用数据源别名和响应字段：

```liquid theme={null}
You have {{ data_feed.rewards.points }} points!
Your membership status is {{ data_feed.rewards.status_level }}.
```

这告诉 OneSignal：

* 使用数据源
* 使用 `rewards` 数据源
  * 请记住：`rewards` 数据源知道用收件人的 `external_id` 调用 API
* 从响应中，插入 `points` 项的值（193）和 `status_level` 项的值（Gold）

***

## 要求和限制

您的 API 需要：

* **接受单步身份验证**，在标头中使用身份验证令牌
* **快速响应。** 推荐在 250 毫秒以内（这直接影响发送速度）
* **返回 JSON。** 目前不支持其他格式。
  * 如果您需要其他格式，请[分享您的用例](https://survey.survicate.com/954895d3e7ed1348/?p=anonymous)。
* **处理您的发送量。** 如果您的 API 速率限制较低，会减慢消息投递速度。
* **返回合理大小的负载。** 建议保持响应在 50 KB 以下以获得最佳性能。

当前限制：

* **每个模板一个数据源。** 在单次 API 响应中获取您需要的所有数据。
* **每个数据源每条消息一次 API 调用。**
* **仅限 Journeys。** 尚未适用于其他发送方法。
* **没有链式调用。** 一个数据源的负载不能用于调用另一个数据源。

<Info>
  需要每个模板支持多个数据源或其他渠道的支持？[分享您的用例](https://survey.survicate.com/954895d3e7ed1348/?p=anonymous)以帮助确定这些功能的优先级。
</Info>

***

## 设置您的 API

在创建数据源之前，确保您的 API 能够处理以下要求：

### 身份验证

您的 API 应通过标头接受身份验证：

```
Authorization: Bearer YOUR_TOKEN
```

或

```
X-API-Key: YOUR_KEY
```

### JSON 请求体

如果您需要在请求中包含请求体，您的 API 应接受 JSON。这可能意味着您的标头需要包含 `Content-Type: application/json`。

### JSON 响应

您的 API 应返回 JSON 对象。通常这意味着您的标头将包含 `Accept: application/json`。

### 个性化参数

您通常会在 URL 中传递用户标识符，如下所示：

```liquid theme={null}
https://api.example.com/users/{{external_id}}/data
https://api.example.com/rewards?email={{email | url_encode}}
```

和/或在请求体中：

```json theme={null}
{
	"customer_id": "{{ external_id }}",
	"email": "{{ subscription.email }}"
}
```

确保这些数据在 OneSignal 中存在（通常作为标签，但也有其他选项，如[自定义事件属性](#examples-and-advanced-use-cases)）。

### 速率限制

考虑您的 API 速率限制。向 10,000 个用户发送意味着快速连续进行 10,000 次 API 调用。确保您的 API 能够处理此数量。

### 错误处理

如果您的 API 返回错误或没有用户数据，消息不会发送给该收件人。确保您的 API 为所有预期用户返回数据。

***

## 入门清单

在实施数据源之前，请回答以下问题：

* 我想在消息中显示什么数据？从包含要从 API 填充的项目的简单大纲开始，有助于整理思路。
* 这些数据是否可以通过单个 API 端点获得？
* 我将如何验证 API 请求？
* 我将使用什么标识符或其他数据项来获取个性化数据？
* 该标识符是否已经存储在 OneSignal 中？如果没有，将如何填充？
* 我的 API 能否处理我将产生的请求量？
* 如果我的 API 没有用户数据会怎样？

***

## 示例和高级用例

数据源可以与 Liquid 语法结合使用，或与其他功能创造性地结合使用，以产生更复杂的个性化效果。

<Tabs>
  <Tab title="循环迭代：废弃购物车">
    假设您有一个数据源 cart，它返回用户购物车中的商品数组，以及购物车的总金额：

    ```json theme={null}
    {
      "items": [
        {
          "name": "Blue Running Shoes",
          "price": 84.00,
          "image_url": "https://acme.com/blue-running-shoes.png"
        },
        {
          "name": "Protein Bar",
          "price": 5.99,
          "image_url": "https://acme.com/protein-bar.png"
        }
      ],
      "total": 89.99
    }
    ```

    如果您想显示购物车中的每个商品以及购物车总额，您可以在 Liquid 中使用 for 循环：

    ```html theme={null}
    <ul>
      {% for item in data_feed.cart.items %}
        <li>
          <strong>{{ item.name }}</strong><br>
          ${{ item.price }}<br>
          <img src="{{ item.image_url }}" alt="{{ item.name }}">
        </li>
      {% endfor %}
    </ul>

    <p>Cart total: ${{ data_feed.cart.total }}</p>

    ```

    这将产生：

    ```text theme={null}
    - Blue Running Shoes
    - $84.00
    - <running shoes image>
    - Protein Bar
    - $5.99
    - <protein bar image>
    Cart total: $89.99
    ```

    <Note>
      如果您使用电子邮件块编辑器，当插入这种复杂的 Liquid 语法时，特别是如果您需要包含图像或链接，最好使用自定义 HTML 块元素以获得最佳结果。
    </Note>

    <Tip>
      想了解如何使用自定义事件触发此废弃购物车邮件？请查看**自定义事件属性**标签页了解完整工作流程。
    </Tip>
  </Tab>

  <Tab title="自定义事件属性">
    继续上一个废弃购物车示例，我们首先如何知道要获取那个特定的购物车呢？

    一种方法可能是创建一个由 `cart_abandoned` [自定义事件](./custom-events)触发的 Journey，其中属性包含 cart\_id。在此示例中，该事件通过 API 发送到 OneSignal：

    ```bash theme={null}
    curl --request POST \
      --url https://api.onesignal.com/apps/{app_id}/custom_events \
      --header 'Accept: application/json' \
      --data '{
      "events": [
        {
          "name": "cart_abandoned",
          "external_id": "user_12345",
          "properties": {
            "cart_id": 98765
          }
        }
      ]
    }'
    ```

    <Frame caption="Journey 入口的自定义事件">
      <img src="https://mintcdn.com/onesignal/ciRrThfP6xMpI7GY/images/dashboard/data-feed-custom-event-journey-entry.png?fit=max&auto=format&n=ciRrThfP6xMpI7GY&q=85&s=6bb357d09ef9a2830ee6e9a19109afc1" alt="Journey entry node triggered by a custom event" width="936" height="548" data-path="images/dashboard/data-feed-custom-event-journey-entry.png" />
    </Frame>

    当此事件触发时，用户 `user_12345` 进入旅程，然后到达发送电子邮件的节点。该电子邮件模板使用 `cart` 数据源设置，其中 URL 设置为检索特定购物车的内容，如下所示：

    ```liquid theme={null}
    https://acme.com/carts/{{ journey.event.cart_abandoned.data.cart_id }}
    ```

    因此，当摄取此特定事件并触发 Journey 时：

    1. `cart_id` 值 `98765` 将存储到 Journey 中
    2. 当到达电子邮件步骤时，`cart` 数据源将引用该 `cart_id` 值并使用它来调用购物车 API
    3. 返回的 JSON 属性将被解析并插入到电子邮件中，如上面的示例所示

    <Tip>
      想了解如何根据订单状态有条件地显示数据源内容？请查看**条件显示：订单状态**标签页了解更多。
    </Tip>
  </Tab>

  <Tab title="条件显示：订单状态">
    假设您想包含客户订单的状态，但仅在订单已发货时才包含跟踪号链接。您可以使用 `if` 语句来实现：

    ```liquid theme={null}
    Your order is {{data_feed.order.status}}!

    {% if data_feed.order.tracking_number != empty %}
    Track it here: {{data_feed.order.tracking_url}}
    {% endif %}
    ```

    在这里，只有在 `tracking_number` 存在时才会显示跟踪链接。
  </Tab>

  <Tab title="无个性化的自动化">
    数据源可以用于自动向您的消息中插入最新信息，而不一定需要针对每个收件人进行个性化。

    例如，您可能在电子邮件顶部插入横幅图像，并每月更改以跟上节假日和其他月度活动。与其每月记得向 OneSignal 上传新图像并更改所有模板，您可以设置一个数据源，从您的 CMS 或其他资产管理位置获取当前横幅图像 URL。

    您将设置一个 `banner` 数据源，指向 URL 中**不含**任何变量的端点，如下所示：

    ```liquid theme={null}
    https://acme.com/assets/email-banner
    ```

    它返回包含当前横幅 URL 的响应：

    ```json theme={null}
    {
    	"banner_url": "https://acme.com/assets/email-banner/2025july.png"
    }
    ```

    您将设置您的电子邮件模板使用 `{{ data_feed.banner.banner_url }}` 作为图像源 URL，从而自动化此流程。
  </Tab>

  <Tab title="个性化优惠券码">
    本示例介绍如何使用数据源在电子邮件中发送个性化的一次性优惠券码，该数据源会在发送时通过 API 为每个收件人获取唯一值。

    ### 目标

    发送如下电子邮件：

    > 您好 George，
    >
    > 在接下来的 2 小时内完成预订，使用您的专属码 XYZ123ABC 立享 10% 折扣

    每个用户收到唯一的优惠券码，在发送电子邮件时通过外部 API 实时生成，在给定时间窗口内有效，且与该用户绑定。

    ### 前提条件

    * 在 OneSignal 中[已配置电子邮件渠道](./email-setup)（您的应用已启用电子邮件功能）
    * 一个外部 API，接受用户标识符（例如 [`external_id`](./users#external-id)）和活动标识符，并返回包含优惠券码、折扣和到期时间的 JSON
    * 每个用户的唯一标识符（如 `external_id`），您的 API 可用其生成优惠券
    * 用于通过 OneSignal Journey 发送电子邮件的[细分](./segmentation)或触发条件（例如"过去 24 小时内的废弃搜索"）

    ### 第 1 步：创建数据源

    <Steps>
      <Step title="导航至数据源">
        在您的 OneSignal 应用中，从导航栏选择**数据源**，然后点击**新建数据源**。
      </Step>

      <Step title="配置数据源">
        配置以下字段：

        * **数据源名称**：`coupon_code_generator`
        * **别名**：`coupon`
        * **方法**：`GET`
        * **URL**：`https://api.example.com/generate-coupon?userId={{ external_id }}&campaign=AbandonedBooking10`
        * **标头**：
          ```json theme={null}
          {
            "Authorization": "Bearer YOUR_API_TOKEN"
          }
          ```
      </Step>

      <Step title="引用 API 响应">
        当 API 返回如下 JSON 时：

        ```json theme={null}
        {
          "code": "AB10-5F3K-HT9L",
          "discount_percent": "10%",
          "expires_in_hours": 2
        }
        ```

        您可以在电子邮件模板中引用其值：

        * `{{ data_feed.coupon.code }}`
        * `{{ data_feed.coupon.discount_percent }}`
        * `{{ data_feed.coupon.expires_in_hours }}`
      </Step>

      <Step title="测试并激活数据源">
        点击**发送测试**以验证您的配置，然后点击**激活**使数据源可在模板中使用。
      </Step>
    </Steps>

    ### 第 2 步：创建电子邮件模板

    1. 在 OneSignal 中，转到**消息 → 电子邮件 → 新建模板**
    2. 在消息正文中使用数据源别名和字段。例如：

    ```html theme={null}
    <h2>Hi {{ first_name }},</h2>
    <p>
    Complete your booking in the next {{ data_feed.coupon.expires_in_hours }} hours and save
    {{ data_feed.coupon.discount_percent }} with your personal code:
    <strong>{{ data_feed.coupon.code }}</strong>
    </p>

    <p><a href="https://example.com/checkout?coupon={{ data_feed.coupon.code }}">Use Code Now →</a></p>
    ```

    <Note>
      * 使用 `{{ data_feed.<alias>.<field> }}` 格式的 Liquid 语法
      * 确保数据源已附加到模板
      * 如果使用拖放编辑器并包含自定义 Liquid 逻辑，请使用 HTML 块
    </Note>

    ### 第 3 步：附加数据源并触发电子邮件

    1. 在模板编辑器中，在**个性化**下，打开**数据源**并选择您的数据源（`coupon_code_generator`）
    2. 这确保 OneSignal 在发送时为每个收件人进行 API 调用，填充数据并注入到电子邮件中
    3. 设置 Journey 以自动发送消息：
       * **入口条件**：细分，如"过去 24 小时内的废弃搜索"
       * **[等待直到](./custom-events#wait-until-event)**：创建 `booking_completed` 自定义事件。配置等待条件，如果此事件触发则退出 Journey，否则在 1 小时后继续。如果用户完成预订，则退出而不接收电子邮件；否则继续接收优惠券。
       * **发送电子邮件**：使用个性化优惠券电子邮件模板
       * 确保 Journey 使用电子邮件渠道，且收件人已订阅电子邮件

    ### 第 4 步：管理优惠券兑换和追踪

    您的后端应：

    1. 记录每个生成的码，包含 `userId`、`code`、`campaign`、`expiration_time` 和 `redeemed` 标志
    2. 在结账时验证并将码标记为已兑换
    3. 记录兑换数据（用户、活动和时间）以进行 ROI 分析

    ### 完整工作流程示例

    | 步骤 | 事件               | 操作                                                               |
    | -- | ---------------- | ---------------------------------------------------------------- |
    | 1  | 用户触发"废弃搜索"细分     | 用户通过细分进入 Journey                                                 |
    | 2  | Journey 触发电子邮件发送 | OneSignal 附加数据源，使用用户的 `external_id` 和活动名称调用您的 API                |
    | 3  | API 返回 JSON      | OneSignal 填充数据源优惠券字段并发送电子邮件                                      |
    | 4  | 用户收到电子邮件         | 示例："Hi George! Save 10% with your personal code: AB10-5F3K-HT9L" |
    | 5  | 用户兑换码            | 后端验证并记录兑换                                                        |

    ### 测试

    * 使用已知 `external_id` 的用户进行测试
    * 手动调用您的 API 以确认正确的 JSON 响应
    * 在 OneSignal 模板编辑器中使用**预览**验证数据源优惠券字段是否正确填充
    * 检查 API 日志中的延迟和错误
    * 如果数据源调用失败，OneSignal 将跳过向该收件人发送消息
  </Tab>
</Tabs>

***

## 常见问题

### 我的数据源值未出现在消息中，应检查什么？

按顺序检查以下内容：

1. 数据源已**附加**到模板（在**个性化 > 数据源**下）。
2. 您的 Liquid 语法与 JSON 响应结构完全匹配——`{{ data_feed.<alias>.<field> }}`。
3. 使用相同标识符手动调用 API 端点时返回有效 JSON。
4. 收件人在 OneSignal 中存储了所需的标识符（例如 `external_id`）。

### 为什么消息发送缓慢？

数据源 API 调用在发送时对每个收件人运行。如果您的 API 响应缓慢或无法处理并发请求，消息投递速度会成比例降低。目标响应时间在 250 毫秒以内，并确保您的基础设施能够处理您的发送量。

### 为什么某些收件人没有收到消息？

如果某个收件人的数据源 API 调用失败——由于 404、超时或数据缺失——OneSignal 将完全跳过该收件人。请检查数据源配置中的错误日志以及您自己的 API 日志中的失败情况。验证这些用户在 OneSignal 中是否具有所需的标识符。

### 我能在一个模板中使用多个数据源吗？

目前不支持。每个模板支持一个数据源。在单次 API 响应中获取您需要的所有数据。如果您需要多个数据源，请[分享您的用例](https://survey.survicate.com/954895d3e7ed1348/?p=anonymous)。

### 数据源是否适用于推送通知或短信？

否。数据源目前仅适用于通过 Journeys 发送的电子邮件消息。计划支持其他渠道——[分享您的用例](https://survey.survicate.com/954895d3e7ed1348/?p=anonymous)以帮助确定优先级。

### 如果我的 API 在消息发送时宕机会怎样？

OneSignal 将跳过任何数据源调用失败的收件人。消息不会发送给该收件人，也不会插入任何回退值。请在计划发送期间监控您的 API 正常运行时间和错误率。

## 相关页面

<Columns cols={2}>
  <Card title="Liquid 语法" icon="code" href="./using-liquid-syntax">
    OneSignal 消息中 Liquid 模板的完整参考。
  </Card>

  <Card title="Journeys" icon="route" href="./journeys-overview">
    构建触发数据源电子邮件的自动化消息工作流程。
  </Card>

  <Card title="自定义事件" icon="bolt" href="./custom-events">
    触发 Journeys 并传递事件属性以用于数据源 URL。
  </Card>

  <Card title="消息个性化" icon="user-pen" href="./message-personalization">
    所有个性化方法的概述——标签、Liquid、动态内容和数据源。
  </Card>
</Columns>
