Aller au contenu principal

Guide Supabase

Une nouvelle ligne dans Supabase,
un email et un WhatsApp partent.

Un database webhook appelle une Edge Function à chaque insert, la fonction fait un appel API, et le message de bienvenue ou de commande part de votre boîte mail, de votre numéro WhatsApp ou de votre téléphone Android. Gratuit, avec le code et un prompt pour votre éditeur IA.

Pressé ? Résumez cet article avec une IA

La réponse courte

Comment envoyer email, SMS et WhatsApp depuis Supabase ?

Créez un database webhook sur votre table (profiles, orders) qui appelle une Edge Function Supabase à chaque INSERT. La fonction lit la nouvelle ligne et fait une requête POST /message à Unlimited Messaging, qui envoie l'email depuis votre boîte mail, le WhatsApp depuis votre numéro et le SMS depuis votre téléphone Android. Les database webhooks passent par pg_net : l'insert n'attend jamais le message.

Supabase n'a pas d'API pour les messages que votre application envoie. Son service d'email intégré sert aux emails d'Auth : il envoie 2 messages par heure, uniquement aux adresses de l'équipe du projet, et Supabase précise qu'il n'est pas prévu pour la production. Un email de bienvenue, une confirmation de commande ou un WhatsApp au client, c'est à vous de les envoyer.

Une Edge Function est le bon endroit : elle tourne côté serveur, lit les secrets avec Deno.env.get, et le plan Free de Supabase inclut 500 000 invocations. Le montage habituel, c'est un fournisseur par canal, une API email, Twilio pour le SMS, la Cloud API de Meta pour WhatsApp : trois clés, trois factures. Ici une seule requête couvre les trois canaux, et le plan Free d'Unlimited Messaging ne facture rien au message.

Ce guide couvre les messages envoyés par votre application. Les emails d'Auth (confirmation d'inscription, magic link, mot de passe oublié) et l'OTP par téléphone restent dans les réglages de Supabase Auth, où vous branchez un serveur SMTP ou un fournisseur SMS.

À lire aussi : email et WhatsApp en une seule requête API, et l'API SMS gratuite qui envoie depuis votre téléphone.

Illustration : des nœuds d'automatisation qui relient un déclencheur à un message et à un mail, avec le titre « Une ligne dans Supabase, un message envoyé ».

Pas à pas

Comment le mettre en place, étape par étape ?

