---
title: Channel Conditions - Smart Notification Filtering
sidebarTitle: Conditions
description: Master Echobell's condition system to filter notifications intelligently. Complete guide to conditional expressions, operators, time-based filtering, and best practices for reducing alert fatigue.
---

# Channel Conditions

Channel conditions are powerful expressions that determine when notifications should be sent. By setting conditions on your channel, you can filter notifications based on the content of variables or HTTP headers, ensuring subscribers only receive relevant alerts. This is essential for reducing alert fatigue and maintaining high signal-to-noise ratio in your notification system.

Think of conditions as the gatekeeper for your notifications - they evaluate incoming trigger data and only allow notifications through when specific criteria are met.

## Understanding Conditions

Conditions are expressions that evaluate to either `true` or `false`. When a channel is triggered:

- If conditions are **not set** (empty), notifications are sent to all subscribers.
- If conditions are **set**, notifications are only sent when the expression evaluates to `true`.

## Writing Conditions

Conditions are written as expressions without the `{{}}` wrappers that are used in templates. For example:

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

This condition will only allow notifications to be sent when the `status` variable equals "active".

## Common Use Cases

Here are some practical examples of how you might use conditions:

### Basic Variable Checks

```
amount > 100
```

Only notify when the "amount" variable is greater than 100.

```
message != ""
```

Only notify when the "message" variable is not empty.

```
isUrgent == true
```

Only notify when the "isUrgent" variable is true.

### Checking HTTP Headers

You can access HTTP headers using the special `header` variable:

```
header["user-agent"].includes("Mozilla")
```

Only notify when the request comes from a Mozilla browser.

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

Only notify when the content type is JSON.

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

Only notify when a custom priority header is set to "high".

<Callout type="info">All the keys in headers are lowercase.</Callout>

### Complex Conditions

You can combine multiple conditions using logical operators:

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

Only notify when either temperature exceeds 30 or pressure exceeds 100, and the status is "monitoring".

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

Only notify for critical or high-level errors in the production environment.

## Supported Operators

The following operators are supported in condition expressions:

| Operator                  | Description              | Example                                     |
| ------------------------- | ------------------------ | ------------------------------------------- |
| `==`                      | Equal to                 | `status == "active"`                        |
| `!=`                      | Not equal to             | `status != "inactive"`                      |
| `!`                       | Logical NOT              | `!isCompleted`                              |
| `<`                       | Less than                | `count < 10`                                |
| `>`                       | Greater than             | `price > 99.99`                             |
| `<=`                      | Less than or equal to    | `battery <= 20`                             |
| `>=`                      | Greater than or equal to | `confidence >= 0.95`                        |
| `&&`                      | Logical AND              | `isAdmin && isActive`                       |
| <code>&#124;&#124;</code> | Logical OR               | <code>isError &#124;&#124; isWarning</code> |

## Condition Variables

When a channel is triggered via webhook, you can access:

1. **Query parameters** from the URL
2. **JSON body** from POST requests
3. **HTTP headers** via the `header` object

For email triggers, you can access:

- `from`: The email sender address
- `to`: The recipient address
- `subject`: The email subject line
- `text`: The plain text body content
- `html`: The HTML body content

### System Time Variables (UTC)

These read-only variables are always available in both conditions and templates. All values are computed in UTC.

- `timezone`: The constant string `"UTC"`
- `now` / `iso`: Current time as ISO‑8601 string (e.g., `2025-05-06T12:34:56.789Z`)
- `epochMs`: Milliseconds since Unix epoch (number)
- `epochSeconds`: Seconds since Unix epoch (number)
- `year`: 4‑digit year (number)
- `month`: Month number `1–12`
- `monthName`: Month name `January–December`
- `dayOfMonth`: Day of month `1–31`
- `dayOfWeek`: Day of week `0–6` (Sunday = 0)
- `dayOfWeekName`: Day name `Sunday–Saturday`
- `hour`: Hour of day `0–23`
- `minute`: Minute `0–59`
- `second`: Second `0–59`
- `date`: `YYYY-MM-DD` string
- `time`: `HH:mm:ss` string

Examples:

```
// Weekdays during 09:00–17:00 UTC
hour >= 9 && hour < 17 && dayOfWeek >= 1 && dayOfWeek <= 5

// Weekends only
dayOfWeek == 0 || dayOfWeek == 6

// First day of month at top of hour
dayOfMonth == 1 && minute == 0
```

## Best Practices

### Start Simple
Begin with basic conditions and add complexity as needed:

**Phase 1:** Start with single conditions
```
temperature > 30
```

**Phase 2:** Add logical operators
```
temperature > 30 && location == "server-room"
```

**Phase 3:** Add nested logic
```
(temperature > 30 || humidity > 80) && location == "server-room" && status == "monitoring"
```

### Test Thoroughly
Test your conditions with various inputs to ensure they work as expected:

1. **Test with normal values** - Verify conditions work in expected scenarios
2. **Test edge cases** - What happens at exactly the threshold value?
3. **Test with missing variables** - How does the condition handle absent data?
4. **Test with unexpected types** - What if a number is sent as a string?
5. **Use test webhooks** - Send test triggers with different data combinations

### Document Your Conditions
Add comments in your channel's note field to explain complex conditions:

```
Channel Note:
Condition: (cpu > 80 && memory > 90) || diskSpace < 10

This condition triggers alerts when:
- Both CPU is above 80% AND memory is above 90%
- OR when disk space drops below 10GB
```

