/** * Email Gate — form handling, n8n webhook, retry logic, fallback */ (function () { 'use strict'; var App = window.BenchmarkApp; var N8N_WEBHOOK_URL = 'https://n8n.netpeak.net/webhook/amazon-benchmark'; var WEBHOOK_TOKEN = 'nptk-bench-2026-a7f3x'; var PENDING_KEY = 'benchmark_pending_submission'; function isValidEmail(email) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); } function delay(ms) { return new Promise(function (resolve) { setTimeout(resolve, ms); }); } function postToWebhook(payload) { return fetch(N8N_WEBHOOK_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + WEBHOOK_TOKEN }, body: JSON.stringify(payload) }).then(function (res) { if (!res.ok) throw new Error('HTTP ' + res.status); return res.json(); }); } /** * Submit email with retry logic (3 attempts: immediate, +2s, +4s). * @returns {Promise} top_companies data or null on failure */ App.submitEmail = function (email, params, scoring, recommendations, variant) { var payload = { email: email, company: params.companyRaw, industry: params.industry, revenue: params.revenue, budget: params.budget, asins: params.asins, growth: params.growth, tier: scoring.subTier, tier_letter: scoring.tier, weighted_score: scoring.weightedScore, ab_variant: variant, recommendations: {}, timestamp: new Date().toISOString() }; var leverNames = ['ppc', 'listing', 'seo', 'account']; for (var i = 0; i < leverNames.length; i++) { var name = leverNames[i]; payload.recommendations[name] = { score: recommendations[name].score, priority: recommendations[name].priority }; } var delays = [0, 2000, 4000]; function attempt(index) { return postToWebhook(payload).then(function (data) { if (data && data.success) return data; throw new Error('Unsuccessful response'); }).catch(function (err) { if (index < delays.length - 1) { return delay(delays[index + 1]).then(function () { return attempt(index + 1); }); } throw err; }); } return attempt(0).catch(function () { // Level 2 fallback: save to localStorage try { localStorage.setItem(PENDING_KEY, JSON.stringify({ payload: payload, timestamp: Date.now() })); } catch (e) {} App.trackEvent('benchmark_fallback_triggered', { reason: 'webhook_failed' }); return null; }); }; /** * Check and retry any pending submission from localStorage. */ App.retryPendingSubmission = function () { try { var raw = localStorage.getItem(PENDING_KEY); if (!raw) return; var pending = JSON.parse(raw); // Only retry if less than 24 hours old if (Date.now() - pending.timestamp > 86400000) { localStorage.removeItem(PENDING_KEY); return; } postToWebhook(pending.payload).then(function (data) { if (data && data.success) { localStorage.removeItem(PENDING_KEY); } }).catch(function () { // Silent fail — will retry next visit }); } catch (e) {} }; /** * Check if honeypot was filled (bot detection). */ App.isBot = function (formEl) { var honeypot = formEl.querySelector('input[name="website"]'); return honeypot && honeypot.value.length > 0; }; })();