ย 
Znote (recipes)
ย ย Get Znote ย 

๐Ÿ“ฌ Newsletter Subscription with Brevo

Set up a newsletter signup form with Google reCAPTCHA, save emails to a Brevo

ย 

๐Ÿ“ฌ Newsletter Subscription with Brevo

Create a simple newsletter signup using Node.js, Brevo (formerly Sendinblue), and Google reCAPTCHA.


๐Ÿ“ฆ Prerequisites

Install Required Packages

npm install -S sib-api-v3-sdk express body-parser node-fetch@^2.6.6

๐Ÿ”‘ Brevo API Setup

  1. Go to Brevo API Keys
  2. Generate a new API key
  3. Save the key in a local file brevo.json:
{ "key": "YOUR_BREVO_API_KEY" }

Optional โ€“ Create the credential file from a block:

const credentials = loadBlock('brevo');
_fs.writeFileSync(`${__dirname}/brevo.json`, credentials);

โœ… Google reCAPTCHA Setup

  1. Go to Google reCAPTCHA Admin
  2. Register a new site
  3. Add the following domains:
    1. localhost
    2. worker1.znote.io
  4. Copy your site (public) and secret (private) keys
  5. Save them securely

๐Ÿงพ Newsletter Form

Create a simple HTML form using Bootstrap and reCAPTCHA v3:

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://www.google.com/recaptcha/api.js?render=YOUR_PUBLIC_RECAPTCHA_KEY"></script>

<form id="subscription-form">
  <div id="form-feedback" class="alert alert-success d-none">Thank you! Weโ€™ll be in touch.</div>
  <input type="email" class="form-control mb-2" id="email" placeholder="Email" required>
  <button id="submit-form" class="btn btn-primary w-100">Subscribe</button>
</form>

<script>
  document.getElementById("subscription-form").addEventListener("submit", function(event) {
    event.preventDefault();
    const email = document.getElementById("email").value;
    if (!email.includes("@")) return;

    grecaptcha.ready(() => {
      grecaptcha.execute('YOUR_PUBLIC_RECAPTCHA_KEY', { action: 'submit' }).then((token) => {
        document.getElementById("form-feedback").classList.remove("d-none");
        document.getElementById("submit-form").disabled = true;

        const data = new URLSearchParams();
        data.append('email', email);
        data.append('g-recaptcha-response', token);

        fetch("http://localhost:4000/subscribe", {
          method: "POST",
          body: data
        });
      });
    });
  });
</script>

๐Ÿš€ Backend โ€“ Subscribe via Brevo

//exec: node
//hide
const express = require('express');
const bodyParser = require('body-parser');
const fetch = require('node-fetch');
const SibApiV3Sdk = require('sib-api-v3-sdk');
const credentials = require('./brevo.json');

const app = express();
app.use(bodyParser.urlencoded({ extended: true }));

// Setup Brevo client
const defaultClient = SibApiV3Sdk.ApiClient.instance;
defaultClient.authentications['api-key'].apiKey = credentials.key;
const apiInstance = new SibApiV3Sdk.ContactsApi();

app.get('/', (req, res) => res.send('OK'));

app.post('/subscribe', async (req, res) => {
  try {
    const recaptchaRes = await fetch("https://www.google.com/recaptcha/api/siteverify", {
      method: "POST",
      body: new URLSearchParams({
        secret: 'YOUR_PRIVATE_RECAPTCHA_KEY',
        response: req.body["g-recaptcha-response"]
      })
    });

    const captchaValidation = await recaptchaRes.json();
    if (!captchaValidation.success) return res.status(403).send("Captcha failed");

    const email = req.body.email;
    const contactData = {
      email: email,
      listIds: [2], // Replace with your list ID from Brevo
      updateEnabled: false
    };

    await apiInstance.createContact(contactData);
    return res.send("done");

  } catch (error) {
    console.error("Subscription error:", error);
    return res.status(500).send("error");
  }
});

app.listen(4000, () => console.log("Server running on http://localhost:4000"));

๐Ÿ“ Summary

This template lets you:

  • Securely collect emails via a form protected by Google reCAPTCHA
  • Send new subscribers directly to a Brevo contact list
  • Use Node.js with minimal setup

Related recipes