Compare commits
2 commits
6e499e2e9c
...
8f1495cf0c
Author | SHA1 | Date | |
---|---|---|---|
8f1495cf0c | |||
bc4639a055 |
6 changed files with 77 additions and 0 deletions
|
@ -8,6 +8,10 @@ Provide ways to send notifications to signal-cli through webhooks
|
|||
virtualenv -p python3 --system-site-packages venv
|
||||
source venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Configure
|
||||
cp signal_webhook/configuration.sample.py signal_webhook/configuration.py
|
||||
$EDITOR signal_webhook/configuration.py
|
||||
```
|
||||
|
||||
**Beware!** Sending messages to Signal requires `gi`, which cannot be installed
|
||||
|
|
2
requirements.txt
Normal file
2
requirements.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
Flask
|
||||
pydbus
|
1
signal_webhook/.gitignore
vendored
Normal file
1
signal_webhook/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
configuration.py
|
47
signal_webhook/app.py
Normal file
47
signal_webhook/app.py
Normal file
|
@ -0,0 +1,47 @@
|
|||
import typing as t
|
||||
from collections import defaultdict
|
||||
from flask import Flask, request
|
||||
from . import signal
|
||||
from . import configuration
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.route("/")
|
||||
def root() -> t.Tuple[str, int]:
|
||||
return "Not supported.", 400
|
||||
|
||||
|
||||
@app.route("/alertmanager", methods=["POST"])
|
||||
def alertmanager():
|
||||
data = request.get_json(cache=False)
|
||||
|
||||
if "version" not in data or int(data["version"]) != 4:
|
||||
return "Bad API version", 400
|
||||
if "alerts" not in data:
|
||||
return "No alerts", 400
|
||||
if "status" not in data:
|
||||
return "No status", 400
|
||||
if data["status"] != "firing":
|
||||
# Ignore
|
||||
return "OK", 200
|
||||
|
||||
severities = defaultdict(int)
|
||||
alert_lines = []
|
||||
for alert in data["alerts"]:
|
||||
try:
|
||||
severities[alert["labels"]["severity"]] += 1
|
||||
alert_lines.append(
|
||||
f"<{alert['labels']['alertname']}> {alert['annotations']['description']}"
|
||||
)
|
||||
except KeyError as exn:
|
||||
alert_lines.append(f"(malformed alert — {exn})")
|
||||
|
||||
msg = f"[PROMETHEUS] {len(data['alerts'])} firing: "
|
||||
msg += ", ".join([f"{count} {typ}" for typ, count in severities.items()])
|
||||
msg += "\n\n"
|
||||
msg += "\n".join(["* " + line for line in alert_lines])
|
||||
|
||||
signal.signal_send(configuration.RECIPIENTS[configuration.DEFAULT_RECIPIENT], msg)
|
||||
|
||||
return "OK", 200
|
5
signal_webhook/configuration.sample.py
Normal file
5
signal_webhook/configuration.sample.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Signal 'address book'
|
||||
RECIPIENTS = {"foo": "+42..."} # FIXME
|
||||
|
||||
# Recipient from the dict above to send to by default
|
||||
DEFAULT_RECIPIENT = "foo" # FIXME
|
18
signal_webhook/signal.py
Normal file
18
signal_webhook/signal.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
import logging
|
||||
from pydbus import SystemBus
|
||||
from gi.repository.GLib import GError
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def signal_send(recipient, message):
|
||||
try:
|
||||
bus = SystemBus()
|
||||
signal_bus = bus.get("org.asamk.Signal")
|
||||
signal_bus.sendMessage(
|
||||
message,
|
||||
[],
|
||||
[recipient],
|
||||
)
|
||||
except GError as exn:
|
||||
logger.error("Cannot send Signal notification: %s", exn)
|
Loading…
Reference in a new issue