A secure, containerized contact form API similar to Formspree that sends beautiful emails via SMTP.
2.3K

Haven't you always wanted a contact form on your website, but to keep your email private and not spend a ton of money on a paid service? FormFling is a self-hosted contact form service that forwards submissions to your email via SMTP. Think Formspree, but running on your own server.
git clone https://github.com/FormFling/FormFling.git
cd FormFling
cp docker-compose.yml docker-compose.local.yml
# Edit docker-compose.local.yml with your settings
docker-compose -f docker-compose.local.yml up -d
docker run -d \
--name formfling \
-p 8080:8080 \
-e [email protected] \
-e SMTP_PASSWORD=your-app-password \
-e [email protected] \
-e [email protected] \
-e ALLOWED_ORIGINS=https://www.yourdomain.com \
dungfu/form-fling:latest
Configure via environment variables:
Required:
SMTP_USERNAME - SMTP UsernameSMTP_PASSWORD - SMTP Password (Gmail setup guide)FROM_EMAIL - Sender emailTO_EMAIL - Where to send form submissionsOptional:
PORT - Server port (default: 8080)SMTP_HOST - SMTP server (default: smtp.gmail.com)SMTP_PORT - SMTP port (default: 587)ALLOWED_ORIGINS - Comma-separated allowed domains (default: all)FORM_TITLE - Form name in emails (default: Contact Me)RECAPTCHA_SITE_KEY - reCAPTCHA v3 site keyRECAPTCHA_SECRET_KEY - reCAPTCHA v3 secret keyRECAPTCHA_MIN_SCORE - Minimum score threshold (default: 0.5)RECAPTCHA_ACTION - Expected action name (default: submit)ENABLE_TEST_FORM - Enable /test_form endpoint (default: false)See .env.example for all options.
Add this form to your website:
<form action="https://your-formfling-domain.com/submit" method="POST">
<input type="text" name="name" required>
<input type="email" name="email" required>
<textarea name="message" required></textarea>
<button type="submit">Send</button>
</form>
<script src="https://www.google.com/recaptcha/api.js"></script>
<form id="contact-form">
<input type="text" name="name" required>
<input type="email" name="email" required>
<textarea name="message" required></textarea>
<button type="submit"
class="g-recaptcha"
data-sitekey="reCAPTCHA_site_key"
data-callback='onSubmit'
data-action='submit'>
Send
</button>
</form>
<script>
function onSubmit(token) {
document.getElementById("contact-form").submit();
}
</script>
fetch('https://your-formfling-domain.com/submit', {
method: 'POST',
body: new FormData(form)
})
.then(response => response.json())
.then(data => {
if (data.status === 'message sent') {
// Success
}
});
document.getElementById('contact-form').addEventListener('submit', function(e) {
e.preventDefault();
grecaptcha.ready(() => {
grecaptcha.execute('YOUR_SITE_KEY', {action: 'submit'}).then(token => {
fetch('https://your-formfling-domain.com/submit', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
name: form.name.value,
email: form.email.value,
message: form.message.value,
'g-recaptcha-response': token
})
})
.then(response => response.json())
.then(data => {
if (data.status === 'message sent') {
// Success
} else {
// Handle error: data.error
}
});
});
});
});
POST /submit - Submit formGET /health - Health checkGET /status - Status pageGET /test_form - reCAPTCHA token generator (when ENABLE_TEST_FORM=true)Response format:
{"status": "message sent"}
{"status": "error", "error": "description"}
Set ENABLE_TEST_FORM=true and visit /test_form to generate reCAPTCHA tokens for testing:
# Set environment variables
export RECAPTCHA_SITE_KEY=your-site-key
export RECAPTCHA_SECRET_KEY=your-secret-key
export ENABLE_TEST_FORM=true
# Visit http://localhost:8080/test_form in browser
# Copy the generated curl command and run it:
curl -X POST http://localhost:8080/submit \
-H "Content-Type: application/json" \
-d '{
"name": "Test User",
"email": "[email protected]",
"message": "Test message",
"g-recaptcha-response": "generated-token-here"
}'
docker run -d \
-v /path/to/template.html:/templates/custom.html \
-e EMAIL_TEMPLATE=/templates/custom.html \
dungfu/form-fling:latest
Template variables:
{{.FormData.Name}} - Sender's name{{.FormData.Email}} - Sender's email{{.FormData.Subject}} - Email subject{{.FormData.Message}} - Email message{{.FormData.Phone}} - Sender's phone number{{.FormData.Website}} - Sender's website{{.SubmittedTime}} - Time the form was submitted (e.g., "03:04 PM"){{.SubmittedDate}} - Date the form was submitted (e.g., "02 January 2006"){{.Origin}} - Origin URL where the form was submitted fromdocker run -d \
-v /path/to/template.html:/templates/custom.html \
-e STATUS_TEMPLATE=/templates/custom.html \
dungfu/form-fling:latest
Template variables:
{{.Status}} - Status type (success or error){{.FormTitle}} - The form title{{.Message}} - Status message to display{{.RedirectURL}} - URL to redirect the user back to (if any)git clone https://github.com/fireph/FormFling.git
cd FormFling
go mod download
go run .
ALLOWED_ORIGINS to restrict accessMIT License - see LICENSE file.
Content type
Image
Digest
sha256:ac33d1c7f…
Size
7.7 MB
Last updated
about 1 year ago
docker pull dungfu/form-fling