first commit

This commit is contained in:
Andy Dixon
2025-11-10 15:35:40 +00:00
commit 80a89306a3
3 changed files with 875 additions and 0 deletions
+182
View File
@@ -0,0 +1,182 @@
# Webhook Email Forwarder
A simple, elegant PHP solution for debugging webhooks by forwarding them directly to your email.
## 🌟 Features
- **Email Delivery**: Receive complete webhook data directly in your inbox
- **Secure**: Built-in email validation and XSS protection
- **Instant**: Real-time webhook processing and forwarding
- **Simple**: No database or complex setup required
- **Universal**: Supports all HTTP methods and content types
## 📋 Overview
This webhook service captures incoming HTTP requests and forwards complete request details (headers, body, metadata) to your specified email address. Perfect for debugging webhooks, testing integrations, and monitoring API callbacks.
## 🚀 Quick Start
### 1. Encode Your Email
Replace `@` with `%40` in your email address:
- `test@example.com` becomes `test%40example.com`
### 2. Configure Webhook
Use the following URL format as your webhook endpoint:
```
https://your-domain.com/{encoded-email}
```
### 3. Check Your Inbox
Receive detailed webhook data instantly in your email with the subject:
```
‼️ Webhook Request Received - [timestamp]
```
## 💡 Usage Examples
### cURL - POST Request with JSON
```bash
curl -X POST https://your-domain.com/test%40example.com \
-H "Content-Type: application/json" \
-d '{"event": "user.created", "user_id": 12345}'
```
### cURL - GET Request with Parameters
```bash
curl https://your-domain.com/test%40example.com?event=test&id=123
```
### JavaScript - Fetch API
```javascript
fetch('https://your-domain.com/test%40example.com', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
event: 'order.completed',
order_id: 'ORD-789',
total: 99.99
})
});
```
### Python - Requests Library
```python
import requests
response = requests.post(
'https://your-domain.com/test%40example.com',
json={'event': 'payment.received', 'amount': 250.00},
headers={'X-Custom-Header': 'MyValue'}
)
print(response.text)
```
## 📦 Installation
1. Clone the repository:
```bash
git clone https://github.com/andydixon/webhook.git
```
2. Upload the files to your web server (ensure PHP is installed and configured)
3. Ensure the web server has permission to send emails (PHP `mail()` function)
4. Access the root URL to view the documentation page
## 🔧 Requirements
- PHP 7.0 or higher
- Web server (Apache, Nginx, etc.)
- PHP `mail()` function enabled
- Outbound SMTP/email capability
## 📧 What You Receive
Each webhook email contains:
- **Request Timestamp**: Exact date and time when the webhook was received
- **Request Information**: IP address, HTTP method, and Content-Type
- **Request Headers**: All HTTP headers sent with the request
- **Request Body**: Complete raw body content (JSON, XML, form data, etc.)
- **PHP Variables**: Parsed GET, POST, REQUEST, and FILES superglobals
## 🔒 Security Features
- **Email Validation**: Only valid email addresses are accepted
- **XSS Protection**: All output is sanitized using `htmlspecialchars()`
- **No Data Storage**: Webhook data is forwarded immediately and not stored
- **Error Logging**: Failed email attempts are logged for monitoring
> **Privacy Note**: Anyone with your webhook URL can send data to your email address. Only use this service for testing and debugging purposes. Do not use for sensitive production data without additional authentication.
## ✅ Supported Features
### HTTP Methods
- GET, POST, PUT, PATCH, DELETE
- Any custom HTTP method
### Content Types
- application/json
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
- text/xml
- Any custom content type
## 🎯 Common Use Cases
- **Debugging**: See exactly what data third-party services are sending
- **Integration Testing**: Test webhook integrations before implementing full handlers
- **Monitoring**: Monitor webhook activity and payload changes over time
- **Documentation**: Capture real examples for API documentation
- **Development**: Quickly test webhook flows during development
- **Troubleshooting**: Diagnose issues with webhook payloads and headers
## 💡 Tips & Best Practices
- **Email Filtering**: Create an email filter for the subject line "‼️ Webhook Request Received" to organize incoming webhooks
- **Plus Addressing**: Use email plus addressing (e.g., `yourname+github%40gmail.com`) to track which services are sending webhooks
- **Timestamp in Emails**: Check the "Date Received" field to verify webhook timing and debug delivery delays
- **Parse the Body**: The raw body section contains the exact payload - perfect for copying into your code for testing
## 📝 Error Handling
### Invalid Email Address
If the email address in the URL is invalid or missing:
```
HTTP 400 Bad Request
Invalid email address provided in URL path.
```
## 📄 License
This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) file for details.
## 👤 Author
**Andy Dixon**
- Website: [andydixon.com](https://andydixon.com)
- GitHub: [@andydixon](https://github.com/andydixon)
## 🤝 Contributing
Contributions, issues, and feature requests are welcome! Feel free to check the [issues page](https://github.com/andydixon/webhook/issues).
## ⭐ Show Your Support
Give a ⭐️ if this project helped you!
## 📜 Version History
- **1.0.0** - Initial release
- Basic webhook forwarding functionality
- HTML email formatting
- Email validation and XSS protection
- Documentation page
---
Built with PHP and ADHD medication 💊
+491
View File
@@ -0,0 +1,491 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webhook Email Forwarder - Documentation</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
<style>
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 40px 0;
}
.doc-container {
background: white;
border-radius: 15px;
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
padding: 40px;
margin-bottom: 40px;
}
.hero {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 60px 40px;
border-radius: 15px;
margin-bottom: 40px;
text-align: center;
}
.code-block {
background: #f8f9fa;
border-left: 4px solid #667eea;
padding: 15px;
border-radius: 5px;
font-family: 'Courier New', monospace;
overflow-x: auto;
}
.feature-card {
border: none;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
transition: transform 0.2s;
height: 100%;
}
.feature-card:hover {
transform: translateY(-5px);
}
.badge-custom {
font-size: 0.85rem;
padding: 0.5em 0.8em;
}
h2 {
color: #667eea;
margin-top: 30px;
margin-bottom: 20px;
}
h3 {
color: #764ba2;
margin-top: 25px;
margin-bottom: 15px;
}
.alert-info {
border-left: 4px solid #0dcaf0;
}
.alert-warning {
border-left: 4px solid #ffc107;
}
.alert-success {
border-left: 4px solid #198754;
}
</style>
</head>
<body>
<div class="container">
<!-- Hero Section -->
<div class="hero">
<h1 class="display-4"><i class="bi bi-webhook"></i> Webhook Email Forwarder</h1>
<p class="lead">A simple, elegant solution for debugging webhooks by forwarding them directly to your email</p>
<p class="mb-0">Version 1.0 | Made with ❤️ by Andy Dixon</p>
</div>
<!-- Overview Section -->
<div class="doc-container">
<h2><i class="bi bi-info-circle"></i> Overview</h2>
<p class="lead">This webhook service captures incoming HTTP requests and forwards complete request details (headers, body, metadata) to your specified email address.</p>
<div class="row mt-4">
<div class="col-md-4 mb-3">
<div class="card feature-card">
<div class="card-body text-center">
<i class="bi bi-envelope-check text-primary" style="font-size: 3rem;"></i>
<h5 class="card-title mt-3">Email Delivery</h5>
<p class="card-text">Receive webhook data directly in your inbox</p>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card feature-card">
<div class="card-body text-center">
<i class="bi bi-shield-check text-success" style="font-size: 3rem;"></i>
<h5 class="card-title mt-3">Secure</h5>
<p class="card-text">Email validation and XSS protection built-in</p>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card feature-card">
<div class="card-body text-center">
<i class="bi bi-lightning-charge text-warning" style="font-size: 3rem;"></i>
<h5 class="card-title mt-3">Instant</h5>
<p class="card-text">Real-time webhook processing and forwarding</p>
</div>
</div>
</div>
</div>
</div>
<!-- How It Works Section -->
<div class="doc-container">
<h2><i class="bi bi-gear"></i> How It Works</h2>
<ol class="lead">
<li>You configure a third-party service to send webhooks to this URL with your email encoded in the path</li>
<li>When a webhook request arrives, the service captures all request data</li>
<li>The complete request details are formatted into a readable HTML email</li>
<li>The email is sent to your specified address</li>
<li>A confirmation response is returned to the webhook sender</li>
</ol>
<div class="alert alert-info mt-4">
<i class="bi bi-lightbulb"></i> <strong>Perfect for:</strong> Debugging webhooks, testing integrations, monitoring API callbacks, and understanding third-party service payloads.
</div>
</div>
<!-- Usage Section -->
<div class="doc-container">
<h2><i class="bi bi-code-square"></i> Usage</h2>
<h3>Basic URL Format</h3>
<p>The URL format is simple - just append your URL-encoded email address to the domain:</p>
<div class="code-block mb-4">
https://<?php echo $_SERVER['HTTP_HOST']; ?>/<strong>{email-address}</strong>
</div>
<h3>URL Encoding Your Email</h3>
<p>The <code>@</code> symbol must be URL-encoded as <code>%40</code>:</p>
<div class="row mt-3">
<div class="col-md-6">
<div class="card">
<div class="card-header bg-light">
<strong>Original Email</strong>
</div>
<div class="card-body">
<code>john@example.com</code>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header bg-light">
<strong>Webhook URL</strong>
</div>
<div class="card-body">
<code><?php echo $_SERVER['HTTP_HOST']; ?>/john%40example.com</code>
</div>
</div>
</div>
</div>
<h3 class="mt-4">Example Requests</h3>
<h4>cURL - POST Request with JSON</h4>
<div class="code-block">
curl -X POST https://<?php echo $_SERVER['HTTP_HOST']; ?>/test%40example.com \
-H "Content-Type: application/json" \
-d '{"event": "user.created", "user_id": 12345}'
</div>
<h4 class="mt-3">cURL - GET Request with Parameters</h4>
<div class="code-block">
curl https://<?php echo $_SERVER['HTTP_HOST']; ?>/test%40example.com?event=test&id=123
</div>
<h4 class="mt-3">JavaScript - Fetch API</h4>
<div class="code-block">
fetch('https://<?php echo $_SERVER['HTTP_HOST']; ?>/test%40example.com', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
event: 'order.completed',
order_id: 'ORD-789',
total: 99.99
})
});
</div>
<h4 class="mt-3">Python - Requests Library</h4>
<div class="code-block">
import requests
response = requests.post(
'https://<?php echo $_SERVER['HTTP_HOST']; ?>/test%40example.com',
json={'event': 'payment.received', 'amount': 250.00},
headers={'X-Custom-Header': 'MyValue'}
)
print(response.text)
</div>
<div class="alert alert-warning mt-4">
<i class="bi bi-exclamation-triangle"></i> <strong>Important:</strong> Make sure to URL-encode your email address. Most programming languages and tools have built-in functions for this (e.g., <code>encodeURIComponent()</code> in JavaScript, <code>urllib.parse.quote()</code> in Python).
</div>
</div>
<!-- Response Section -->
<div class="doc-container">
<h2><i class="bi bi-arrow-return-left"></i> What to Expect</h2>
<h3>Immediate HTTP Response</h3>
<p>When your webhook is successfully received, you'll get an immediate response:</p>
<div class="card">
<div class="card-header bg-success text-white">
<strong>HTTP 200 OK</strong>
</div>
<div class="card-body">
<div class="code-block">
Webhook received and forwarded to: test@example.com
Request data:
Array
(
[event] => test
[id] => 123
)
</div>
</div>
</div>
<h3 class="mt-4">Email Contents</h3>
<p>Within moments, you'll receive a styled HTML email containing:</p>
<div class="row mt-3">
<div class="col-md-6 mb-3">
<div class="card">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-clock"></i> Request Timestamp</h5>
<p class="card-text">Exact date and time when the webhook was received</p>
</div>
</div>
</div>
<div class="col-md-6 mb-3">
<div class="card">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-info-square"></i> Request Information</h5>
<p class="card-text">IP address, HTTP method (GET/POST/etc), and Content-Type</p>
</div>
</div>
</div>
<div class="col-md-6 mb-3">
<div class="card">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-list-ul"></i> Request Headers</h5>
<p class="card-text">All HTTP headers sent with the request</p>
</div>
</div>
</div>
<div class="col-md-6 mb-3">
<div class="card">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-file-earmark-text"></i> Request Body</h5>
<p class="card-text">Complete raw body content (JSON, XML, form data, etc.)</p>
</div>
</div>
</div>
<div class="col-md-12 mb-3">
<div class="card">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-code-slash"></i> PHP Variables</h5>
<p class="card-text">Parsed GET, POST, REQUEST, and FILES superglobals for easy access</p>
</div>
</div>
</div>
</div>
<div class="alert alert-success mt-4">
<i class="bi bi-check-circle"></i> <strong>Subject Line:</strong> Emails arrive with the subject <strong>"‼️ Webhook Request Received - [timestamp]"</strong> for easy filtering and identification.
</div>
</div>
<!-- Error Handling Section -->
<div class="doc-container">
<h2><i class="bi bi-exclamation-octagon"></i> Error Handling</h2>
<h3>Invalid Email Address</h3>
<p>If the email address in the URL is invalid or missing, you'll receive:</p>
<div class="card">
<div class="card-header bg-danger text-white">
<strong>HTTP 400 Bad Request</strong>
</div>
<div class="card-body">
<div class="code-block">
Invalid email address provided in URL path.
</div>
</div>
</div>
<div class="alert alert-info mt-4">
<i class="bi bi-shield-check"></i> <strong>Validation:</strong> The service validates email addresses using PHP's built-in <code>FILTER_VALIDATE_EMAIL</code> filter to ensure proper formatting.
</div>
</div>
<!-- Security Section -->
<div class="doc-container">
<h2><i class="bi bi-shield-lock"></i> Security Features</h2>
<ul class="lead">
<li><strong>Email Validation:</strong> Only valid email addresses are accepted</li>
<li><strong>XSS Protection:</strong> All output is sanitized using <code>htmlspecialchars()</code></li>
<li><strong>No Data Storage:</strong> Webhook data is forwarded immediately and not stored on the server</li>
<li><strong>Error Logging:</strong> Failed email attempts are logged for monitoring</li>
</ul>
<div class="alert alert-warning">
<i class="bi bi-exclamation-triangle"></i> <strong>Privacy Note:</strong> Anyone with your webhook URL can send data to your email address. Only use this service for testing and debugging purposes. Do not use for sensitive production data without additional authentication.
</div>
</div>
<!-- Supported Features Section -->
<div class="doc-container">
<h2><i class="bi bi-check2-square"></i> Supported Features</h2>
<div class="row">
<div class="col-md-6">
<h5><i class="bi bi-check-circle text-success"></i> HTTP Methods</h5>
<ul>
<li>GET</li>
<li>POST</li>
<li>PUT</li>
<li>PATCH</li>
<li>DELETE</li>
<li>Any custom method</li>
</ul>
</div>
<div class="col-md-6">
<h5><i class="bi bi-check-circle text-success"></i> Content Types</h5>
<ul>
<li>application/json</li>
<li>application/x-www-form-urlencoded</li>
<li>multipart/form-data</li>
<li>text/plain</li>
<li>text/xml</li>
<li>Any custom content type</li>
</ul>
</div>
</div>
</div>
<!-- Use Cases Section -->
<div class="doc-container">
<h2><i class="bi bi-star"></i> Common Use Cases</h2>
<div class="row">
<div class="col-md-4 mb-3">
<div class="card feature-card">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-bug"></i> Debugging</h5>
<p class="card-text">See exactly what data third-party services are sending to your webhooks</p>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card feature-card">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-plugin"></i> Integration Testing</h5>
<p class="card-text">Test webhook integrations before implementing full handlers</p>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card feature-card">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-eye"></i> Monitoring</h5>
<p class="card-text">Monitor webhook activity and payload changes over time</p>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card feature-card">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-book"></i> Documentation</h5>
<p class="card-text">Capture real examples for API documentation</p>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card feature-card">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-diagram-3"></i> Development</h5>
<p class="card-text">Quickly test webhook flows during development</p>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card feature-card">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-search"></i> Troubleshooting</h5>
<p class="card-text">Diagnose issues with webhook payloads and headers</p>
</div>
</div>
</div>
</div>
</div>
<!-- Tips Section -->
<div class="doc-container">
<h2><i class="bi bi-lightbulb"></i> Tips & Best Practices</h2>
<div class="alert alert-info">
<h5><i class="bi bi-envelope-at"></i> Email Filtering</h5>
<p class="mb-0">Create an email filter for the subject line "‼️ Webhook Request Received" to organize incoming webhooks in your inbox.</p>
</div>
<div class="alert alert-info">
<h5><i class="bi bi-plus-slash-minus"></i> Use Plus Addressing</h5>
<p class="mb-0">Use email plus addressing (e.g., <code>yourname+github%40gmail.com</code>) to track which services are sending webhooks.</p>
</div>
<div class="alert alert-info">
<h5><i class="bi bi-clock-history"></i> Timestamp in Emails</h5>
<p class="mb-0">Check the "Date Received" field in emails to verify webhook timing and debug delivery delays.</p>
</div>
<div class="alert alert-info">
<h5><i class="bi bi-code"></i> Parse the Body</h5>
<p class="mb-0">The raw body section contains the exact payload - perfect for copying into your code for testing.</p>
</div>
</div>
<!-- Quick Start Section -->
<div class="doc-container">
<h2><i class="bi bi-rocket-takeoff"></i> Quick Start</h2>
<p class="lead">Get started in 3 simple steps:</p>
<div class="row">
<div class="col-md-4 mb-3">
<div class="card text-center feature-card border-primary">
<div class="card-body">
<div class="display-4 text-primary">1</div>
<h5 class="card-title mt-3">Encode Your Email</h5>
<p class="card-text">Replace <code>@</code> with <code>%40</code> in your email address</p>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card text-center feature-card border-success">
<div class="card-body">
<div class="display-4 text-success">2</div>
<h5 class="card-title mt-3">Configure Webhook</h5>
<p class="card-text">Use <code><?php echo $_SERVER['HTTP_HOST']; ?>/{your-email}</code> as the webhook URL</p>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card text-center feature-card border-warning">
<div class="card-body">
<div class="display-4 text-warning">3</div>
<h5 class="card-title mt-3">Check Your Inbox</h5>
<p class="card-text">Receive detailed webhook data instantly in your email</p>
</div>
</div>
</div>
</div>
<div class="text-center mt-4">
<h5>Try it now!</h5>
<div class="code-block text-start d-inline-block">
curl -X POST https://<?php echo $_SERVER['HTTP_HOST']; ?>/YOUR-EMAIL-HERE \
-d '{"test": "Hello World!"}'
</div>
</div>
</div>
<!-- Footer -->
<div class="text-center text-white mt-5">
<p class="mb-1"><i class="bi bi-code-slash"></i> Built with PHP and ADHD medication</p>
<p><small>© 2025-2026 Andy Dixon | <a href="https://<?php echo $_SERVER['HTTP_HOST']; ?>/" class="text-white"><?php echo $_SERVER['HTTP_HOST']; ?></a></small></p>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
Executable
+202
View File
@@ -0,0 +1,202 @@
<?php
/**
* Webhook Email Forwarder
*
* This script captures incoming webhook requests and forwards the complete request details
* (headers, body, metadata) to an email address specified in the URL path.
*
* Usage: <?php echo $_SERVER['HTTP_HOST']; ?>/email%40domain.com
*
* @author Dixon
* @version 1.0
*/
// Prevent any output buffering issues
if (ob_get_level()) {
ob_end_clean();
}
// Retrieve the complete request URI from the server superglobal
$requestUri = $_SERVER['REQUEST_URI'] ?? '';
// Parse the URL to extract only the path component, excluding any query strings
// This ensures that any GET parameters don't interfere with email extraction
$path = parse_url($requestUri, PHP_URL_PATH);
// Remove leading and trailing forward slashes from the path
// Example: '/email%40domain.com/' becomes 'email%40domain.com'
$emailEncoded = trim($path, '/');
// Decode the URL-encoded email address (e.g., %40 becomes @)
// Example: 'email%40domain.com' becomes 'email@domain.com'
$email = urldecode($emailEncoded);
if(empty($email)) {
include'docs.htm';
die();
}
// Validate the extracted email address using PHP's built-in filter
// This ensures the email is in a valid format before proceeding
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
// Set HTTP response code to 400 Bad Request
http_response_code(400);
// Return error message to the client
echo 'Invalid email address provided in URL path.';
// Terminate script execution
exit;
}
// Capture the current date and time when the webhook request was received
// Format: YYYY-MM-DD HH:MM:SS (24-hour format)
$dateReceived = date('Y-m-d H:i:s');
// Retrieve the IP address of the client making the request
// Note: This may be a proxy IP if behind a load balancer or CDN
$ipAddress = $_SERVER['REMOTE_ADDR'] ?? 'Unknown';
// Capture the HTTP method used for this request (GET, POST, PUT, DELETE, etc.)
$requestMethod = $_SERVER['REQUEST_METHOD'] ?? 'Unknown';
// Retrieve the Content-Type header sent by the client
// Use null coalescing operator to provide a default if not set
$contentType = $_SERVER['CONTENT_TYPE'] ?? 'N/A';
// Retrieve all HTTP headers sent with the request
// getallheaders() returns an associative array of all headers
$headersArray = getallheaders();
// Initialize an empty string to store formatted headers
$headersText = '';
// Iterate through each header and format it as "Key: Value"
foreach ($headersArray as $key => $value) {
// Concatenate each header on a new line
$headersText .= htmlspecialchars($key, ENT_QUOTES, 'UTF-8') . ': ' .
htmlspecialchars($value, ENT_QUOTES, 'UTF-8') . "\n";
}
// Read the raw request body from the input stream
// php://input allows access to the raw POST data regardless of Content-Type
$rawBody = file_get_contents('php://input');
// Sanitise the raw body for HTML output to prevent XSS attacks
$rawBodySafe = htmlspecialchars($rawBody, ENT_QUOTES, 'UTF-8');
// Compile all PHP superglobal variables into an array for debugging purposes
// This provides visibility of all data received with the request
$variables = [
'_GET' => $_GET,
'_POST' => $_POST,
'_REQUEST' => $_REQUEST,
'_FILES' => $_FILES,
];
// Convert the variables array to a human-readable string format
// The second parameter (true) makes print_r return the output instead of printing it
$variablesText = print_r($variables, true);
// Sanitise the variables text for HTML output
$variablesTextSafe = htmlspecialchars($variablesText, ENT_QUOTES, 'UTF-8');
// Sanitise individual metadata fields for HTML output
$dateReceivedSafe = htmlspecialchars($dateReceived, ENT_QUOTES, 'UTF-8');
$ipAddressSafe = htmlspecialchars($ipAddress, ENT_QUOTES, 'UTF-8');
$requestMethodSafe = htmlspecialchars($requestMethod, ENT_QUOTES, 'UTF-8');
$contentTypeSafe = htmlspecialchars($contentType, ENT_QUOTES, 'UTF-8');
// Construct the HTML email body using a heredoc string for better readability
// This creates a styled HTML email with all webhook details
$html = <<<HTML
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webhook Request Received</title>
<style>
/* Main body styling with dark blue background */
body {
background-color: #004080;
color: white;
font-family: Arial, sans-serif;
padding: 20px;
margin: 0;
}
/* Section heading styling */
h2 {
color: white;
border-bottom: 1px solid #ccc;
padding-bottom: 5px;
margin-top: 20px;
}
/* Preformatted text block styling for code/data display */
pre {
background-color: #002f5f;
padding: 15px;
border-radius: 5px;
color: #f0f0f0;
font-family: monospace;
white-space: pre-wrap;
word-wrap: break-word;
overflow-x: auto;
}
</style>
</head>
<body>
<!-- Display the timestamp of when the webhook was received -->
<h2>Request Received</h2>
<pre>Date: $dateReceivedSafe</pre>
<!-- Display metadata about the request origin and method -->
<h2>Request Information</h2>
<pre>IP Address: $ipAddressSafe
Request Method: $requestMethodSafe
Content-Type: $contentTypeSafe</pre>
<!-- Display all HTTP headers sent with the request -->
<h2>Request Headers</h2>
<pre>$headersText</pre>
<!-- Display the raw request body exactly as received -->
<h2>Request Body</h2>
<pre>$rawBodySafe</pre>
<!-- Display all PHP superglobal variables for complete request context -->
<h2>PHP Variables</h2>
<pre>$variablesTextSafe</pre>
</body>
</html>
HTML;
// Construct the email subject line with an attention-grabbing emoji and timestamp
$subject = "‼️ Webhook Request Received - $dateReceived";
// Build email headers to ensure proper HTML rendering and sender information
// MIME-Version declares email format capabilities
$emailHeaders = "MIME-Version: 1.0\r\n";
// Content-type specifies HTML email with UTF-8 character encoding
$emailHeaders .= "Content-type: text/html; charset=UTF-8\r\n";
// From header sets the sender address to a no-reply address on the same domain
$emailHeaders .= "From: no-reply@" . ($_SERVER['SERVER_NAME'] ?? 'localhost') . "\r\n";
// Send the email using PHP's built-in mail function
// Parameters: recipient, subject, message body, headers
$mailSent = mail($email, $subject, $html, $emailHeaders);
// Check if the email was sent successfully
if (!$mailSent) {
// Log error or handle failure (note: mail() return value is unreliable on some systems)
error_log("Failed to send webhook email to: $email");
}
// Set the Content-Type header for the HTTP response to plain text
header('Content-Type: text/plain; charset=UTF-8');
// Return a simple acknowledgement to the webhook sender
// This confirms the webhook was received and processed
echo "Webhook received and forwarded to: $email\n\n";
// Include a sanitised copy of the REQUEST data in the response for debugging
echo "Request data:\n";
print_r($_REQUEST);