> ## 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.

# 事件流

> 将消息数据实时从 OneSignal 发送到您选择的目标。

事件流允许您将消息数据实时从 OneSignal 发送到您选择的目标。事件流是将 OneSignal 连接到营销生态系统中其他产品的绝佳方式。它们使您的团队能够触发相应的消息传递、维护记录等等。

可用的事件类型包括：

* 推送消息事件（已发送、已接收、已点击、失败、已取消订阅）
* 邮件事件（已发送、已打开、已点击、已退回、已取消订阅等）
* 短信事件（已发送、失败、已取消订阅等）
* 应用内消息事件（展示、已点击等）
* 实时活动事件（已发送、已投递、确认投递、失败、已取消订阅、已点击）

## 常见用例

* **集中参与数据** — 将事件流传输到 CRM、CDP 或数据仓库，使跨渠道活动（打开、点击、退回）集中存放在一处，而不是分散在各个独立工具中。
* **分析、报告与合规** — 将每条消息事件落地到数据仓库，用于趋势分析、审计或法规记录保存。
* **监控用户流失** — 在自有系统中跟踪取消订阅、退回和关闭事件，尽早发现用户留存风险。
* **触发外部工作流** — 当用户打开或点击消息时，在其他工具中触发自动化（例如更新潜在客户评分、启动跟进序列）。
* **替代批量同步和额外集成** — 实时响应事件，将 OneSignal 直接连接到目标，减少中间工具和维护成本。

### 让技术团队快速上手

设置事件流需要营销/产品负责人（决定*哪些*事件重要以及*发送到哪里*）和工程团队（构建接收端点并配置流）共同协作。以下是工程方面的工作内容：

