GitHunt
AL

Aldaviva/EmergencyPager

๐Ÿ“Ÿ Trigger a PagerDuty incident when UptimeObserver detects that a service is down.

EmergencyPager EmergencyPager

GitHub Actions Testspace Coveralls

When an alert is triggered in PagerDuty, turn on Kasa smart outlets and send push notifications that show toasts on Windows.

    ๐Ÿšจ Turn on a smart outlet when an incident is triggered.
    ๐Ÿž Show an interactive desktop toast notification when an incident is triggered.

Prerequisites

PagerDuty Incidents โ†’ spinning red light

Installation

  1. Download the ZIP file for your operating system and CPU architecture from the latest release page.
  2. Extract the ZIP file to a directory of your choice, such as C:\Program Files\EmergencyPager\ or /opt/emergencypager/.
    • When installing updates, don't overwrite appsettings.json.
  3. Install the service so it will start automatically when your computer boots.
    • Windows: & '.\Install service.ps1'
      • If this PowerShell script doesn't run, try removing the Mark of the Web by unblocking the file or calling Set-ExecutionPolicy RemoteSigned.
    • Linux with systemd:
      sudo cp emergencypager.service /etc/systemd/system/
      sudo systemctl daemon-reload
      sudo systemctl enable emergencypager.service
      • If the installation directory is not /opt/emergencypager/, make sure to edit emergencypager.service to match.

Configuration

Procedure

  1. Create a Webhook integration in PagerDuty.
    1. Sign into your PagerDuty account.
    2. Go to Integrations โ€บ Generic Webhooks (v3).
    3. Click + New Webhook.
    4. Set the Webhook URL to the location of your EmergencyPager server, such as http://myserver.example.com:37374/pagerduty.
    5. Choose whether events should be fired for all Services in your account, or just one Service.
    6. Choose which Events should be fired, such as incident.acknowledged, incident.escalated, incident.reassigned, incident.reopened, incident.resolved, incident.triggered, and incident.unacknowledged
    7. Click Add Webhook.
    8. Copy the Signing Secret to the pagerDutyWebhookSecrets array in the appsettings.json configuration file.
  2. Specify the smart outlets to turn on when PagerDuty incidents are triggered.
    1. In appsettings.json, add a new key-value pair to the alarmLightUrlsByPagerDutySubdomain property.
      • The key is the PagerDuty organization subdomain, also known as company name. For example, if your PagerDuty web admin UI URL is https://mycompany.pagerduty.com, then set this key to mycompany.
      • The value is an array of one or more URLs representing Kasa smart outlets. The hostname is the IP address or domain name of your outlet, and the optional path is an integer specifying the 0-indexed socket ID if your outlet has multiple sockets, such as the EP40.
      • Example:
        "alarmLightUrlsByPagerDutySubdomain": {
            "mycompany": ["tcp://192.168.1.100"]
        }

Options

These go in appsettings.json.

alarmLightUrlsByPagerDutySubdomain
{ "mycompany": ["tcp://192.168.1.100", "tcp://192.168.1.101/0"] }

Object where each key is the company name or subdomain of a PagerDuty organization, and its value is an array of URLs of Kasa smart outlets to turn on when an incident in that organization is triggered. The URL path is a 0-indexed integer that identifies which socket on the outlet to control, which can be 0 or the empty string if the outlet only has one socket. The scheme doesn't matter.

kestrel.endpoints.https.url
http://0.0.0.0:37374

URI specifying the hostname and TCP port on which to listen for HTTP requests from the EmergencyPager webhook client. Must be publicly accessible on the WAN.

pagerDutyWebhookSecrets
["u565tpiQ3TnIโ€ฆ"]

Array of one or more PagerDuty webhook signing secrets, which are generated by PagerDuty when you create a new webhook subscription. Only required if you want to turn on smart outlets or show toast notifications on Windows.

Execution

  1. Start the service.
    • Windows: Restart-Service EmergencyPager
    • Linux with systemd: sudo systemctl restart emergencypager.service

Signal Flow

  1. Something triggers an alert in PagerDuty PagerDuty.
  2. PagerDuty PagerDuty creates a new incident for this alert.
  3. PagerDuty PagerDuty sends an HTTP POST request to Aldaviva EmergencyPager with the newly triggered incident.
  4. Aldaviva EmergencyPager sends a TCP JSON object to a Kasa smart outlet, commanding it to turn on its electrical socket.
  5. Aldaviva EmergencyPager sends a WebSocket message containing the newly triggered incident to any connected Aldaviva EmergencyPager.Toast clients, which show Windows toast notifications.
  6. When the Incident is eventually resolved in PagerDuty PagerDuty, it sends another POST request to Aldaviva EmergencyPager, which turns off the smart outlet and dismisses the toasts.

PagerDuty Incidents โ†’ Desktop Push Notifications

PagerDuty makes it easy to receive push notifications for triggered incidents through their Android and iOS apps, SMS, email, and PSTN calls. However, it's not as easy to get an obvious, actionable notification if you're only on a computer while your phone isn't nearby. Phone Link and Google Messages for Web are very unreliable, and emails are easy to miss.

You can solve this with a background program that runs on Windows, connects to the EmergencyPager server, and receives push notifications for triggered incidents which it shows as native Windows toasts. These are rich notifications with buttons to acknowledge or resolve the incident with one click. You can also click on the body of the toast to open the incident web page in your browser.

Test Service. Example incident. #55 Triggered

Installation

  1. Download EmergencyPager.Toast-win-x64 from the latest release page.
  2. Extract the EXE from the ZIP file to your hard drive.
  3. Register this program to start when you log into Windows by adding its absolute path to a new string value in the registry key HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run.

Configuration

  1. Create a configuration JSON file.
    1. Save the example configuration file to %appdata%\EmergencyPager\Toast.config.json.
  2. Set the hubAddress to the URL of your EmergencyPager server, with the path /pagerduty/toasts. This connects the Toast client to the WebSocket server.
  3. Replace the myorg key in the pagerDutyAccountsBySubdomain object with the subdomain of your PagerDuty organization (the part of the hostname before the .pagerduty.com base domain in the web interface, not including that base domain).
    • This is used to determine which organization of the following information should be used for a given incident, if you are subscribed to webhooks from multiple organizations.
  4. Set the userId of the organization object to the ID of your user, which is the last path segment of your PagerDuty profile page accessible from People โ€บ Users.
    • This is used to record which user acknowledged or resolved an incident.
  5. Set the userEmailAddress to your account's email address.
    • This prevents you from receiving toasts for incidents which are assigned to different people.
  6. Create an API access key in PagerDuty.
    1. Sign into your PagerDuty account.
    2. Go to Integrations โ€บ API Access Keys.
    3. Click + Create New API Key.
    4. Enter a descriptive name, and make sure Read-only API Key is unchecked.
    5. Click Create Key.
    6. Set the apiAccessKey in Toast.config.json to this new access key.
    • This is used to acknowledge and resolve incidents, since Events V2 Integration Keys are not able to do this because they control alerts, not incidents.

Execution

  1. Double-click the EXE file to start it. It will run in the background and not show any UI until an incident is triggered.
Aldaviva/EmergencyPager | GitHunt