---
title: Điều kiện của kênh - Lọc thông báo thông minh
sidebarTitle: Điều kiện
description: "Lọc thông báo Echobell bằng biểu thức điều kiện: toán tử, quy tắc theo thời gian và thực hành tốt nhất để giảm mệt mỏi vì cảnh báo."
---

# Điều kiện của kênh

Điều kiện của kênh là những biểu thức mạnh mẽ quyết định khi nào thông báo được gửi đi. Bằng cách đặt điều kiện cho kênh, bạn có thể lọc thông báo dựa trên nội dung của biến hoặc HTTP header, đảm bảo người đăng ký chỉ nhận những cảnh báo thực sự liên quan. Đây là điều then chốt để giảm mệt mỏi vì cảnh báo và giữ tỷ lệ tín hiệu trên nhiễu ở mức cao trong hệ thống thông báo của bạn.

Bạn có thể hình dung điều kiện như người gác cổng cho thông báo - chúng đánh giá dữ liệu kích hoạt đi vào và chỉ cho thông báo đi qua khi những tiêu chí cụ thể được thỏa mãn.

## Hiểu về điều kiện

Điều kiện là những biểu thức cho ra kết quả `true` hoặc `false`. Khi một kênh được kích hoạt:

- Nếu điều kiện **không được đặt** (để trống), thông báo sẽ được gửi tới toàn bộ người đăng ký.
- Nếu điều kiện **được đặt**, thông báo chỉ được gửi khi biểu thức cho kết quả `true`.

## Viết điều kiện

Điều kiện được viết dưới dạng biểu thức, không có cặp `{{}}` bao quanh như khi dùng trong mẫu. Ví dụ:

```
status == "active"
```

Điều kiện này chỉ cho phép gửi thông báo khi biến `status` bằng "active".

## Các trường hợp sử dụng phổ biến

Dưới đây là vài ví dụ thực tế về cách bạn có thể dùng điều kiện:

### Kiểm tra biến cơ bản

```
amount > 100
```

Chỉ thông báo khi biến "amount" lớn hơn 100.

```
message != ""
```

Chỉ thông báo khi biến "message" không rỗng.

```
isUrgent == true
```

Chỉ thông báo khi biến "isUrgent" là true.

### Kiểm tra HTTP header

Bạn có thể truy cập HTTP header bằng biến đặc biệt `header`:

```
header["x-webhook-source"] == "grafana"
```

Chỉ thông báo khi header nguồn tùy chỉnh khớp chính xác với "grafana".

```
header["content-type"] == "application/json"
```

Chỉ thông báo khi kiểu nội dung là JSON.

```
header["x-priority"] == "high"
```

Chỉ thông báo khi header ưu tiên tùy chỉnh được đặt là "high".

<Callout type="info">Mọi khóa trong header đều là chữ thường.</Callout>

### Điều kiện phức tạp

Bạn có thể kết hợp nhiều điều kiện bằng toán tử logic:

```
(temperature > 30 || pressure > 100) && status == "monitoring"
```

Chỉ thông báo khi nhiệt độ vượt 30 hoặc áp suất vượt 100, và trạng thái là "monitoring".

```
environment == "production" && (errorLevel == "critical" || errorLevel == "high")
```

Chỉ thông báo cho những lỗi ở mức critical hoặc high trong môi trường production.

## Các toán tử được hỗ trợ

Những toán tử sau được hỗ trợ trong biểu thức điều kiện:

| Toán tử                   | Mô tả                    | Ví dụ                                       |
| ------------------------- | ------------------------ | ------------------------------------------- |
| `==`                      | Bằng                     | `status == "active"`                        |
| `!=`                      | Khác                     | `status != "inactive"`                      |
| `!`                       | Phủ định logic           | `!isCompleted`                              |
| `<`                       | Nhỏ hơn                  | `count < 10`                                |
| `>`                       | Lớn hơn                  | `price > 99.99`                             |
| `<=`                      | Nhỏ hơn hoặc bằng        | `battery <= 20`                             |
| `>=`                      | Lớn hơn hoặc bằng        | `confidence >= 0.95`                        |
| `&&`                      | VÀ logic                 | `isAdmin && isActive`                       |
| <code>&#124;&#124;</code> | HOẶC logic               | <code>isError &#124;&#124; isWarning</code> |

## Biến dùng trong điều kiện

