Beta privadaMailbeam está en beta privada: la API pública todavía no está abierta.Únete a la lista de espera

Mailbeam
Supabase + Edge FunctionsIntermedio25 minutosActualizado en enero de 2025

Verificación de email con Supabase

Supabase permite interceptar los eventos de autenticación con Auth Hooks. Este tutorial crea una Edge Function que llama a Mailbeam antes de que Supabase cree un usuario nuevo, bloqueando los emails desechables e inválidos en la capa de identidad.

Requisitos previos

  • Un proyecto de Supabase (con la CLI instalada)
  • Una clave de API de Mailbeam (regístrate gratis)

Crea la Edge Function

supabase functions new verify-email
// supabase/functions/verify-email/index.ts
import { serve } from "https://deno.land/std@0.168.0/http/server.ts";

const MAILBEAM_KEY = Deno.env.get("MAILBEAM_KEY")!;
const MIN_SCORE = 60;

serve(async (req) => {
  const payload = await req.json();
  // El payload del Auth Hook trae los datos del usuario en payload.user
  const email = payload?.user?.email ?? payload?.email;

  if (!email) {
    return new Response(JSON.stringify({ decision: "reject" }), {
      headers: { "Content-Type": "application/json" },
    });
  }

  try {
    const response = await fetch("https://api.mailbeam.dev/v1/verify", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${MAILBEAM_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ email }),
      signal: AbortSignal.timeout(5000),
    });

    if (!response.ok) throw new Error(`HTTP ${response.status}`);

    const { valid, score, reason } = await response.json();

    if (!valid || score < MIN_SCORE) {
      const message =
        reason === "disposable_domain"
          ? "Usa una dirección de email permanente."
          : "Escribe una dirección de email válida y alcanzable.";

      return new Response(
        JSON.stringify({ decision: "reject", message }),
        { status: 200, headers: { "Content-Type": "application/json" } }
      );
    }
  } catch (err) {
    // Falla en abierto: no rechaces por un error de la API de Mailbeam
    console.error("Error de Mailbeam:", err);
  }

  return new Response(
    JSON.stringify({ decision: "continue" }),
    { status: 200, headers: { "Content-Type": "application/json" } }
  );
});

Define la variable de entorno

supabase secrets set MAILBEAM_KEY=mb_live_xxxxxxxxxxxxxxxxxxxx

Despliega y conéctala al Auth Hook

supabase functions deploy verify-email

En el panel de Supabase → Authentication → Hooks:

  • Activa Before User Creation
  • Selecciona tu Edge Function verify-email

Pruébala en local

supabase start
supabase functions serve verify-email --env-file .env.local

# Prueba con curl
curl -X POST http://localhost:54321/functions/v1/verify-email \
  -H "Content-Type: application/json" \
  -d '{"user": {"email": "temp@mailinator.com"}}'
# → {"decision":"reject","message":"Usa una dirección de email permanente."}

Buenas prácticas

  • Devuelve siempre { decision: "continue" } en el bloque catch: falla en abierto
  • Pon AbortSignal.timeout(5000) para que la función no se quede colgada
  • Registra los errores en los logs de funciones de Supabase para poder vigilarlos

Siguientes pasos