forked from GithubBackups/healthchecks
Send emails using djrill (Mandrill)
This commit is contained in:
parent
b2dc319e6c
commit
c54cb6469d
@ -8,9 +8,11 @@ from django.core.mail import send_mail
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import HttpResponseBadRequest
|
||||
from django.shortcuts import redirect, render
|
||||
from django.template import loader
|
||||
|
||||
from hc.accounts.forms import EmailForm
|
||||
from hc.api.models import Check
|
||||
from hc.lib.emails import send
|
||||
|
||||
|
||||
def _make_user(email):
|
||||
@ -28,6 +30,18 @@ def _associate_demo_check(request, user):
|
||||
check.save()
|
||||
|
||||
|
||||
def _send_login_link(user):
|
||||
token = str(uuid.uuid4())
|
||||
user.set_password(token)
|
||||
user.save()
|
||||
|
||||
login_link = reverse("hc-check-token", args=[user.username, token])
|
||||
login_link = settings.SITE_ROOT + login_link
|
||||
ctx = {"login_link": login_link}
|
||||
|
||||
send(user.email, "emails/login", ctx)
|
||||
|
||||
|
||||
def login(request):
|
||||
if request.method == 'POST':
|
||||
form = EmailForm(request.POST)
|
||||
@ -43,16 +57,7 @@ def login(request):
|
||||
if user.is_staff:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
token = str(uuid.uuid4())
|
||||
user.set_password(token)
|
||||
user.save()
|
||||
|
||||
login_link = reverse("hc-check-token", args=[user.username, token])
|
||||
login_link = settings.SITE_ROOT + login_link
|
||||
body = "login link: %s" % login_link
|
||||
|
||||
send_mail('Log In', body, settings.DEFAULT_FROM_EMAIL, [email],
|
||||
fail_silently=False)
|
||||
_send_login_link(user)
|
||||
|
||||
return redirect("hc-login-link-sent")
|
||||
|
||||
|
@ -6,3 +6,12 @@ from hc.api.models import Check
|
||||
@admin.register(Check)
|
||||
class ChecksAdmin(admin.ModelAdmin):
|
||||
list_display = ("id", "code", "user", "last_ping")
|
||||
actions = ["send_alert"]
|
||||
|
||||
def send_alert(self, request, qs):
|
||||
for check in qs:
|
||||
check.send_alert()
|
||||
|
||||
self.message_user(request, "%d alert(s) sent" % qs.count())
|
||||
|
||||
send_alert.short_description = "Send Alert"
|
||||
|
@ -5,7 +5,6 @@ from django.core.management.base import BaseCommand
|
||||
from django.utils import timezone
|
||||
|
||||
from hc.api.models import Check
|
||||
from hc.lib.emails import send_status_notification
|
||||
|
||||
|
||||
def _log(message):
|
||||
@ -14,7 +13,7 @@ def _log(message):
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Ensures triggers exist in database'
|
||||
help = 'Sends UP/DOWN email alerts'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
|
||||
@ -29,7 +28,7 @@ class Command(BaseCommand):
|
||||
check.status = "down"
|
||||
|
||||
_log("\nSending email about going down for %s\n" % check.code)
|
||||
send_status_notification(check)
|
||||
check.send_alert()
|
||||
ticks = 0
|
||||
|
||||
# Save status after the notification is sent
|
||||
@ -44,7 +43,7 @@ class Command(BaseCommand):
|
||||
check.status = "up"
|
||||
|
||||
_log("\nSending email about going up for %s\n" % check.code)
|
||||
send_status_notification(check)
|
||||
check.send_alert()
|
||||
ticks = 0
|
||||
|
||||
# Save status after the notification is sent
|
||||
|
@ -5,8 +5,22 @@ from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
|
||||
from hc.lib.emails import send
|
||||
|
||||
STATUSES = (("up", "Up"), ("down", "Down"), ("new", "New"))
|
||||
DEFAULT_TIMEOUT = td(days=1)
|
||||
TIMEOUT_CHOICES = (
|
||||
("15 minutes", td(minutes=15)),
|
||||
("30 minutes", td(minutes=30)),
|
||||
("1 hour", td(hours=1)),
|
||||
("3 hours", td(hours=3)),
|
||||
("6 hours", td(hours=6)),
|
||||
("12 hours", td(hours=12)),
|
||||
("1 day", td(days=1)),
|
||||
("2 days", td(days=2)),
|
||||
("3 days", td(days=3)),
|
||||
("1 week", td(weeks=1))
|
||||
)
|
||||
|
||||
|
||||
class Check(models.Model):
|
||||
@ -21,3 +35,15 @@ class Check(models.Model):
|
||||
|
||||
def url(self):
|
||||
return settings.PING_ENDPOINT + str(self.code)
|
||||
|
||||
def send_alert(self):
|
||||
ctx = {
|
||||
"timeout_choices": TIMEOUT_CHOICES,
|
||||
"check": self,
|
||||
"checks": self.user.check_set.order_by("created")
|
||||
}
|
||||
|
||||
if self.status in ("up", "down"):
|
||||
send(self.user.email, "emails/alert", ctx)
|
||||
else:
|
||||
raise NotImplemented("Unexpected status: %s" % self.status)
|
||||
|
@ -1,19 +1,6 @@
|
||||
from datetime import timedelta as td
|
||||
|
||||
from django import forms
|
||||
|
||||
TIMEOUT_CHOICES = (
|
||||
("15 minutes", td(minutes=15)),
|
||||
("30 minutes", td(minutes=30)),
|
||||
("1 hour", td(hours=1)),
|
||||
("3 hours", td(hours=3)),
|
||||
("6 hours", td(hours=6)),
|
||||
("12 hours", td(hours=12)),
|
||||
("1 day", td(days=1)),
|
||||
("2 days", td(days=2)),
|
||||
("3 days", td(days=3)),
|
||||
("1 week", td(weeks=1))
|
||||
)
|
||||
from hc.api.models import TIMEOUT_CHOICES
|
||||
|
||||
|
||||
class TimeoutForm(forms.Form):
|
||||
|
@ -1,16 +1,18 @@
|
||||
from django.conf import settings
|
||||
from django.core.mail import send_mail
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
|
||||
def send_status_notification(check):
|
||||
if check.status == "down":
|
||||
subject = "Alert DOWN"
|
||||
body = "Hi, the check %s has gone down" % check.code
|
||||
elif check.status == "up":
|
||||
subject = "Alert UP"
|
||||
body = "Hi, the check %s has gone up" % check.code
|
||||
else:
|
||||
raise NotImplemented("Unexpected status: %s" % check.status)
|
||||
def send(to, template_directory, ctx):
|
||||
""" Send HTML email using Mandrill.
|
||||
|
||||
send_mail(subject, body, settings.DEFAULT_FROM_EMAIL, [check.user.email],
|
||||
fail_silently=False)
|
||||
Expect template_directory to be a path containing
|
||||
- subject.txt
|
||||
- body.html
|
||||
|
||||
"""
|
||||
|
||||
from_email = settings.DEFAULT_FROM_EMAIL
|
||||
subject = render_to_string("%s/subject.txt" % template_directory, ctx)
|
||||
body = render_to_string("%s/body.html" % template_directory, ctx)
|
||||
send_mail(subject, "", from_email, [to], html_message=body)
|
||||
|
@ -30,6 +30,7 @@ INSTALLED_APPS = (
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'djrill',
|
||||
|
||||
'hc.accounts',
|
||||
'hc.api',
|
||||
@ -92,13 +93,7 @@ STATIC_URL = '/static/'
|
||||
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, 'static-collected')
|
||||
|
||||
# AWS
|
||||
EMAIL_BACKEND = 'django_ses_backend.SESBackend'
|
||||
AWS_SES_ACCESS_KEY_ID = "---"
|
||||
AWS_SES_SECRET_ACCESS_KEY = "---"
|
||||
AWS_SES_REGION_NAME = 'us-east-1'
|
||||
AWS_SES_REGION_ENDPOINT = 'email.us-east-1.amazonaws.com'
|
||||
|
||||
EMAIL_BACKEND = "djrill.mail.backends.djrill.DjrillBackend"
|
||||
|
||||
try:
|
||||
from local_settings import *
|
||||
|
@ -2,4 +2,5 @@ Django==1.8.2
|
||||
django-ses
|
||||
psycopg2==2.6
|
||||
django-ses-backend
|
||||
djrill
|
||||
pygments
|
51
templates/emails/alert/body.html
Normal file
51
templates/emails/alert/body.html
Normal file
@ -0,0 +1,51 @@
|
||||
{% load humanize %}
|
||||
|
||||
<p>Hello,</p>
|
||||
<p>This is a notification sent by healthchecks.io</p>
|
||||
<p>The check "{{ check.name }}" has gone {{ check.status }}.</p>
|
||||
<p>Here is a summary of all your checks:</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Name</th>
|
||||
<th>URL</th>
|
||||
<th>Frequency</th>
|
||||
<th>Last Ping</th>
|
||||
</tr>
|
||||
{% for check in checks %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if check.status == "new" %}
|
||||
<span class="glyphicon glyphicon-question-sign new"></span>
|
||||
{% elif now < check.alert_after %}
|
||||
<span class="glyphicon glyphicon-ok-sign up"></span>
|
||||
{% else %}
|
||||
<span class="glyphicon glyphicon-exclamation-sign down"></span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{{ check.name }}
|
||||
</td>
|
||||
<td class="url-cell">
|
||||
<code>{{ check.url }}</code>
|
||||
</td>
|
||||
<td>
|
||||
{% for label, value in timeout_choices %}
|
||||
{% if check.timeout == value %}
|
||||
{{ label }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
{% if check.last_ping %}
|
||||
{{ check.last_ping|naturaltime }}
|
||||
{% else %}
|
||||
Never
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
|
2
templates/emails/alert/subject.txt
Normal file
2
templates/emails/alert/subject.txt
Normal file
@ -0,0 +1,2 @@
|
||||
{{ check.name }} is {{ check.status }}
|
||||
|
5
templates/emails/login/body.html
Normal file
5
templates/emails/login/body.html
Normal file
@ -0,0 +1,5 @@
|
||||
<p>Hello from healthchecks.io!</p>
|
||||
|
||||
<p>Here's a link to log yourself in:</p>
|
||||
<p><a href="{{ login_link }}">{{ login_link }}</a></p>
|
||||
|
1
templates/emails/login/subject.txt
Normal file
1
templates/emails/login/subject.txt
Normal file
@ -0,0 +1 @@
|
||||
Log in to healthchecks.io
|
Loading…
x
Reference in New Issue
Block a user