==============
Webhook Sender
==============

:py:class:`~herostools.actor.webhook.HEROWebhookSender` subscribes to a named
event a HERO object and posts every incoming metadata + payload as JSON to an
arbitrary incoming-webhook endpoint. Since the request body is fully defined by
a `Jinja2 <https://jinja.palletsprojects.com/en/stable/>`_ template, it works
with any webhook-compatible platform (Slack, Mattermost, Discord, MS Teams, ...).


Payload templates
-----------------

The ``body_template`` is rendered against two variables:

``payload``
    The event data.

``metadata``
    The per-event metadata merged over ``default_metadata`` (per-event values
    take precedence on key collision).

The rendered string must be valid JSON — it is validated with ``json.loads``
before being sent. Note that Jinja2 does not escape interpolated values, so
apply the ``tojson`` filter wherever a variable takes the position of a JSON
value, otherwise payloads containing quotes or special characters will break
the document:

.. code:: text

    {"text": {{ payload.message | tojson }}, "channel": "{{ channel }}"}


Usage
-----

.. autoclass:: herostools.actor.webhook.HEROWebhookSender

**BOSS configuration example**

.. code:: json

    {
      "_id": "mattermost-notifier",
      "classname": "herostools.actor.webhook.HEROWebhookSender",
      "arguments": {
        "object_selector": "my-device",
        "event_name": "alarm",
        "webhook_url": "https://mattermost.example.com/hooks/abc123",
        "default_metadata": {
          "channel": "town-square"
        },
        "body_template": "{\"text\": {{ payload.message | tojson }}, \"channel\": {{ channel | tojson }}}"
      }
    }


Error handling
--------------

Failures are handled exactly like in the
:py:class:`~herostools.actor.archiver.HERODataArchiver`: any failed delivery
(including payloads whose template does not render to valid JSON) is logged
with a warning and re-queued up to ``max_retries`` times. Once the limit is
exceeded, the item is dropped with an error log.


