forked from GithubBackups/healthchecks
Apprise Integration
This commit is contained in:
parent
d39a1d5955
commit
c2b1d00422
@ -41,6 +41,7 @@ CHANNEL_KINDS = (
|
||||
("trello", "Trello"),
|
||||
("matrix", "Matrix"),
|
||||
("whatsapp", "WhatsApp"),
|
||||
("apprise", "Apprise"),
|
||||
)
|
||||
|
||||
PO_PRIORITIES = {-2: "lowest", -1: "low", 0: "normal", 1: "high", 2: "emergency"}
|
||||
@ -392,6 +393,8 @@ class Channel(models.Model):
|
||||
return transports.Matrix(self)
|
||||
elif self.kind == "whatsapp":
|
||||
return transports.WhatsApp(self)
|
||||
elif self.kind == "apprise":
|
||||
return transports.Apprise(self)
|
||||
else:
|
||||
raise NotImplementedError("Unknown channel kind: %s" % self.kind)
|
||||
|
||||
|
@ -3,6 +3,7 @@ from django.template.loader import render_to_string
|
||||
from django.utils import timezone
|
||||
import json
|
||||
import requests
|
||||
import apprise
|
||||
from urllib.parse import quote, urlencode
|
||||
|
||||
from hc.accounts.models import Profile
|
||||
@ -273,7 +274,7 @@ class PagerTree(HttpTransport):
|
||||
class PagerTeam(HttpTransport):
|
||||
def notify(self, check):
|
||||
url = self.channel.value
|
||||
headers = {"Conent-Type": "application/json"}
|
||||
headers = {"Content-Type": "application/json"}
|
||||
payload = {
|
||||
"incident_key": str(check.code),
|
||||
"event_type": "trigger" if check.status == "down" else "resolve",
|
||||
@ -461,3 +462,17 @@ class Trello(HttpTransport):
|
||||
}
|
||||
|
||||
return self.post(self.URL, params=params)
|
||||
|
||||
class Apprise(HttpTransport):
|
||||
def notify(self, check):
|
||||
a = apprise.Apprise()
|
||||
title = tmpl("apprise_title.html", check=check)
|
||||
body = tmpl("apprise_description.html", check=check)
|
||||
|
||||
a.add(self.channel.value)
|
||||
|
||||
notify_type = apprise.NotifyType.SUCCESS \
|
||||
if check.status == "up" else apprise.NotifyType.FAILURE
|
||||
|
||||
return "Failed" if not \
|
||||
a.notify(body=body, title=title, notify_type=notify_type) else None
|
||||
|
@ -159,3 +159,8 @@ class AddMatrixForm(forms.Form):
|
||||
self.cleaned_data["room_id"] = doc["room_id"]
|
||||
|
||||
return v
|
||||
|
||||
|
||||
class AddAppriseForm(forms.Form):
|
||||
error_css_class = "has-error"
|
||||
url = forms.CharField(max_length=512)
|
||||
|
21
hc/front/tests/test_add_apprise.py
Normal file
21
hc/front/tests/test_add_apprise.py
Normal file
@ -0,0 +1,21 @@
|
||||
from hc.api.models import Channel
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
|
||||
class AddSlackTestCase(BaseTestCase):
|
||||
def test_instructions_work(self):
|
||||
self.client.login(username="alice@example.org", password="password")
|
||||
r = self.client.get("/integrations/add_apprise/")
|
||||
self.assertContains(r, "Integration Settings", status_code=200)
|
||||
|
||||
def test_it_works(self):
|
||||
form = {"url": "json://example.org"}
|
||||
|
||||
self.client.login(username="alice@example.org", password="password")
|
||||
r = self.client.post("/integrations/add_apprise/", form)
|
||||
self.assertRedirects(r, "/integrations/")
|
||||
|
||||
c = Channel.objects.get()
|
||||
self.assertEqual(c.kind, "apprise")
|
||||
self.assertEqual(c.value, "json://example.org")
|
||||
self.assertEqual(c.project, self.project)
|
@ -43,6 +43,7 @@ channel_urls = [
|
||||
path("add_trello/", views.add_trello, name="hc-add-trello"),
|
||||
path("add_trello/settings/", views.trello_settings, name="hc-trello-settings"),
|
||||
path("add_matrix/", views.add_matrix, name="hc-add-matrix"),
|
||||
path("add_apprise/", views.add_apprise, name="hc-add-apprise"),
|
||||
path("<uuid:code>/checks/", views.channel_checks, name="hc-channel-checks"),
|
||||
path("<uuid:code>/name/", views.update_channel_name, name="hc-channel-name"),
|
||||
path("<uuid:code>/test/", views.send_test_notification, name="hc-channel-test"),
|
||||
|
@ -44,6 +44,7 @@ from hc.front.forms import (
|
||||
ChannelNameForm,
|
||||
EmailSettingsForm,
|
||||
AddMatrixForm,
|
||||
AddAppriseForm,
|
||||
)
|
||||
from hc.front.schemas import telegram_callback
|
||||
from hc.front.templatetags.hc_extras import num_down_title, down_title, sortchecks
|
||||
@ -1325,6 +1326,29 @@ def add_matrix(request):
|
||||
return render(request, "integrations/add_matrix.html", ctx)
|
||||
|
||||
|
||||
@login_required
|
||||
def add_apprise(request):
|
||||
if request.method == "POST":
|
||||
form = AddAppriseForm(request.POST)
|
||||
if form.is_valid():
|
||||
channel = Channel(project=request.project, kind="apprise")
|
||||
channel.value = form.cleaned_data["url"]
|
||||
channel.save()
|
||||
|
||||
channel.assign_all_checks()
|
||||
messages.success(request, "The Apprise integration has been added!")
|
||||
return redirect("hc-channels")
|
||||
else:
|
||||
form = AddAppriseForm()
|
||||
|
||||
ctx = {
|
||||
"page": "channels",
|
||||
"project": request.project,
|
||||
"form": form,
|
||||
}
|
||||
return render(request, "integrations/add_apprise.html", ctx)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_POST
|
||||
def trello_settings(request):
|
||||
|
@ -204,6 +204,7 @@ MATRIX_HOMESERVER = os.getenv("MATRIX_HOMESERVER")
|
||||
MATRIX_USER_ID = os.getenv("MATRIX_USER_ID")
|
||||
MATRIX_ACCESS_TOKEN = os.getenv("MATRIX_ACCESS_TOKEN")
|
||||
|
||||
|
||||
if os.path.exists(os.path.join(BASE_DIR, "hc/local_settings.py")):
|
||||
from .local_settings import *
|
||||
else:
|
||||
|
@ -4,3 +4,4 @@ django_compressor==2.2
|
||||
psycopg2==2.7.5
|
||||
pytz==2019.1
|
||||
requests==2.22.0
|
||||
apprise==0.7.9
|
||||
|
BIN
static/img/integrations/apprise.png
Normal file
BIN
static/img/integrations/apprise.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
@ -69,6 +69,8 @@
|
||||
{% endif %}
|
||||
{% elif ch.kind == "webhook" %}
|
||||
Webhook
|
||||
{% elif ch.kind == "apprise" %}
|
||||
Apprise
|
||||
{% elif ch.kind == "pushbullet" %}
|
||||
Pushbullet
|
||||
{% elif ch.kind == "discord" %}
|
||||
@ -211,6 +213,15 @@
|
||||
|
||||
<a href="{% url 'hc-add-webhook' %}" class="btn btn-primary">Add Integration</a>
|
||||
</li>
|
||||
<li>
|
||||
<img src="{% static 'img/integrations/apprise.png' %}"
|
||||
class="icon" alt="Pushover icon" />
|
||||
|
||||
<h2>Apprise</h2>
|
||||
<p>Receive instant push notifications using Apprise; see <a href="https://github.com/caronc/apprise#popular-notification-services" >all of the supported services here</a>.</p>
|
||||
|
||||
<a href="{% url 'hc-add-apprise' %}" class="btn btn-primary">Add Integration</a>
|
||||
</li>
|
||||
{% if enable_pushover %}
|
||||
<li>
|
||||
<img src="{% static 'img/integrations/po.png' %}"
|
||||
|
@ -432,6 +432,12 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="col-md-2 col-sm-4 col-xs-6">
|
||||
<div class="integration">
|
||||
<img src="{% static 'img/integrations/apprise.png' %}" class="icon" alt="Apprise icon" />
|
||||
<h3>WhatsApp<br><small>Chat</small></h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row tour-section">
|
||||
|
49
templates/integrations/add_apprise.html
Normal file
49
templates/integrations/add_apprise.html
Normal file
@ -0,0 +1,49 @@
|
||||
{% extends "base.html" %}
|
||||
{% load humanize static hc_extras %}
|
||||
|
||||
{% block title %}Add Apprise - {% site_name %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<h1>Apprise</h1>
|
||||
|
||||
<p>
|
||||
Identify as many Apprise URLs as you wish. You can use a comma (,) to identify
|
||||
more than on URL if you wish to.
|
||||
|
||||
For a detailed list of all supported Apprise Notification URLs simply
|
||||
<a href="https://github.com/caronc/apprise#popular-notification-services" >click here</a>.
|
||||
</p>
|
||||
|
||||
<h2>Integration Settings</h2>
|
||||
|
||||
<form method="post" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
|
||||
<div class="form-group {{ form.room_id.css_classes }}">
|
||||
<label for="url" class="col-sm-2 control-label">Apprise URL</label>
|
||||
<div class="col-sm-6">
|
||||
<input
|
||||
id="url"
|
||||
type="text"
|
||||
class="form-control"
|
||||
name="url"
|
||||
value="{{ form.url.value|default:"" }}">
|
||||
|
||||
{% if form.url.errors %}
|
||||
<div class="help-block">
|
||||
{{ form.url.errors|join:"" }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<button type="submit" class="btn btn-primary">Save Integration</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
5
templates/integrations/apprise_description.html
Normal file
5
templates/integrations/apprise_description.html
Normal file
@ -0,0 +1,5 @@
|
||||
{% load humanize %}
|
||||
{{ check.name_then_code }} is {{ check.status|upper }}.
|
||||
{% if check.status == "down" %}
|
||||
Last ping was {{ check.last_ping|naturaltime }}.
|
||||
{% endif %}
|
1
templates/integrations/apprise_title.html
Normal file
1
templates/integrations/apprise_title.html
Normal file
@ -0,0 +1 @@
|
||||
{{ check.name_then_code }} is {{ check.status|upper }}
|
Loading…
x
Reference in New Issue
Block a user