Validate Emails

The script validates email addresses in your NocoDB database, ensuring they conform to standard email formatting rules. It scans through specified email fields and generates a report of all records with invalid email addresses, helping you maintain data quality and improve communication deliverability.

let settings = input.config({
    title: "Validate emails",
    description: "This script will list all invalid emails for a field you pick.",
    items: [
        input.config.table("table", { label: "Table" }),
        input.config.field("field", {
            parentTable: "table",
            label: "Email field",
        }),
    ],
});

let { table, field } = settings as {
    table: Table,
    field: Field
};

let emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;

// Function to validate a single email
function validateEmail(email: string) {
    if (!email || typeof email !== 'string') {
        return { isValid: false, error: 'Empty or invalid data type' };
    }

    // Trim whitespace
    email = email.trim();

    if (email === '') {
        return { isValid: false, error: 'Empty after trimming whitespace' };
    }

    // Check length (email addresses shouldn't be longer than 254 characters)
    if (email.length > 254) {
        return { isValid: false, error: 'Email too long (>254 characters)' };
    }

    // Check for multiple @ symbols
    if ((email.match(/@/g) || []).length !== 1) {
        return { isValid: false, error: 'Invalid number of @ symbols' };
    }

    // Validate against regex
    if (!emailRegex.test(email)) {
        return { isValid: false, error: 'Invalid email format' };
    }

    // Check for consecutive dots
    if (email.includes('..')) {
        return { isValid: false, error: 'Consecutive dots not allowed' };
    }

    // Check if starts or ends with dot
    let [localPart, domain] = email.split('@');
    if (localPart.startsWith('.') || localPart.endsWith('.')) {
        return { isValid: false, error: 'Local part cannot start or end with dot' };
    }

    if (domain.startsWith('.') || domain.endsWith('.')) {
        return { isValid: false, error: 'Domain cannot start or end with dot' };
    }

    return { isValid: true, error: null };
}

// Function to handle multiple emails in one cell
function validateMultipleEmails(cellValue) {
    if (!cellValue || typeof cellValue !== 'string') {
        return [{ email: cellValue, isValid: false, error: 'Empty or invalid data type' }];
    }

    // Check if multiple emails are present (separated by common delimiters)
    let emails = [];
    let delimiters = /[,;|\n\r]/;

    if (delimiters.test(cellValue)) {
        // Multiple emails detected
        emails = cellValue.split(delimiters).map(email => email.trim()).filter(email => email !== '');
    } else {
        // Single email
        emails = [cellValue.trim()];
    }

    return emails.map(email => {
        let validation = validateEmail(email);
        return {
            email: email,
            isValid: validation.isValid,
            error: validation.error
        };
    });
}

// Fetch records from the selected table
let queryResult = await table.selectRecordsAsync({
    fields: [field],
});

// Handle pagination - load all records if there are more pages
while (queryResult.hasMoreRecords) {
    await queryResult.loadMoreRecords();
}

// Array to store validation results
let results = [];
let totalEmailsChecked = 0;
let totalInvalidEmails = 0;

// Process each record
for (let record of queryResult.records) {
    let recordName = record.name || record.id;
    let cellValue = record.getCellValue(field);

    // Validate emails in this cell
    let emailValidations = validateMultipleEmails(cellValue);

    for (let validation of emailValidations) {
        totalEmailsChecked++;

        if (!validation.isValid) {
            totalInvalidEmails++;
            results.push({
                Record: recordName,
                Email: validation.email || '(empty)',
                Error: validation.error,
                'Original Cell Value': cellValue || '(empty)'
            });
        }
    }
}

// Display results
if (results.length === 0) {
    output.text(
        `✅ All emails are valid! (${totalEmailsChecked} emails in ${queryResult.records.length} records validated)`
    );
} else {
    output.text(
        `❌ ${totalInvalidEmails} invalid emails found in ${results.length} entries. (${totalEmailsChecked} total emails in ${queryResult.records.length} records validated)`
    );

    // Group results by error type for better readability
    let errorGroups = {};
    for (let result of results) {
        if (!errorGroups[result.Error]) {
            errorGroups[result.Error] = [];
        }
        errorGroups[result.Error].push(result);
    }

    // Display grouped results
    for (let [errorType, items] of Object.entries(errorGroups)) {
        output.markdown(`\n**${errorType}** (${items.length} ${items.length === 1 ? 'email' : 'emails'}):`);
        output.table(items.map(item => ({
            Record: item.Record,
            Email: item.Email,
            'Original Cell Value': item['Original Cell Value']
        })));
    }
}

Use Cases

  • Data Quality Assurance: Ensure all email addresses in your database are properly formatted
  • Marketing Campaign Prep: Clean email lists before sending campaigns to improve deliverability
  • Contact Management: Identify and fix invalid email addresses in customer databases
  • Import Validation: Check imported data for email formatting issues
  • Compliance Auditing: Verify email data quality for regulatory compliance requirements

How it Works

  1. Select Email Field: Choose the email field you want to validate
  2. Run Validation: The script checks each email address against standard email format rules
  3. Generate Report: View a list of all records with invalid email addresses
  4. Review Results: Examine the invalid emails and their associated records

Requirements

  • An Email field or Text field containing email addresses
  • Records with email data to validate

Validation Rules

The script checks for common email format issues:

  • Missing @ symbol: userexample.com
  • Invalid domain format: user@domain
  • Multiple @ symbols: us@er@example.com
  • Invalid characters: user@exam<ple.com
  • Missing local part: @example.com
  • Missing domain: user@
  • Improper spacing: user @example.com

Example Output

Invalid Email Report:

Record ID | Email Address | Issue
----------|---------------|--------
123       | user.example.com | Missing @ symbol
145       | admin@domain | Invalid domain format
167       | test@@example.com | Multiple @ symbols
189       | contact@exam ple.com | Invalid spacing
201       | @example.com | Missing local part

Common Invalid Formats

Missing @ Symbol

❌ Invalid: johndoeexample.com
✅ Valid: johndoe@example.com

Incomplete Domain

❌ Invalid: admin@company
✅ Valid: admin@company.com

Extra Characters

❌ Invalid: user@exam<ple.com
✅ Valid: user@example.com

Spacing Issues

❌ Invalid: contact @example.com
✅ Valid: contact@example.com

Benefits

  • Data Quality: Maintain high-quality email data for better communication
  • Deliverability: Improve email campaign success rates by removing invalid addresses
  • Error Prevention: Catch email formatting issues before they cause problems
  • Compliance: Meet data quality standards for email marketing and communication
  • Efficiency: Quickly identify problematic emails across large datasets

Field Types

The email validation script works with:

  • Email fields: Purpose-built email fields in NocoDB
  • Text fields: Any text field containing email addresses
  • Single Line Text: Standard text fields with email content

Last updated on

Latest product updates?See Changelog
Stay in the loop? Follow us onLinkedInLinkedInYouTubeYouTubeXX