EmailVerify LogoEmailVerify

Jotform

Email checker for Jotform. Verify emails in Jotform submissions and workflows.

Integreer EmailVerify met JotForm om e-mailadressen in realtime te verifiëren en kwalitatieve formulierinzendingen te garanderen.

Integratiemethoden

MethodeBeste voorComplexiteit
WebhookServer-side verificatieLaag
WidgetRealtime validatieGemiddeld
ZapierNo-code automatiseringLaag

Methode 1: Webhook-integratie

Stel een webhook in om e-mails te verifiëren wanneer formulieren worden ingediend.

JotForm Webhook configureren

  1. Open uw formulier in JotForm
  2. Ga naar SettingsIntegrations
  3. Zoek naar WebHooks
  4. Voeg uw webhook URL toe: https://uwsite.com/api/jotform/webhook

Webhook Handler

// pages/api/jotform/webhook.js
import EmailVerify from '@emailverify/sdk';

const bv = new EmailVerify(process.env.EMAILVERIFY_API_KEY);

export default async function handler(req, res) {
    if (req.method !== 'POST') {
        return res.status(405).json({ error: 'Method not allowed' });
    }

    // JotForm sends data as form-urlencoded
    const { rawRequest, formID, submissionID } = req.body;

    // Parse the raw request
    const formData = JSON.parse(rawRequest || '{}');

    // Find email field
    const email = findEmailField(formData);

    if (!email) {
        return res.status(200).json({ message: 'No email field found' });
    }

    // Verify email
    const result = await bv.verify({ email });

    // Process result
    await processVerification({
        formId: formID,
        submissionId: submissionID,
        email,
        verification: result,
    });

    res.status(200).json({ success: true });
}

function findEmailField(formData) {
    // JotForm field names are like q3_email, q5_yourEmail, etc.
    for (const [key, value] of Object.entries(formData)) {
        if (typeof value === 'string' && value.includes('@')) {
            // Basic email pattern check
            if (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
                return value;
            }
        }
    }
    return null;
}

async function processVerification({ formId, submissionId, email, verification }) {
    // Store result in your database
    await storeResult({
        formId,
        submissionId,
        email,
        status: verification.status,
        score: verification.score,
        isDisposable: verification.is_disposable,
        verifiedAt: new Date().toISOString(),
    });

    // Handle invalid emails
    if (verification.status === 'invalid' || verification.is_disposable) {
        await handleInvalidEmail({
            formId,
            submissionId,
            email,
            reason: verification.status === 'invalid'
                ? 'Invalid email address'
                : 'Disposable email detected',
        });
    }
}

async function handleInvalidEmail({ formId, submissionId, email, reason }) {
    // Option 1: Send notification
    await sendNotification({
        type: 'invalid_email',
        formId,
        submissionId,
        email,
        reason,
    });

    // Option 2: Update JotForm submission (mark as spam)
    await updateSubmission(submissionId, {
        flag: 'spam',
        note: `Email verification failed: ${reason}`,
    });
}

JotForm-inzending bijwerken

Gebruik de JotForm API om inzendingen te markeren of bij te werken:

async function updateSubmission(submissionId, updates) {
    const response = await fetch(
        `https://api.jotform.com/submission/${submissionId}?apiKey=${process.env.JOTFORM_API_KEY}`,
        {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: new URLSearchParams({
                'submission[flag]': updates.flag || '0',
                'submission[new]': '0',
            }),
        }
    );

    return response.json();
}

Methode 2: Aangepaste widget

Maak een aangepaste JotForm-widget voor realtime e-mailvalidatie.

Widget-code

<!-- widget.html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>E-mailverificatie Widget</title>
    <link href="https://cdn.jotfor.ms/stylebuilder/static/form-common.css" rel="stylesheet">
    <style>
        .widget-container {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
        }

        .email-input {
            width: 100%;
            padding: 10px;
            font-size: 14px;
            border: 1px solid #ccc;
            border-radius: 4px;
            box-sizing: border-box;
        }

        .email-input:focus {
            outline: none;
            border-color: #4a90d9;
        }

        .email-input.valid {
            border-color: #28a745;
        }

        .email-input.invalid {
            border-color: #dc3545;
        }

        .status-message {
            margin-top: 5px;
            font-size: 12px;
        }

        .status-message.verifying {
            color: #666;
        }

        .status-message.valid {
            color: #28a745;
        }

        .status-message.invalid {
            color: #dc3545;
        }

        .loader {
            display: inline-block;
            width: 12px;
            height: 12px;
            border: 2px solid #ccc;
            border-top-color: #666;
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }

        @keyframes spin {
            to { transform: rotate(360deg); }
        }
    </style>
