Alert Monitoring
This recipe shows how to build a complete alert monitoring system: create subscriptions for different alert types, stream triggered events in real-time, and receive push notifications via webhooks with signature verification.
Full Example
import { Chaos } from '@chaoslabs/ai-sdk';
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
// Step 1: Create a price alert
const priceAlert = await chaos.alerts.subscriptions.create({
alert: {
alert_type: 'price_change',
asset: 'ETH',
target_price: 3000,
condition: 'below',
},
});
console.log(`Created alert: ${priceAlert.id} (${priceAlert.name})`);
// Step 2: Create a whale watch alert with webhook delivery
const whaleAlert = await chaos.alerts.subscriptions.create({
alert: {
alert_type: 'whale_watch',
chain: 'ethereum',
min_balance: 1_000_000,
profit_type: 'realized',
},
webhook: {
url: 'https://your-api.com/alerts/webhook',
secret: 'your-hmac-secret',
},
});
// Step 3: Stream alerts in real-time
const stream = chaos.alerts.connect();
stream.on('alert', (event) => {
console.log(`[${event.severity}] ${event.title}`);
console.log(`Summary: ${event.summary}`);
// Access evidence data
for (const point of event.evidence.dataPoints) {
console.log(` ${point.label}: ${point.value}${point.unit ?? ''}`);
}
});
stream.on('connected', () => console.log('Listening for alerts...'));
stream.on('error', (err) => console.error('Stream error:', err));
// Step 4: Poll inbox for any missed alerts
const { events } = await chaos.alerts.inbox.list({
readState: 'unread',
severity: ['warning', 'critical'],
});
for (const event of events) {
console.log(`Missed: ${event.title} (${event.triggeredAt})`);
await chaos.alerts.inbox.markRead(event.id);
}Step-by-Step Breakdown
1. Create Alerts from Templates
Browse available templates and create alerts from them instead of building configs manually.
// Browse available templates
const { templates } = await chaos.alerts.templates.list();
for (const t of templates) {
console.log(`${t.name} (${t.category}): ${t.description}`);
console.log(` Required: ${t.requiredParams.map((p) => p.key).join(', ')}`);
}
// Find a specific template
const priceTemplates = await chaos.alerts.templates.list(undefined, 'price');2. Create Alerts from Natural Language
Let the AI parse a plain-English alert description into a typed subscription.
const result = await chaos.alerts.fromQuery({
query: 'Alert me when ETH drops 10% in a day',
userId: 'user-123',
});
switch (result.mode) {
case 'created':
console.log('Alert created:', result.alert?.name);
break;
case 'interactive':
console.log('Needs clarification — show options to user');
break;
case 'form':
console.log('Needs more info — show form to user');
break;
case 'error':
console.error('Failed:', result.error);
break;
}3. Manage Alert Lifecycle
Snooze, mute, update, and clean up alerts.
// List all active subscriptions
const subs = await chaos.alerts.subscriptions.list();
console.log(`${subs.length} active alerts`);
// Snooze an alert for 1 day
await chaos.alerts.subscriptions.snooze(subs[0].id, '1d');
// Mute indefinitely
await chaos.alerts.subscriptions.mute(subs[0].id);
// Update channels — add email delivery
await chaos.alerts.subscriptions.update(subs[0].id, {
channels: { inApp: true, push: true, telegram: false, email: true },
});
// Check trigger history for a subscription
const { events, total } = await chaos.alerts.subscriptions.getEvents(subs[0].id);
console.log(`Fired ${total} times`);
// Delete an alert
await chaos.alerts.subscriptions.delete(subs[0].id);4. Webhook Signature Verification
When Chaos delivers alerts to your webhook, each request includes an X-Chaos-Signature header containing an HMAC-SHA256 signature of the request body, signed with the secret you provided when creating the subscription.
import { createHmac, timingSafeEqual } from 'crypto';
import express from 'express';
const WEBHOOK_SECRET = 'your-hmac-secret';
const app = express();
app.post('/alerts/webhook', express.text({ type: '*/*' }), (req, res) => {
const signature = req.headers['x-chaos-signature'] as string;
const expected = createHmac('sha256', WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
if (!timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return res.status(401).send('Invalid signature');
}
const alert = JSON.parse(req.body);
console.log(`[${alert.severity}] ${alert.title}`);
console.log(`Summary: ${alert.summary}`);
res.status(200).send('OK');
});
app.listen(3000, () => console.log('Webhook server on :3000'));import hmac
import hashlib
import json
from flask import Flask, request, abort
WEBHOOK_SECRET = "your-hmac-secret"
app = Flask(__name__)
@app.route("/alerts/webhook", methods=["POST"])
def handle_alert():
signature = request.headers.get("X-Chaos-Signature", "")
expected = hmac.new(
WEBHOOK_SECRET.encode(), request.data, hashlib.sha256
).hexdigest()
if not hmac.compare_digest(signature, expected):
abort(401, "Invalid signature")
alert = json.loads(request.data)
print(f"[{alert['severity']}] {alert['title']}")
print(f"Summary: {alert['summary']}")
return "OK", 2005. Configure Notification Settings
Set up global notification preferences including Do Not Disturb hours and severity-based channel routing.
// Set up DND hours and severity routing
await chaos.alerts.settings.update({
channels: { inApp: true, push: true, telegram: true, email: false },
dnd: {
enabled: true,
startTime: '22:00',
endTime: '08:00',
timezone: 'America/New_York',
},
});
// Check current settings
const settings = await chaos.alerts.settings.get();
console.log('DND:', settings.dnd?.enabled ? 'on' : 'off');
console.log('Channels:', settings.channels);