Test LineNotify integration with healthcheck

This commit is contained in:
carson.wang 2020-08-13 18:04:15 +08:00 committed by Pēteris Caune
parent 2346ac3e80
commit 65b65188d1
No known key found for this signature in database
GPG Key ID: E28D7679E9A9EDE2
15 changed files with 200 additions and 0 deletions

View File

@ -51,6 +51,7 @@ CHANNEL_KINDS = (
("zulip", "Zulip"),
("spike", "Spike"),
("call", "Phone Call"),
("linenotify", "LineNotify"),
)
PO_PRIORITIES = {-2: "lowest", -1: "low", 0: "normal", 1: "high", 2: "emergency"}
@ -463,6 +464,8 @@ class Channel(models.Model):
return transports.Spike(self)
elif self.kind == "call":
return transports.Call(self)
elif self.kind == "linenotify":
return transports.LineNotify(self)
else:
raise NotImplementedError("Unknown channel kind: %s" % self.kind)
@ -747,6 +750,14 @@ class Channel(models.Model):
doc = json.loads(self.value)
return doc["to"]
@property
def linenotify_token(self):
assert self.kind == "linenotify"
if not self.value.startswith("{"):
return self.value
doc = json.loads(self.value)
return doc["token"]
class Notification(models.Model):
class Meta:

View File

@ -619,3 +619,17 @@ class Spike(HttpTransport):
}
return self.post(url, json=payload, headers=headers)
class LineNotify(HttpTransport):
URL = "https://notify-api.line.me/api/notify"
def notify(self, check):
headers = {
"Content-Type": "multipart/form-data",
"Authorization": "Bearer %s" % settings.LINE_NOTIFY_ACCESS_TOKEN,
}
payload = {
"message": tmpl("linenotify_message.html", check=check)
}
return self.post(URL, headers=headers, params=payload)

View File

@ -104,6 +104,8 @@ class AddOpsGenieForm(forms.Form):
region = forms.ChoiceField(initial="us", choices=(("us", "US"), ("eu", "EU")))
key = forms.CharField(max_length=40)
class AddLineNotifyForm(forms.Form):
token = forms.CharField(max_length=40)
PRIO_CHOICES = [
("-2", "Lowest Priority"),

View File

@ -0,0 +1,16 @@
from django.test.utils import override_settings
from hc.api.models import Channel
from hc.test import BaseTestCase
@override_settings(LINE_NOTIFY_ACCESS_TOKEN="foo")
class AddLineNotifyTestCase(BaseTestCase):
url = "/integrations/add_linenotify/"
def setUp(self):
super(AddLineNotifyTestCase, self).setUp()
self.url = "/projects/%s/add_linenotify/" % self.project.code
def test_instructions_work(self):
self.client.login(username="alice@example.org", password="password")
r = self.client.get(self.url)
self.assertContains(r, "LineNotify")

View File

@ -79,6 +79,7 @@ project_urls = [
path("add_whatsapp/", views.add_whatsapp, name="hc-add-whatsapp"),
path("add_zulip/", views.add_zulip, name="hc-add-zulip"),
path("add_spike/", views.add_spike, name="hc-add-spike"),
path("add_linenotify/", views.add_linenotify, name="hc-add-linenotify"),
path("badges/", views.badges, name="hc-badges"),
path("checks/", views.my_checks, name="hc-checks"),
path("checks/add/", views.add_check, name="hc-add-check"),

View File

@ -273,6 +273,7 @@ def index(request):
"enable_telegram": settings.TELEGRAM_TOKEN is not None,
"enable_trello": settings.TRELLO_APP_KEY is not None,
"enable_whatsapp": settings.TWILIO_USE_WHATSAPP,
"enable_linenotify": settings.LINE_NOTIFY_ACCESS_TOKEN is not None,
"registration_open": settings.REGISTRATION_OPEN,
}
@ -711,6 +712,7 @@ def channels(request, code):
"enable_telegram": settings.TELEGRAM_TOKEN is not None,
"enable_trello": settings.TRELLO_APP_KEY is not None,
"enable_whatsapp": settings.TWILIO_USE_WHATSAPP,
"enable_linenotify": settings.LINE_NOTIFY_ACCESS_TOKEN is not None,
"use_payments": settings.USE_PAYMENTS,
}
@ -1381,6 +1383,26 @@ def add_opsgenie(request, code):
ctx = {"page": "channels", "project": project, "form": form}
return render(request, "integrations/add_opsgenie.html", ctx)
# @require_setting("LINE_NOTIFY_ACCESS_TOKEN")
@login_required
def add_linenotify(request, code):
project = _get_project_for_user(request, code)
if request.method == "POST":
form = forms.AddLineNotifyForm(request.POST)
if form.is_valid():
channel = Channel(project=project, kind="linenotify")
channel.value = form.cleaned_data["value"]
channel.save()
channel.assign_all_checks()
return redirect("hc-p-channels", project.code)
else:
form = forms.AddLineNotifyForm()
ctx = {"page": "channels", "project": project, "form": form}
return render(request, "integrations/add_linenotify.html", ctx)
@login_required
def add_victorops(request, code):

