Architecture finale (Option A choisie) :
1. User submit form → contact créé en HubSpot avec reference_client
2. HubSpot envoie l'email de double opt-in (sans la ref ni l'adresse Paris)
3. User clique 'Confirmer' → HubSpot met hs_emailconfirmationstatus = CONFIRMED
4. Cron Cloudflare (toutes les 5 min) :
- Liste les contacts CONFIRMED + créés après le cutoff
- Filtre via Cloudflare KV (welcomed:<email>) pour idempotence
- Envoie le welcome email via EmailJS REST API avec :
• firstname
• reference_client
• paris_address (depuis env var PARIS_DEPOT_ADDRESS)
- Marque envoyé dans KV avec TTL 1 an
Protection :
- L'adresse du dépôt Paris ne quitte JAMAIS Cloudflare/EmailJS
- Elle n'arrive au client que dans le mail de bienvenue post-opt-in
- Bots qui n'ont pas un vrai email ne peuvent pas valider → ne reçoivent rien
- Anti-spam et anti-cartons-vides blindé
Ajout d'une action 'triggerWelcomeQueue' pour debug/manual run.
Doc complète dans cloudflare-worker/DEPLOIEMENT.md (étapes 1 à 6).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
8.2 KiB
Déploiement Cloudflare Worker — Welcome cron MVA
Ce Worker fait deux choses :
- Proxy HubSpot (déjà fonctionnel — vérification doublon + numéro de référence)
- Cron Welcome (NOUVEAU — envoie l'email de bienvenue après que le client a cliqué sur "Confirmer" dans le mail HubSpot de double opt-in)
L'email de bienvenue contient le numéro de référence client ET (à ajouter dans le template EmailJS) l'adresse du dépôt à Paris. Ces infos ne sont jamais envoyées avant validation de l'email — protection contre les bots et les expéditions de cartons vides.
Étapes de déploiement (10 min)
1. Mettre à jour le code du Worker
- Aller sur https://dash.cloudflare.com/
- Workers & Pages → cliquer sur
mva-hubspot-proxy - Onglet Modifier le code (ou Quick edit)
- Tout sélectionner et remplacer par le contenu de
cloudflare-worker/hubspot-proxy.js(de ce repo) - Cliquer Déployer / Save and deploy
2. Variables d'environnement
Dans Paramètres → Variables et secrets, ajouter (si pas déjà là) :
| Nom | Valeur |
|---|---|
HUBSPOT_TOKEN |
pat-eu1-... (existant — vérifier que le scope est read+write contacts) |
EMAILJS_PUBLIC_KEY |
8KUlaQ7BDVIbkZRyP |
EMAILJS_SERVICE_ID |
service_aeamo3x |
EMAILJS_TEMPLATE_ID |
template_s1kr2et |
PARIS_DEPOT_ADDRESS |
Ton adresse exacte à Paris (rue, code postal, ville, étage, nom à indiquer sur le carton…) |
⚠️ PARIS_DEPOT_ADDRESS est l'info la plus sensible — c'est l'adresse que tu veux protéger. Elle ne quitte jamais Cloudflare/EmailJS et n'arrive au client que dans le mail de bienvenue, qui n'est envoyé qu'aux contacts qui ont confirmé leur email.
Si une variable n'est pas définie, le Worker utilise le fallback hardcodé.
3. Stockage KV (idempotence — empêche de spammer le welcome)
Dans Paramètres → Stockage et bases de données → Bindings KV :
- Cliquer Ajouter un binding
- Variable name :
WELCOME_KV - Namespace : Créer un nouveau namespace nommé
mva-welcome-tracker - Sauvegarder
4. Cron Trigger — toutes les 5 minutes
Dans Paramètres → Déclencheurs (Triggers) → Cron Triggers :
- Cliquer Add Cron Trigger
- Schedule :
*/5 * * * * - Sauvegarder
5a. EmailJS — mettre à jour le template pour inclure l'adresse Paris
- Aller sur https://dashboard.emailjs.com/admin/templates
- Cliquer sur le template
template_s1kr2et - Modifier le contenu pour inclure les variables suivantes :
{{firstname}}— prénom du client{{reference_client}}— sa référence (ex :MVA-001){{paris_address}}— l'adresse complète du dépôt à Paris
- Exemple de corps d'email recommandé :
Bonjour {{firstname}},
Bienvenue chez MVA Global Fret ! Votre inscription est confirmée.
══════════════════════════════════════════════
VOTRE NUMÉRO DE RÉFÉRENCE CLIENT
{{reference_client}}
══════════════════════════════════════════════
Conservez précieusement ce numéro — il vous permet de suivre vos colis
et nous facilite la prise en charge.
📦 ADRESSE DU DÉPÔT À PARIS
{{paris_address}}
⚠️ Important : indiquez bien votre numéro de référence
({{reference_client}}) sur chaque colis que vous nous envoyez.
Cela nous permet de vous identifier rapidement.
Pour toute question, contactez-nous via Messenger ou par WhatsApp.
— L'équipe MVA Global Fret
+261 38 49 737 51
- Sauvegarder le template
5b. EmailJS — autoriser les appels serveur (CRITIQUE)
Sans cette étape, le Worker ne pourra pas envoyer les emails (erreur 403).
- Aller sur https://dashboard.emailjs.com/admin/account
- Onglet Security
- Décocher "Allow EmailJS API for non-browser applications"
- Le terme est trompeur : décocher autorise les appels serveur
- (Cocher = bloquer les appels serveur pour anti-spam)
- Sauvegarder
6. Vérifier le scope HubSpot
Le token HubSpot doit avoir :
- ✅
crm.objects.contacts.read - ✅
crm.objects.contacts.write(NOUVEAU — pour mettre à jour la propriété en cas de besoin) - ✅
crm.lists.read(déjà bon)
Si tu obtiens des erreurs 403, regénère le token sur https://app-eu1.hubspot.com/private-apps/148163754/
Test manuel
Une fois tout déployé, tu peux forcer une exécution du cron sans attendre 5 min :
curl -X POST https://mva-hubspot-proxy.mvaglobalfret.workers.dev \
-H "Content-Type: application/json" \
-d '{"action":"triggerWelcomeQueue"}'
Réponse attendue :
{ "ok": true, "stats": { "scanned": 3, "sent": 1, "skipped": 2, "errors": 0 } }
scanned: combien de contacts confirmés ont été inspectéssent: combien d'emails de bienvenue ont été envoyés cette fois-ciskipped: déjà envoyés précédemment (KV tracking)errors: envois qui ont échoué
Logs en production
Cloudflare → ton Worker → Logs (en temps réel) : tu verras chaque exécution cron avec les stats.
En cas de problème
| Symptôme | Cause probable | Fix |
|---|---|---|
EmailJS 403: API access disabled |
Étape 5 pas faite | Décocher "Allow API for non-browser" sur EmailJS |
HubSpot 403 |
Token n'a pas le scope write | Regénérer token avec scope contacts.write |
HubSpot 401 |
Token invalide / expiré | Regénérer un Private App token |
| Le cron ne tourne pas | Cron trigger pas activé | Vérifier Triggers → Cron Triggers |
KV: env.WELCOME_KV is undefined |
Binding pas créé | Vérifier Storage & Databases → KV bindings |
| Aucun email envoyé même après confirmation | Le filtre HubSpot ne matche pas | Inspecter dans Logs : voir si searchConfirmedContacts retourne des résultats |
Architecture finale
┌──────────────────────────────────────────────────────────────────┐
│ 1. User remplit le formulaire sur contact.html │
│ ↓ │
│ 2. form-handler.js soumet à HubSpot (Forms API) │
│ ↓ │
│ 3. HubSpot crée le contact AVEC reference_client │
│ ↓ │
│ 4. HubSpot envoie l'email de double opt-in (sujet + bouton │
│ « Confirmer » seulement — PAS la référence ni l'adresse) │
│ ↓ │
│ ─────── User clique sur « Confirmer » ─────── │
│ ↓ │
│ 5. HubSpot met à jour hs_emailconfirmationstatus = CONFIRMED │
│ ↓ │
│ 6. Cron Cloudflare (toutes les 5 min) : │
│ - cherche les contacts CONFIRMED non encore welcomed │
│ - vérifie KV : welcomed:{email} │
│ - envoie email via EmailJS REST API │
│ (template contient : prénom, ref, adresse Paris) │
│ - écrit welcomed:{email} dans KV │
│ ↓ │
│ 7. Le client reçoit son welcome email avec sa référence ET │
│ l'adresse de dépôt à Paris. │
└──────────────────────────────────────────────────────────────────┘
Conclusion : il est désormais impossible pour un bot de récupérer ta référence client ou ton adresse Paris sans avoir au préalable un email valide ET cliqué sur le lien de confirmation. Anti-spam blindé. ✅