Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Simple Form Handler

A lightweight, self-hosted form submission handler that sends form data via email using Google SMTP. Perfect for static websites that need contact forms without relying on third-party services.

Features

  • πŸš€ Easy to deploy with Docker
  • πŸ“§ Send form submissions via Gmail SMTP
  • πŸ”’ Domain whitelisting for CORS protection
  • 🎯 Simple REST API
  • πŸ“¦ Minimal dependencies
  • βœ… Production-ready with health checks

Prerequisites

  • Docker and Docker Compose installed
  • A Gmail account with 2-Factor Authentication enabled
  • Google App Password (see setup instructions below)

Quick Start

1. Clone or Create Project Directory

git clone git@github.com:raditotev/simple-form-handler.git
cd simple-form-handler

2. Set Up Google App Password

  1. Go to your Google Account
  2. Navigate to Security β†’ 2-Step Verification
  3. Go to https://myaccount.google.com/apppasswords
  4. Enter app name and submit
  5. Copy the 16-character password (you won't see it again)

3. Configure Environment Variables

Edit docker-compose.yml and update:

environment:
  - GMAIL_USER=youremail@gmail.com # Your Gmail address
  - GMAIL_APP_PASSWORD=abcd efgh ijkl mnop # Google App Password
  - RECIPIENT_EMAIL=recipient@example.com # Where to send submissions
  - EMAIL_SUBJECT=New Form Submission # Email subject line
  - ALLOWED_DOMAINS=https://yoursite.com,https://www.yoursite.com

ALLOWED_DOMAINS: Comma-separated list of domains allowed to submit forms. Include both www and non-www versions if needed.

4. Build and Run

# Build the Docker image
docker compose build

# Start the service
docker compose up -d

# Check logs
docker compose logs -f

5. Verify It's Running

Open your browser and visit:

http://localhost:3000/health

You should see:

{
  "status": "ok",
  "allowedDomains": ["https://yourdomain.com", "http://localhost:3000"]
}

Usage

HTML Form Example

<!DOCTYPE html>
<html>
  <head>
    <title>Contact Form</title>
  </head>
  <body>
    <form id="contactForm">
      <input type="text" name="name" placeholder="Your name" required />
      <input type="email" name="email" placeholder="Your email" required />
      <textarea name="message" placeholder="Your message" required></textarea>
      <button type="submit">Send</button>
    </form>

    <div id="status"></div>

    <script>
      document
        .getElementById('contactForm')
        .addEventListener('submit', async (e) => {
          e.preventDefault()

          const formData = new FormData(e.target)
          const data = Object.fromEntries(formData)

          try {
            const response = await fetch('http://localhost:3000/submit', {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify(data),
            })

            const result = await response.json()

            if (result.success) {
              document.getElementById('status').innerHTML =
                '<p style="color: green;">Message sent successfully!</p>'
              e.target.reset()
            } else {
              document.getElementById('status').innerHTML =
                '<p style="color: red;">Failed to send message.</p>'
            }
          } catch (error) {
            document.getElementById('status').innerHTML =
              '<p style="color: red;">Error: ' + error.message + '</p>'
          }
        })
    </script>
  </body>
</html>

JavaScript/React Example

const handleSubmit = async (formData) => {
  try {
    const response = await fetch('https://your-form-handler.com/submit', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(formData),
    })

    const result = await response.json()

    if (result.success) {
      console.log('Form submitted successfully!')
    }
  } catch (error) {
    console.error('Submission error:', error)
  }
}

API Endpoints

POST /submit

Submit form data to be emailed.

Request:

{
  "name": "John Doe",
  "email": "john@example.com",
  "message": "Hello, this is a test message"
}

Response (Success):

{
  "success": true,
  "message": "Form submitted successfully!"
}

Response (Error):

{
  "success": false,
  "message": "Failed to send email"
}

GET /health

Check service status and view allowed domains.

Response:

{
  "status": "ok",
  "allowedDomains": ["https://yourdomain.com"]
}

Configuration

Environment Variables

Variable Required Description Example
GMAIL_USER Yes Your Gmail address your-email@gmail.com
GMAIL_APP_PASSWORD Yes Google App Password abcd efgh ijkl mnop
RECIPIENT_EMAIL Yes Email to receive submissions contact@example.com
EMAIL_SUBJECT No Subject line for emails New Form Submission
ALLOWED_DOMAINS Yes Comma-separated allowed domains https://example.com,https://www.example.com
PORT No Port to run on (default: 3000) 3000

Domain Whitelisting

Only domains listed in ALLOWED_DOMAINS can submit forms. This prevents unauthorized use of your form handler.

Example configurations:

# Single domain
- ALLOWED_DOMAINS=https://mysite.com

# Multiple domains
- ALLOWED_DOMAINS=https://mysite.com,https://www.mysite.com,https://app.mysite.com

# Development and production
- ALLOWED_DOMAINS=https://mysite.com,http://localhost:3000,http://localhost:8080

Important: Include the protocol (http:// or https://) and don't add trailing slashes.

Docker Commands

# Start the service
docker compose up -d

# Stop the service
docker compose down

# View logs
docker compose logs -f form-handler

# Restart the service
docker compose restart

# Rebuild after code changes
docker compose build --no-cache
docker compose up -d

# Remove everything including volumes
docker compose down -v

License

MIT

Support

For issues, questions, or contributions, please open an issue on the project repository.

Changelog

v1.0.0

  • Initial release
  • Gmail SMTP support
  • Domain whitelisting
  • Docker deployment
  • Health check endpoint

About

A lightweight, self-hosted form submission handler that sends form data via email using Google SMTP. Perfect for static websites that need contact forms without relying on third-party services.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages