Ressource gratuite
Ton CRM, tes séquences automatisées et ton tracking, hébergés chez toi, pour une fraction du prix des plateformes classiques.
L'envoi
L'API qui envoie tes emails et te renvoie les ouvertures et les clics par webhook.
Choisis bien l'offre transactionnelle et non l'offre marketing : la marketing te facture au nombre de contacts stockés, ce qui revient beaucoup plus cher.
Créer un compte ResendLe CRM
La base de données qui stocke tes contacts, tes tags et tes séquences, et le cron qui déclenche les envois.
Une étape à faire une seule fois, avant ton premier envoi.
Utilise les flèches pour les parcourir une par une
Tu vas me construire un système d'email marketing complet et auto-hébergé, basé sur Supabase (base de données + Edge Functions + cron) et Resend. RÈGLE FONDATRICE On utilise Resend en mode TRANSACTIONNEL uniquement, jamais leur offre marketing. Je paye au volume d'emails envoyés, et je gère mon CRM moi-même dans Supabase. Ne me propose jamais de stocker mes contacts chez Resend. Avant de coder, pose-moi les questions nécessaires : mon domaine d'envoi, mon nom d'expéditeur, et la ou les séquences que je veux mettre en place. === 1. LE CRM === - Table `contacts` : email, prénom, date d'inscription, source du consentement, date de désinscription, et un `one_click_token` (uuid). ANTI-DOUBLON en deux couches : un CHECK (email = lower(email)) sur la colonne ET un index unique sur lower(email). Sinon « Pierre@ » et « pierre@ » créent deux contacts et la personne reçoit tout en double. Le token « un clic » permet de s'inscrire à un événement ou de se désinscrire depuis un email, sans formulaire ni login. Il ne donne accès qu'à cette action précise, jamais à la lecture de données, et n'expire jamais (sinon les vieux emails cassent). - Tables `tags` + liaison contacts/tags, pour savoir d'où vient chaque personne et construire des audiences. - Table `leads` : une ligne par capture, avec les UTM complets (utm_source, utm_medium, utm_campaign, utm_content, fbclid, landing_url), la date de capture et la date d'achat. - Table `emails_planifies` : contact, type d'email, date d'envoi prévue, statut (PENDING / SENT / FAILED / SKIPPED), compteur de tentatives, l'identifiant retourné par Resend, et deux colonnes opened_at / clicked_at. === 2. LES SÉQUENCES === Une fonction qui récupère les emails à envoyer, et une Edge Function appelée par un cron chaque minute. ANTI DOUBLE-ENVOI : la récupération doit utiliser FOR UPDATE SKIP LOCKED avec un compteur de tentatives plafonné à 3. Sans ça, deux exécutions qui se chevauchent envoient deux fois le même email. CONDITIONS DE SORTIE : avant chaque envoi, vérifier si la personne s'est désinscrite, si elle a acheté entre-temps (ne jamais envoyer une relance « dernière chance » à quelqu'un qui vient de payer), et si la fenêtre d'envoi est dépassée. Si oui, statut SKIPPED. ENVOI PAR VAGUES : prévoir un délai d'environ 600 ms entre chaque envoi (Resend limite à 2 requêtes par seconde) et traiter par lots de 50. Un échec d'envoi ne doit jamais faire planter le reste du lot. === 3. LE TRACKING === Une Edge Function qui reçoit les webhooks Resend (email.opened et email.clicked) et met à jour l'email correspondant via l'identifiant Resend. DEUX RÈGLES IMPORTANTES : - Garder le PREMIER timestamp, ne jamais écraser une valeur déjà posée (sinon on mesure la dernière relecture, pas la première ouverture). - Si un clic arrive sans ouverture enregistrée, poser AUSSI l'ouverture. Les bloqueurs d'images masquent le pixel et sous-estiment les taux. Propager les UTM du lead jusqu'aux metadata de l'abonnement Stripe au moment de l'achat, pour calculer un vrai ROAS par campagne. Crée aussi une vue qui agrège tout par contact : ses tunnels d'origine, ses emails envoyés / ouverts / cliqués, et sa conversion. === 4. LES EMAILS === Des templates HTML simples et responsives, avec un lien de désinscription dans chaque email. L'expéditeur doit être sur un domaine vérifié dans Resend, idéalement un sous-domaine dédié pour ne pas pénaliser la réputation du domaine principal. === 5. LA FINITION === Un .env.example avec toutes les variables, et un README expliquant comment vérifier le domaine dans Resend, créer le webhook et poser les secrets. Procède étape par étape. Après chaque partie, montre-moi ce que tu as fait et attends ma validation avant de continuer.
Rejoins ma newsletter personnelle et reçois toutes mes ressources, actuelles et futures. Un email par semaine, une ressource par semaine.
Rejoindre la newsletter