SciPost Code Repository

Skip to content
Snippets Groups Projects
Commit 45de3919 authored by George Katsikas's avatar George Katsikas :goat:
Browse files

create mailgun webhook endpoint

send message to slack channel on failure
parent 7413733b
No related branches found
No related tags found
No related merge requests found
......@@ -632,3 +632,7 @@ GITLAB_KEY = get_secret("GITLAB_KEY")
# ORCID API
ORCID_CLIENT_ID = get_secret("ORCID_CLIENT_ID")
ORCID_CLIENT_SECRET = get_secret("ORCID_CLIENT_SECRET")
# SLACK API
SLACK_WEBHOOK_URL_MAILGUN_ALERTS = get_secret("SLACK_WEBHOOK_URL_MAILGUN_ALERTS")
......@@ -25,3 +25,5 @@ from .stored_message import (
StoredMessageUpdateReadAPIView,
StoredMessageUpdateTagAPIView,
)
from .integrations import mailgun_webhook
__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
__license__ = "AGPL v3"
import json
from django.conf import settings
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
def mailgun_webhook_is_signed(timestamp, token, signature):
"""
Verify the signature of a mailgun webhook.
"""
import hmac
encoded_token = hmac.new(
settings.MAILGUN_API_KEY.encode(),
(timestamp + token).encode(),
"sha256",
).hexdigest()
return encoded_token == signature
def send_mailgun_alert_slack_message(event_data: dict):
"""
Format mailgun event data and send an alert to Slack
"""
import requests
event = event_data.get("event", "unknown")
reason = event_data.get("reason", "unknown")
recipient = event_data.get("message", {}).get("headers", {}).get("to", "unknown")
sender = event_data.get("message", {}).get("headers", {}).get("from", "unknown")
subject = event_data.get("message", {}).get("headers", {}).get("subject", "unknown")
message = f"[{event.upper()}] {recipient} -> {sender}\nSubject: {subject}\nReason: {reason}"
response = requests.post(
settings.SLACK_WEBHOOK_URL_MAILGUN_ALERTS,
json={"text": message},
headers={"Content-type": "application/json"},
)
return response
@csrf_exempt
def mailgun_webhook(request):
"""
Endpoint to receive POST requests for mailgun webhook.
Executes custom integrations upon reception.
"""
if request.method != "POST":
return HttpResponse(status=405)
data = json.loads(request.body)
if "signature" not in data:
return HttpResponse(status=400)
# Verify signature, return 403 if invalid
if not mailgun_webhook_is_signed(**data.get("signature")):
return HttpResponse(status=403)
# Apply custom integrations here
event_data = data.get("event-data", {})
send_mailgun_alert_slack_message(event_data)
return HttpResponse(status=200)
......@@ -117,5 +117,6 @@ urlpatterns = [
path( # /mail/attachment_file/<uuid>
"attachment_file/<uuid:uuid>", views.attachment_file, name="attachment_file"
),
path("mailgun_webhook", apiviews.mailgun_webhook, name="mailgun_webhook"),
path("", views.mail, name="mail"), # /mail
]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment