---
title: "Actions"
description: "Định nghĩa các hành động được kích hoạt bởi tương tác của người dùng trong builder."
---

Bảng **Interactions** cho phép bạn định nghĩa cách các phần tử trong flow phản hồi với các sự kiện — như thao tác chạm, phần tử xuất hiện, và gửi form. Với mỗi sự kiện, bạn gán một hoặc nhiều hành động: điều hướng giữa các màn hình, hiển thị hoặc ẩn phần tử, mở URL, đặt biến, và nhiều hơn nữa. Dùng điều kiện để tùy chỉnh flow dựa trên dữ liệu người dùng.

Mỗi tương tác gồm ba phần liên kết:

1. **Element**: Thành phần màn hình bắt đầu tương tác — một nút, câu trả lời quiz, trường nhập liệu, hoặc bất cứ thứ gì khác.
2. **Trigger**: Sự kiện kích hoạt logic, chẳng hạn như thao tác chạm, phần tử xuất hiện, hoặc gửi form.
3. **Action**: Tác vụ mà flow thực hiện để phản hồi. Một trigger có thể chạy nhiều action theo thứ tự.

## Thiết lập tương tác \{#set-up-interactions\}

Để thiết lập một tương tác:

1. Chọn một phần tử trên màn hình hoặc trong bảng **Layers**.
2. Ở phía phải, chuyển sang bảng **Interactions** và nhấn **Add trigger**.

