Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Listener YAML reference

The file format aviso listen (and aviso replay with positional files) reads.

A listener file has one top-level key, listeners:, with a list of listener definitions. The same shape is accepted inside the main config file (~/.config/aviso/config.yaml).

Minimal example

listeners:
  - name: mars-od
    event: mars
    identifiers:
      class: od
    triggers:
      - type: echo

All fields

FieldTypeRequiredDefaultDescription
namestringnounnamedLabel for logs and the echo trigger’s leader line.
eventstringyesEvent type to subscribe to. Must match a type the server publishes.
identifiersmapno{}Filter using supported identifier fields. Spatial filters can use different names from the schema: polygon for point clouds or point for polygons. See Spatial filters. Conditions combine with AND. Empty map allowed only when the schema has no required filter fields.
triggerslistno[]Triggers to run for each matching notification. Empty list is accepted, but a useful listener normally has at least one trigger.
from_idintegernounsetDefault starting sequence for the first connection. Overridden by --from.
from_datestringnounsetDefault starting ISO-8601 datetime. The value is sent verbatim to the server, so it must be in a form the server accepts: YYYY-MM-DDTHH:MM:SSZ, YYYY-MM-DDTHH:MM:SS.ffffffZ, or YYYY-MM-DD HH:MM:SS+HH:MM. A bare YYYY-MM-DD is not accepted here (the CLI’s --from flag does that normalisation, but the YAML field does not). Mutually exclusive with from_id.

Identifier values may have any JSON-compatible YAML shape. Spatial values use latitude first. This listener filters point-cloud notifications with a polygon:

listeners:
  - name: alpine-observations
    event: observations
    identifiers:
      date: "20260601"
      polygon:
        - [46, 8]
        - [46, 9]
        - [47, 9]
        - [47, 8]
        - [46, 8]
    triggers:
      - type: echo

A point is [latitude, longitude]. Polygons need at least four pairs, with the first pair repeated last. Providers send point_cloud; subscribers send polygon. This uses the observations schema from Publish and listen.

Constraint mappings

Use YAML mappings for constraints, not strings containing JSON. With the schema and seed records from the weather tutorial, put this in weather-listeners.yaml:

listeners:
  - name: selected-weather
    event: weather
    identifiers:
      date: "20260913"
      severity:
        gte: 5
      anomaly:
        between: [40, 50]
      region:
        in: [north, south]
    triggers:
      - type: echo

Quote the date so it stays a string. Leave numeric operands unquoted. This selects B and C; the central operator reference explains the allowed mappings.

Run the file directly, replaying the retained seeds before listening live:

aviso listen weather-listeners.yaml --from 0 --no-state-store
aviso replay weather-listeners.yaml --from 0

The listen command runs until Ctrl+C; run replay separately. Alternatively, place the same listeners: block in your client config, weather-config.yaml, alongside your connection settings. Select its listener by name for replay:

aviso --config weather-config.yaml listen --from 0 --no-state-store
aviso --config weather-config.yaml replay --listener selected-weather --from 0

Both config commands use the same mapping; they do not read the positional listener file. AVISO_BASE_URL can supply the test server address for either form.

Trigger fields

Every trigger entry has a type: field plus per-kind fields. Shared options:

FieldTypeDefaultApplies toDescription
retriesinteger0allAdditional attempts after the first failure. Total attempts = retries + 1.
requiredbooleantrueallWhen true, a final failure stops the listener. When false, the failure logs a WARN and the listener keeps running.
timeoutduration30s for HTTP triggers; absent for commandcommand, webhook, teams, postPer-attempt wall clock. humantime syntax: 30s, 2m, 1h30m, 500ms.
fail_fastbooleantruecommand, webhook, teams, postWhen true, deterministic failures (4xx, template errors, non-zero command exit) bypass the retry budget. When false, every failure is retryable.

echo

- type: echo

No required fields. Writes the notification to stdout (pretty JSON on a TTY, NDJSON otherwise).

log

- type: log
  path: /var/log/aviso/mars.log
FieldRequiredDescription
pathyesPath to a file. Resolves relative to the working directory of the aviso process when not absolute. The parent directory must exist; the trigger does not create directories.

Appends one line of compact JSON per notification.

command

- type: command
  command: "./on-event.sh {{ notification.event_type }} {{ notification.sequence }}"
  env:
    DATA_DIR: /var/lib/aviso/data
  working_dir: /var/lib/aviso
  timeout: 30s
FieldRequiredDescription
commandyesShell command to run. Goes through the template engine; notification values are quoted so the shell reads each as one literal argument.
envnoExtra environment variables, applied on top of the dispatcher-injected AVISO_* set. Values are not template-rendered.
working_dirnoDirectory to spawn the shell in.

Unix only.

webhook

- type: webhook
  url: "https://hooks.example/notify"
  method: POST
  headers:
    Authorization: "Bearer {{ env.WEBHOOK_TOKEN }}"
  body_template: '{"event": "{{ notification.event_type }}", "seq": {{ notification.sequence }}}'
FieldRequiredDefaultDescription
urlyesTemplate-rendered URL.
methodnoPOSTOne of GET, POST, PUT, PATCH, DELETE. Uppercase.
headersnoMap of header name → template-rendered value.
body_templatenothe compact JSON of the notificationTemplate-rendered body.

teams

- type: teams
  url: "{{ env.TEAMS_WEBHOOK_URL }}"
  title_template: "Custom {{ notification.event_type }}"
FieldRequiredDefaultDescription
urlyesTeams Workflows webhook URL.
title_templatenoaviso {{ notification.event_type }} #{{ notification.sequence }}Template-rendered title.

Builds the Adaptive Card body automatically from the notification.

post

- type: post
  url: "https://receiver.example/aviso"
  headers:
    Authorization: "Bearer {{ env.RECEIVER_TOKEN }}"
FieldRequiredDefaultDescription
urlyesReceiver URL.
headersnoMap of header name → template-rendered value.

Body is always the server’s original CloudEvent envelope. No body_template, no method (always POST).

Templates

The template engine for trigger fields is documented at Triggers: template engine. Two namespaces inside {{ ... }}:

  • {{ notification.<dotted.path> }}: a field of the notification.
  • {{ env.<NAME> }}: a process environment variable.

Resolution and precedence

When you run aviso listen:

  1. Positional YAML files replace the global config’s listeners: for this invocation. They do not merge with it.
  2. With multiple positional files, the listener lists are concatenated in argv order.
  3. With no positional files, the global config’s listeners: block is used.
  4. With no listeners anywhere, aviso listen exits with code 2.

--event with either --identifiers or repeated --identifier (inline mode) takes precedence over positional YAML files when both are present.

What next