# `Wardrik.Notify`

Tells people when an agent parks, fails or finishes while nobody is watching.

Name your targets in Wardrik's `:notify` option:

    notify: [
      targets: [
        audit: {Wardrik.Notify.Webhook, url: "https://hooks.example.com/wardrik", secret: secret},
        ops: {Wardrik.Notify.Room, channel: "slack", room: "#ops", approvers: ["@maria"]}
      ]
    ]

An agent's definition routes its notices with `notify`:

    # A target
    notify: "ops"

    # A room in one of Wardrik's channels
    notify: "slack:#updates"

    # Several
    notify: ["ops", "slack:#updates"]

    # Which kinds of `Wardrik.Notice` to send. `["parked", "failed"]` unless set.
    notify: %{to: ["ops"], on: ["finished"]}

Conversations aren't routed anywhere.

## Options

  * `:targets` - targets by name, as `{module, opts}`. A target's `:orgs` limits it to those
    orgs' agents. Routing another org's agent to it is refused.
  * `:retries` - how failed deliveries are retried. See `WardrikCore.Retry`.
    `[attempts: 3, max_wait: 10_000]` unless set. After that, the notice is logged and dropped.

## Delivery

One process in the cluster follows every agent's log. Each notice is sent at least once: after
a restart it picks up where it left off. Tell repeats apart by agent, kind and `at`.

# `route`

```elixir
@type route() :: %{to: [String.t()], on: [Wardrik.Notice.kind()]}
```

Where an agent's notices go (`:to`), and which kinds are sent (`:on`).

# `deliver`

```elixir
@callback deliver(Wardrik.Notice.t(), opts :: keyword()) ::
  :ok | {:skip, String.t()} | {:error, term()}
```

Sends `notice`. Returns `{:skip, why}` if it shouldn't be sent, or `{:error, reason}` to retry.

`opts` are the target's own, plus `:wardrik`, the instance, and `:target`, the target's name.

# `check`

```elixir
@spec check(Wardrik.t(), String.t(), map()) :: :ok | {:error, Wardrik.Error.t()}
```

Returns `:ok` if every place `definition` routes to exists and accepts the agent `id`.

# `deliver`

```elixir
@spec deliver(Wardrik.t(), String.t(), Wardrik.Notice.t()) ::
  :ok | {:skip, String.t()} | {:error, term()}
```

Sends `notice` to `name`, a target or a channel's room.

Returns `{:skip, why}` if there's nowhere to send it. Skips aren't retried.

# `route`

```elixir
@spec route(map()) :: route() | nil
```

Returns the route in `definition`'s `notify`, or `nil`.

    Wardrik.Notify.route(%{"notify" => "ops"})
    #=> %{to: ["ops"], on: [:parked, :failed]}

# `settings`

```elixir
@spec settings(keyword() | nil) :: %{
  targets: %{required(String.t()) =&gt; {module(), keyword()}},
  retries: keyword()
}
```

Returns the `:notify` option's targets by name, and its retries.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
