.. include:: ../variables.rst .. _notifications: Notifications ============= |APPNAME| can push real-time notifications out to a Microsoft Teams channel, a Slack channel, or any HTTPS endpoint that accepts JSON. Configure as many subscriptions as you need --- different channels for different teams, different severities for different audiences --- and |APPNAME| will fan an outbound message to every matching subscription each time something noteworthy happens (a report finishes, an audit session closes, a target is missed, a dashboard threshold is crossed, and so on). Setting up a notification is a two-step exercise: 1. **In the destination application** (Teams, Slack, or your own service), generate a webhook URL that accepts an inbound message. 2. **In** |APPNAME|, create a Teams Integration subscription that points at that URL and pick which severities and modules should reach it. The two steps can happen in either order, but you will need the URL from step 1 to finish step 2. The Teams Integration page is available to root users and to account administrators. Account administrators see and manage only their own account's subscriptions; root users can see and manage subscriptions across every customer account. .. _notifications.clearpath: Configuring Teams Integration in |APPNAME| ------------------------------------------ To open the Teams Integration list, go to :blue:`Accounts` | :blue:`Advanced` | :blue:`Teams Integration`. .. figure:: /images/lightmode/teams-integration-list.png :align: center |br| Stat Chips ^^^^^^^^^^ Three cards across the top of the page summarise the current state of your subscriptions: * ``Total`` --- the total number of subscriptions configured for your account. * ``Enabled`` --- how many of those are currently active and will deliver events. * ``Failing`` --- how many have at least one consecutive delivery failure on record. A subscription is automatically disabled after ten consecutive failures so that a dead channel does not generate runaway log noise. Toolbar ^^^^^^^ The toolbar above the table provides: * **Search** --- filter the table by name, URL, or module list. * **Provider** --- show only Microsoft Teams, Slack, or Generic JSON subscriptions. * **State** --- show only ``Enabled`` or only ``Disabled`` rows. * **Refresh** --- reload the table. Table Columns ^^^^^^^^^^^^^ The Teams Integration table has the following columns: * **State** --- a coloured pill showing whether the subscription is currently ``Enabled`` (green) or ``Disabled`` (grey). This is the leftmost column so you can scan the page at a glance for any subscription that is not actively delivering. * **Account** *(root users only)* --- the customer account that owns this subscription. This column is hidden for account administrators because they only ever see their own account's rows. * **Name** --- the friendly name of the subscription, with the destination URL shown beneath it. The URL is truncated for display; hover over it to see the full address. * **Provider** --- a coloured pill identifying the destination type (``Microsoft Teams``, ``Slack``, ``Generic JSON``). * **Filters** --- the severity and module filters applied to this subscription. ``all severities`` and ``all modules`` mean no filter is in place; otherwise each selected severity and each named module appears as a small pill. * **Last Fired** --- the most recent date and time |APPNAME| attempted to deliver an event to this subscription, or ``never`` if no attempt has been made yet. * **Last Result** --- the HTTP status returned by the destination on the last attempt (for example ``200 OK``). A 2xx code is shown in green; anything else is shown in red. * A three-dot menu for per-row actions. Row Menu ^^^^^^^^ The three-dot menu on each row exposes these actions, in order: * ``Edit`` --- opens the webhook editor for the selected row. * ``Send test`` --- delivers a synthetic test event immediately so you can confirm the destination is reachable. The result is shown as a toast and is also written to the row's ``Last Result`` column. * ``Disable`` (or ``Enable``) --- toggles the subscription on or off without opening the editor. * ``Delete`` --- removes the subscription after a confirmation prompt; styled as a danger action. Creating or Editing a Subscription ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Click ``New Webhook`` at the top right of the page (or ``Edit`` from a row menu) to open the editor: .. figure:: /images/lightmode/teams-integration-detail-teams.png :align: center |br| Fill in the following fields: * ``Account`` --- the customer account this subscription belongs to. * Root users can target any account, including the system-wide Primary Account. * Account administrators see their own account pre-selected and the dropdown disabled --- you cannot create a subscription for any other customer. * ``Enabled`` --- a slider on the same row as the account dropdown. Slide right to switch the subscription on; slide left to switch it off without deleting it. * ``Name`` --- a short, friendly name. This is what appears in the list and in any error messages, so make it specific (for example *Teams --- IPC channel* or *Slack --- night shift coordinators*). * ``Provider`` --- the destination type. Pick one of: * **Microsoft Teams (Adaptive Card via Workflows)** --- |APPNAME| will format the message as an Adaptive Card and POST it to the Power Automate Workflows URL you paste in below. * **Slack (Incoming Webhook)** --- |APPNAME| will format the message using Slack's standard message JSON. * **Generic JSON** --- |APPNAME| will POST a flat JSON object to the URL. Use this when you are integrating with your own service. * ``Webhook URL`` --- the destination URL you generated in the destination application. Must use ``https://``. |APPNAME| treats this URL as a secret --- anyone holding it can post into your channel --- so the URL is masked from non-root users in the table. A small **clipboard** icon at the right edge of the field copies the current URL to the clipboard in one click. * ``Severity Filter`` --- tick one or more of ``Event``, ``Minor``, ``Major``, ``Critical`` to deliver only those severities to this destination. Leave **all checkboxes unticked** to deliver every severity. * ``Module Filter`` --- a comma-separated list of module names that should reach this destination, or ``*`` for all modules. Examples: ``reports``, ``audit,compliance``. Leave the field at ``*`` (the default) to receive notifications from every module. * ``Signing Secret`` *(Generic JSON only)* --- an optional shared secret. When set, |APPNAME| sends it as the ``X-clearPath-Signature`` HTTP header on every delivery so your receiver can verify the message came from |APPNAME|. Click ``Save`` to store the subscription, or ``Send test`` to fire a synthetic event right now. The test fire is the same payload a real event would produce, so it is the fastest way to confirm both ends of the pipe. What Triggers a Webhook ^^^^^^^^^^^^^^^^^^^^^^^ |APPNAME| fans out to your matching webhook subscriptions every time the system records a notification event. The most common triggers include: * A scheduled report finishes generating. * An audit session is submitted or auto-closed. * A compliance threshold or target is missed. * A unit is locked or unlocked. * A user account is locked or has its password reset. Each subscription only receives events that match its severity and module filters and that belong to its account. A subscription you create on the *Hope Memorial* account will never receive events from a different customer account. Delivery is fire-and-forget --- |APPNAME| sends one HTTP POST per event and moves on. If the destination is unreachable the failure is recorded against the subscription's row and counted toward the auto-disable threshold; the event itself is still recorded normally in |APPNAME|. What Recipients See ^^^^^^^^^^^^^^^^^^^ For Microsoft Teams subscriptions the message arrives as an Adaptive Card with: * A **bold title** carrying the event description, coloured by severity (red for major and critical, amber for minor, neutral for events). * A **fact set** showing the severity name, the module that raised the event, the account, and the timestamp in UTC. * A **detail block** with the event's free-text detail when one is present. * An ``Open in clearPath`` button that links the recipient straight to the relevant page inside |APPNAME|. Slack messages arrive as a single coloured message with the description, severity, and module fields. Generic JSON deliveries arrive as a flat JSON document; see :ref:`notifications.generic` below for the exact field list. .. _notifications.destination: Setting up the destination -------------------------- This is the third-party side of the integration --- creating the webhook URL inside Microsoft Teams, Slack, or your own service so that |APPNAME| has somewhere to deliver events to. You only need to do this once per channel. Microsoft Teams ^^^^^^^^^^^^^^^ .. note:: Microsoft retired the legacy Office 365 *Incoming Webhook* connector in late 2025. Existing ``outlook.office.com/webhook/...`` URLs no longer work. The supported path is now **Power Automate Workflows**, which |APPNAME| supports natively. .. tip:: For a step-by-step video walkthrough of creating the Power Automate Workflows webhook URL inside Microsoft Teams, see `this YouTube tutorial `_. To create a Workflows webhook URL: 1. Open Microsoft Teams and navigate to the channel where you want notifications to land. 2. Right-click the channel name (or click the **...** menu beside it) and choose ``Workflows``. 3. From the template gallery, pick **"Post to a channel when a webhook request is received"**. Microsoft maintains this template; you do not need to author the flow yourself. 4. Give the flow a friendly name (for example *clearPath Notifications*) and click ``Next``. 5. Confirm the **Team** and **Channel** the flow should post to and click ``Create flow``. 6. Power Automate generates a long URL that looks like this: .. code-block:: text https://prod-12.canadacentral.logic.azure.com/workflows//triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig= 7. Copy that URL and click ``Done``. 8. In |APPNAME|, open :blue:`Accounts` | :blue:`Advanced` | :blue:`Teams Integration`, click ``New Webhook``, choose ``Microsoft Teams`` as the provider, paste the URL into the ``Webhook URL`` field, and click ``Send test``. A test card should appear in the channel within a few seconds. .. warning:: The signature in the ``sig=`` query parameter is what authenticates |APPNAME| to your channel --- treat the URL as you would a password. Anyone holding it can post into the channel. |APPNAME| stores the URL as a secret and masks it for non-root users in the webhooks list, but if the URL is exposed by accident, regenerate it from inside Power Automate (which invalidates the old signature). Slack ^^^^^ To create a Slack incoming webhook URL: 1. In your Slack workspace, open ``Apps`` | ``Manage`` | ``Custom Integrations`` | ``Incoming Webhooks``. 2. Click ``Add to Slack``. 3. Choose the channel where you want notifications to land and click ``Add Incoming Webhooks integration``. 4. Slack displays a webhook URL of the form: .. code-block:: text https://hooks.slack.com/services/T01ABCDEFGH/B02IJKLMNOP/<24-char-token> 5. Copy that URL. 6. In |APPNAME|, open :blue:`Accounts` | :blue:`Advanced` | :blue:`Teams Integration`, click ``New Webhook``, choose ``Slack`` as the provider, paste the URL into the ``Webhook URL`` field, and click ``Send test``. .. note:: Everything after ``/services/`` in the URL is the credential. As with Teams, treat the URL as a secret. If it is ever exposed, regenerate it from the Slack admin and update the |APPNAME| subscription. .. _notifications.generic: Generic JSON ^^^^^^^^^^^^ The Generic JSON provider is for integrating with your own services --- a SIEM, a paging system, an internal dashboard, anything that can accept an HTTPS POST. The destination URL can be any HTTPS endpoint your network allows |APPNAME| to reach. |APPNAME| sends a flat JSON object on every event: .. code-block:: json { "description": "Audit session submitted", "severity": "minor", "severitynum": 3, "module": "audit", "corporation": 122, "occuredon": "2026-05-07T14:33:21Z", "link": "audit.session.detail.html?id=4711", "hostip": "10.6.18.40", "detail": [ "Submitted by: Sarah Patel (RN)", "Unit: 4 East", "Score: 92%" ] } Field notes: * ``severity`` is the human-readable severity name; ``severitynum`` is the same value as an integer (0 = ignore, 1 = log, 2 = event, 3 = minor, 4 = major, 5 = critical). * ``occuredon`` is in ISO-8601 UTC. * ``link`` is a relative path inside |APPNAME|; prepend your |APPNAME| base URL to build a clickable link. * ``detail`` is an array of free-text detail strings; it may be empty. To use the optional **signing secret**, set the ``Signing Secret`` field on the webhook editor (the field is only visible when ``Generic JSON`` is selected). |APPNAME| will then send the secret on every delivery as an ``X-clearPath-Signature`` HTTP header, so your receiver can confirm the message came from |APPNAME| and reject any request that does not carry the expected secret. A typical Generic JSON setup: .. figure:: /images/lightmode/teams-integration-detail-generic.png :align: center |br|