Khi một kênh được kích hoạt qua webhook, bạn có thể truy cập:

1. **Tham số query** từ URL
2. **Body JSON** từ request POST
3. **HTTP header** thông qua object `header`

Với kích hoạt qua email, bạn có thể truy cập:

- `from`: Địa chỉ email người gửi
- `to`: Địa chỉ email người nhận
- `subject`: Tiêu đề email
- `text`: Nội dung body dạng văn bản thuần
- `html`: Nội dung body dạng HTML

### Biến thời gian hệ thống (UTC)

Những biến chỉ đọc này luôn có sẵn cả trong điều kiện lẫn trong mẫu. Mọi giá trị đều được tính theo UTC.

Các giá trị sau được đưa vào trực tiếp (dạng phẳng) và có thể dùng theo tên:

- `year`: Năm 4 chữ số (dạng số)
- `month`: Số tháng `1–12`
- `dayOfMonth`: Ngày trong tháng `1–31`
- `dayOfWeek`: Thứ trong tuần `0–6` (Chủ nhật = 0)
- `hour`: Giờ trong ngày `0–23`
- `minute`: Phút `0–59`
- `second`: Giây `0–59`
- `date`: Chuỗi `YYYY-MM-DD`
- `time`: Chuỗi `HH:mm:ss`
- `iso`: Thời gian hiện tại dạng chuỗi ISO‑8601 (ví dụ: `2025-05-06T12:34:56.789Z`)

Một số giá trị khác **chỉ** có trong không gian tên `sys.` (chúng không được đưa vào dưới dạng tên phẳng):

- `sys.timezone`: Chuỗi hằng `"UTC"`
- `sys.now`: Thời gian hiện tại dạng chuỗi ISO‑8601 (cùng giá trị với `iso`)
- `sys.epochMs`: Số mili giây tính từ mốc Unix epoch (dạng số)
- `sys.epochSeconds`: Số giây tính từ mốc Unix epoch (dạng số)
- `sys.monthName`: Tên tháng `January–December`
- `sys.dayOfWeekName`: Tên thứ `Sunday–Saturday`

Không gian tên `sys.` cũng phản chiếu mọi giá trị phẳng (ví dụ `sys.year`, `sys.hour`).

Ví dụ:

```
// Ngày trong tuần, từ 09:00–17:00 UTC
hour >= 9 && hour < 17 && dayOfWeek >= 1 && dayOfWeek <= 5

// Chỉ cuối tuần
dayOfWeek == 0 || dayOfWeek == 6

// Ngày đầu tháng, đúng đầu giờ
dayOfMonth == 1 && minute == 0
```

## Thực hành tốt nhất

### Bắt đầu đơn giản
Hãy bắt đầu với điều kiện cơ bản rồi tăng dần độ phức tạp khi cần:

**Giai đoạn 1:** Bắt đầu với một điều kiện duy nhất
```
temperature > 30
```

**Giai đoạn 2:** Thêm toán tử logic
```
temperature > 30 && location == "server-room"
```

**Giai đoạn 3:** Thêm logic lồng nhau
```
(temperature > 30 || humidity > 80) && location == "server-room" && status == "monitoring"
```

### Kiểm thử kỹ lưỡng
Hãy thử điều kiện với nhiều dữ liệu đầu vào khác nhau để đảm bảo chúng hoạt động đúng như mong đợi:

1. **Thử với giá trị bình thường** - Xác nhận điều kiện hoạt động trong những tình huống dự kiến
2. **Thử các trường hợp biên** - Chuyện gì xảy ra khi giá trị đúng bằng ngưỡng?
3. **Thử khi thiếu biến** - Điều kiện xử lý dữ liệu vắng mặt ra sao?
4. **Thử với kiểu dữ liệu bất ngờ** - Nếu một con số được gửi dưới dạng chuỗi thì sao?
5. **Dùng webhook thử nghiệm** - Gửi các lần kích hoạt thử với những tổ hợp dữ liệu khác nhau

### Ghi chú lại điều kiện của bạn
Hãy thêm chú thích vào ô ghi chú của kênh để giải thích những điều kiện phức tạp:

```
Ghi chú kênh:
Điều kiện: (cpu > 80 && memory > 90) || diskSpace < 10

Điều kiện này kích hoạt cảnh báo khi:
- CPU trên 80% VÀ bộ nhớ trên 90%
- HOẶC khi dung lượng đĩa trống tụt dưới 10GB
```