</head>
<body>
    <div class="widget-container">
        <input
            type="email"
            id="email"
            class="email-input"
            placeholder="Voer uw e-mail in"
        />
        <div id="status" class="status-message"></div>
    </div>

    <script src="https://cdn.jotfor.ms/static/prototype.forms.js"></script>
    <script src="https://cdn.jotfor.ms/static/jotform.forms.js"></script>
    <script>
        var JFCustomWidget = {
            subscribe: function(event, callback) {
                if (event === 'ready') {
                    callback();
                }
            }
        };

        // Configuration from widget settings
        var widgetConfig = {};

        JFCustomWidget.subscribe('ready', function() {
            // Get widget settings
            var settings = JFCustomWidget.getWidgetSettings();
            widgetConfig.apiEndpoint = settings.apiEndpoint || '/api/verify-email';
            widgetConfig.blockDisposable = settings.blockDisposable !== 'false';

            initWidget();
        });

        function initWidget() {
            var emailInput = document.getElementById('email');
            var statusEl = document.getElementById('status');
            var verifyTimeout;
            var isValid = false;

            emailInput.addEventListener('blur', function() {
                var email = this.value.trim();

                if (!email) {
                    clearStatus();
                    return;
                }

                if (!isValidFormat(email)) {
                    showStatus('invalid', 'Voer een geldig e-mailformaat in');
                    return;
                }

                clearTimeout(verifyTimeout);
                verifyTimeout = setTimeout(function() {
                    verifyEmail(email);
                }, 300);
            });

            function verifyEmail(email) {
                showStatus('verifying', '<span class="loader"></span> Verifiëren...');

                fetch(widgetConfig.apiEndpoint, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ email: email })
                })
                .then(function(response) { return response.json(); })
                .then(function(result) {
                    if (result.status === 'valid' && !result.disposable) {
                        showStatus('valid', '✓ E-mail geverifieerd');
                        isValid = true;
                    } else if (result.status === 'invalid') {
                        showStatus('invalid', '✗ Voer een geldig e-mailadres in');
                        isValid = false;
                    } else if (result.disposable && widgetConfig.blockDisposable) {
                        showStatus('invalid', '✗ Gebruik een permanent e-mailadres');
                        isValid = false;
                    } else {
                        showStatus('valid', '✓ E-mail geverifieerd');
                        isValid = true;
                    }

                    // Send value to JotForm
                    JFCustomWidget.sendData({
                        value: email,
                        valid: isValid
                    });
                })
                .catch(function(error) {
                    console.error('Verification error:', error);
                    // Allow on error
                    isValid = true;
                    clearStatus();
                    JFCustomWidget.sendData({ value: email, valid: true });
                });
            }

            function showStatus(type, message) {
                statusEl.innerHTML = message;
                statusEl.className = 'status-message ' + type;
                emailInput.className = 'email-input ' + (type === 'verifying' ? '' : type);
            }

            function clearStatus() {
                statusEl.innerHTML = '';
                statusEl.className = 'status-message';
                emailInput.className = 'email-input';
            }

            function isValidFormat(email) {
                return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
            }
        }
    </script>
</body>
</html>

Widget hosten en registreren

  1. Host de widget HTML op uw server
  2. Ga in JotForm naar Form BuilderAdd Form ElementWidgets
  3. Zoek naar uw widget of gebruik "Custom HTML"
  4. Configureer de widget URL

Methode 3: Zapier-integratie

Verbind JotForm met EmailVerify via Zapier.

Zap-setup

Stap 1: Trigger

  • App: JotForm
  • Event: New Submission

