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

# 旅程操作

> 定义等待期、根据用户行为分支旅程并使用旅程步骤标记用户。

使用**旅程操作**来控制用户在您的旅程中的移动方式和时间、个性化体验并测试结果。

## 等待

按特定时间量延迟用户的旅程进程——分钟、小时、天或周。

用途：

* 间隔消息和步骤
* 在分支之前给用户时间参与消息

<Frame caption="等待节点，显示当前等待在旅程中前进的用户">
  <img src="https://mintcdn.com/onesignal/yt4lRKoquAlWvRvF/images/docs/wait-node.png?fit=max&auto=format&n=yt4lRKoquAlWvRvF&q=85&s=13178c10c8f9d0e439c47e601ad00978" width="644" height="391" data-path="images/docs/wait-node.png" />
</Frame>

***

## 等待直到

在此步骤中暂停用户，直到他们满足特定条件：

* 进入细分
* 触发消息事件（如特定消息已投递、打开或点击）
  * **目前每个等待直到步骤仅支持一个消息事件**。
* 触发自定义事件（如入门完成、进行购买）

您可以**添加多个条件**并根据用户\_满足的第一个条件\_对用户进行分支。如果这些条件在一定时间内未满足，您可以设置**过期分支**来继续用户通过旅程或完全退出他们。

<Note>
  如果用户在到达此步骤时已经满足某个条件，他们将立即进入该分支，无需等待。条件按顺序从上到下（A–Z）进行评估。
</Note>

