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

Mailbeam
Firebase + Cloud FunctionsIntermédiaire25 minutesMis à jour en janvier 2025

Vérification d'e-mails avec Firebase

Firebase Authentication permet d'intercepter les inscriptions via les fonctions bloquantes beforeCreate. Ce tutoriel ajoute la vérification Mailbeam à ce hook, de sorte que les adresses invalides et jetables sont bloquées avant qu'un enregistrement utilisateur Firebase ne soit créé.

Prérequis

  • Un projet Firebase sur le plan Blaze (nécessaire pour les Cloud Functions)
  • La CLI Firebase installée
  • Une clé d'API Mailbeam (inscription gratuite)

Mise en place

firebase init functions
cd functions
npm install axios

Déclarez la clé Mailbeam comme variable d'environnement Firebase :

firebase functions:config:set mailbeam.key="mb_live_xxxxxxxxxxxxxxxxxxxx"

Créer la fonction bloquante

// functions/index.js
const functions = require("firebase-functions");
const { getAuth } = require("firebase-admin/auth");
const axios = require("axios");

// beforeCreate s'exécute AVANT l'écriture de l'utilisateur dans Firebase Auth
exports.validateEmailBeforeCreate = functions.auth
  .user()
  .beforeCreate(async (user, context) => {
    const email = user.email;
    if (!email) return; // Pas d'adresse — autres fournisseurs, on passe

    const apiKey = functions.config().mailbeam.key;

    try {
      const { data } = await axios.post(
        "https://api.mailbeam.dev/v1/verify",
        { email },
        {
          headers: { Authorization: `Bearer ${apiKey}` },
          timeout: 5000,
        }
      );

      const { valid, score, reason } = data;

      if (!valid || score < 60) {
        const message =
          reason === "disposable_domain"
            ? "Merci d'utiliser une adresse e-mail permanente, pas une adresse temporaire."
            : "Merci de fournir une adresse e-mail valide et joignable.";

        throw new functions.auth.HttpsError("invalid-argument", message);
      }
    } catch (err) {
      // S'il s'agit déjà de notre HttpsError, on la relance
      if (err.code === "functions/invalid-argument") throw err;
      // Sinon : on journalise et on laisse passer
      functions.logger.error("Échec de la vérification Mailbeam", { error: err.message });
    }
  });

Version TypeScript

// functions/src/index.ts
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
import axios from "axios";

admin.initializeApp();

export const validateEmailBeforeCreate = functions.auth
  .user()
  .beforeCreate(async (user) => {
    if (!user.email) return;

    const apiKey = functions.config().mailbeam.key;

    try {
      const { data } = await axios.post<{
        valid: boolean;
        score: number;
        reason: string | null;
      }>(
        "https://api.mailbeam.dev/v1/verify",
        { email: user.email },
        { headers: { Authorization: `Bearer ${apiKey}` }, timeout: 5000 }
      );

      if (!data.valid || data.score < 60) {
        throw new functions.auth.HttpsError(
          "invalid-argument",
          data.reason === "disposable_domain"
            ? "Merci d'utiliser une adresse e-mail permanente."
            : "Merci d'utiliser une adresse e-mail valide et joignable."
        );
      }
    } catch (err: unknown) {
      if ((err as { code?: string }).code === "functions/invalid-argument") throw err;
      functions.logger.error("Erreur Mailbeam", err);
    }
  });

Déployer

firebase deploy --only functions

Tester

// Utilisez la Firebase Emulator Suite pour tester en local
firebase emulators:start

// Essayez de créer un utilisateur avec une adresse jetable via le SDK Firebase
const { createUserWithEmailAndPassword } = require("firebase/auth");

try {
  await createUserWithEmailAndPassword(auth, "temp@mailinator.com", "password");
} catch (error) {
  console.log(error.code);    // "auth/invalid-argument"
  console.log(error.message); // "Merci d'utiliser une adresse e-mail permanente."
}

Bonnes pratiques

  • Utilisez beforeCreate et non onCreate : beforeCreate s'exécute avant l'enregistrement, onCreate après
  • Relancez toujours functions.auth.HttpsError et échouez en mode permissif pour toutes les autres erreurs
  • Utilisez functions.logger.error plutôt que console.error, pour une journalisation structurée dans Firebase

Prochaines étapes