Bêta privéeMailbeam est en bêta privée : l'API publique n'est pas encore ouverte.Rejoindre la liste d'attente

Mailbeam
Node.js + ExpressDébutant15 minutesMis à jour en janvier 2025

Vérification d'e-mails en Node.js

Dans ce tutoriel, vous allez ajouter la vérification d'e-mails en temps réel à une application Node.js sous Express. À la fin, les adresses jetables, les boîtes inexistantes et les adresses mal tapées seront rejetées au niveau de l'endpoint d'inscription, avant la création du moindre enregistrement utilisateur.

Ce que vous allez construire

Un middleware Express réutilisable qui :

  • Vérifie une adresse via l'API Mailbeam
  • Renvoie un 422 avec un code d'erreur exploitable par la machine en cas d'échec
  • Échoue en mode permissif sur les erreurs d'API (pour qu'une panne de Mailbeam ne casse pas vos inscriptions)
  • Met éventuellement les résultats en cache pour éviter les vérifications en double

Prérequis

  • Node.js 18 ou plus récent
  • Un projet npm, pnpm ou yarn
  • Un compte Mailbeam et une clé d'API (inscription gratuite)

Étape 1 — Ajouter un petit client

Il n'y a pas de SDK à installer. Mailbeam se résume à un endpoint HTTP : une douzaine de lignes dans votre propre code suffisent, et il n'y a rien à maintenir à jour. Des SDK officiels sont à la feuille de route ; voici ce qu'il faut faire aujourd'hui.

// lib/mailbeam.js
const ENDPOINT = "https://api.mailbeam.dev/v1/verify";

export async function verifyEmail(email, { timeoutMs = 3000 } = {}) {
  const response = await fetch(ENDPOINT, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.MAILBEAM_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ email }),
    signal: AbortSignal.timeout(timeoutMs),
  });

  if (!response.ok) {
    const { error, message } = await response.json();
    throw Object.assign(new Error(message), { code: error });
  }

  return response.json();
}

Étape 2 — Déclarer votre clé d'API

Ajoutez votre clé à .env ou .env.local :

MAILBEAM_KEY=mb_live_xxxxxxxxxxxxxxxxxxxx

Étape 3 — Créer le middleware de vérification

Créez middleware/verifyEmail.js :

import { verifyEmail } from "../lib/mailbeam.js";

/**
 * Middleware Express qui vérifie l'adresse présente dans req.body.email.
 * Appelle next() en cas de succès, renvoie un 422 en cas d'échec.
 * Échec permissif sur les erreurs de l'API Mailbeam — ne bloquez pas
 * vos utilisateurs si l'API est indisponible.
 */
export async function verifyEmail(req, res, next) {
  const { email } = req.body;

  if (!email) {
    return res.status(400).json({ error: "email is required." });
  }

  try {
    const { valid, score, reason } = await verifyEmail(email);

    if (!valid || score < 60) {
      return res.status(422).json({
        error: "Merci de fournir une adresse e-mail valide.",
        code: reason ?? "invalid_email",
      });
    }

    // Attache le résultat à la requête, pour les handlers en aval
    req.emailVerification = { valid, score, reason };
    next();
  } catch (err) {
    // Journalise sans bloquer — une panne de Mailbeam ne doit pas casser l'inscription
    console.error("[Mailbeam] erreur de vérification :", err.message);
    next();
  }
}

Étape 4 — L'ajouter à votre route d'inscription

// routes/auth.js
import express from "express";
import { verifyEmail } from "../middleware/verifyEmail.js";

const router = express.Router();

router.post("/signup", verifyEmail, async (req, res) => {
  const { email, password } = req.body;

  try {
    const user = await db.createUser({ email, password });
    res.status(201).json({ user });
  } catch (err) {
    res.status(500).json({ error: "La création du compte a échoué." });
  }
});

export default router;

Et la configuration de votre application Express :

// app.js
import express from "express";
import authRoutes from "./routes/auth.js";

const app = express();
app.use(express.json());
app.use("/api/auth", authRoutes);

app.listen(3000, () => {
  console.log("Serveur démarré sur http://localhost:3000");
});

Tester l'intégration

Démarrez votre serveur, puis testez avec cURL :

# Adresse valide — doit renvoyer 201
curl -X POST http://localhost:3000/api/auth/signup \
  -H "Content-Type: application/json" \
  -d '{"email": "valid@example.com", "password": "secretpass"}'

# Adresse jetable — doit renvoyer 422
curl -X POST http://localhost:3000/api/auth/signup \
  -H "Content-Type: application/json" \
  -d '{"email": "throwaway@mailinator.com", "password": "secretpass"}'

Utilisez les domaines de test de Mailbeam dans votre chaîne d'intégration continue, pour ne pas entamer votre quota :

# Renvoie toujours valide (score 99)
curl ... -d '{"email": "user@valid.mailbeam-test.dev", ...}'

# Renvoie toujours invalide
curl ... -d '{"email": "user@invalid.mailbeam-test.dev", ...}'

Ajouter une couche de cache (facultatif)

Pour des inscriptions à fort trafic, mettez les résultats en cache afin d'éviter les appels redondants :

import { LRUCache } from "lru-cache";

const cache = new LRUCache({
  max: 500,
  ttl: 1000 * 60 * 60, // 1 heure
});

export async function verifyEmail(req, res, next) {
  const { email } = req.body;
  if (!email) return res.status(400).json({ error: "email is required." });

  const normalised = email.toLowerCase().trim();
  const cached = cache.get(normalised);

  if (cached) {
    if (!cached.valid || cached.score < 60) {
      return res.status(422).json({
        error: "Merci de fournir une adresse e-mail valide.",
        code: cached.reason ?? "invalid_email",
      });
    }
    return next();
  }

  try {
    const result = await verifyEmail(normalised);
    cache.set(normalised, result);

    if (!result.valid || result.score < 60) {
      return res.status(422).json({
        error: "Merci de fournir une adresse e-mail valide.",
        code: result.reason ?? "invalid_email",
      });
    }
    next();
  } catch (err) {
    console.error("[Mailbeam] erreur de vérification :", err.message);
    next();
  }
}

Bonnes pratiques

PratiquePourquoi
Échec permissif sur les erreurs d'APIUne panne de Mailbeam ne doit pas empêcher les inscriptions
Mettre en cache (TTL d'une heure)Évite de vérifier deux fois la même adresse
Passer en minuscules et élaguer avant de vérifierÉvite les ratés de cache pour des différences insignifiantes
Utiliser les domaines de test en CINe consomme pas le quota de production dans les tests automatisés
Journaliser les erreurs, pas les adressesÉvite de journaliser des données personnelles en production

Liste de contrôle avant la mise en production

  • MAILBEAM_KEY déclarée comme secret de plateforme (pas dans le code source)
  • Journalisation des erreurs en place (sans écrire l'adresse elle-même)
  • Couche de cache ajoutée sur les routes à fort trafic
  • Domaines de test utilisés dans la chaîne d'intégration continue
  • Seuil de score arrêté et documenté (60 par défaut)
  • Le front-end affiche un message clair quand un 422 revient

Prochaines étapes