1. **确定目标和范围** — 商定事件应落地的位置（自有 API、数据仓库、CDP 等）、要流传输的事件类型（推送、邮件、短信、IAM、实时活动）以及消息量估算，以便对端点进行适当的容量规划。
2. **设置 HTTP 端点** — 构建或配置可公开访问的端点，接受 POST 请求。它应快速记录事件，无需繁重处理，以保持低响应时间。请参阅[重试/禁用](#retries--disabling)了解性能预期以及端点落后时会发生什么。
3. **在 OneSignal 中配置事件流** — 在**数据 > 事件流**中，选择事件、设置 URL 和身份验证标头，并使用[事件流数据](./event-streams-data)字段和 [Liquid 语法](./using-liquid-syntax)定义 JSON 正文。
4. **端到端测试** — 使用 [webhook.site](https://webhook.site) 在切换到生产端点之前验证有效载荷结构和标头（请参阅[测试](#testing)）。

***

## 设置

您可以在**数据 > 事件流 > 新建事件流**下为您的 OneSignal 应用程序配置新的事件流。

<Frame caption="新建事件流按钮">
  <img src="https://mintcdn.com/onesignal/kAXbp86YqdTAbPtE/images/dashboard/new-event-stream-button.png?fit=max&auto=format&n=kAXbp86YqdTAbPtE&q=85&s=d3789025a7b3ac3af683020430b867ad" alt="新建事件流按钮" width="2344" height="1526" data-path="images/dashboard/new-event-stream-button.png" />
</Frame>

**要求**

除非满足以下要求，否则无法发送事件：

* 指向可公开访问的 **HTTP(S) 端点**的有效 URL 或 IP 地址
* URL 和 IP 地址必须可公开路由
* 域名必须包含已识别的顶级域名（例如".com"、".net"）

### 事件选择

为您的事件流命名，然后点击**选择事件**。

<Frame caption="事件流名称和选择事件按钮">
  <img src="https://mintcdn.com/onesignal/kAXbp86YqdTAbPtE/images/dashboard/event-stream-name-and-select-events-button.png?fit=max&auto=format&n=kAXbp86YqdTAbPtE&q=85&s=ec933172254e9bed4f6caabc09a6ad86" alt="事件流设置，显示选择事件和 webhook 触发器选项" width="2256" height="1438" data-path="images/dashboard/event-stream-name-and-select-events-button.png" />
</Frame>

这将打开事件选择页面，您可以在其中选择要触发事件流的事件。

<Warning>
  每个事件都计入您计划的消息事件量。对大量受众流传输**每种**事件类型（尤其是 `sent`）可能会迅速消耗您的配额——例如，单次向 100,000 名用户发送就会单独产生 100,000 个 `sent` 事件。

  管理用量的方法：

  * **仅选择您需要的事件类型** — 例如，如果您不需要发送级别的跟踪，`received` 和 `clicked` 可能已足够。
  * \*\*使用[事件流过滤器](#event-stream-filters)\*\*将事件限制在特定消息或模板，而不是流传输所有流量。
</Warning>

<Frame caption="事件选择页面">
  <img src="https://mintcdn.com/onesignal/kAXbp86YqdTAbPtE/images/dashboard/event-selection-page.png?fit=max&auto=format&n=kAXbp86YqdTAbPtE&q=85&s=ab975f206e86a2a47ab93feb11efb592" alt="事件流事件选择，勾选了渠道和事件类型" width="2344" height="1526" data-path="images/dashboard/event-selection-page.png" />
</Frame>

#### 事件流过滤器

您可以通过指定一个或多个消息或模板的标识符来进一步优化事件，使您只接收与特定消息相关的事件。

<Frame caption="按模板过滤事件">
  <img src="https://mintcdn.com/onesignal/4HyuQPBpu-4xjmQC/images/docs/d3459b5c919e7f10b4712268475c839b05a7e63389942ceec2c98a94019c8db6-image2.png?fit=max&auto=format&n=4HyuQPBpu-4xjmQC&q=85&s=1f4be18daaa363bc74f9ef633a9f07ee" alt="消息和模板 ID 的事件流过滤器字段" width="1092" height="561" data-path="images/docs/d3459b5c919e7f10b4712268475c839b05a7e63389942ceec2c98a94019c8db6-image2.png" />
</Frame>

模板标识符可以通过导航到**消息 > 模板**来复制。在要跟踪的模板旁边，选择**选项 > 复制模板 ID**，然后将其粘贴到事件流过滤器中。

<Frame caption="复制模板的模板 ID">
  <img src="https://mintcdn.com/onesignal/kAXbp86YqdTAbPtE/images/dashboard/copy-template-id.png?fit=max&auto=format&n=kAXbp86YqdTAbPtE&q=85&s=fabf546844a6a282b19459ec4402fb46" alt="消息操作菜单，包含复制模板 ID 选项" width="2358" height="1646" data-path="images/dashboard/copy-template-id.png" />
</Frame>

### 配置事件流

选择 HTTP 方法、URL，并为事件流添加头部。这是应该配置身份验证的地方，以确保 OneSignal 和您的系统之间的安全通信。

URI 和头部可以包含 liquid 语法，这些语法来自用户属性和事件流的属性。

#### 认证头部

您可以添加认证头部来验证发送到您端点的请求确实来自 OneSignal。常见的认证方法包括：

* **授权头部**：添加一个 `Authorization` 头部，其中 `YOUR_TOKEN` 由您的系统或第三方提供，如：
  * `Basic {{YOUR_TOKEN}}`
  * `Bearer {{YOUR_TOKEN}}`
  * `ApiKey {{YOUR_API_KEY}}`
* **自定义头部**：您也可以添加自定义头部，如：
  * `X-API-Key: {{YOUR_API_KEY}}`

*注意：OneSignal 不提供加密服务*

#### 测试您的配置

如果您正在寻找一种简单的测试方法，请使用 [webhook.site](https://webhook.site)。在页面中央找到"您的唯一 URL"。复制该 URL 并在您的事件流配置的 URL 字段中使用它。

<Frame caption="配置 Webhook">
  <img src="https://mintcdn.com/onesignal/_KaXe4GQkxsEfa17/images/docs/3c3a05f-Configure_Webhook.jpg?fit=max&auto=format&n=_KaXe4GQkxsEfa17&q=85&s=3c3011e3cfd1bab888044f2151ea1f3c" alt="配置了 webhook.site 测试 URL 的事件流 URL 字段" width="2248" height="822" data-path="images/docs/3c3a05f-Configure_Webhook.jpg" />
</Frame>

#### 禁用的头部

以下头部是受限的，无法设置。

* `content-length`
* `referer`
* `metadata-flavor`
* `x-google-metadata-request`
* `host`
* `x-onesignal*`

### 正文

事件流的正文将是 JSON 格式。正文 JSON 可以定义为单独的键/值对，也可以定义为可编辑的代码块。要更改输入方法，请使用正文标题下的第一个下拉菜单并选择自定义正文。

<Frame caption="事件流正文选项">
  <img src="https://mintcdn.com/onesignal/3zq1PvSaqvUE2bIx/images/docs/2490576-Screenshot_2023-11-27_at_11.04.42_PM.png?fit=max&auto=format&n=3zq1PvSaqvUE2bIx&q=85&s=f71ea7f3a0aced9003ded0a71edb2e22" alt="带有键值和自定义正文选项的事件流正文编辑器" width="1388" height="286" data-path="images/docs/2490576-Screenshot_2023-11-27_at_11.04.42_PM.png" />
</Frame>

在右侧，您可以看到根据事件流设置期间输入的内容构建的示例 cURL 请求

<Frame caption="事件流的 cURL 预览">
  <img src="https://mintcdn.com/onesignal/tNi1OgLc_p9hiq7_/images/docs/1a107a3-Screenshot_2023-11-27_at_11.04.49_PM.png?fit=max&auto=format&n=tNi1OgLc_p9hiq7_&q=85&s=c990246f1ed4d7f972b5a7ce2f5830bb" alt="已配置事件流请求的 cURL 预览面板" width="1360" height="400" data-path="images/docs/1a107a3-Screenshot_2023-11-27_at_11.04.49_PM.png" />
</Frame>

### 个性化

您可以使用预定义的[事件流数据](./event-streams-data)个性化事件流中的所有字段。可以使用 [Liquid 语法](./using-liquid-syntax)添加此数据。这为您使用事件流应对几乎任何用例提供了灵活性。

<Info>
  查看[事件流数据](./event-streams-data)了解所有可用于个性化的事件、消息和用户事件数据列表。
</Info>

#### 示例正文

在下拉菜单中选择"自定义正文"：

```json JSON theme={null}
{
  "Event Data": {
    "event.kind": "{{ event.kind }}",
    "event.id": "{{ event.id }}",
    "event.timestamp": "{{ event.timestamp }}",
    "event.datetime": "{{ event.datetime }}",
    "event.app_id": "{{ event.app_id }}",
    "event.subscription_device_type": "{{ event.subscription_device_type }}",
    "event.subscription_id": "{{ event.subscription_id }}",
    "event.onesignal_id": "{{ event.onesignal_id }}",
    "event.external_id": "{{ event.external_id }}",
    "event.data.page_name": "{{ event.data.page_name}}",
    "event.data.page_id": "{{ event.data.page_id}}",
    "event.data.target_name": "{{ event.data.target_name}}",
    "event.data.target_id": "{{ event.data.target_id}}",
    "event.data.failure_reason": "{{ event.data.failure_reason}}"
  },
  "Message Data": {
    "message.id": "{{ message.id }}",
    "message.name": "{{ message.name }}",
    "message.title": "{{ message.title.en }}",
    "message.contents": "{{ message.contents.en }}",
    "message.template_id": "{{ message.template_id }}",
    "message.url": "{{ message.url }}",
    "message.app_url": "{{ message.app_url }}",
    "message.web_url": "{{ message.web_url }}"
  }
}
```

<Frame caption="自定义正文">
  <img src="https://mintcdn.com/onesignal/YOTSrtBSoqdrJ37A/images/docs/4dff42d10dffb762bf72a1c7255fbac2f50fef512541eb7db29e2ee8a117e8c9-Screenshot_2025-01-17_at_2.25.40_PM.png?fit=max&auto=format&n=YOTSrtBSoqdrJ37A&q=85&s=4460da08476423fa1f7c8eac700cfbd3" alt="带有 Liquid 占位符的事件流自定义 JSON 正文" width="2112" height="1410" data-path="images/docs/4dff42d10dffb762bf72a1c7255fbac2f50fef512541eb7db29e2ee8a117e8c9-Screenshot_2025-01-17_at_2.25.40_PM.png" />
</Frame>

#### 在 JSON 中使用 Liquid 语法

在 JSON 中使用 Liquid 语法时，正确的引用取决于数据类型：

**JSON 格式化指南**

* **字符串** → **必须**用引号包围。
* **数字** → **不要**用引号包围。
* **对象** → **必须不**用引号包围。

<Note>
  以下**正确**示例中的 `//` 注释行仅用于可读性。请在您的实际事件流正文中删除它们——严格的 JSON 不允许 `//` 注释。
</Note>

**示例**

<Tabs>
  <Tab title="字符串">
    **✅ 正确** — 用引号包围：

    ```liquid JSON theme={null}
    {
      "user_id": "{{ user.onesignal_id }}"
    }
    ```

    **❌ 错误** — 缺少引号会产生无效的 JSON：

    ```liquid JSON theme={null}
    {
      "user_id": {{ user.onesignal_id }}
    }
    ```
  </Tab>

  <Tab title="数字和布尔值">
    **✅ 正确** — 不使用引号：

    ```liquid JSON theme={null}
    {
      "user_score": {{ user.tags.score }}
    }
    ```

    **❌ 错误** — 引号会将数字变成字符串：

    ```liquid JSON theme={null}
    {
      "user_score": "{{ user.tags.score }}"
    }
    ```
  </Tab>

  <Tab title="对象">
    **✅ 正确** — 不使用引号：

    ```liquid JSON theme={null}
    {
      "user_data": {{ user.tags }}
    }
    ```

    **❌ 错误** — 引号会将对象变成字符串：

    ```liquid JSON theme={null}
    {
      "user_data": "{{ user.tags }}"
    }
    ```
  </Tab>
</Tabs>

**在 liquid 语法中处理多语言条件语句的最佳实践**

为避免基于语言的条件语句问题

1. **使用直接语言检查**：在条件语句中始终直接检查 `user.language`，而不是在变量（如 `userLang`）中检查，以获得更好的兼容性。
2. **从简单开始**：从基本短语开始，然后逐渐增加复杂性。
3. **避免过度嵌套**：保持条件语句扁平化以防止解析问题。
4. **首先测试基本标点符号**：在使用特殊字符之前，先使用简单句子和标点符号开始。
5. **使用回退机制**：确保在缺少翻译的情况下有默认语言（例如英语）。
6. **坚持使用标准键**：使用标准 OneSignal 键（如 `content/title/en`）以确保可靠性。

这种方法可以最大限度地减少解析错误并确保与系统的兼容性。

<Info>
  有关如何使用 Liquid 语法个性化消息的详细信息和选项，请查看我们的[使用 Liquid 语法指南](./using-liquid-syntax)。
</Info>

***

## 结果与调试

监控事件流的性能并排查问题：

**报告选项卡** — 显示历史总计、事件流的当前状态以及随时间推移 HTTP 响应代码的时序图表。

| 响应            | 含义                                          |
| ------------- | ------------------------------------------- |
| **2xx**       | 事件已成功被您的端点接收。                               |
| **4xx / 5xx** | 您的端点返回了错误。请检查日志选项卡以获取具体状态代码和响应正文。           |
| **超时**        | 您的端点未在允许的时间窗口内响应。OneSignal 关闭了连接并将此次投递视为失败。 |

**日志选项卡** — 显示最近请求的样本，包括完整的请求正文、标头以及端点的响应。这是排查问题时首先查看的最佳位置——您可以看到 OneSignal 发送了什么以及您的服务器返回了什么。

如果有效载荷或配置需要调整，请编辑事件流并使用**发送测试**按钮发送示例请求。反复调试直到有效载荷符合端点的预期，然后正式上线。

<Frame caption="事件流日志和指标">
  <img src="https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/b03288f-Screenshot_2023-11-27_at_11.10.42_PM.png?fit=max&auto=format&n=56ctKxZSV4m5VEkn&q=85&s=5cd4cedc3b1b49d51b4e9fb0e04c31a7" alt="带有图表和 HTTP 响应状态随时间变化的事件流报告" width="1366" height="812" data-path="images/docs/b03288f-Screenshot_2023-11-27_at_11.10.42_PM.png" />
</Frame>

### 重试/禁用

**重试行为** — 当请求因可恢复状态（例如 `429`）失败时，OneSignal 会以递增的延迟进行重试。如果单个事件的重试持续失败，该事件将被标记为永久失败，不再重试。

**自动禁用** — 如果您的端点在大量事件中持续返回失败，OneSignal 可能会禁用整个事件流。发生这种情况时：

1. 当失败量达到一定程度（禁用前）以及流被禁用时，应用和组织管理员都会收到电子邮件通知。
2. 仪表板中的**事件流**索引页面上也会出现横幅。
3. 修复根本问题，使用**日志**选项卡或 [webhook.site](https://webhook.site) 进行测试，然后重新启用流。

**性能指导** — 您的端点应能处理消息发送产生的事件量。为避免积压和被禁用：

* **快速记录事件** — 将传入事件写入队列或数据存储，无需进行繁重的内联处理。
* **避免响应缓慢和 429** — 持续的慢响应时间或速率限制响应会导致事件积压，进而导致 OneSignal 禁用流。
* **根据发送量进行容量规划** — 如果您发送 10 万条消息，则每个选定事件类型最多预计产生 10 万个事件。请查看您的计划消息量并据此进行规划。

**去重** — 每个投递的事件都包含一个唯一的 `event.id`。将其包含在标头或 JSON 正文中，以便您的系统在同一事件被重试或重放时能够去重。

### 成功提示

* **优先将流指向自己的服务器。** 您*可以*直接连接到第三方 API，但当您不控制接收端时，调试、速率限制处理和用量管理会更加困难。
* **在转发给第三方之前进行缓冲。** OneSignal 以用户触发事件的速度发送——大量发送可能产生一次性流量冲击，压垮外部速率限制或增加费用（尤其是 SMS 提供商）。构建一个轻量级服务来接受事件、将其加入队列，然后以您控制的节奏转发给外部 API。
* **查看第三方 API 文档。** 许多服务提供您可以通过事件流访问的公开 HTTP API。在配置流之前，查找其关于身份验证、接受的有效载荷格式和速率限制的文档。

### 消息事件数据限制

通过 Journeys 或 API 发送的消息数据在 OneSignal 中仅保留 30 天。这意味着在 Journey 或 API 消息发送后 30 天以上发生的任何消息事件（如点击、打开、取消订阅等）将无法在事件流中获取。这在您的分析中可能表现为空白或缺失的数据。

要解决此限制，可将这些已点击/已打开/已取消订阅事件的 `message.id` 与具有相同 `message.id` 的原始 `sent` 事件关联起来。原始 `sent` 事件应包含相关的消息数据（标题、模板等）。

***

## 测试

使用 [webhook.site](https://webhook.site) 进行端到端测试演练。将**您的唯一 URL** 粘贴到事件流的 **URL** 字段中，使用 **POST** 方法。

<Frame caption="URL 匹配来自 webhook.site 的&#x22;您的唯一 URL&#x22;">
  <img src="https://mintcdn.com/onesignal/MUgio66t0sYhGEvj/images/docs/64af09f47cba448ba82b28ffa1d9dfc2309752900d98072f73a06aa0138e24a3-Screenshot_2025-03-04_at_3.31.14_PM.png?fit=max&auto=format&n=MUgio66t0sYhGEvj&q=85&s=e57076d0108dcca27ad6aa2a7d0e1fcd" alt="事件流 URL 字段与 webhook.site 唯一 URL 匹配" width="1460" height="706" data-path="images/docs/64af09f47cba448ba82b28ffa1d9dfc2309752900d98072f73a06aa0138e24a3-Screenshot_2025-03-04_at_3.31.14_PM.png" />
</Frame>

设置您想要跟踪的事件。在此示例中，我们将使用推送事件，但任何事件都可以。

<Frame caption="选择了推送消息事件，但任何事件都可以用于测试。">
  <img src="https://mintcdn.com/onesignal/Z6xkXGfmy814If53/images/docs/d66663960101c0a9d7a513ac86ebf01c202e66d42d3b445ea4ef27e178f23bbe-Screenshot_2025-03-04_at_3.31.52_PM.png?fit=max&auto=format&n=Z6xkXGfmy814If53&q=85&s=ebd5aae6ec73eb2c7e63c53ab6ee7e9d" alt="勾选了推送消息事件用于测试的事件选择" width="1452" height="402" data-path="images/docs/d66663960101c0a9d7a513ac86ebf01c202e66d42d3b445ea4ef27e178f23bbe-Screenshot_2025-03-04_at_3.31.52_PM.png" />
</Frame>

在此示例中，我们将使用上述[示例正文](#body)。

保存事件并将其设置为生效。

发送消息以触发事件。在 webhook.site 中，我们将看到包含以下数据的事件：

<Frame caption="使用 webhook.site 的示例">
  <img src="https://mintcdn.com/onesignal/Z6xkXGfmy814If53/images/docs/dc8857b0e81ef767840eefd953c8d94a24420eb576c20af72156900fb0909d3a-Screenshot_2025-03-04_at_4.49.16_PM.png?fit=max&auto=format&n=Z6xkXGfmy814If53&q=85&s=b69262aeada09efebd45f0ceffa86044" alt="webhook.site 显示传入的事件流请求正文和标头" width="2464" height="1650" data-path="images/docs/dc8857b0e81ef767840eefd953c8d94a24420eb576c20af72156900fb0909d3a-Screenshot_2025-03-04_at_4.49.16_PM.png" />
</Frame>

这显示了以下内容：

* **主机**：请求来源的 IP 地址。请参阅 [REST API 概述](/reference/rest-api-overview)了解可能的 IP 列表。
* **请求内容**：在事件流正文中发送的数据。

***