使用自定义事件入口规则，您还可以添加[事件匹配](#event-matching)来控制如果多次进入用户，哪个用户实例会通过旅程进行。

<Frame caption="等待直到用户进入细分或触发自定义事件">
  <img src="https://mintcdn.com/onesignal/yt4lRKoquAlWvRvF/images/journeys/journeys-wait-until-action.png?fit=max&auto=format&n=yt4lRKoquAlWvRvF&q=85&s=1a27c7d1bb9e26bc68a9980d9662b400" width="952" height="1462" data-path="images/journeys/journeys-wait-until-action.png" />
</Frame>

当自定义事件与条件匹配时，该事件会代表用户进行存储，并可以在发送旅程消息时[在 Liquid 语法中引用](./custom-events#liquid-syntax-for-custom-events)。

### 事件匹配

使用自定义事件入口规则，您可以让用户多次进入旅程。通过等待直到步骤的**事件匹配**设置，您可以控制用户的哪个实例通过旅程进行。

要求：

* 将旅程入口规则设置为使用自定义事件。
* 在用户进入旅程时包含事件属性。

例如，您有一个“调查提醒”旅程。您有多个调查，这意味着用户可以多次进入旅程（每个调查一次）。如果他们没有完成调查，您希望发送提醒消息，如果完成了则移除他们。

您可以使用**事件匹配**设置来控制用户的哪个实例通过旅程进行。

**Example**:

<Steps>
  <Step title="设置旅程入口规则和自定义事件属性">
    将旅程入口规则设置为使用自定义事件。**示例**：`survey_start`

    <Frame caption="使用自定义事件的旅程入口规则">
      <img src="https://mintcdn.com/onesignal/yt4lRKoquAlWvRvF/images/journeys/survey_start.png?fit=max&auto=format&n=yt4lRKoquAlWvRvF&q=85&s=146924d7b2a759c1894496745a078c4f" width="469" height="298" data-path="images/journeys/survey_start.png" />
    </Frame>

    用户将通过[自定义事件 API](/reference/create-custom-events)进入旅程。

    自定义事件将 `name` 设置为 `survey_start`，并具有 `payload` 属性 `survey_id`，其值为他们正在进行的调查（如 `survey_1`）。

    ```json 入口触发事件示例 theme={null}
    {
      "events": [
        {
          "external_id": "UserA",
          "name": "survey_start",
          "properties": {
              "survey_id": "survey_1"
          }
        }
      ]
    }
    ```
  </Step>

  <Step title="创建等待直到步骤和自定义事件属性">
    将等待直到条件设置为使用自定义事件。**示例**：`survey_complete`

    设置**事件匹配**选项，通过匹配以下内容来指定用户的哪个实例通过等待直到步骤进行：

    * **触发事件属性**：在旅程入口触发事件中设置（如 `survey_id`）
    * **等待事件属性**：在等待直到事件中设置（如 `survey_type`）

    ```json 等待直到事件示例 theme={null}
    {
      "events": [
        {
          "external_id": "UserA",
          "name": "survey_complete",
          "properties": {
              "survey_type": "survey_1"
          }
        }
      ]
    }
    ```

    当 `survey_id` 的值与 `survey_type` 的值匹配时，用户的该实例将通过旅程进行。

    <Warning>
      您可以在**触发事件属性**和**等待事件属性**中使用相同的属性（如 `survey_id`）。此示例使用不同的属性（如 `survey_id` 和 `survey_type`）来演示概念。

      属性区分大小写！`survey_1` 不等于 `Survey_1`。
    </Warning>

    **过期分支**：

    如果等待直到事件在过期时间内未发生，用户将通过旅程进行。此示例给用户 1 周时间来完成调查。

    <Frame caption="使用自定义事件的等待直到步骤">
      <img src="https://mintcdn.com/onesignal/yt4lRKoquAlWvRvF/images/journeys/survey_complete.png?fit=max&auto=format&n=yt4lRKoquAlWvRvF&q=85&s=59ad63e1af649a09f5c3a18a32a979b8" width="488" height="648" data-path="images/journeys/survey_complete.png" />
    </Frame>
  </Step>

  <Step title="添加消息步骤">
    为完成示例，在过期分支内添加消息步骤来发送提醒。

    <Frame caption="过期分支内的消息步骤">
      <img src="https://mintcdn.com/onesignal/yt4lRKoquAlWvRvF/images/journeys/survey_reminder.png?fit=max&auto=format&n=yt4lRKoquAlWvRvF&q=85&s=1a367c270dec75e70a6409b3c66be36e" width="955" height="572" data-path="images/journeys/survey_reminder.png" />
    </Frame>
  </Step>

  <Step title="测试一下！">
    按照上述步骤操作后，您可以进行测试：

    * 在[自定义事件 API](/reference/create-custom-events)中将 `external_id` 替换为您的外部 ID
    * 使用 `survey_id` 为 `survey_1` 触发 `survey_start` 事件
      * 您将看到用户进入旅程并流入等待直到步骤

    <Warning>
      事件不是立即的，但非常快！您可能需要等待几分钟才能处理事件。

      检查自定义事件列表以查看事件是否已处理。
    </Warning>

    * 使用 `survey_id` 为 `survey_2` 触发另一个 `survey_start` 事件
      * 您将看到 2 个用户进入旅程和等待直到步骤
    * 使用 `survey_type` 为 `survey_1` 触发 `survey_complete` 事件
      * 您将看到用户通过旅程进行
    * 使用 `survey_type` 为 `survey_2` 触发另一个 `survey_complete` 事件
      * 您将看到用户的两个实例都通过旅程进行并退出

    <Check>
      您已完成带有事件匹配的旅程自定义事件示例！
    </Check>
  </Step>
</Steps>

***

## 时间窗口

基于**特定日期和时间**限制用户何时可以移动到旅程中的下一步。

**示例**：仅允许用户在周末晚上接收消息。

<Frame caption="显示时间窗口节点示例的截图">
  <img src="https://mintcdn.com/onesignal/3zq1PvSaqvUE2bIx/images/docs/31f4664-Screenshot_2024-03-21_at_15.56.12.png?fit=max&auto=format&n=3zq1PvSaqvUE2bIx&q=85&s=07267995ec158e725ecd0c6afb28af20" width="540" height="448" data-path="images/docs/31f4664-Screenshot_2024-03-21_at_15.56.12.png" />
</Frame>

### 时间窗口行为如何工作

如果用户在允许时间之外进入此节点：

* OneSignal 设置计时器将用户延迟到**下一个可用窗口**
* **进入窗口的时间是随机的**

时间窗口可在时区数据可用时使用**用户的时区**。如果用户没有时区数据，则使用应用的默认时区。

**示例**：
如果您的时间窗口是周二太平洋标准时间下午1:00到6:00，而用户在周一到达节点，他们可能会在周二的随机时间（如下午5:45）继续。

### 将时间窗口用于定期发送

将时间窗口节点与[重新进入规则](./journeys-settings#re-entry-rules)结合使用，可按计划（每天、每周等）发送定期消息。将时间窗口作为 Journey 中的**第一步**，这样用户在收到消息之前会等待正确的日期和时间。

选择重新进入持续时间时，将其设置为**长于时间窗口持续时间**但短于发送间隔。这可以防止在同一窗口内重复发送，同时确保用户足够早地重新进入以赶上下一个窗口。

**示例——每日发送：**

* 时间窗口：每天上午10:00至下午6:00（8小时窗口）
* 重新进入：12小时（长于8小时窗口，短于24小时）
* 结果：用户在退出后约12小时重新进入，始终在第二天窗口关闭之前到达，并每天收到一条消息

完整示例请参阅[特定日期的定期旅程](./journeys-examples#recurring-journeys-for-specific-days)和[我可以安排每天发送消息吗？](./journeys-examples#can-i-schedule-a-message-to-send-every-day)。

***

## 是/否分支

基于**细分成员身份**或**消息行为**对用户进行分支。

### 分组成员身份

根据用户所在的细分创建分支。

**示例**：
如果用户按计划类型打标签：

* "免费"分支 = 推广升级
* "付费"分支 = 突出高级功能

### 消息行为

根据与旅程中先前消息的交互进行分支：

* **推送**：点击、已投递
* **电子邮件**：点击、已打开、已投递

**注意**：Safari 不支持确认投递。

***

## 分割分支

随机将用户分布在不同路径上，以测试消息传递、渠道或旅程流程。

<Frame caption="3路分割分支的示例">
  <img src="https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/b7a62545ad25878949fe7b0fffc1b64ddee30730dbe351cd51eaea5ed8e9964f-Screenshot_2024-12-23_at_1.37.49_PM.png?fit=max&auto=format&n=56ctKxZSV4m5VEkn&q=85&s=b9f67d64e3721cba629798663860be3f" width="1916" height="1430" data-path="images/docs/b7a62545ad25878949fe7b0fffc1b64ddee30730dbe351cd51eaea5ed8e9964f-Screenshot_2024-12-23_at_1.37.49_PM.png" />
</Frame>

<Warning>
  旅程上线后，您**无法编辑**分割分支。要更改分支数量，请创建新的旅程。
</Warning>

### 工作原理

* 最多 20 个分支
* 设置等分或自定义百分比分割
* 百分比四舍五入到整数（如 3 路分割变为 34/33/33）
* 小样本量的分布可能会略有差异

<Frame caption="分割分支设置">
  <img src="https://mintcdn.com/onesignal/jFWn5xzleD8du3j6/images/docs/517165a9f4f78a584ce252ae7581c6fc48f05e040a0ba921d759392577218988-Screenshot_2024-12-23_at_11.28.53_AM.png?fit=max&auto=format&n=jFWn5xzleD8du3j6&q=85&s=57308fa43c451864c80af0c97a4a9cfa" width="460" height="456" data-path="images/docs/517165a9f4f78a584ce252ae7581c6fc48f05e040a0ba921d759392577218988-Screenshot_2024-12-23_at_11.28.53_AM.png" />
</Frame>

默认情况下，用户每次重新进入旅程时都会重新随机化。
要让他们留在同一分支上，请关闭**重新进入时随机化**。

使用**标记用户**操作追踪用户遵循的分支。

### A/B/N 测试

使用嵌套的分割分支同时测试两个以上的变体。

**示例**：
要将用户平均分割为 3 个变体：

1. 第一个分支：33% 对 67%
2. 在 67% 分支下，添加另一个 50/50 分割分支

这在每个路径上给出约 33%。

### 控制组

通过留下一个空分支（无消息节点）来测试消息传递的影响。这样您可以与完全不接收消息的用户进行比较。

### 选择胜者

一旦确定了获胜变体，请更新分支将\*\*100%\*\*的流量发送到该路径。

为了持续测量长期影响，可以考虑保留一小部分**保留组**——即不接收获胜消息的一定比例用户。

***

## 标记用户

使用此操作在旅程期间应用或删除标签。

**常见用例**：

* 追踪旅程进度（如 `journeyStep: welcome`）
* 通过在关键时刻为用户打标签来支持应用内消息
* 使用活动标签从其他旅程中排除用户

<Frame caption="简单的入门/欢迎流程">
  <img src="https://mintcdn.com/onesignal/6tscVAtiSqz353kV/images/docs/99f568ee808ea29f528fd83830bf9a7ebed7e590e95d34047e6495fc810015f2-image.png?fit=max&auto=format&n=6tscVAtiSqz353kV&q=85&s=cb4cbbbe43b252f44f22f08379b9b709" width="237" height="485" data-path="images/docs/99f568ee808ea29f528fd83830bf9a7ebed7e590e95d34047e6495fc810015f2-image.png" />
</Frame>

### 示例：入门流程控制

1. 第一步：添加标签（如 `onboardingJourney: active`）
2. 使用此标签创建细分，以从其他旅程中排除
3. 最后一步：通过将值设置为空白来删除标签

<Frame caption="标签节点设置，从用户中删除标签">
  <img src="https://mintcdn.com/onesignal/4HyuQPBpu-4xjmQC/images/docs/d4199348801030819f94a56976af9b180a77434be6f8b76fd24c7c5a283fc0ba-image.png?fit=max&auto=format&n=4HyuQPBpu-4xjmQC&q=85&s=004b49369e6eb2a13a55dfa1b93855bf" width="651" height="193" data-path="images/docs/d4199348801030819f94a56976af9b180a77434be6f8b76fd24c7c5a283fc0ba-image.png" />
</Frame>

***

### 最佳实践：将标签与 Webhook 或个性化一起使用

在旅程中添加或删除标签后，这些更改可能需要一小段时间才能在下一步中准备好使用。为确保一切顺利运行：

* **对于 Webhook**：在使用 Webhook 发送数据之前，设置标签后添加短暂等待。
* **对于个性化**：在将标签用于电子邮件中的个性化内容之前，设置或删除标签后添加短暂等待。

<Tip>
  我们建议在标签操作和下一步之间添加 **15 分钟等待节点**。这确保标签已完全准备好，以便您的 Webhook 或电子邮件始终包含正确的数据。
</Tip>

***

## 常见问题

### 我可以根据点击的推送操作按钮来分支 Journey 吗？

仅靠内置的是/否分支无法实现——消息行为条件只能检测"已点击"或"已送达"，而不能检测点击了哪个具体按钮。要根据按钮进行分支，请在您的 SDK 中监听点击事件，读取 Action ID，并发送[自定义事件](./custom-events)。然后使用[等待直到](#wait-until)步骤根据哪个自定义事件最先触发进行分支。

有关包含代码示例的完整演练，请参阅[根据操作按钮点击分支 Journey](./journeys-examples#branch-a-journey-by-action-button-clicked)。

### 在 Journey 中使用自定义事件需要编写代码吗？

是的。自定义事件通过 [SDK](./mobile-sdk-reference#custom-events) 从您的应用或网站发送到 OneSignal，或通过 [REST API](/reference/create-custom-events) 从您的后端发送。没有仅通过仪表板触发自定义事件的方式。一旦事件流入 OneSignal，您就可以在 Journey 和细分中通过仪表板使用它们，无需额外代码。
