# alerts

Readings come in; a limit decides who hears about it. `alerts.notify` stands in for a real channel such as email or a push message: here it only records what it would send, in `ctx.sent`, the flow's shared state, so a story can check it.

$when alerts.check (readings: Array, limit: Float) {
  high = readings filter (r => r.value > limit)
  if (high is empty) {
    payload = "all normal"
  } else {
    names = high map (r => r.sensor) mkString ", "
    alerts.notify (to = "on-call", text = "over ${limit}: ${names}")
    if (readings exists (r => r.value > limit * 2.0)) {
      alerts.notify (to = "manager", text = "critical: ${names}")
    }
    payload = high map (r => r.sensor)
  }
}

Every notification goes through this one rule, so there's one place to change when a real channel arrives. Reading `sent` finds the flow's value; writing `ctx.sent` changes it for everyone.

$when alerts.notify (to: String, text: String) {
  ctx.sent = (sent ?? []) ++ [{to: to, text: text}]
}

Try it: [[Story:alerts]], or in the [Fiddle](/fiddle?tab=stories&topic=Story:alerts).
