Mail Service API hinzugefügt
parent
ece6b49254
commit
317669d24c
1 changed files with 380 additions and 0 deletions
380
Mail-Service-API.md
Normal file
380
Mail-Service-API.md
Normal file
|
|
@ -0,0 +1,380 @@
|
||||||
|
# Mail Service API
|
||||||
|
|
||||||
|
**Multi-Tenant Mail-Weiterleitung für Kontaktformulare**
|
||||||
|
|
||||||
|
## Endpoint
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /v1/mail/send
|
||||||
|
```
|
||||||
|
|
||||||
|
**Zweck:** Leitet Kontaktformular-Daten als E-Mail an konfigurierte Empfänger weiter. Jeder API-Key erhält seine eigene Mail-Konfiguration.
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
```http
|
||||||
|
X-API-Key: your-tenant-api-key
|
||||||
|
```
|
||||||
|
|
||||||
|
**Warum Tenant-basiert:** Jeder API-Key definiert:
|
||||||
|
- Eigenen Mail-Empfänger
|
||||||
|
- Eigene SMTP-Konfiguration
|
||||||
|
- Eigene Subject-Präfixe
|
||||||
|
- Isolierte Mail-Logs
|
||||||
|
|
||||||
|
Dadurch kann ein Furt-Gateway Kontaktformulare für mehrere Websites gleichzeitig verwalten.
|
||||||
|
|
||||||
|
## Request Format
|
||||||
|
|
||||||
|
### Required Fields
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "string (required, non-empty)",
|
||||||
|
"email": "string (required, valid email)",
|
||||||
|
"message": "string (required, non-empty, max 5000 chars)"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Optional Fields
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"subject": "string (optional, max 200 chars)"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Complete Example
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "John Doe",
|
||||||
|
"email": "john@example.com",
|
||||||
|
"subject": "Partnership Inquiry",
|
||||||
|
"message": "Hello, I'm interested in discussing a potential partnership. Could we schedule a call this week?"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation Rules
|
||||||
|
|
||||||
|
**Warum strenge Validation:** Verhindert Spam und gewährleistet brauchbare Mails.
|
||||||
|
|
||||||
|
### Name Validation
|
||||||
|
- **Required:** Feld muss vorhanden sein
|
||||||
|
- **Non-empty:** Keine leeren Strings oder nur Whitespace
|
||||||
|
- **Type:** Muss String sein
|
||||||
|
|
||||||
|
```json
|
||||||
|
// Invalid examples
|
||||||
|
{"name": ""} // Empty string
|
||||||
|
{"name": " "} // Only whitespace
|
||||||
|
{"name": null} // Null value
|
||||||
|
{"name": 123} // Wrong type
|
||||||
|
```
|
||||||
|
|
||||||
|
### Email Validation
|
||||||
|
- **Required:** Feld muss vorhanden sein
|
||||||
|
- **Format:** Basis-Regex-Validation `^[^@]+@[^@]+%.[^@]+$`
|
||||||
|
- **Type:** Muss String sein
|
||||||
|
|
||||||
|
```json
|
||||||
|
// Invalid examples
|
||||||
|
{"email": "notanemail"} // Missing @
|
||||||
|
{"email": "user@"} // Missing domain
|
||||||
|
{"email": "@domain.com"} // Missing user
|
||||||
|
{"email": "user@domain"} // Missing TLD
|
||||||
|
```
|
||||||
|
|
||||||
|
### Message Validation
|
||||||
|
- **Required:** Feld muss vorhanden sein
|
||||||
|
- **Non-empty:** Keine leeren Strings oder nur Whitespace
|
||||||
|
- **Length:** Maximum 5000 Zeichen
|
||||||
|
- **Type:** Muss String sein
|
||||||
|
|
||||||
|
### Subject Validation (Optional)
|
||||||
|
- **Optional:** Feld kann fehlen
|
||||||
|
- **Length:** Maximum 200 Zeichen wenn vorhanden
|
||||||
|
- **Type:** Muss String sein wenn vorhanden
|
||||||
|
- **Default:** "Contact Form Message" wenn nicht angegeben
|
||||||
|
|
||||||
|
## Response Format
|
||||||
|
|
||||||
|
### Success Response (HTTP 200)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"message": "Mail sent successfully",
|
||||||
|
"request_id": "1632150000-1234",
|
||||||
|
"tenant": {
|
||||||
|
"name": "your-website",
|
||||||
|
"recipient": "contact@your-website.com",
|
||||||
|
"smtp_server": "mail.your-provider.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Tenant-Info:** Zeigt welche Konfiguration verwendet wurde. Nützlich für Debugging bei Multi-Tenant-Setups.
|
||||||
|
|
||||||
|
### Error Responses
|
||||||
|
|
||||||
|
#### Validation Error (HTTP 400)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": false,
|
||||||
|
"error": "Name is required and cannot be empty",
|
||||||
|
"code": "VALIDATION_ERROR",
|
||||||
|
"request_id": "1632150000-1234"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Mögliche Validation-Errors:**
|
||||||
|
- `"Name is required and cannot be empty"`
|
||||||
|
- `"Valid email address is required"`
|
||||||
|
- `"Message is required and cannot be empty"`
|
||||||
|
- `"Subject must be a string with max 200 characters"`
|
||||||
|
- `"Message too long (max 5000 characters)"`
|
||||||
|
|
||||||
|
#### JSON Error (HTTP 400)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": false,
|
||||||
|
"error": "Invalid JSON",
|
||||||
|
"code": "INVALID_JSON",
|
||||||
|
"body": "the-invalid-json-string"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Missing Body Error (HTTP 400)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": false,
|
||||||
|
"error": "No request body",
|
||||||
|
"code": "MISSING_BODY"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Configuration Error (HTTP 500)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": false,
|
||||||
|
"error": "Mail configuration error: No recipient configured for this API key",
|
||||||
|
"code": "CONFIG_ERROR",
|
||||||
|
"request_id": "1632150000-1234"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Warum Config-Errors:** Wenn ein API-Key keine vollständige Mail-Konfiguration hat (fehlender Empfänger, SMTP-Server, etc.).
|
||||||
|
|
||||||
|
#### SMTP Error (HTTP 500)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": false,
|
||||||
|
"error": "Failed to send email: SMTP connection failed",
|
||||||
|
"code": "SMTP_ERROR",
|
||||||
|
"request_id": "1632150000-1234",
|
||||||
|
"tenant": "your-website"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Multi-Tenant Configuration
|
||||||
|
|
||||||
|
**Warum Multi-Tenant:** Ermöglicht einem Furt-Gateway, Mails für verschiedene Websites zu verwalten.
|
||||||
|
|
||||||
|
### Tenant-spezifische Features
|
||||||
|
|
||||||
|
#### Subject Prefix
|
||||||
|
Jeder Tenant kann ein Subject-Präfix konfigurieren:
|
||||||
|
|
||||||
|
```
|
||||||
|
Tenant-Config: subject_prefix = "[Website-A] "
|
||||||
|
User-Subject: "Partnership Inquiry"
|
||||||
|
Final-Subject: "[Website-A] Partnership Inquiry"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Mail Content
|
||||||
|
Die gesendete Mail enthält alle Kontext-Informationen:
|
||||||
|
|
||||||
|
```
|
||||||
|
Website: your-website (your-api-key)
|
||||||
|
From: John Doe <john@example.com>
|
||||||
|
Subject: Partnership Inquiry
|
||||||
|
|
||||||
|
Hello, I'm interested in discussing a potential partnership.
|
||||||
|
Could we schedule a call this week?
|
||||||
|
|
||||||
|
---
|
||||||
|
Sent via Furt Gateway
|
||||||
|
API Key: your-website
|
||||||
|
Request ID: 1632150000-1234
|
||||||
|
```
|
||||||
|
|
||||||
|
**Warum detaillierte Mails:** Empfänger sehen sofort von welcher Website die Mail kommt und haben alle nötigen Infos für die Antwort.
|
||||||
|
|
||||||
|
## Rate Limiting
|
||||||
|
|
||||||
|
Mail-Requests unterliegen Rate-Limiting pro API-Key:
|
||||||
|
|
||||||
|
- **Standard:** 60 Requests pro Minute
|
||||||
|
- **Konfigurierbar:** Per Tenant anpassbar
|
||||||
|
- **Headers:** Rate-Limit-Status in Response-Headers
|
||||||
|
|
||||||
|
```http
|
||||||
|
X-RateLimit-Limit: 60
|
||||||
|
X-RateLimit-Remaining: 45
|
||||||
|
X-RateLimit-Reset: 1632150000
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rate-Limit-Exceeded Response (HTTP 429):**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": false,
|
||||||
|
"error": "Rate limit exceeded",
|
||||||
|
"code": "RATE_LIMIT_EXCEEDED"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integration Examples
|
||||||
|
|
||||||
|
### HTML Form (Basic)
|
||||||
|
|
||||||
|
```html
|
||||||
|
<form id="contact-form">
|
||||||
|
<input type="text" name="name" required>
|
||||||
|
<input type="email" name="email" required>
|
||||||
|
<input type="text" name="subject">
|
||||||
|
<textarea name="message" required maxlength="5000"></textarea>
|
||||||
|
<button type="submit">Send Message</button>
|
||||||
|
</form>
|
||||||
|
```
|
||||||
|
|
||||||
|
### JavaScript Integration
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
document.getElementById('contact-form').addEventListener('submit', async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const formData = new FormData(e.target);
|
||||||
|
const data = Object.fromEntries(formData);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('/v1/mail/send', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-API-Key': 'your-api-key'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
alert('Message sent successfully!');
|
||||||
|
e.target.reset();
|
||||||
|
} else {
|
||||||
|
alert('Error: ' + result.error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
alert('Network error: ' + error.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hugo Shortcode Integration
|
||||||
|
|
||||||
|
```go
|
||||||
|
{{< furt-contact-form
|
||||||
|
api-endpoint="https://api.dragons-at-work.de/v1/mail/send"
|
||||||
|
api-key="your-api-key"
|
||||||
|
success-url="/contact/thanks/"
|
||||||
|
fields="name,email,subject,message"
|
||||||
|
>}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### curl Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Valid request
|
||||||
|
curl -X POST https://api.dragons-at-work.de/v1/mail/send \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "X-API-Key: your-api-key" \
|
||||||
|
-d '{
|
||||||
|
"name": "Test User",
|
||||||
|
"email": "test@example.com",
|
||||||
|
"subject": "Test Message",
|
||||||
|
"message": "This is a test message from the API."
|
||||||
|
}'
|
||||||
|
|
||||||
|
# Test validation error
|
||||||
|
curl -X POST https://api.dragons-at-work.de/v1/mail/send \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "X-API-Key: your-api-key" \
|
||||||
|
-d '{
|
||||||
|
"name": "",
|
||||||
|
"email": "invalid-email",
|
||||||
|
"message": ""
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
### Input Sanitization
|
||||||
|
- **HTML-Escaping:** User-Input wird in der Mail HTML-escaped
|
||||||
|
- **Length-Limits:** Verhindert Memory-Exhaustion-Attacks
|
||||||
|
- **Email-Validation:** Verhindert Mail-Header-Injection
|
||||||
|
|
||||||
|
### SMTP Security
|
||||||
|
- **Per-Tenant-SMTP:** Jeder Tenant nutzt eigene SMTP-Credentials
|
||||||
|
- **Connection-Pooling:** Wiederverwendung von SMTP-Connections
|
||||||
|
- **Error-Isolation:** SMTP-Failures eines Tenants beeinflussen andere nicht
|
||||||
|
|
||||||
|
### Rate Limiting
|
||||||
|
- **Spam-Protection:** Verhindert Missbrauch als Mail-Relay
|
||||||
|
- **Per-Key-Limits:** Isolierte Limits pro Tenant
|
||||||
|
- **Configurable:** Limits können per Tenant angepasst werden
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
**"Mail configuration error":**
|
||||||
|
- API-Key hat keine vollständige Mail-Konfiguration
|
||||||
|
- Prüfe `/etc/furt/furt.conf` oder `/usr/local/etc/furt/furt.conf`
|
||||||
|
- Tenant muss `to_address`, `from_address`, SMTP-Details haben
|
||||||
|
|
||||||
|
**"SMTP connection failed":**
|
||||||
|
- SMTP-Server nicht erreichbar
|
||||||
|
- Falsche SMTP-Credentials
|
||||||
|
- Firewall blockiert SMTP-Port (587/465)
|
||||||
|
|
||||||
|
**"Validation errors":**
|
||||||
|
- Prüfe Request-Format gegen Validation-Rules
|
||||||
|
- Stelle sicher dass alle Required-Fields vorhanden sind
|
||||||
|
- Prüfe Field-Types (String vs. Number, etc.)
|
||||||
|
|
||||||
|
### Debug Mode
|
||||||
|
|
||||||
|
Für Debugging können detaillierte Logs aktiviert werden:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Server-Logs anzeigen
|
||||||
|
journalctl -fu furt # Linux
|
||||||
|
tail -f /var/log/daemon # OpenBSD
|
||||||
|
```
|
||||||
|
|
||||||
|
**Log-Format:**
|
||||||
|
```
|
||||||
|
Mail endpoint called - Method: POST, Path: /v1/mail/send
|
||||||
|
Authenticated as: your-website (your-api-key)
|
||||||
|
Sending mail for tenant: your-website
|
||||||
|
To: contact@your-website.com
|
||||||
|
From: noreply@your-website.com
|
||||||
|
SMTP: mail.your-provider.com:587
|
||||||
|
```
|
||||||
Loading…
Add table
Add a link
Reference in a new issue