View File

@ -208,6 +208,9 @@ PD_VENDOR_KEY = os.getenv("PD_VENDOR_KEY")
# Trello
TRELLO_APP_KEY = os.getenv("TRELLO_APP_KEY")
# Line notify integration
LINE_NOTIFY_ACCESS_TOKEN = os.getenv("LINE_NOTIFY_ACCESS_TOKEN")
# Matrix
MATRIX_HOMESERVER = os.getenv("MATRIX_HOMESERVER")
MATRIX_USER_ID = os.getenv("MATRIX_USER_ID")

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

@ -412,6 +412,17 @@
<a href="{% url 'hc-add-zulip' project.code %}" class="btn btn-primary">Add Integration</a>
</li>
{% comment %} {% if enable_linenotify %} {% endcomment %}
<li>
<img src="{% static 'img/integrations/linenotify.png' %}"
class="icon" alt="LineNotify icon" />
<h2>LineNotify</h2>
<p>Get a LineNotify message when a check goes up or down.</p>
<a href="{% url 'hc-add-linenotify' project.code %}" class="btn btn-primary">Add Integration</a>
</li>
{% comment %} {% endif %} {% endcomment %}
<li class="link-to-github">
<img src="{% static 'img/integrations/missing.png' %}"
class="icon" alt="Suggest New Integration" />

View File

@ -642,6 +642,15 @@
</h3>
</div>
</div>
{% comment %} {% if enable_linenotify %} {% endcomment %}
<div class="col-lg-2 col-md-3 col-sm-4 col-xs-6">
<div class="integration">
<img src="{% static 'img/integrations/linenotify.png' %}" class="icon" alt="" />
<h3>LineNotify<br><small>Chat</small></h3>
</div>
</div>
{% comment %} {% endif %} {% endcomment %}
</div>
<div class="row tour-section">

View File

@ -0,0 +1,105 @@
{% extends "base.html" %}
{% load humanize static hc_extras %}
{% block title %}LineNotify Integration for {% site_name %}{% endblock %}
{% block content %}
<div class="row">
<div class="col-sm-12">
<h1>LineNotify</h1>
<p><a href="https://notify-bot.line.me/en/">LineNotify</a>
allows you to send web notifications directly to your LINE chats.
If you use or plan on using LineNotify,
you can set up {% site_name %} to post status updates directly to an appropriate LineNotify channel.
Here are a few steps that can integrate it with your {% site_name %} account.</p>
<h2>Setup Guide</h2>
<div class="row ai-step">
<div class="col-sm-6">
<span class="step-no"></span>
<p>
Log into your Line account,
go to <strong>My Pages</strong> in the upper right corner.
In the <strong>My Pages</strong>, scroll to the bottom of the page,
and click on <strong>Generate token</strong> button.
</p>
</div>
<div class="col-sm-6">
<div class="marker-wrap">
<span style="left: 77%; top: 14%;" class="marker"></span>
<img
class="ai-guide-screenshot"
alt="Screenshot"
src="{% static 'img/integrations/setup_linenotify_1.png' %}" />
</div>
</div>
</div>
<div class="row ai-step">
<div class="col-sm-6">
<span class="step-no"></span>
<p>
It will pop up the <strong>Generate token</strong> Form.
Fill out the details, and click the button.
</p>
</div>
<div class="col-sm-6">
<img
class="ai-guide-screenshot"
alt="Screenshot"
src="{% static 'img/integrations/setup_linenotify_2.png' %}">
</div>
</div>
<div class="row ai-step">
<div class="col-sm-6">
<span class="step-no"></span>
<p>
Copy the displayed <strong>Token</strong> and paste it
in the form below.
Save the integration, and it's done!
</p>
</div>
<div class="col-sm-6">
<img
class="ai-guide-screenshot"
alt="Screenshot"
src="{% static 'img/integrations/setup_linenotify_3.png' %}">
</div>
</div>
<h2>Integration Settings</h2>
<form method="post" class="form-horizontal">
{% csrf_token %}
<div class="form-group {{ form.value.css_classes }}">
<label for="api-token" class="col-sm-2 control-label">API Token</label>
<div class="col-sm-10">
<input
id="api-token"
type="text"
class="form-control"
name="token"
placeholder=""
value="{{ form.token.value|default:"" }}">
{% if form.token.errors %}
<div class="help-block">
{{ form.token.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 %}

View File

@ -0,0 +1,6 @@
{% load humanize %}
{% if check.status == "down" %}
The check "{{ check.name_then_code }}" is <b>DOWN</b>. Last ping was {{ check.last_ping|naturaltime }}.
{% else %}
The check "{{ check.name_then_code }}" is now <b>UP</b>.
{% endif %}