Nhờ vậy các thành viên trong nhóm hiểu được logic cảnh báo mà không phải ngồi phân tích biểu thức.

### Lưu ý các trường hợp biên
Hãy tính đến những biến bị thiếu hoặc giá trị bất ngờ:

- **Biến bị thiếu**: Biến chưa được định nghĩa sẽ được đánh giá là rỗng/false - hãy đảm bảo logic của bạn xử lý được điều đó
- **So sánh số học**: `<`, `>`, `<=` và `>=` chuyển **cả hai** toán hạng bằng `Number()`, nên chúng so sánh theo giá trị số chứ không theo thứ tự từ điển. `"100" > "20"` là `true` (100 > 20), chứ không theo thứ tự từ điển.
- **Giá trị không phải số**: Nếu một trong hai vế của phép so sánh `<`, `>`, `<=` hay `>=` không phải là số, `Number()` sẽ cho ra `NaN` và phép so sánh luôn là `false`.
- **Bằng nhau so với so sánh thứ tự**: `==` và `!=` dùng phép so sánh bằng lỏng (nên `count == "5"` khớp với số 5), còn các toán tử so sánh thứ tự thì luôn so sánh dưới dạng số.
- **Phân biệt chữ hoa chữ thường**: `status == "Active"` khác với `status == "active"`

### Ngăn bão cảnh báo
Hãy dùng điều kiện để tránh những loạt thông báo dồn dập vì các sự cố thoáng qua:

```
errorCount > 5    # Chứ không phải chỉ errorCount > 0
cpuUsage > 90     # Chứ không phải cpuUsage > 50
failureRate > 0.1 # Chứ không phải chỉ hasFailures
```

Hãy kết hợp với những ngưỡng phù hợp để giảm nhiễu mà không bỏ lỡ sự kiện quan trọng.

### Lọc theo giờ làm việc
Hãy kết hợp mức nghiêm trọng với điều kiện theo thời gian:

```
severity == "critical" || (severity == "high" && hour >= 9 && hour < 17)
```

Cách này gửi cảnh báo nguy cấp 24/7, còn cảnh báo mức ưu tiên cao thì chỉ trong giờ làm việc.

### Tận dụng việc kiểm tra header
Hãy xác thực nguồn gửi webhook để chặn spam hoặc những lần kích hoạt trái phép:

```
header["x-webhook-source"] == "grafana" || header["x-webhook-source"] == "prometheus"
```

Cách này thêm một lớp bảo mật bằng việc kiểm tra nguồn gốc của request.

## Ví dụ thực tế

### Giám sát máy chủ - Cảnh báo theo mức độ
```
# Chỉ cảnh báo khi CPU cao kéo dài, không phải những lần tăng vọt thoáng qua
cpu > 80 && duration >= 300
```

### Thương mại điện tử - Đơn hàng giá trị cao
```
# Chỉ thông báo với đơn trên $500 hoặc đơn bị gắn cờ gian lận
orderAmount > 500 || isFraudSuspected == true
```

### Phát triển - Lỗi build nghiêm trọng
```
# Chỉ cảnh báo khi nhánh chính lỗi hoặc triển khai thất bại
(branch == "main" || branch == "master") && status == "failed"
```

### IoT - Giám sát môi trường
```
# Nhiệt độ vượt ra ngoài khoảng chấp nhận được
temperature < 15 || temperature > 28
```

### Bảo mật - Đăng nhập thất bại
```
# Nhiều lần đăng nhập thất bại từ cùng một IP trong thời gian ngắn
failedAttempts >= 3 && timeSinceFirst < 300
```

### CI/CD - Theo dõi triển khai
```
# Chỉ thông báo khi deploy lên production hoặc khi staging thất bại
(environment == "production") || (environment == "staging" && status == "failed")
```

### Giao dịch - Cảnh báo giá
```
# Biến động giá đáng kể vượt ngưỡng
(priceChange > 5 || priceChange < -5) && volume > 1000000
```

### Hỗ trợ - Vi phạm SLA
```
# Ticket sắp chạm hoặc đã vượt SLA
ticketAge > slaThreshold || priority == "urgent"
```

## Các mẫu hình điều kiện thường gặp

