Skip to content

escVelocity

Helping Businesses Grow πŸš€ using AI πŸ€– and Automation βš™οΈ

Menu
  • Blog
  • Automate Your Business
Menu
Contact form Google sheets

WordPress contact-form using Google Sheets (FREE)

Posted on May 16, 2026May 16, 2026 by Sudhir Mantena

Typeform, Jotform all charge a monthly fee to collect form submissions. WordPress contact form plugins (WPForms, Contact Form 7, Gravity Forms) are free but have terrible UI. Form submissions data is stuck inside WordPress database. Neither is a great option for your small business.


So I built an alternative using Google Apps Script. Copy & Paste this into your WordPress or any other website to display a contact form & capture leads in Google spreadsheets. Forever Free. You could even customize the look and feel to match your own website.

The WordPress Problem

WordPress contact form plugins have two fundamental issues.

  • The UI is not yours. You get their fields, their styling, their stylesheet fighting your theme. Customizing it means paying for pro or writing CSS overrides that break on the next update.
  • Submissions sit in the WordPress database and exporting it to your own CRM or Email Marketing software is a painful.

    This solution fixes both. Plain HTML form, you control the design. Submissions go directly to Google Sheets. Drop it into any WordPress page via a Custom HTML block.


    How It Works

    User submits form
    ↓
    HTML sends POST to Apps Script URL
    ↓
    Script writes row to Google Sheets
    ↓
    Script emails you instantly
    ↓
    User sees confirmation

    No database. No monthly subscription to pay for. Just free Google spreadsheet.


    Here’s how to create one

    1. Open Google Spreadsheet. File β‡’ New β‡’ Spreadsheet. Save it.
    2. Click Extensions β‡’ Apps Script β‡’ Paste the script given below
    3. Replace name@email.com in “NOTIFY_EMAIL” at the top.
    4. Click Deploy β‡’ New Deployments
    5. Select Type (Gear icon) β‡’ Web App (Execute as: Me; Access: Anyone)
    6. Authorize Access β‡’ Google verification β‡’ Advanced
    7. Click on “Go to untitled project” β‡’ Permissions “Select All” β‡’ Continue
    8. Copy the Web App URL
    9. Open contact-form.html and paste above Web App URL in “SCRIPT_URL”
    10. Send test email: Run β‡’ Run function β‡’ sendTestEmail

    Change the Colors to match your website

    What It Does Not Cover

    File uploads, payments, high volume (thousands/day), or GDPR storage outside Google. For those use-cases, use a proper backend. For a contact or lead capture form on a small business site, this is everything you need, without paying monthly subscription fee.


    Google App Script & HTML code

    Includes apps-script.js, contact-form.html, and a README with full setup instructions.

    /**
    * escVelocity Contact Form - Google Apps Script
    *
    * Receives form submissions, writes to Google Sheets,
    * sends email notifications, and rate limits by email.
    *
    * Setup:
    * 1. Open your Google Sheet β†’ Extensions β†’ Apps Script
    * 2. Paste this script and configure the constants below
    * 3. Deploy as Web App (Execute as: Me, Access: Anyone)
    * 4. Run sendTestEmail() once to authorize Gmail permissions
    * 5. Copy the Web App URL into your HTML form's fetch() call
    */

    // ─── CONFIGURATION ───────────────────────────────────────────
    const NOTIFY_EMAIL = 'your@email.com'; // Email to receive notifications
    const RATE_LIMIT_WINDOW_MINUTES = 60; // Time window for rate limiting
    const RATE_LIMIT_MAX_SUBMISSIONS = 5; // Max submissions per email per window
    const FORM_NAME = 'Contact Form'; // Used in email subject line
    // ─────────────────────────────────────────────────────────────

    function doPost(e) {
    try {
    var data = JSON.parse(e.postData.contents);
    data.phone = data.phone ? data.phone.toString().trim() : '';

    if (isRateLimited(data.email)) {
    return ContentService
    .createTextOutput(JSON.stringify({ result: 'error', message: 'Rate limit exceeded' }))
    .setMimeType(ContentService.MimeType.JSON);
    }

    writeToSheet(data);
    sendNotification(data);

    return ContentService
    .createTextOutput(JSON.stringify({ result: 'success' }))
    .setMimeType(ContentService.MimeType.JSON);

    } catch(err) {
    return ContentService
    .createTextOutput(JSON.stringify({ result: 'error', message: err.message }))
    .setMimeType(ContentService.MimeType.JSON);
    }
    }

    function writeToSheet(data) {
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    var newRow = sheet.getLastRow() + 1;

    // Timestamp gets its own format, rest forced to plain text to avoid formula errors
    sheet.getRange(newRow, 1).setValue(new Date());
    sheet.getRange(newRow, 2).setNumberFormat('@').setValue(data.name || '');
    sheet.getRange(newRow, 3).setNumberFormat('@').setValue(data.email || '');
    sheet.getRange(newRow, 4).setNumberFormat('@').setValue(data.phone || '');
    sheet.getRange(newRow, 5).setNumberFormat('@').setValue(data.website || '');
    sheet.getRange(newRow, 6).setNumberFormat('@').setValue(data.description || '');
    }

    function sendNotification(data) {
    var subject = 'πŸ“₯ New ' + FORM_NAME + ' submission - ' + data.name;
    var body = [
    'A new form submission just came in.',
    '',
    'Name: ' + (data.name || '-'),
    'Email: ' + (data.email || '-'),
    'Phone: ' + (data.phone || '-'),
    'Website: ' + (data.website || '-'),
    '',
    'Message:',
    (data.description || '-'),
    '',
    'Submitted at ' + new Date().toLocaleString()
    ].join('\n');

    MailApp.sendEmail(NOTIFY_EMAIL, subject, body);
    }

    function isRateLimited(email) {
    var cache = CacheService.getScriptCache();
    var key = 'rl_' + email.replace(/[^a-zA-Z0-9]/g, '_');
    var current = cache.get(key);
    var count = current ? parseInt(current) : 0;

    if (count >= RATE_LIMIT_MAX_SUBMISSIONS) {
    return true;
    }

    cache.put(key, count + 1, RATE_LIMIT_WINDOW_MINUTES * 60);
    return false;
    }

    /**
    * Run this function once manually to authorize Gmail permissions.
    * Delete or keep it β€” it won't affect live form submissions.
    */
    function sendTestEmail() {
    sendNotification({
    name: 'Test User',
    email: 'test@example.com',
    phone: '+1 555 000 0000',
    website: 'https://example.com',
    description: 'This is a test submission to verify email notifications are working.'
    });
    }

    Entire source code available on my Github repository: WordPress Contact Form using Google Sheets

    If this saved you a monthly subscription fee or a few hours of time, like, repost or comment here and also star the Github repository. Much appreciated.


    Related

    Category: Artificial Intelligence

    Leave a ReplyCancel reply

    • Contact form Google sheets
      WordPress contact-form using Google Sheets (FREE)
      Typeform, Jotform all charge a monthly fee to collect form...
    • Hermes-Gbrain-Slack-Whatsapp
      Save Slack and Whatsapp Conversations into Hermes + Gbrain Longterm Memory
      You converse with your Hermes Agent via Whatsapp & Slack....
    • Hermes Notion Gbrain
      Hermes + Notion + GBrain: A Complete Setup Guide
      This post is a continuation in a series detailing how...
    • Hermes GBrain
      Hermes + GBrain: A Complete Setup Guide
      How I set up a self-improving, always-on personal knowledge base...
    • Hermes AI Agent on AWS EC2
      Hermes AI Agent on AWS EC2
      A practical guide to running Hermes as an always-on service on AWS EC2 Ubuntu, with the architecture, setup sequence, and failure modes that matter most.
    • Hermes-ai-agent
      Hermes AI Agent Setup on AWS VPS
      Background: I gave up after 2-weeks, trying to set up...
    • Size Is Not a Moat
      In a marketplace, size is not moat. There are 3 phases that every marketplace goes through. Before Allee threshold, Cross Escape Velocity and Above Escape velocity.
    • Product Manager
      Good Product Managers Make Good Leaders
      Great product managers don’t just executeβ€”they inspire, influence, and drive meaningful outcomes with limited resources. The very skills that make a product manager successful are also great leadership skills.
    © 2026 escVelocity | Powered by Minimalist Blog WordPress Theme

    Loading Comments...