forked from GithubBackups/healthchecks
Webhook for Mandrill inbound email notifications
This commit is contained in:
parent
f640b9f3be
commit
b75ab00d18
29
hc/api/migrations/0009_auto_20150801_1250.py
Normal file
29
hc/api/migrations/0009_auto_20150801_1250.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('api', '0008_auto_20150801_1213'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='ping',
|
||||||
|
name='scheme',
|
||||||
|
field=models.CharField(max_length=10, default='http'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='ping',
|
||||||
|
name='method',
|
||||||
|
field=models.CharField(blank=True, max_length=10),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='ping',
|
||||||
|
name='remote_addr',
|
||||||
|
field=models.GenericIPAddressField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
]
|
@ -63,7 +63,8 @@ class Check(models.Model):
|
|||||||
class Ping(models.Model):
|
class Ping(models.Model):
|
||||||
owner = models.ForeignKey(Check)
|
owner = models.ForeignKey(Check)
|
||||||
created = models.DateTimeField(auto_now_add=True)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
remote_addr = models.GenericIPAddressField()
|
scheme = models.CharField(max_length=10, default="http")
|
||||||
method = models.CharField(max_length=10)
|
remote_addr = models.GenericIPAddressField(blank=True, null=True)
|
||||||
|
method = models.CharField(max_length=10, blank=True)
|
||||||
ua = models.CharField(max_length=200, blank=True)
|
ua = models.CharField(max_length=200, blank=True)
|
||||||
body = models.TextField(blank=True)
|
body = models.TextField(blank=True)
|
||||||
|
31
hc/api/tests/test_email_webhook.py
Normal file
31
hc/api/tests/test_email_webhook.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from hc.api.models import Check, Ping
|
||||||
|
|
||||||
|
|
||||||
|
class EmailTestCase(TestCase):
|
||||||
|
|
||||||
|
def test_it_works(self):
|
||||||
|
check = Check()
|
||||||
|
check.save()
|
||||||
|
|
||||||
|
payload = [{
|
||||||
|
"event": "inbound",
|
||||||
|
"msg": {
|
||||||
|
"raw_msg": "This is raw message",
|
||||||
|
"to": ["somewhere@example.com", "%s@example.com" % check.code]
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
|
||||||
|
data = {"mandrill_events": json.dumps(payload)}
|
||||||
|
r = self.client.post("/handle_email/", data=data)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
same_check = Check.objects.get(code=check.code)
|
||||||
|
assert same_check.status == "up"
|
||||||
|
|
||||||
|
pings = list(Ping.objects.all())
|
||||||
|
assert pings[0].scheme == "email"
|
||||||
|
assert pings[0].body == "This is raw message"
|
@ -15,6 +15,9 @@ class PingTestCase(TestCase):
|
|||||||
same_check = Check.objects.get(code=check.code)
|
same_check = Check.objects.get(code=check.code)
|
||||||
assert same_check.status == "up"
|
assert same_check.status == "up"
|
||||||
|
|
||||||
|
pings = list(Ping.objects.all())
|
||||||
|
assert pings[0].scheme == "http"
|
||||||
|
|
||||||
def test_post_works(self):
|
def test_post_works(self):
|
||||||
check = Check()
|
check = Check()
|
||||||
check.save()
|
check.save()
|
||||||
|
@ -6,4 +6,5 @@ urlpatterns = [
|
|||||||
url(r'^ping/([\w-]+)/$', views.ping, name="hc-ping-slash"),
|
url(r'^ping/([\w-]+)/$', views.ping, name="hc-ping-slash"),
|
||||||
url(r'^ping/([\w-]+)$', views.ping, name="hc-ping"),
|
url(r'^ping/([\w-]+)$', views.ping, name="hc-ping"),
|
||||||
url(r'^status/([\w-]+)/$', views.status, name="hc-status"),
|
url(r'^status/([\w-]+)/$', views.status, name="hc-status"),
|
||||||
|
url(r'^handle_email/$', views.handle_email, name="hc-handle-email"),
|
||||||
]
|
]
|
||||||
|
@ -26,6 +26,7 @@ def ping(request, code):
|
|||||||
ping = Ping(owner=check)
|
ping = Ping(owner=check)
|
||||||
headers = request.META
|
headers = request.META
|
||||||
ping.remote_addr = headers.get("HTTP_X_REAL_IP", headers["REMOTE_ADDR"])
|
ping.remote_addr = headers.get("HTTP_X_REAL_IP", headers["REMOTE_ADDR"])
|
||||||
|
ping.scheme = headers.get("HTTP_X_SCHEME", "http")
|
||||||
ping.method = headers["REQUEST_METHOD"]
|
ping.method = headers["REQUEST_METHOD"]
|
||||||
# If User-Agent is longer than 200 characters, truncate it:
|
# If User-Agent is longer than 200 characters, truncate it:
|
||||||
ping.ua = headers.get("HTTP_USER_AGENT", "")[:200]
|
ping.ua = headers.get("HTTP_USER_AGENT", "")[:200]
|
||||||
@ -37,6 +38,34 @@ def ping(request, code):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
@csrf_exempt
|
||||||
|
def handle_email(request):
|
||||||
|
events = json.loads(request.POST["mandrill_events"])
|
||||||
|
for event in events:
|
||||||
|
for to_address in event["msg"]["to"]:
|
||||||
|
code, domain = to_address.split("@")
|
||||||
|
try:
|
||||||
|
check = Check.objects.get(code=code)
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
except Check.DoesNotExist:
|
||||||
|
continue
|
||||||
|
|
||||||
|
check.last_ping = timezone.now()
|
||||||
|
if check.status == "new":
|
||||||
|
check.status = "up"
|
||||||
|
|
||||||
|
check.save()
|
||||||
|
|
||||||
|
ping = Ping(owner=check)
|
||||||
|
ping.scheme = "email"
|
||||||
|
ping.body = event["msg"]["raw_msg"]
|
||||||
|
ping.save()
|
||||||
|
|
||||||
|
response = HttpResponse("OK")
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
@uuid_or_400
|
@uuid_or_400
|
||||||
def status(request, code):
|
def status(request, code):
|
||||||
response = {
|
response = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user