Stap 2: E-mail verifiëren

  • App: Webhooks by Zapier
  • Event: POST
  • Configuratie:
    URL: https://api.emailverify.ai/v1/verify
    Headers:
      Authorization: Bearer YOUR_API_KEY
      Content-Type: application/json
    Data:
      {"email": "{{email_field}}"}

Stap 3: Filter

  • Alleen doorgaan als: {{status}} is niet gelijk aan valid

Stap 4: Actie (voor ongeldige e-mails)

  • App: Gmail
  • Event: Send Email
  • Configuratie:
    To: admin@uwbedrijf.com
    Subject: Ongeldige e-mailinzending - JotForm
    Body: E-mail {{email}} is niet geverifieerd. Status: {{status}}

JotForm API-integratie

Voor geavanceerde workflows, gebruik de JotForm API rechtstreeks.

Inzendingen ophalen en verifiëren

// services/jotform.js
import EmailVerify from '@emailverify/sdk';

const bv = new EmailVerify(process.env.EMAILVERIFY_API_KEY);
const jotformApiKey = process.env.JOTFORM_API_KEY;

class JotFormService {
    async getFormSubmissions(formId, options = {}) {
        const params = new URLSearchParams({
            apiKey: jotformApiKey,
            limit: options.limit || 100,
            offset: options.offset || 0,
            filter: JSON.stringify(options.filter || {}),
        });

        const response = await fetch(
            `https://api.jotform.com/form/${formId}/submissions?${params}`
        );

        const data = await response.json();
        return data.content;
    }

    async verifySubmissions(formId) {
        const submissions = await this.getFormSubmissions(formId, {
            filter: { 'status:ne': 'DELETED' }
        });

        const results = [];

        for (const submission of submissions) {
            const email = this.findEmailInSubmission(submission);

            if (!email) continue;

            const verification = await bv.verify({ email });

            results.push({
                submissionId: submission.id,
                email,
                status: verification.status,
                score: verification.score,
                isDisposable: verification.is_disposable,
            });

            // Update submission with verification result
            if (verification.status === 'invalid' || verification.is_disposable) {
                await this.flagSubmission(submission.id);
            }
        }

        return results;
    }

    findEmailInSubmission(submission) {
        const answers = submission.answers || {};

        for (const [questionId, answer] of Object.entries(answers)) {
            if (answer.type === 'control_email') {
                return answer.answer;
            }

            // Also check text fields that might contain email
            if (answer.answer && typeof answer.answer === 'string') {
                if (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(answer.answer)) {
                    return answer.answer;
                }
            }
        }

        return null;
    }

    async flagSubmission(submissionId) {
        const response = await fetch(
            `https://api.jotform.com/submission/${submissionId}?apiKey=${jotformApiKey}`,
            {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: new URLSearchParams({
                    'submission[flag]': '1',
                }),
            }
        );

        return response.json();
    }

    async addSubmissionNote(submissionId, note) {
        // JotForm doesn't have a direct note API, but you can update custom fields
        // or use a separate tracking system
    }
}

export const jotformService = new JotFormService();

Gebruik

import { jotformService } from './services/jotform';

// Verify all submissions for a form
async function verifyFormSubmissions(formId) {
    const results = await jotformService.verifySubmissions(formId);

    const stats = {
        total: results.length,
        valid: results.filter(r => r.status === 'valid' && !r.isDisposable).length,
        invalid: results.filter(r => r.status === 'invalid').length,
        disposable: results.filter(r => r.isDisposable).length,
    };

    console.log('Verification Results:', stats);

    return results;
}

Conditional Logic-integratie

Gebruik verificatieresultaten om formuliergedrag te sturen.

Pre-submit validatie