### Cảnh báo theo ngưỡng
```
value > threshold
percentage >= 90
count < minimumRequired
```

### Lọc theo trạng thái
```
status == "error" || status == "critical"
state != "healthy"
isActive == true
```

### Lọc theo khung thời gian
```
# Chỉ trong giờ làm việc (9 giờ sáng - 5 giờ chiều UTC, thứ Hai đến thứ Sáu)
hour >= 9 && hour < 17 && dayOfWeek >= 1 && dayOfWeek <= 5

# Chỉ ngoài giờ làm việc
hour < 9 || hour >= 17 || dayOfWeek == 0 || dayOfWeek == 6

# Khung bảo trì cuối tuần
(dayOfWeek == 0 || dayOfWeek == 6) && hour >= 2 && hour < 6
```

### Điều kiện đa yếu tố
```
# Kết hợp nhiều tiêu chí
severity == "high" && environment == "production" && region == "us-east-1"

# Hoặc mức critical, hoặc production với mức nghiêm trọng cao
severity == "critical" || (severity == "high" && environment == "production")
```

### So khớp chuỗi
```
# Khớp chính xác (không có toán tử "contains")
status == "error"
errorType == "database"

# So sánh chuỗi
environment == "production"
username != "test-user"
```

## Kết hợp điều kiện với mẫu

Điều kiện và [mẫu](/docs/template) phối hợp với nhau để tạo ra những thông báo thông minh, đúng bối cảnh:

**Điều kiện** (lọc xem lần kích hoạt nào được gửi thông báo):
```
temperature > 30 || humidity > 80
```

**Mẫu** (định dạng nội dung thông báo):
```
Title: {{location}} Environment Alert
Body: Temp: {{temperature}}°C, Humidity: {{humidity}}%
```

Sự tách bạch này cho phép bạn:
1. **Lọc** những thông báo không mong muốn bằng điều kiện
2. **Định dạng** những thông báo quan trọng bằng mẫu
3. **Điều chỉnh** nội dung thông báo theo mức độ nghiêm trọng

Tìm hiểu thêm về [cú pháp và tính năng của mẫu](/docs/template).

## Gỡ lỗi điều kiện

Nếu điều kiện không hoạt động như mong đợi:

1. **Đơn giản hóa điều kiện** - Thử từng phép so sánh một
2. **Kiểm tra tên biến** - Đảm bảo chúng khớp chính xác (phân biệt chữ hoa chữ thường)
3. **Kiểm tra kiểu dữ liệu** - Dùng webhook thử nghiệm để xác nhận kiểu của biến
4. **Thử logic boolean** - Tách điều kiện phức tạp thành từng phần nhỏ
5. **Xem lại thứ tự ưu tiên của toán tử** - Dùng dấu ngoặc để làm rõ ý định
6. **Kiểm tra lỗi gõ** - Phải là `header["content-type"]` chứ không phải `header["Content-Type"]`

## Tài liệu liên quan

- **[Hướng dẫn về mẫu](/docs/template)** - Định dạng nội dung thông báo bằng biến
- **[Tích hợp Webhook](/docs/webhook)** - Truyền biến qua HTTP request
- **[Kích hoạt qua Email](/docs/email-trigger)** - Những biến có được từ kích hoạt qua email
- **[Bắt đầu](/docs)** - Thiết lập kênh có điều kiện đầu tiên của bạn

## Bước tiếp theo

Giờ bạn đã hiểu về điều kiện:

- **[Tạo cảnh báo giám sát thông minh](/docs/developer/grafana)** - Lọc cảnh báo hạ tầng
- **[Thiết lập thông báo CI/CD](/docs/developer/github)** - Chỉ cảnh báo với những sự kiện build quan trọng
- **[Cấu hình cảnh báo theo thời gian](/blog/time-window-notifications-using-utc-conditions)** - Lọc theo giờ làm việc
- **[Khám phá mọi tính năng](/docs/features)** - Xem Echobell còn làm được những gì

---

Nếu dùng điều kiện một cách hiệu quả, bạn có thể giảm nhiễu thông báo và đảm bảo người đăng ký chỉ nhận những cảnh báo thực sự liên quan và có thể hành động được với họ. Hãy bắt đầu bằng những điều kiện đơn giản, rồi dần dần xây dựng logic lọc tinh vi hơn khi nhu cầu của bạn thay đổi.