Cinq étapes, environ 15 minutes. Il vous faut un projet Supabase, la CLI Supabase et un compte Unlimited Messaging gratuit.

  1. Connectez vos canaux et créez une clé API

    Dans l'application Unlimited Messaging, liez votre numéro WhatsApp par QR code, connectez votre boîte mail en IMAP/SMTP (un mot de passe d'application Gmail suffit) et, pour le SMS, connectez-vous à l'application Android gratuite sur un téléphone avec une SIM. Ne connectez que les canaux utiles, puis créez une clé API.

    supabase/functions/.env.env
    # supabase/functions/.env (gitignored, local only)
    # Created at app.unlimitedmessaging.app > API keys
    UM_API_KEY=um_live_xxxx
    # Any long random string, shared with the database webhook
    WEBHOOK_SECRET=change-me-to-a-long-random-string
  2. Créez la fonction et enregistrez les secrets

    Créez la fonction avec la CLI et poussez les deux secrets dans votre projet. Ils restent dans l'environnement de la fonction : ne mettez jamais la clé API dans une variable VITE_ ou NEXT_PUBLIC_, ni nulle part dans le code frontend.

    TerminalSupabase CLI
    supabase functions new notify-signup
    
    # Push the secrets to your project (never to the frontend)
    supabase secrets set --env-file supabase/functions/.env
    supabase secrets list
  3. Écrivez la fonction

    La fonction vérifie le secret partagé, lit la ligne insérée, envoie l'email à chaque fois et le WhatsApp seulement si la ligne a un numéro. priority: transactional fait passer le message devant un envoi en masse déjà dans votre file.

    notify-signup/index.tsDeno / TypeScript
    // supabase/functions/notify-signup/index.ts
    type Profile = { id: string; email: string; phone: string | null; full_name: string | null };
    type WebhookPayload = {
      type: 'INSERT' | 'UPDATE' | 'DELETE';
      table: string;
      schema: string;
      record: Profile;
      old_record: Profile | null;
    };
    
    Deno.serve(async (req) => {
      // The database webhook sends this header; nobody else knows it
      if (req.headers.get('x-webhook-secret') !== Deno.env.get('WEBHOOK_SECRET')) {
        return new Response('Unauthorized', { status: 401 });
      }
    
      const { record } = (await req.json()) as WebhookPayload;
      const name = record.full_name ?? 'there';
    
      // Email always, WhatsApp when the row has a phone (E.164: +33612345678).
      // Use { channel: 'SMS' } instead for people who are not on WhatsApp.
      const channels: Array<{ channel: 'EMAIL' | 'WHATSAPP' | 'SMS' }> = [{ channel: 'EMAIL' }];
      if (record.phone) channels.push({ channel: 'WHATSAPP' });
    
      const res = await fetch('https://api.unlimitedmessaging.app/message', {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${Deno.env.get('UM_API_KEY')}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          to: { email: record.email, phone: record.phone ?? undefined },
          channels,
          subject: 'Welcome aboard',
          text: `Hi ${name}, your account is ready. Reply to this message if you need anything.`,
          priority: 'transactional',
        }),
      });
    
      if (!res.ok) console.error('Unlimited Messaging', res.status, await res.text());
      return new Response(null, { status: res.ok ? 200 : 502 });
    });
  4. Déployez-la, protégée par votre propre secret

    Un database webhook n'envoie pas de JWT utilisateur : désactivez la vérification de la plateforme pour cette seule fonction (--no-verify-jwt, ou verify_jwt = false dans config.toml). L'en-tête x-webhook-secret vérifié par la fonction bloque les inconnus.

    TerminalSupabase CLI
    # A database webhook sends no user JWT: turn the platform check off
    # for this function only, the x-webhook-secret header protects it
    supabase functions deploy notify-signup --no-verify-jwt
    
    # Or keep it in supabase/config.toml:
    # [functions.notify-signup]
    # verify_jwt = false
  5. Créez le database webhook

    Dans le dashboard, Database > Webhooks : choisissez la table (profiles ici), l'événement Insert, le type Supabase Edge Functions et la fonction notify-signup, puis ajoutez un en-tête x-webhook-secret avec la même valeur. Insérez une ligne de test : voici le corps que reçoit la fonction.

    Corps du POSTWebhook payload
    {
      "type": "INSERT",
      "table": "profiles",
      "schema": "public",
      "record": {
        "id": "8f1c2d3e-0000-4000-8000-000000000000",
        "email": "[email protected]",
        "phone": "+33612345678",
        "full_name": "Lea"
      },
      "old_record": null
    }

Vibe coding

Vous codez avec Lovable, Cursor ou Claude Code ? Collez ce prompt

Le prompt donne à votre éditeur IA le bon schéma : une Edge Function, les secrets dans Supabase, un appel REST. Il vous demande avant tout envoi réel.

Prompt à copier
Ajoute des notifications transactionnelles à ce projet Supabase avec Unlimited Messaging (email, WhatsApp et SMS envoyés depuis mes propres comptes).

1. Crée une Edge Function Supabase nommée notify-signup. Lis UM_API_KEY et WEBHOOK_SECRET avec Deno.env.get. Ne mets jamais la clé dans le code frontend ni dans une variable VITE_ / NEXT_PUBLIC_.
2. La fonction reçoit le payload d'un database webhook Supabase { type, table, schema, record, old_record }. Renvoie 401 si l'en-tête x-webhook-secret est différent de WEBHOOK_SECRET.
3. Envoie un POST https://api.unlimitedmessaging.app/message avec l'en-tête Authorization: Bearer UM_API_KEY et le JSON { to: { email, phone }, channels: [{ channel: 'EMAIL' }, { channel: 'WHATSAPP' }], subject, text, priority: 'transactional' }. N'ajoute WHATSAPP (ou SMS) que si la ligne a un numéro au format E.164.
4. Donne-moi les commandes : supabase secrets set, supabase functions deploy notify-signup --no-verify-jwt, et comment créer le database webhook sur INSERT de ma table avec l'en-tête x-webhook-secret.
5. Référence de l'API : https://docs.unlimitedmessaging.app. Je crée la clé API sur https://app.unlimitedmessaging.app.

