iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🗄️

Implementing HubSpot Form Submission Limits with HubDB and Serverless Functions (Code Included)

に公開

How to Implement HubSpot Form Submission Limits with HubDB & Serverless Functions (with Code) 💻

2025-04-29 · Reina

Introduction 🌿

HubSpot forms do not have a built-in feature to set a submission limit. To solve this challenge, I implemented a solution using HubDB and Serverless Functions 💻

Demo Image

Mechanism (Behavior in the Demo Video) 🎥

This is how the system works!

Increments the HubDB count via a Serverless Function.

Hides the form (displays a message) when the limit is reached.

Automatically hides the form once the application deadline (UTC-based) has passed!

https://23823306.fs1.hubspotusercontent-na1.net/hubfs/23823306/MeowBit.dev/Blog images/Screencast from 2025-04-29 21-15-34 (video-converter.com).mp4

Organizing the Prerequisites ☕

Scenario

  • Users sign up via a HubSpot form.
  • We want to limit the number of registrants.
  • Automatically hide the form once the limit is exceeded.
  • Also, add a deadline timing for form submissions.

Configuration Overview

  • Manage information for each form in HubDB.
  • Use within CMS templates.
  • Increment the count upon form submission.
  • Update via the HubDB API on the Serverless Function side.

Operation Image

Technologies, Files, and Tools Used ⚡

Implementation Code Overview 🔧

HubDB Table (Example)

Column Name Purpose Data Type
form_guid Target form ID (used to identify the sender) text
current_submissions Current number of submissions number
max_submissions Maximum allowable submissions number
deadline Application deadline (UTC) datetime

This table is for managing the submission status of each form. The if statement in the template will toggle the form visibility based on the submission limit and deadline.

HubL within Templates

{# Getting the current local time and converting it to UNIX timestamp #}
{% set today = unixtimestamp(local_dt) %} 
{# Fetch data by specifying the HubDB Table ID! #}
{% set table = hubdb_table_rows("HUBDB_ID_HERE") %} 
{% for row in table %}
  {% if row.form_guid  "FORM_GUID_HERE" %}
    {% set current_submissions = row.current_submissions %}
    {% set submission_limit = row.max_submissions %}
    {% set deadline_timestamp = row.deadline %}

    {% if current_submissions < submission_limit and today < deadline_timestamp %}
      {# Display the form if both submission count and deadline are OK! #}
      <div id="my-form-wrapper">
        <div id="my-form-target"></div>
        <script src="https://js.hsforms.net/forms/v2.js"></script>
        <script>
          hbspt.forms.create({
            region: "na1",
            portalId: "YOUR_PORTAL_ID",
            formId: "FORM_GUID_HERE",
            target: '#my-form-target',
            onFormSubmit: function($form) {
              // Call the serverless function to increment the count upon submission!
              fetch('/_hcms/api/update-form-submissions', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ form_guid: 'FORM_GUID_HERE' })
              });
            }
          });
        </script>
      </div>
    {% else %}
      {# Show a deadline message if the limit is reached or the deadline has passed! #}
      <div class="form-closed-message">
        <p>This form is now closed 🙇‍♀️</p>
      </div>
    {% endif %}
  {% endif %}
{% endfor %}

Using if current_submissions < submission_limit and today < deadline_timestamp ensures that the form is only displayed if neither the submission count nor the deadline has been reached.

Serverless Functions

const HUBSPOT_PRIVATE_APP_TOKEN = process.env.FORM_LIMIT_MANAGER; // Set the token in an environment variable!

exports.main = async (context = {}, sendResponse) => {
  try {
    const body = context.body || {};
    const formGuid = body.form_guid;
    const tableId = 'YOUR_TABLE_ID'; // Specify the HubDB table ID

    if (!formGuid) {
      return sendResponse({ statusCode: 400, body: { message: 'form_guid is missing from the request' } });
    }

    // Fetch HubDB row data and find the corresponding form_guid
    const recordsResponse = await fetch(`https://api.hubapi.com/cms/v3/hubdb/tables/${tableId}/rows`, { ... });
    const records = await recordsResponse.json();
    const targetRecord = records.results.find(record => record.values.form_guid = formGuid);

    if (!targetRecord) {
      return sendResponse({ statusCode: 404, body: { message: 'Corresponding record not found' } });
    }

    // Prepare to increment the current submission count by 1!
    const rowResponse = await fetch(`https://api.hubapi.com/cms/v3/hubdb/tables/${tableId}/rows/${targetRecord.id}`, { ... });
    const rowData = await rowResponse.json();
    const updatedValues = {
      ...rowData.values,
      current_submissions: (targetRecord.values.current_submissions || 0) + 1
    };

    // Update to draft...
    await fetch(`https://api.hubapi.com/cms/v3/hubdb/tables/${tableId}/rows/${targetRecord.id}/draft`, { ... });

    // Then publish to finalize!
    await fetch(`https://api.hubapi.com/cms/v3/hubdb/tables/${tableId}/draft/publish`, { ... });

    return sendResponse({ statusCode: 200, body: { message: 'Submission count updated and published', newCount: updatedValues.current_submissions } });
  } catch (error) {
    return sendResponse({ statusCode: 500, body: { message: 'An error occurred', error: error.message } });
  }
};

serverless.json (Example)

{
  "runtime": "nodejs18.x",
  "version": "1.0",
  "secrets": ["FORM_LIMIT_MANAGER"],
  "endpoints": {
    "update-form-submissions": { "method": "POST", "file": "form-limit-updater.js" }
  }
}

This serverless function is triggered by a form submission event, executing a request that increments the value of the "current_submissions" column in HubDB by 1.

Points of Caution ⚡

  • deadline / max_submissions require manual management.
  • When handling multiple forms, you need to be strategic about how form_guid is specified on the template side.
  • Be careful not to mess up the flow of updating HubDB drafts and then publishing them.

Summary ✨

Even "submission limits & deadline control," which were difficult with standard HubSpot features alone, can be achieved with a little customization!

By building a solid mechanism, managing events and workshops becomes much easier 🌸

Operation Image

Discussion