Browse Source

Webhook for Mandrill inbound email notifications

pull/7/head
Pēteris Caune 9 years ago
parent
commit
b75ab00d18
6 changed files with 96 additions and 2 deletions
  1. +29
    -0
      hc/api/migrations/0009_auto_20150801_1250.py
  2. +3
    -2
      hc/api/models.py
  3. +31
    -0
      hc/api/tests/test_email_webhook.py
  4. +3
    -0
      hc/api/tests/test_ping.py
  5. +1
    -0
      hc/api/urls.py
  6. +29
    -0
      hc/api/views.py

+ 29
- 0
hc/api/migrations/0009_auto_20150801_1250.py View 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),
),
]

+ 3
- 2
hc/api/models.py View File

@ -63,7 +63,8 @@ class Check(models.Model):
class Ping(models.Model):
owner = models.ForeignKey(Check)
created = models.DateTimeField(auto_now_add=True)
remote_addr = models.GenericIPAddressField()
method = models.CharField(max_length=10)
scheme = models.CharField(max_length=10, default="http")
remote_addr = models.GenericIPAddressField(blank=True, null=True)
method = models.CharField(max_length=10, blank=True)
ua = models.CharField(max_length=200, blank=True)
body = models.TextField(blank=True)

+ 31
- 0
hc/api/tests/test_email_webhook.py View 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": ["[email protected]", "%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"

+ 3
- 0
hc/api/tests/test_ping.py View File

@ -15,6 +15,9 @@ class PingTestCase(TestCase):
same_check = Check.objects.get(code=check.code)
assert same_check.status == "up"
pings = list(Ping.objects.all())
assert pings[0].scheme == "http"
def test_post_works(self):
check = Check()
check.save()


+ 1
- 0
hc/api/urls.py View File

@ -6,4 +6,5 @@ urlpatterns = [
url(r'^ping/([\w-]+)/$', views.ping, name="hc-ping-slash"),
url(r'^ping/([\w-]+)$', views.ping, name="hc-ping"),
url(r'^status/([\w-]+)/$', views.status, name="hc-status"),
url(r'^handle_email/$', views.handle_email, name="hc-handle-email"),
]

+ 29
- 0
hc/api/views.py View File

@ -26,6 +26,7 @@ def ping(request, code):
ping = Ping(owner=check)
headers = request.META
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"]
# If User-Agent is longer than 200 characters, truncate it:
ping.ua = headers.get("HTTP_USER_AGENT", "")[:200]
@ -37,6 +38,34 @@ def ping(request, code):
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
def status(request, code):
response = {


Loading…
Cancel
Save