// Embed this in your form page
<script>
document.addEventListener('DOMContentLoaded', function() {
    const form = document.querySelector('form[id^="form_"]');
    const emailField = document.querySelector('input[type="email"]');

    let emailVerified = false;
    let verificationResult = null;

    // Verify on blur
    emailField.addEventListener('blur', async function() {
        const email = this.value;

        if (!email) return;

        try {
            const response = await fetch('/api/verify-email', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ email }),
            });

            verificationResult = await response.json();
            emailVerified = verificationResult.status === 'valid' &&
                           !verificationResult.disposable;

            updateFieldUI(emailField, verificationResult);
        } catch (error) {
            // Allow on error
            emailVerified = true;
        }
    });

    // Validate on submit
    form.addEventListener('submit', function(e) {
        if (!emailVerified) {
            e.preventDefault();

            alert('Voer een geldig e-mailadres in om door te gaan.');
            emailField.focus();
            return false;
        }
    });

    function updateFieldUI(field, result) {
        // Remove existing classes
        field.classList.remove('valid', 'invalid');

        // Find or create status element
        let statusEl = field.parentNode.querySelector('.email-status');
        if (!statusEl) {
            statusEl = document.createElement('span');
            statusEl.className = 'email-status';
            field.parentNode.appendChild(statusEl);
        }

        if (result.status === 'valid' && !result.disposable) {
            field.classList.add('valid');
            statusEl.textContent = '✓ E-mail geverifieerd';
            statusEl.style.color = '#28a745';
        } else {
            field.classList.add('invalid');
            statusEl.textContent = result.disposable
                ? '✗ Gebruik een permanent e-mailadres'
                : '✗ Voer een geldig e-mailadres in';
            statusEl.style.color = '#dc3545';
        }
    }
});
</script>

Bulk-verificatie voor bestaande data

Verwerk historische inzendingen:

async function bulkVerifyJotFormData(formId) {
    console.log('Starting bulk verification...');

    // Get all submissions
    const allSubmissions = [];
    let offset = 0;
    const limit = 100;

    while (true) {
        const submissions = await jotformService.getFormSubmissions(formId, {
            limit,
            offset,
        });

        if (submissions.length === 0) break;

        allSubmissions.push(...submissions);
        offset += limit;

        console.log(`Fetched ${allSubmissions.length} submissions...`);
    }

    console.log(`Total submissions: ${allSubmissions.length}`);

    // Extract emails
    const emailMap = new Map();
    for (const submission of allSubmissions) {
        const email = jotformService.findEmailInSubmission(submission);
        if (email) {
            emailMap.set(submission.id, email);
        }
    }

    console.log(`Found ${emailMap.size} emails to verify`);

    // Bulk verify
    const emails = [...emailMap.values()];
    const job = await bv.verifyBulk(emails);

    console.log(`Job ID: ${job.job_id}`);

    // Wait for completion
    let status;
    do {
        await sleep(5000);
        status = await bv.getBulkJobStatus(job.job_id);
        console.log(`Progress: ${status.progress_percent}%`);
    } while (status.status !== 'completed');

    // Get results
    const results = await bv.getBulkJobResults(job.job_id);

    // Process results
    const stats = { valid: 0, invalid: 0, disposable: 0 };

    for (const result of results.results) {
        if (result.status === 'valid') stats.valid++;
        else stats.invalid++;
        if (result.is_disposable) stats.disposable++;

        // Find and flag invalid submissions
        if (result.status === 'invalid' || result.is_disposable) {
            for (const [submissionId, email] of emailMap.entries()) {
                if (email === result.email) {
                    await jotformService.flagSubmission(submissionId);
                    break;
                }
            }
        }
    }

    console.log('Verification complete:', stats);
    return stats;
}

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

Best practices

1. Behandel API-fouten graceful

try {
    const result = await verifyEmail(email);
    // Process result
} catch (error) {
    console.error('Verification failed:', error);
    // Don't block submission on API errors
    return { valid: true };
}

2. Cache resultaten

const cache = new Map();
const CACHE_TTL = 24 * 60 * 60 * 1000; // 24 hours

async function verifyWithCache(email) {
    const cached = cache.get(email);
    if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
        return cached.result;
    }

    const result = await bv.verify({ email });
    cache.set(email, { result, timestamp: Date.now() });

    return result;
}

3. Rate limiting voor webhooks

const rateLimiter = new Map();

function checkRateLimit(ip, limit = 10, windowMs = 60000) {
    const now = Date.now();
    const requests = rateLimiter.get(ip) || [];

    // Remove old requests
    const recent = requests.filter(time => now - time < windowMs);

    if (recent.length >= limit) {
        return false;
    }

    recent.push(now);
    rateLimiter.set(ip, recent);

    return true;
}

Gerelateerde bronnen

On this page