Implemented a production-ready TypeScript/Express.js service to receive and log MailGun webhook events (delivered, failed, opened, clicked, etc.). Key features: - Webhook endpoint (POST /webhook) with comprehensive event logging - Full TypeScript type definitions for all MailGun event types - Prometheus metrics integration for monitoring - Health check endpoint (GET /ping) - Comprehensive Jest test suite with 87.76% coverage - Docker containerization with build scripts Removed template/example code: - All SQL/MSSQL dependencies and related code - Example auth router and middleware - PRTG metrics support (simplified to Prometheus only) - Unused middleware (CORS, IP whitelist, request parsing/validation) - Template documentation (kept only MailGun webhook API spec) The service is clean, minimal, and focused solely on receiving and logging MailGun webhook events to the console. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
5.0 KiB
5.0 KiB
MailGun Webhook API Specification
Overview
This document specifies the API for receiving webhook events from MailGun. The service logs all received event data to the console for monitoring and debugging purposes.
API Endpoints
POST /webhook
Receives webhook events from MailGun when email events occur.
Request Format
- Method: POST
- Content-Type:
application/x-www-form-urlencodedormultipart/form-data - Headers:
- No custom headers required for initial implementation
Request Parameters
MailGun sends various parameters depending on the event type. Common parameters include:
Event Identification:
event(string) - Type of event (delivered, failed, opened, clicked, bounced, complained, unsubscribed)timestamp(number) - Unix timestamp when the event occurredtoken(string) - Randomly generated string for message signature verificationsignature(string) - String with hexadecimal digits for signature verification
Message Information:
message-id(string) - MailGun message IDrecipient(string) - Email address of the recipientdomain(string) - Domain from which the email was sentMessage-Id(string) - SMTP Message-ID header
Event-Specific Parameters:
For delivered events:
message-headers(string) - JSON string of message headers
For failed events:
severity(string) - Severity level (temporary/permanent)reason(string) - Reason for failurenotification(string) - Detailed notification message
For opened events:
city(string) - City where email was openedcountry(string) - Country codedevice-type(string) - Device type (desktop/mobile/tablet)client-os(string) - Operating systemclient-name(string) - Email client nameip(string) - IP address
For clicked events:
url(string) - URL that was clickedcity,country,device-type,client-os,client-name,ip- Same as opened events
For bounced events:
code(string) - SMTP error codeerror(string) - Detailed error messagenotification(string) - Bounce notification
For complained events:
- No additional parameters
For unsubscribed events:
- No additional parameters
Success Response
- HTTP Status: 200 OK
- Content-Type:
application/json - Response Body:
{ "status": "received", "message": "Webhook event logged successfully" }
Error Responses
Invalid Request (400 Bad Request):
- Content-Type:
application/json - Response Body:
{ "error": "Invalid request format" }
Server Error (500 Internal Server Error):
- Content-Type:
application/json - Response Body:
{ "error": "Internal server error" }
Execution Flow
- Receive webhook POST request from MailGun
- Parse request body (form-urlencoded or multipart data)
- Extract event data from request parameters
- Log event data to console with structured formatting:
- Event type
- Timestamp (both Unix and human-readable)
- Recipient
- All additional event-specific parameters
- Return success response to MailGun
Edge Cases
Missing Event Type
- Detection: Check if
eventparameter is present - Handling: Log warning and return 400 Bad Request
Malformed Timestamp
- Detection: Check if
timestampcan be parsed as number - Handling: Log with current timestamp instead, continue processing
Large Payload
- Detection: Monitor request body size
- Handling: Log truncated data if exceeds reasonable size
Duplicate Events
- Detection: MailGun may send duplicate webhooks
- Handling: Log all events (no deduplication in initial implementation)
Security Considerations
Future Enhancements
For production deployment, consider:
- Signature Verification: Verify webhook authenticity using
timestamp,token, andsignature - IP Whitelisting: Restrict to MailGun's IP ranges
- Rate Limiting: Prevent abuse
Database Integration
- Current Implementation: No database operations required
- Future Enhancement: Store events in database for analysis
Third-Party API Calls
- Current Implementation: No third-party API calls
- Future Enhancement: Could integrate with notification services
Logging Format
Console output format:
========================================
MailGun Webhook Event Received
========================================
Event Type: delivered
Timestamp: 1234567890 (2024-01-01 12:00:00 UTC)
Recipient: user@example.com
Domain: mail.example.com
Message ID: <20240101120000.1.ABC123@mail.example.com>
----------------------------------------
Additional Parameters:
{
"message-headers": "[...]",
"token": "...",
"signature": "..."
}
========================================
Implementation Notes
- Use Express body-parser middleware for form data parsing
- All logging should use structured logger (debug package)
- Maintain type safety with TypeScript interfaces for event data
- Follow template's error handling patterns