Flux complet du double opt-in : 1. User soumet le formulaire → contact créé en HubSpot avec sa référence 2. HubSpot envoie un email 'Confirmez votre inscription' 3. User clique 'Confirmer' → HubSpot le marque 'subscribed' 4. HubSpot redirige vers confirmation.html?email=... 5. La page lit l'email, appelle le Worker Cloudflare pour récupérer la référence du contact, et déclenche l'envoi de l'email de bienvenue via EmailJS (avec la référence dedans) 6. Affiche succès + référence à l'écran Idempotence via localStorage pour éviter de spammer l'email à chaque rechargement de la page. À configurer dans HubSpot Settings > Marketing > Email > Confirmation d'inscription : URL de redirection après confirmation = https://mva-global-fret.github.io/site-mva-global-fret/confirmation.html?email={{contact.email}} Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
111 lines
3.7 KiB
JavaScript
111 lines
3.7 KiB
JavaScript
// ============================================================
|
|
// MVA Global Fret — Page de confirmation post-double-opt-in
|
|
// ============================================================
|
|
// Cette page est la cible de redirection après que l'utilisateur
|
|
// a cliqué sur "Confirmer" dans l'email de validation HubSpot.
|
|
//
|
|
// HubSpot redirige vers :
|
|
// https://mva-global-fret.github.io/site-mva-global-fret/confirmation.html?email={contact.email}
|
|
//
|
|
// Étapes :
|
|
// 1. Lire l'email depuis l'URL
|
|
// 2. Demander au Cloudflare Worker la fiche du contact (incluant reference_client)
|
|
// 3. Envoyer un email de bienvenue via EmailJS contenant la référence
|
|
// 4. Afficher la référence à l'écran
|
|
//
|
|
// Si une étape échoue, on affiche un fallback poli (l'inscription
|
|
// reste valide côté HubSpot, c'est juste l'email qui ne part pas).
|
|
// ============================================================
|
|
|
|
const WORKER_PROXY_URL = 'https://mva-hubspot-proxy.mvaglobalfret.workers.dev';
|
|
const EMAILJS_PUBLIC_KEY = '8KUlaQ7BDVIbkZRyP';
|
|
const EMAILJS_SERVICE_ID = 'service_aeamo3x';
|
|
const EMAILJS_TEMPLATE_ID = 'template_s1kr2et';
|
|
|
|
// Marqueur localStorage : empêche de relancer l'envoi si l'utilisateur
|
|
// recharge la page après confirmation (par sécurité ET pour ne pas
|
|
// renvoyer 3 fois le même email).
|
|
const STORAGE_KEY_PREFIX = 'mva-confirm-sent-';
|
|
|
|
document.addEventListener('DOMContentLoaded', async () => {
|
|
if (typeof emailjs !== 'undefined') {
|
|
emailjs.init({ publicKey: EMAILJS_PUBLIC_KEY });
|
|
}
|
|
|
|
const email = getEmailFromUrl();
|
|
|
|
if (!email) {
|
|
// Pas d'email dans l'URL : on affiche quand même un succès générique
|
|
// (l'utilisateur a bien confirmé puisqu'il atterrit ici depuis HubSpot)
|
|
showSuccess(null);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const contact = await fetchContact(email);
|
|
|
|
if (!contact) {
|
|
// Contact non trouvé via Worker — on affiche succès quand même
|
|
showSuccess(null);
|
|
return;
|
|
}
|
|
|
|
const ref = contact.reference_client || null;
|
|
|
|
// Idempotence : un seul email par confirmation
|
|
const storageKey = STORAGE_KEY_PREFIX + email.toLowerCase();
|
|
if (!localStorage.getItem(storageKey)) {
|
|
await sendWelcomeEmail({
|
|
firstname: contact.firstname || '',
|
|
email: email,
|
|
reference_client: ref || '',
|
|
});
|
|
localStorage.setItem(storageKey, String(Date.now()));
|
|
}
|
|
|
|
showSuccess(ref);
|
|
} catch (err) {
|
|
console.warn('[confirmation] flow failed:', err);
|
|
showError();
|
|
}
|
|
});
|
|
|
|
function getEmailFromUrl() {
|
|
const params = new URLSearchParams(window.location.search);
|
|
const raw = params.get('email');
|
|
if (!raw) return null;
|
|
const email = raw.trim().toLowerCase();
|
|
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email) ? email : null;
|
|
}
|
|
|
|
async function fetchContact(email) {
|
|
const res = await fetch(WORKER_PROXY_URL, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ email }),
|
|
});
|
|
if (!res.ok) throw new Error('Worker error: ' + res.status);
|
|
const data = await res.json();
|
|
if (!data.results || data.results.length === 0) return null;
|
|
return data.results[0].properties;
|
|
}
|
|
|
|
async function sendWelcomeEmail(payload) {
|
|
if (typeof emailjs === 'undefined') return;
|
|
await emailjs.send(EMAILJS_SERVICE_ID, EMAILJS_TEMPLATE_ID, payload);
|
|
}
|
|
|
|
function showSuccess(ref) {
|
|
document.getElementById('cardLoading').style.display = 'none';
|
|
document.getElementById('cardSuccess').style.display = '';
|
|
if (ref) {
|
|
document.getElementById('refDisplay').textContent = ref;
|
|
document.getElementById('refBlock').style.display = '';
|
|
}
|
|
}
|
|
|
|
function showError() {
|
|
document.getElementById('cardLoading').style.display = 'none';
|
|
document.getElementById('cardError').style.display = '';
|
|
}
|