No description
  • Go 99.3%
  • Dockerfile 0.7%
Find a file
Joshua Stübner 84047f24c5 feat: add webhook delivery
Tenants can forward submissions as JSON to a webhook instead of or in
addition to SMTP. The webhook supports a bearer token, custom headers and
a timeout. All configured channels are attempted; any failure redirects
to the error page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 08:36:35 +02:00
testdata feat: add webhook delivery 2026-10-18 08:36:35 +02:00
.dockerignore initial version 2026-06-05 11:00:15 +02:00
.gitignore initial version 2026-06-05 11:00:15 +02:00
altcha.go feat: setup CORS 2026-06-09 11:48:20 +02:00
altcha_test.go feat: setup CORS 2026-06-09 11:48:20 +02:00
config.docker.yaml initial version 2026-06-05 11:00:15 +02:00
config.go feat: add webhook delivery 2026-10-18 08:36:35 +02:00
config.yaml.example feat: add webhook delivery 2026-10-18 08:36:35 +02:00
config_test.go feat: add webhook delivery 2026-10-18 08:36:35 +02:00
cors.go feat: setup CORS 2026-06-09 11:48:20 +02:00
cors_test.go feat: setup CORS 2026-06-09 11:48:20 +02:00
docker-compose.example.yml chore: fix initial build 2026-06-09 09:24:04 +02:00
docker-compose.yml chore: fix initial build 2026-06-09 09:24:04 +02:00
Dockerfile chore: fix initial build 2026-06-09 09:24:04 +02:00
form.go initial version 2026-06-05 11:00:15 +02:00
form_test.go initial version 2026-06-05 11:00:15 +02:00
go.mod feat: add altcha 2026-06-09 10:17:40 +02:00
go.sum feat: add altcha 2026-06-09 10:17:40 +02:00
handler.go feat: add webhook delivery 2026-10-18 08:36:35 +02:00
handler_test.go feat: add webhook delivery 2026-10-18 08:36:35 +02:00
helpers_test.go initial version 2026-06-05 11:00:15 +02:00
LICENSE initial version 2026-06-05 11:00:15 +02:00
mailer.go initial version 2026-06-05 11:00:15 +02:00
mailer_test.go initial version 2026-06-05 11:00:15 +02:00
main.go initial version 2026-06-05 11:00:15 +02:00
README.md feat: add webhook delivery 2026-10-18 08:36:35 +02:00
spam.go feat: add altcha 2026-06-09 10:17:40 +02:00
spam_test.go initial version 2026-06-05 11:00:15 +02:00
webhook.go feat: add webhook delivery 2026-10-18 08:36:35 +02:00
webhook_test.go feat: add webhook delivery 2026-10-18 08:36:35 +02:00

Post2Mail

Send your contact forms via email

Warning: this project is pretty much vibe coded from an existing node project.

Intro

Contact forms on websites are the most common method for users to reach out to the owners. They're also super simple to implement... theoretically. Forwarding them through email is not as straight forward. You'll need some kind of server for this.

This is my attempt to build the simplest docker service possible to allow exactly that. Handle contact form submissions via POST and forward them via configurable SMTP credentials and/or a webhook.

Quick start:

  1. cp docker-compose.example.yml docker-compose.yml
  2. cp config.yaml.example config.yaml
  3. Edit config.yaml (SMTP hosts, tenants, redirects, spam settings)
  4. docker compose up -d --build

Webhooks

Instead of (or in addition to) SMTP, a tenant can forward submissions to a webhook. Add a webhook section to the tenant; at least one of smtp or webhook must be configured. When both are set, both are called and the submission only counts as successful if both succeed.

webhook:
  url: https://hooks.example.test/contact
  token: "${WEBHOOK_TOKEN}"   # sent as "Authorization: Bearer <token>"
  headers:                    # optional, e.g. for services expecting an API key header
    X-Api-Key: "${WEBHOOK_API_KEY}"
  timeout: 10s                # optional, default 10s

The webhook receives a POST with Content-Type: application/json; any 2xx response counts as success:

{
  "tenant": "alpha",
  "subject": "New contact form submission",
  "submitted_at": "2026-10-18T12:00:00Z",
  "fields": { "name": "Alice", "message": "Hi!" },
  "attachments": [
    { "filename": "cv.pdf", "content_type": "application/pdf", "size": 12345, "data": "<base64>" }
  ]
}

Using ALTCHAv2

To use ALTCHAv2, add the altcha section to your tenant config in config.yaml. See the example config for details.

You can specify your algorithm from the PBKDF2 algorithms. The other derivation algorithms are not supported.

On your frontend, it will look something similar to:

<form action="https://mail.example.test/forms/alpha" method="POST" enctype="multipart/form-data">
  <!-- your fields -->
  <altcha-widget challengeurl="https://mail.example.test/forms/alpha/altcha"></altcha-widget>
  <button type="submit">Send</button>
</form>
<!--Or just load it through npm ®-->
<script async defer src="https://cdn.jsdelivr.net/npm/altcha/dist/altcha.min.js" type="module"></script>

ALTCHA Docs