This helps team members understand the alert logic without parsing the expression.

### Consider Edge Cases
Account for missing variables or unexpected values:

- **Missing variables**: Undefined variables evaluate to empty/false - ensure your logic handles this
- **Type mismatches**: Numeric comparisons may fail if values are strings
- **String comparisons**: Remember that `"100" < "20"` is true (lexical order), not numeric comparison
- **Case sensitivity**: `status == "Active"` differs from `status == "active"`

### Prevent Alert Storms
Use conditions to prevent rapid-fire notifications for transient issues:

```
errorCount > 5    # Not just errorCount > 0
cpuUsage > 90     # Not cpuUsage > 50
failureRate > 0.1 # Not just hasFailures
```

Combine with appropriate thresholds to reduce noise without missing critical events.

### Use Business Hours Filtering
Combine severity with time-based conditions:

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

This sends critical alerts 24/7, but high-priority alerts only during business hours.

### Leverage Header Checks
Validate webhook sources to prevent spam or unauthorized triggers:

```
header["x-webhook-source"] == "grafana" || header["user-agent"].includes("Prometheus")
```

This adds a layer of security by checking request origin.

## Real-World Examples

### Server Monitoring - Progressive Alerts
```
# Only alert when CPU is consistently high, not transient spikes
cpu > 80 && duration >= 300
```

### E-commerce - High-Value Orders
```
# Only notify for orders above $500 or fraud-flagged orders
orderAmount > 500 || isFraudSuspected == true
```

### Development - Critical Build Failures
```
# Alert only for main branch failures or failed deployments
(branch == "main" || branch == "master") && status == "failed"
```

### IoT - Environmental Monitoring
```
# Temperature extremes outside acceptable range
temperature < 15 || temperature > 28
```

### Security - Failed Login Attempts
```
# Multiple failed logins from same IP in short time
failedAttempts >= 3 && timeSinceFirst < 300
```

### CI/CD - Deployment Tracking
```
# Only notify on production deploys or staging failures
(environment == "production") || (environment == "staging" && status == "failed")
```

### Trading - Price Alerts
```
# Significant price movements beyond threshold
(priceChange > 5 || priceChange < -5) && volume > 1000000
```

### Support - SLA Violations
```
# Tickets approaching or exceeding SLA
ticketAge > slaThreshold || priority == "urgent"
```

## Common Condition Patterns

### Threshold-Based Alerting
```
value > threshold
percentage >= 90
count < minimumRequired
```

### Status-Based Filtering
```
status == "error" || status == "critical"
state != "healthy"
isActive == true
```

### Time-Window Filtering
```
# Business hours only (9 AM - 5 PM UTC, Monday-Friday)
hour >= 9 && hour < 17 && dayOfWeek >= 1 && dayOfWeek <= 5

# After hours only
hour < 9 || hour >= 17 || dayOfWeek == 0 || dayOfWeek == 6

# Weekend maintenance windows
(dayOfWeek == 0 || dayOfWeek == 6) && hour >= 2 && hour < 6
```

### Multi-Factor Conditions
```
# Combine multiple criteria
severity == "high" && environment == "production" && region == "us-east-1"

# Either critical OR production with high severity
severity == "critical" || (severity == "high" && environment == "production")
```

### String Matching
```
# Contains check
message.includes("ERROR")
errorType.includes("Database")

# String comparison
environment == "production"
username != "test-user"
```

## Combining Conditions with Templates

Conditions and [templates](/docs/template) work together to create smart, contextual notifications:

**Condition** (filters which triggers send notifications):
```
temperature > 30 || humidity > 80
```

**Template** (formats the notification content):
```
Title: {{location}} Environment Alert
Body: Temp: {{temperature}}°C, Humidity: {{humidity}}%
Status: {{temperature > 35 ? "CRITICAL" : "WARNING"}}
```

This separation allows you to:
1. **Filter** unwanted notifications with conditions
2. **Format** important notifications with templates
3. **Adapt** notification content based on severity

Learn more about [template syntax and features](/docs/template).

## Debugging Conditions

If conditions aren't working as expected:

1. **Simplify the condition** - Test with just one comparison at a time
2. **Check variable names** - Ensure they match exactly (case-sensitive)
3. **Verify data types** - Use test webhooks to confirm variable types
4. **Test boolean logic** - Break complex conditions into smaller parts
5. **Review operator precedence** - Use parentheses to clarify intent
6. **Check for typos** - `header["content-type"]` not `header["Content-Type"]`

## Related Documentation

- **[Template Guide](/docs/template)** - Format notification content with variables
- **[Webhook Integration](/docs/webhook)** - Pass variables via HTTP requests
- **[Email Triggers](/docs/email-trigger)** - Variables from email triggers
- **[Getting Started](/docs)** - Set up your first conditional channel

## Next Steps

Now that you understand conditions:

- **[Create smart monitoring alerts](/docs/developer/grafana)** - Filter infrastructure alerts
- **[Set up CI/CD notifications](/docs/developer/github)** - Alert only on important build events
- **[Configure time-based alerts](/blog/time-window-notifications-using-utc-conditions)** - Business hours filtering
- **[Explore all features](/docs/features)** - Discover what else Echobell can do

---

By using conditions effectively, you can reduce notification noise and ensure that subscribers only receive alerts that are relevant and actionable for them. Start with simple conditions and gradually build more sophisticated filtering logic as your needs evolve.