3. Trong phần **Button triggers**, chọn [loại trigger](#trigger-types).

4. Nhấn **Add action**, nhấn vào tên action, và chọn [loại action](#action-types) từ dropdown trong cửa sổ **Edit action**.

5. Cấu hình thuộc tính action dựa trên [loại action](#action-types) bạn đã chọn.
6. Nếu cần, nhấn **Add action** để thêm nhiều action cho cùng một trigger.

## Loại trigger \{#trigger-types\}

Trigger kích hoạt để phản hồi hành vi người dùng, thay đổi trạng thái phần tử, hoặc khi màn hình tải. **On screen appear** là trigger chung; các trigger còn lại dành riêng cho từng phần tử.

| Trigger | Kích hoạt khi... | Hỗ trợ trên |
|---|---|---|
| **On screen appear** | Màn hình tải | Tất cả phần tử |
| **On tap** | Người dùng chạm vào phần tử | [Buttons](paywall-buttons), [quiz options](onboarding-quizzes), [toggles](builder-toggles), [countdowns](flow-timer), [videos](custom-media) |
| **On changed** | Người dùng thay đổi giá trị của input (nhập liệu, chọn ngày hoặc giờ) | Tất cả [phần tử input](builder-inputs-and-forms) |
| **On submit** | Người dùng gửi text input bằng cách nhấn Enter hoặc Done trên bàn phím | [Text-based inputs](builder-inputs-and-forms) |
| **On timer end** | Phần tử [Countdown](flow-timer) đạt về 0 | [Countdown](flow-timer) |
| **On playback finished** | [Video](custom-media) phát đến cuối | [Video](custom-media) |

Với các phần tử không có tương tác tích hợp sẵn (như [Loader](builder-loaders-and-progress-bars)), **On screen appear** là trigger duy nhất khả dụng.

## Loại action \{#action-types\}

:::important
**Bất kỳ action điều hướng nào** chuyển người dùng sang màn hình khác phải luôn là action cuối cùng trong danh sách. Các action đặt sau nó (như "Set Variable") có thể không được thực thi vì ứng dụng đã chuyển màn hình rồi.
:::

### Navigate to screen \{#navigate-to-screen\}

Đây là action chính để di chuyển người dùng giữa các màn hình. Nó đưa người dùng đến màn hình đích được chỉ định.

Với action này, bạn chỉ cần thiết lập màn hình đích. Nếu muốn bật điều hướng động, xem [Navigation and branching](onboarding-navigation-branching) hoặc phần [Conditional actions](#conditional-actions).

### Navigate next \{#navigate-next\}

Đưa người dùng đến màn hình tiếp theo trong thứ tự màn hình của flow. Dùng cho các flow tuyến tính, nơi thứ tự màn hình trong editor khớp với thứ tự bạn muốn người dùng xem.

### Navigate back \{#navigate-back\}

Quay người dùng về màn hình trước đó trong lịch sử điều hướng của họ, thay vì màn hình trước đó trong chuỗi.

### Open URL \{#open-url\}

:::tip
Dùng [inline links](onboarding-text#inline-link) để chèn liên kết vào văn bản đang chảy.
:::

Mở một địa chỉ web cụ thể. Dùng để đưa người dùng đến các trang web, bài viết, hoặc hồ sơ mạng xã hội bên ngoài màn hình native của ứng dụng.

Với action này, bạn có thể cấu hình hai cài đặt:
- **URL address**: Đặt địa chỉ URL. Ngoài ra, bạn có thể làm cho nó động — ví dụ, điều hướng người dùng đến các trang khác nhau dựa trên câu trả lời quiz hoặc dữ liệu họ đã gửi. Để làm điều này, nhấn Variable icon và chọn biến bạn muốn dùng.
- **Open in external browser**: Xác định nơi bạn muốn mở liên kết ngoài. Theo mặc định, chúng mở trong trình duyệt trong ứng dụng để giữ người dùng trong app. Chọn checkbox **Open in external browser** nếu bạn muốn mở liên kết trong trình duyệt bên ngoài.

### Close flow \{#close-flow\}

Đóng flow hiện tại.

### Show/hide elements \{#showhide-elements\}

Hiển thị hoặc ẩn một phần tử cụ thể trên màn hình.

Action này ghi đè trạng thái ban đầu được đặt trong **Visibility** ở bảng **Design**. Nếu **Visibility** được đặt thành **Hide**, action **Show** sẽ làm cho nó xuất hiện.

:::important
Action **Show** hoặc **Hide** không có phần tử đích [chặn xem trước và xuất bản](builder-save-publish#troubleshooting). Chọn đích hoặc xóa action.
:::

### Show alert \{#show-alert\}

Hiển thị cửa sổ pop-up hệ thống native. Người dùng phải nhấn **Ok** để tiếp tục.

Với alert, bạn phải thiết lập **Title** và **Message**. Trong cả hai, bạn có thể dùng biến để làm nội dung động. Để làm điều này, nhấn Variable icon và chọn biến bạn muốn dùng.

:::important
Action **Show alert** với cấu hình trống hoặc chưa hoàn chỉnh [chặn xem trước và xuất bản](builder-save-publish#troubleshooting). Điền vào cả hai trường hoặc xóa action.
:::

### Set variable \{#set-variable\}

Cập nhật giá trị của một biến trong flow. Trước khi thêm action này, hãy tạo biến trong bảng **Variables** ở bên trái (xem [Variables](onboarding-variables)).

Nhấn **Add variable** và đặt bao nhiêu biến cùng giá trị của chúng tùy ý.

:::important
Action **Set variable** không có phép gán [chặn xem trước và xuất bản](builder-save-publish#troubleshooting). Cấu hình ít nhất một phép gán hoặc xóa action.
:::

### Purchase \{#purchase\}

Kích hoạt luồng mua hàng trực tiếp từ một nút hoặc tương tác trong onboarding. Dùng để cho phép người dùng đăng ký hoặc mua một sản phẩm mà không cần rời khỏi flow.

Bạn có thể cấu hình hai hành vi cho action này:
- **In-app store**: Khởi tạo một giao dịch mua native. Đặt **Product** thành một sản phẩm cụ thể, hoặc thành `products.selectedProduct` cho lựa chọn hiện tại của người dùng trên màn hình.
- **Web payment**: Đưa người dùng đến một [web paywall](web-paywall) thay vì kích hoạt giao dịch mua native. Dùng khi bạn muốn xử lý giao dịch bên ngoài ứng dụng, chẳng hạn cho các ưu đãi đăng ký trên web.

:::important
Action **Purchase** không có **Product** hoặc **Web Paywall URL** đích [chặn xem trước và xuất bản](builder-save-publish#troubleshooting). Gán đích hoặc xóa action.
:::

### Restore purchases \{#restore-purchases\}

Kích hoạt luồng khôi phục giao dịch mua trên thiết bị. Người dùng nhấn vào đây khi họ đã mua gói đăng ký trước đó trên thiết bị khác hoặc sau khi cài lại ứng dụng, và cần khôi phục quyền truy cập vào các quyền lợi của họ.

Không có gì cần cấu hình cho action này — Adapty xử lý việc khôi phục thông qua luồng cửa hàng native.

Action **Restore purchases** cũng được cấu hình sẵn trên liên kết **Restore** trong preset nút **Links** (xem [Set up purchases](paywall-product-block#restore-purchases)).

## Custom actions \{#custom-actions\}

Một custom action kích hoạt **Action ID** được đặt tên mà chính code ứng dụng của bạn xử lý. Dùng khi các loại action tích hợp sẵn không đáp ứng được nhu cầu của bạn.

Adapty cung cấp trigger; ứng dụng của bạn thực hiện hành vi:

1. Trong builder, bạn gán **Action ID** cho tương tác của một phần tử.
2. Khi người dùng kích hoạt tương tác, flow truyền ID cho ứng dụng của bạn.
3. Ứng dụng của bạn khớp ID và chạy code của bạn.

### Thiết lập custom action \{#set-up-a-custom-action\}

1. Trong cửa sổ **Edit action**, gán **Action ID** — một chuỗi mà ứng dụng của bạn sẽ nhận ra (ví dụ: `show_discount`).
2. Trong code ứng dụng của bạn, triển khai một handler cho Action ID này. Xem [Handle paywall actions](handle-paywall-actions) để biết chi tiết triển khai và ví dụ code.

:::important
Action **Custom** không có **Action ID** [chặn xem trước và xuất bản](builder-save-publish#troubleshooting). Gán Action ID hoặc xóa action.
:::

### Bạn có thể làm gì với custom actions \{#what-you-can-do-with-custom-actions\}

Một custom action tự nó không làm gì cả. Bạn đặt một Action ID tĩnh trong builder, và code ứng dụng của bạn xử lý điều xảy ra khi nhận được ID đó. Mọi trường hợp sử dụng dưới đây đều theo cùng một mẫu: gán ID trong flow, sau đó xử lý nó trong code của bạn.

- **Kích hoạt sự kiện trong ứng dụng**: Kích hoạt ID như `viewed_special_offer`, sau đó ghi lại sự kiện vào analytics của bạn khi ứng dụng nhận được nó.
- **Yêu cầu quyền hệ thống**: Kích hoạt ID như `request_location`, sau đó gọi lời nhắc quyền OS từ ứng dụng của bạn. Adapty không hiển thị lời nhắc — ứng dụng của bạn làm điều đó.
- **Bắt đầu xác thực native**: Kích hoạt ID như `login_google`, sau đó hiển thị màn hình đăng nhập của bạn. Flow không thể đăng nhập người dùng.
- **Áp dụng logic nghiệp vụ**: Kích hoạt ID như `apply_discount`, sau đó mở khóa nội dung hoặc thay đổi trạng thái ứng dụng ở phía bạn.
- **Truyền câu trả lời quiz cho ứng dụng**: Gán Action ID khác nhau cho mỗi tùy chọn (ví dụ: `goal_weight_loss` và `goal_muscle`), sau đó đọc ID trong code của bạn. Dùng ID để đặt [custom user attribute](setting-user-attributes#custom-user-attributes) mà bạn có thể phân khúc sau này. Vì action chỉ mang một ID cố định, đây là cách duy nhất để báo cáo lựa chọn — flow không thể gửi giá trị đã chọn.

:::important
Custom action kích hoạt ngay khi người dùng chọn một tùy chọn. Nếu người dùng thay đổi câu trả lời, flow cũng kích hoạt Action ID mới. Ứng dụng của bạn sau đó nhận cả hai theo thứ tự — ví dụ: `goal_weight_loss`, rồi `goal_muscle`. Hãy làm cho handler của bạn idempotent để tín hiệu mới nhất thắng.
:::

### Custom actions không thể làm gì \{#what-custom-actions-cant-do\}

Custom action là tĩnh. Action ID được cố định khi bạn build flow — nó không thể đọc [biến](onboarding-variables) hoặc [input người dùng](builder-inputs-and-forms). Khi action kích hoạt, ứng dụng của bạn chỉ nhận được ID đó, không bao giờ là email, số điện thoại, hoặc input khác mà người dùng đã nhập. Các trường input ở lại trong flow dưới dạng biến để phân nhánh và cá nhân hóa. Để dùng các giá trị đó trong ứng dụng của bạn, hãy thu thập chúng thông qua UI hoặc API của riêng bạn.

## Conditional actions \{#conditional-actions\}

Dùng conditional actions để phân chia flow thành các đường dẫn khác nhau dựa trên dữ liệu người dùng.

Một số trường hợp sử dụng phổ biến:

- Bạn có một quiz trên màn hình và muốn điều hướng người dùng đến các màn hình khác nhau dựa trên câu trả lời của họ. Trong trường hợp này, thêm conditional action vào một nút.
- Bạn muốn cung cấp các sản phẩm và ưu đãi khác nhau cho các nhóm người dùng khác nhau. Đặt chúng trên các màn hình khác nhau và thiết lập điều kiện cho nút điều hướng.
- Bạn muốn bỏ qua một số bước nhất định cho những người dùng đã hoàn thành hướng dẫn trong phiên ứng dụng trước đó.

Conditional actions hoạt động như một chuỗi if / else-if / else. Ứng dụng đọc các quy tắc từ trên xuống dưới và dừng ở kết quả khớp đầu tiên:
1. **IF**: Flow kiểm tra điều kiện chính.
    - Đúng? Flow thực thi ngay các action THEN và dừng.
    - Sai? Flow bỏ qua đến phần tiếp theo.
2. **ELSE IF**: Bạn có thể thêm các kiểm tra bổ sung ở đây (ví dụ: "Nếu không phải Premium, người dùng có đang dùng Trial không?").
3. **ELSE** (Fallback): Nếu không có quy tắc nào khớp ở trên, flow thực thi các action trong phần cuối này.

:::important
- Nếu một quy tắc được thêm vào nhưng không có action được gán, việc khớp điều kiện dẫn đến không làm gì.
- Một quy tắc chưa hoàn chỉnh (không có toán tử hoặc giá trị) [chặn xem trước và xuất bản](builder-save-publish#troubleshooting).
:::

Với mỗi quy tắc, chọn một biến để đánh giá và một action để chạy. Bạn có thể đặt nhiều hơn một action cho mỗi quy tắc.

:::important
Flow chỉ thực thi một quy tắc — quy tắc đầu tiên nó khớp. Nếu bạn cần thực thi cả **IF** và **ELSE IF** cùng lúc, hãy thêm cả hai action vào **IF**.
:::

Để tìm hiểu cách làm cho các phần tử có thể chọn được và tổ chức chúng thành các nhóm để dùng trong điều kiện, xem [Selectable elements and groups](flow-selectable-elements).

## Khắc phục sự cố \{#troubleshooting\}

Bất kỳ action nào thiếu các trường bắt buộc đều chặn xem trước và xuất bản. Xem [Save & publish flows](builder-save-publish#troubleshooting) để biết danh sách đầy đủ.