Docs Sign inGet started
Guides

Alert Slack on real changes

Post a formatted message to Slack when a run finds a significant change, using a webhook.

Webhooks are on paid plans (Starter, Growth and Agency)

Just want a Slack message after each run? Paste a Slack incoming-webhook URL in Settings → Alerts. See Slack and email. This guide is for when you want your own rules and formatting.

What you'll build: a small server that receives Onym's change.detected event, checks its signature, keeps only the changes you care about, and posts them to Slack.

You need: a Slack incoming-webhook URL and somewhere to run a small web server.

1. The handler

Webhook to Slack
import hashlib, hmac, json, os, time

import requests
from flask import Flask, abort, request

ONYM_SECRET = os.environ["ONYM_WEBHOOK_SECRET"]  # whsec_...
SLACK_URL = os.environ["SLACK_WEBHOOK_URL"]      # https://hooks.slack.com/...
app = Flask(__name__)
seen: set[str] = set()


def verify(raw: bytes, header: str) -> bool:
    try:
        parts = dict(p.split("=", 1) for p in header.split(","))
        ts, sig = int(parts["t"]), parts["v1"]
    except (KeyError, ValueError):
        return False
    expected = hmac.new(ONYM_SECRET.encode(), f"{ts}.".encode() + raw, hashlib.sha256).hexdigest()
    return abs(time.time() - ts) <= 300 and hmac.compare_digest(expected, sig)


@app.post("/hooks/onym")
def onym():
    if not verify(request.get_data(), request.headers.get("X-Onym-Signature", "")):
        abort(400)
    event = request.get_json()
    if event["id"] in seen or event["event"] != "change.detected":
        return "", 204
    seen.add(event["id"])
    d = event["data"]
    bad = [c for c in d["events"] if c["tone"] == "bad"]  # only the bad news
    if bad:
        lines = "\n".join(f"• *{c['title']}*: {c['detail']}" for c in bad)
        requests.post(SLACK_URL, json={"text": f":warning: {d['domain']['brand']} on {d['run_date']}\n{lines}\n"
                                               f"<{d['domain']['dashboard']}/changes|Open in Onym>"}, timeout=5)
    return "", 204

2. Deploy and register it

  1. Deploy the handler anywhere with a public HTTPS URL.
  2. In Onym, open Settings → Webhooks, add the URL and select change.detected.
  3. Copy the whsec_ secret into ONYM_WEBHOOK_SECRET and redeploy.
  4. Click Send test. The test is a run.completed event, so the handler acknowledges it and posts nothing; check that Onym shows status 204.

3. Make it yours

  • Post good news to a different channel by filtering on tone == "good".
  • Only alert on certain kinds: competitor and prompt_lost are the ones people act on most. See Changes.
  • Add opportunity.measured to celebrate shipped work that moved the number.