Demande-moi quelle table et quel texte de message utiliser avant d'écrire le code.

Les options

Quelle solution pour envoyer des messages depuis Supabase ?

Quatre façons d'envoyer une notification quand une ligne arrive dans votre base, du service intégré à une seule API pour tous les canaux.

Quelle solution pour envoyer des messages depuis Supabase ?
Email intégré SupabaseEmails d'Auth uniquementResend depuis une fonctionAPI emailTwilio depuis une fonctionAPI SMS et WhatsAppUnlimited MessagingEmail, WhatsApp et SMS
CanauxEmails d'Auth uniquementEmailSMS et WhatsApp, facturés au messageEmail, WhatsApp et SMS en une requête
Gratuit2 emails par heure, adresses de l'équipe uniquement3 000 emails par mois, 100 par jourEssai : 5 numéros vérifiés au maximumPlan Free sans frais par message
ExpéditeurL'adresse de SupabaseVotre domaine vérifiéUn numéro Twilio ou un expéditeur WhatsApp enregistréVotre boîte mail, votre numéro WhatsApp et votre téléphone
Messages WhatsAppNonNonModèles approuvés par Meta pour ouvrir une conversationTexte libre depuis votre numéro lié
Mise en placeAucuneEnregistrements DNS de votre domaineCompte, numéro, enregistrement de l'expéditeur WhatsAppQR code, identifiants IMAP/SMTP, application Android
Idéal pourTester les flux d'AuthL'email en gros volumeLe SMS en volume, le WhatsApp officielLes messages d'une app un par un, gratuit pendant la croissance

Vérifié le 9 novembre 2026 sur supabase.com, resend.com/pricing et la documentation d'essai de Twilio (liens dans les sources). Les offres gratuites changent : suivez les liens avant de construire dessus.

Les contreparties

Quelles sont les limites ?

Gratuit supprime la facture au message. Pas les règles de WhatsApp, de votre téléphone ou de votre boîte mail.

  1. WhatsApp est non officiel, et le spam fait bannir les numéros

    Votre numéro est lié comme un appareil, hors de la plateforme Business de Meta. Écrire à des clients inscrits qui attendent le message est peu risqué ; des envois en masse à des inconnus peuvent faire bannir le numéro. Gardez WhatsApp pour le transactionnel.

  2. Le SMS demande un téléphone Android allumé

    Les SMS partent de la SIM du téléphone, sur votre forfait. Android demande une confirmation au-delà de 30 SMS en 30 minutes, l'application espace donc les envois à environ 30 toutes les 30 minutes : parfait pour des inscriptions et des commandes, pas pour un envoi massif le jour du lancement.

  3. L'email suit les limites de votre boîte mail

    Les emails partent de votre boîte en SMTP, son plafond quotidien s'applique donc : 500 par jour sur un compte Gmail. Pour une newsletter à des milliers de personnes, prenez un service d'emailing.

  4. Les messages du plan Free portent une signature

    Sur le plan Free, les messages se terminent par une courte ligne "Sent with UnlimitedMessaging.app", et les médias et les webhooks sont payants. Medium et Max retirent la ligne.

  5. L'insert n'attend pas le message

    pg_net envoie la requête de façon asynchrone : une fonction en erreur n'annule jamais l'insert. Journalisez la réponse de l'API dans la fonction et surveillez ses logs.

  6. La clé reste côté serveur

    Quiconque ouvre votre bundle frontend peut réutiliser une clé qui s'y trouve. La clé va dans les secrets de l'Edge Function, et le secret du webhook empêche les inconnus d'appeler votre fonction.

FAQ

Questions sur l'envoi de messages depuis Supabase

Ilian, ingénieur logiciel senior

Écrit par

· Senior Software Engineer

Ingénieur logiciel senior, il fonde et dirige plusieurs sociétés tech. Il conçoit des produits autour des API de messagerie, de l’automatisation et de l’intégration de l’IA, et partage ici ce qu’il apprend en construisant.

Voir le profil LinkedInMis à jour le

Envoyez votre première notification Supabase aujourd'hui.

Créez un compte gratuit, connectez une boîte mail ou un numéro WhatsApp, collez la fonction. Sans carte bancaire, sans frais par message.