Automate itLesson 4 of 5

Hear about failures: alerts

Alerts tell you something broke without you opening the Runs page. They live on the project’s Alerts page in three tabs: Channels say where a message goes, Rules say what should alert and when, and History lists every message sent. In this lesson you connect a channel, write a rule for unattended runs, break a script on purpose and watch the Failed and Working again messages arrive.

9 min readBefore this: Run it on a scheduleOpen in Waiso
What you will learn
  • Connect a Slack, Teams, Discord, e-mail or webhook channel and send a test
  • Write a rule: what alerts, on which outcomes, to which channels
  • Understand grouping, Working again and a channel’s delivery health
  • Verify a webhook’s signature on your own server

How alerts work

Waiso checks finished runs every few seconds. Every run of a script, flow or AI Scraper robot that is started at the top level is matched against the project’s active rules; a schedule that was due but could not start counts too. A match becomes a message on each of the rule’s channels — at most one per channel per event, however many rules match.

AlertsGet told when a script, flow, schedule or robot fails — without opening Runs.
Add channelNew rule
Rules3Channels2History
Anything failsEverything · Failed, Working againChannels#opsGrouping15 minActive
Campaign flowcampaign · FailedChannelsops@shop.devGroupingOffActive
Nightly jobsOnly unattended · FailedChannelsTeamsGrouping1 hActive
The Alerts page: Rules, Channels and History tabs, and the Overview panel with active rules and channels that are not delivering.

A message names the item, the first line of the error, the failing step of a flow, what started the run (a schedule, an API token, an event trigger) and a link to the run — never its inputs, outputs or variables. Steps inside a flow alert as their flow, not one by one, and a cancelled run never alerts.

Add a channel

  1. Where

    On Alerts, open Channels and press Add channel (on an empty page, Add a channel). Where should alerts go? — Slack, Microsoft Teams, Discord, E-mail or Webhook. The kind cannot change after saving.

  2. Details

    Give it a Name and its address. Slack: an Incoming Webhook URL. Teams: a Workflows webhook URL. Discord: channel settings → Integrations → Webhooks. E-mail: the addresses under Send to, sent through the project’s e-mail provider. Webhook: any public https:// address. URLs are stored encrypted and never shown again.

  3. Save and test

    Press Save channel, then Send test on its row: Test delivered to #ops-alerts. — or the reason it was not. For a webhook, the next step shows the signing secret once: copy it and press I copied it.

Write a rule

On Rules, press New rule. The wizard has four steps — What, When, Where, Review — and you can go back to any of them.

StepChoicesDefault
What should alert?Everything · Only unattended (runs started by a schedule, an API call or an event — not the ones a person starts from the editor) · Chosen items (scripts and flows you pick)Everything
When: which outcomes?Failed · Working again (the first good run after failures) · Didn’t start (a schedule was due but could not start)Failed + Working again
Where should it go?One or more channels, and Group repeats: 5, 15 or 60 min15 min
ReviewA Name and a summary of what the rule will do; Save rule—

Each rule has an Active switch on its row; a paused rule sends nothing. Deleting a channel that rules use pauses any rule left with no channel, and the page says how many.

Grouping and Working again

The first failure of an item alerts at once (Failed: nightly-import). More failures of the same item are counted, and at most once per grouping window one follow-up goes out — Still failing: nightly-import failed 7 more times since the last alert. The first good run after failures sends Working again, with how long it was broken. So a schedule failing every minute all night is a handful of messages, not hundreds.

A failing scheduled run — the kind of run an Only unattended rule watches.

History and delivery health

History lists every message with its kind (Failed, Still failing, Working again, Didn’t start, Test, Summary), its status (Delivered, Sending, Failed, In a summary) and Open run. A failed delivery is retried after 30, 90 and 180 seconds. Each channel shows its delivery health: Not used yet, Delivering, Last try failed, or Not delivering after its last three deliveries failed — the Overview panel counts those.

The webhook channel

A webhook channel receives a JSON POST per message, signed with X-Waiso-Signature: t=<unix seconds>,v1=<hex>, where v1 is hmac_sha256(secret, "<t>.<body>") over the raw body. Check it before trusting the call, and reject old timestamps so a captured request cannot be replayed.

Expected outputThe body of a Failed message
{
  "type": "failed",
  "project": {
    "id": "p_7Hq2…",
    "name": "Reports"
  },
  "item": {
    "kind": "script",
    "id": "…",
    "name": "nightly-import"
  },
  "error": "RuntimeError: the upstream file was empty",
  "step": null,
  "startedBy": "schedule 'nightly'",
  "count": 1,
  "brokenForSeconds": null,
  "runId": "…",
  "runUrl": "https://<your-waiso-address>/projects/reports/runs?run=…",
  "at": "2026-10-16T03:00:04Z"
}
verify_alert.py
This runs on YOUR server, the one that receives the webhook — not inside Waiso.
import hashlib, hmac, time

def verify(secret: str, header: str, body: bytes, max_age: int = 300) -> bool:
    """header = the X-Waiso-Signature value: "t=1760000000,v1=ab12…"."""
    parts = dict(item.split("=", 1) for item in header.split(","))
    t, v1 = parts.get("t", ""), parts.get("v1", "")
    if not t.isdigit() or abs(time.time() - int(t)) > max_age:
        return False                      # too old: a replayed request
    expected = hmac.new(secret.encode(), f"{t}.".encode() + body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, v1)

Limits

  • Webhook addresses must be public https:// URLs (That address is not allowed: use a public https:// URL.). Each send is checked again, redirects are not followed, and a send times out after 10 seconds.
  • A channel sends at most 20 messages a minute; the rest of that minute is merged into one And 12 more alerts in this minute summary.
  • An e-mail channel needs the project’s e-mail provider (Add one in Integrations → E-mail.).
  • Only admins and the project’s creator can change alerts.
4 / 5