Wykrywanie Catch-All Email: Przewodnik na 2025

Leo
LeoFounder, BillionVerify

Dowiedz się, jak wykrywać adresy e-mail typu catch-all. Poznaj algorytmy detekcji, strategie implementacji i praktyki obsługi domen accept-all w weryfikacji.

Cover Image for Wykrywanie Catch-All Email: Przewodnik na 2025

Podczas weryfikacji adresów e-mail jednym z najtrudniejszych scenariuszy, z jakimi się spotkasz, jest serwer e-mail typu catch-all. Te serwery akceptują pocztę dla dowolnego adresu w swojej domenie, co uniemożliwia określenie za pomocą standardowej weryfikacji SMTP, czy konkretna skrzynka pocztowa faktycznie istnieje. Zrozumienie wykrywania e-maili catch-all jest kluczowe dla każdego, kto poważnie podchodzi do utrzymania jakości listy e-mailowej i maksymalizacji wskaźników dostarczalności.

W tym kompleksowym przewodniku zbadamy wszystko, co musisz wiedzieć o e-mailach catch-all: czym są, dlaczego istnieją, jak je wykrywać i, co najważniejsze, jak je obsługiwać w procesie weryfikacji e-mail. Niezależnie od tego, czy jesteś programistą tworzącym system walidacji e-mail, czy marketerem próbującym wyczyścić swoją listę e-mailową, ten przewodnik dostarczy Ci wiedzy i narzędzi potrzebnych do skutecznego radzenia sobie z domenami catch-all.

Solidna strategia weryfikacji e-mail musi uwzględniać serwery catch-all. Bez odpowiedniego wykrywania i obsługi, wyniki weryfikacji mogą dać Ci fałszywe przekonanie o dostarczalności e-maili. Zanurzmy się w szczegóły techniczne i praktyczne rozwiązania.

Czym jest Serwer E-mail Catch-All?

Serwer e-mail typu catch-all, znany również jako serwer accept-all, jest skonfigurowany tak, aby akceptować przychodzące wiadomości e-mail dla dowolnego adresu w swojej domenie, niezależnie od tego, czy ta konkretna skrzynka pocztowa istnieje. Gdy wysyłasz e-mail na adres dowolnyadres@catchall-domena.com, serwer go akceptuje bez odrzucenia, nawet jeśli nie utworzono nigdy skrzynki o nazwie "dowolnyadres".

Jak Działa Konfiguracja Catch-All

W typowej konfiguracji serwera e-mail, gdy wiadomość przybywa dla nieistniejącej skrzynki pocztowej, serwer odpowiada komunikatem odrzucenia "550 User not found" lub podobnym. To zachowanie pozwala systemom weryfikacji e-mail określić, czy adres istnieje, sprawdzając odpowiedź serwera.

Serwery catch-all zachowują się inaczej. Są skonfigurowane tak, aby akceptować całą przychodzącą pocztę niezależnie od adresu odbiorcy. Poczta może być następnie:

  1. Kierowana do wyznaczonej skrzynki - Administrator otrzymuje wszystkie wiadomości
  2. Przechowywana w ogólnej kolejce - Wiadomości są zatrzymywane do późniejszego sortowania
  3. Cicho odrzucana - Akceptowana, ale usuwana bez dostarczenia
  4. Przekazywana do innego systemu - Wysyłana na inny serwer do przetworzenia

Oto przykład, jak wygląda to w konfiguracji serwera pocztowego Postfix:

# /etc/postfix/main.cf
# Standardowa konfiguracja - odrzuca nieznanych odbiorców
local_recipient_maps = proxy:unix:passwd.byname $alias_maps

# Konfiguracja catch-all - akceptuje wszystkich odbiorców
local_recipient_maps =

Dlaczego Organizacje Używają Serwerów Catch-All

Istnieje kilka uzasadnionych powodów, dla których organizacje konfigurują e-mail catch-all:

1. Zapobieganie Utracie Ważnej Komunikacji Biznesowej

Małe firmy często martwią się o utratę ważnych e-maili z powodu literówek lub odmian w nazwiskach pracowników. Jeśli ktoś wysyła e-mail na jan.kowalski@firma.com, ale faktycznym adresem jest jkowalski@firma.com, konfiguracja catch-all zapewnia, że wiadomość nie zostanie utracona.

2. Elastyczne Kierowanie E-maili

Niektóre organizacje używają catch-all jako części zaawansowanego systemu kierowania e-maili. Cała przychodząca poczta trafia do centralnej kolejki, gdzie jest automatycznie sortowana i dystrybuowana na podstawie reguł.

3. Monitorowanie Bezpieczeństwa

Zespoły bezpieczeństwa czasami konfigurują catch-all, aby monitorować, jakie adresy są celowane przez atakujących lub spamerów. Ta inteligencja pomaga identyfikować próby phishingu lub naruszenia danych.

4. Kompatybilność ze Starszymi Systemami

Organizacje migrujące z jednego systemu e-mail na inny mogą tymczasowo włączyć catch-all, aby zapewnić, że żadne wiadomości nie zostaną utracone podczas przejścia.

5. Ochrona Prywatności

Niektóre organizacje dbające o prywatność używają domen catch-all do tworzenia unikalnych adresów e-mail dla każdej usługi, na którą się rejestrują, co ułatwia śledzenie, które firmy udostępniają lub wyciekają ich dane.

Problem dla Weryfikacji E-mail

W celach weryfikacji e-mail serwery catch-all stanowią znaczące wyzwanie. Gdy przeprowadzasz weryfikację SMTP w domenie catch-all, serwer odpowiada akceptacją "250 OK" dla każdego testowanego adresu—czy jest prawdziwy, czy całkowicie wymyślony.

Rozważ ten przykład sesji SMTP:

> MAIL FROM:<test@verify.local>
< 250 OK
> RCPT TO:<prawdziwy.uzytkownik@catchall-domena.com>
< 250 OK
> RCPT TO:<calkowicie.falszywy.adres@catchall-domena.com>
< 250 OK
> RCPT TO:<asdfghjkl12345@catchall-domena.com>
< 250 OK

Wszystkie trzy adresy otrzymują tę samą pozytywną odpowiedź, co uniemożliwia odróżnienie prawdziwego użytkownika od fałszywych adresów wyłącznie poprzez weryfikację SMTP.

Jak Wykrywać Serwery E-mail Catch-All

Wykrywanie, czy serwer pocztowy jest skonfigurowany jako catch-all, wymaga sprytnego podejścia: testowania z adresem, który definitywnie nie powinien istnieć, i obserwowania odpowiedzi serwera.

Algorytm Detekcji

Podstawowy algorytm wykrywania catch-all działa następująco:

  1. Wygeneruj losowy, nieistniejący adres w domenie docelowej
  2. Przeprowadź weryfikację SMTP dla tego fałszywego adresu
  3. Przeanalizuj odpowiedź:
    • Jeśli serwer akceptuje fałszywy adres → Prawdopodobnie jest to catch-all
    • Jeśli serwer odrzuca fałszywy adres → Stosuje się normalna weryfikacja

Implementacja w Node.js

Oto kompletna implementacja wykrywania catch-all w Node.js:

const net = require('net');
const dns = require('dns').promises;
const crypto = require('crypto');

class CatchAllDetector {
  constructor(options = {}) {
    this.timeout = options.timeout || 10000;
    this.fromEmail = options.fromEmail || 'verify@verify.local';
    this.fromDomain = options.fromDomain || 'verify.local';
  }

  /**
   * Generate a random email address that definitely doesn't exist
   */
  generateRandomEmail(domain) {
    const randomString = crypto.randomBytes(16).toString('hex');
    const timestamp = Date.now();
    return `nonexistent-${randomString}-${timestamp}@${domain}`;
  }

  /**
   * Get the primary MX server for a domain
   */
  async getMXServer(domain) {
    try {
      const records = await dns.resolveMx(domain);
      if (!records || records.length === 0) {
        return null;
      }
      // Sort by priority and return the primary server
      records.sort((a, b) => a.priority - b.priority);
      return records[0].exchange;
    } catch (error) {
      return null;
    }
  }

  /**
   * Perform SMTP verification on an email address
   */
  async smtpVerify(email, mxServer) {
    return new Promise((resolve) => {
      const socket = new net.Socket();
      let step = 0;
      let result = { accepted: false, response: '' };

      const commands = [
        null, // Wait for greeting
        `EHLO ${this.fromDomain}\r\n`,
        `MAIL FROM:<${this.fromEmail}>\r\n`,
        `RCPT TO:<${email}>\r\n`,
        'QUIT\r\n'
      ];

      socket.setTimeout(this.timeout);

      socket.on('data', (data) => {
        const response = data.toString();
        const code = parseInt(response.substring(0, 3));

        if (step === 0 && code === 220) {
          socket.write(commands[1]);
          step++;
        } else if (step === 1 && code === 250) {
          socket.write(commands[2]);
          step++;
        } else if (step === 2 && code === 250) {
          socket.write(commands[3]);
          step++;
        } else if (step === 3) {
          result.response = response.trim();
          result.accepted = code === 250 || code === 251;
          socket.write(commands[4]);
          socket.destroy();
          resolve(result);
        } else if (code >= 400) {
          result.response = response.trim();
          result.accepted = false;
          socket.destroy();
          resolve(result);
        }
      });

      socket.on('timeout', () => {
        result.response = 'Connection timeout';
        socket.destroy();
        resolve(result);
      });

      socket.on('error', (error) => {
        result.response = `Error: ${error.message}`;
        socket.destroy();
        resolve(result);
      });

      socket.connect(25, mxServer);
    });
  }

  /**
   * Detect if a domain is configured as catch-all
   */
  async detectCatchAll(domain) {
    // Get MX server
    const mxServer = await this.getMXServer(domain);
    if (!mxServer) {
      return {
        isCatchAll: null,
        reason: 'Could not resolve MX records',
        domain
      };
    }

    // Generate a random non-existent email
    const fakeEmail = this.generateRandomEmail(domain);

    // Test the fake email
    const result = await this.smtpVerify(fakeEmail, mxServer);

    return {
      isCatchAll: result.accepted,
      reason: result.accepted
        ? 'Server accepts mail for non-existent addresses'
        : 'Server rejects non-existent addresses',
      domain,
      mxServer,
      testEmail: fakeEmail,
      serverResponse: result.response
    };
  }

  /**
   * Verify an email with catch-all detection
   */
  async verifyWithCatchAllDetection(email) {
    const domain = email.split('@')[1];

    // First, detect if domain is catch-all
    const catchAllResult = await this.detectCatchAll(domain);

    if (catchAllResult.isCatchAll === null) {
      return {
        email,
        valid: null,
        catchAll: null,
        reason: catchAllResult.reason
      };
    }

    // Get MX server
    const mxServer = await this.getMXServer(domain);

    // Verify the actual email
    const verifyResult = await this.smtpVerify(email, mxServer);

    return {
      email,
      valid: verifyResult.accepted,
      catchAll: catchAllResult.isCatchAll,
      reason: catchAllResult.isCatchAll
        ? 'Address accepted but domain is catch-all (deliverability uncertain)'
        : verifyResult.accepted
          ? 'Address verified successfully'
          : 'Address rejected by server',
      serverResponse: verifyResult.response
    };
  }
}

// Usage example
async function main() {
  const detector = new CatchAllDetector();

  // Test catch-all detection
  const domains = ['gmail.com', 'example.com', 'company.com'];

  for (const domain of domains) {
    console.log(`\nTesting domain: ${domain}`);
    const result = await detector.detectCatchAll(domain);
    console.log(`Is Catch-All: ${result.isCatchAll}`);
    console.log(`Reason: ${result.reason}`);
    if (result.serverResponse) {
      console.log(`Server Response: ${result.serverResponse}`);
    }
  }

  // Verify specific email with catch-all detection
  const emailResult = await detector.verifyWithCatchAllDetection('user@example.com');
  console.log('\nEmail Verification Result:');
  console.log(JSON.stringify(emailResult, null, 2));
}

main().catch(console.error);

Implementacja w Pythonie

Oto równoważna implementacja w Pythonie:

import socket
import dns.resolver
import secrets
import time
from dataclasses import dataclass
from typing import Optional

@dataclass
class CatchAllResult:
    is_catch_all: Optional[bool]
    reason: str
    domain: str
    mx_server: Optional[str] = None
    test_email: Optional[str] = None
    server_response: Optional[str] = None

@dataclass
class VerificationResult:
    email: str
    valid: Optional[bool]
    catch_all: Optional[bool]
    reason: str
    server_response: Optional[str] = None

class CatchAllDetector:
    def __init__(self, timeout: int = 10, from_email: str = 'verify@verify.local',
                 from_domain: str = 'verify.local'):
        self.timeout = timeout
        self.from_email = from_email
        self.from_domain = from_domain

    def generate_random_email(self, domain: str) -> str:
        """Generate a random email address that definitely doesn't exist."""
        random_string = secrets.token_hex(16)
        timestamp = int(time.time() * 1000)
        return f"nonexistent-{random_string}-{timestamp}@{domain}"

    def get_mx_server(self, domain: str) -> Optional[str]:
        """Get the primary MX server for a domain."""
        try:
            records = dns.resolver.resolve(domain, 'MX')
            mx_records = sorted(
                [(r.preference, str(r.exchange).rstrip('.')) for r in records],
                key=lambda x: x[0]
            )
            return mx_records[0][1] if mx_records else None
        except Exception:
            return None

    def smtp_verify(self, email: str, mx_server: str) -> dict:
        """Perform SMTP verification on an email address."""
        result = {'accepted': False, 'response': ''}

        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(self.timeout)
            sock.connect((mx_server, 25))

            # Receive greeting
            response = sock.recv(1024).decode()
            if not response.startswith('220'):
                result['response'] = response.strip()
                return result

            # Send EHLO
            sock.send(f'EHLO {self.from_domain}\r\n'.encode())
            response = sock.recv(1024).decode()
            if not response.startswith('250'):
                result['response'] = response.strip()
                return result

            # Send MAIL FROM
            sock.send(f'MAIL FROM:<{self.from_email}>\r\n'.encode())
            response = sock.recv(1024).decode()
            if not response.startswith('250'):
                result['response'] = response.strip()
                return result

            # Send RCPT TO
            sock.send(f'RCPT TO:<{email}>\r\n'.encode())
            response = sock.recv(1024).decode()
            result['response'] = response.strip()
            code = int(response[:3])
            result['accepted'] = code in (250, 251)

            # Send QUIT
            sock.send(b'QUIT\r\n')
            sock.close()

        except socket.timeout:
            result['response'] = 'Connection timeout'
        except socket.error as e:
            result['response'] = f'Socket error: {str(e)}'
        except Exception as e:
            result['response'] = f'Error: {str(e)}'

        return result

    def detect_catch_all(self, domain: str) -> CatchAllResult:
        """Detect if a domain is configured as catch-all."""
        # Get MX server
        mx_server = self.get_mx_server(domain)
        if not mx_server:
            return CatchAllResult(
                is_catch_all=None,
                reason='Could not resolve MX records',
                domain=domain
            )

        # Generate a random non-existent email
        fake_email = self.generate_random_email(domain)

        # Test the fake email
        result = self.smtp_verify(fake_email, mx_server)

        return CatchAllResult(
            is_catch_all=result['accepted'],
            reason='Server accepts mail for non-existent addresses' if result['accepted']
                   else 'Server rejects non-existent addresses',
            domain=domain,
            mx_server=mx_server,
            test_email=fake_email,
            server_response=result['response']
        )

    def verify_with_catch_all_detection(self, email: str) -> VerificationResult:
        """Verify an email with catch-all detection."""
        domain = email.split('@')[1]

        # First, detect if domain is catch-all
        catch_all_result = self.detect_catch_all(domain)

        if catch_all_result.is_catch_all is None:
            return VerificationResult(
                email=email,
                valid=None,
                catch_all=None,
                reason=catch_all_result.reason
            )

        # Get MX server
        mx_server = self.get_mx_server(domain)

        # Verify the actual email
        verify_result = self.smtp_verify(email, mx_server)

        if catch_all_result.is_catch_all:
            reason = 'Address accepted but domain is catch-all (deliverability uncertain)'
        elif verify_result['accepted']:
            reason = 'Address verified successfully'
        else:
            reason = 'Address rejected by server'

        return VerificationResult(
            email=email,
            valid=verify_result['accepted'],
            catch_all=catch_all_result.is_catch_all,
            reason=reason,
            server_response=verify_result['response']
        )


# Usage example
if __name__ == '__main__':
    detector = CatchAllDetector()

    # Test catch-all detection
    domains = ['gmail.com', 'example.com', 'company.com']

    for domain in domains:
        print(f"\nTesting domain: {domain}")
        result = detector.detect_catch_all(domain)
        print(f"Is Catch-All: {result.is_catch_all}")
        print(f"Reason: {result.reason}")
        if result.server_response:
            print(f"Server Response: {result.server_response}")

    # Verify specific email with catch-all detection
    email_result = detector.verify_with_catch_all_detection('user@example.com')
    print("\nEmail Verification Result:")
    print(f"  Email: {email_result.email}")
    print(f"  Valid: {email_result.valid}")
    print(f"  Catch-All: {email_result.catch_all}")
    print(f"  Reason: {email_result.reason}")

Zaawansowane Techniki Detekcji

Podstawowe wykrywanie catch-all można ulepszyć za pomocą tych zaawansowanych technik:

1. Testowanie Wieloma Próbami

Zamiast testować tylko jeden fałszywy adres, testuj wieloma losowo generowanymi adresami. Pomaga to zidentyfikować serwery o niespójnym zachowaniu:

async detectCatchAllAdvanced(domain, probeCount = 3) {
  const results = [];

  for (let i = 0; i < probeCount; i++) {
    const fakeEmail = this.generateRandomEmail(domain);
    const result = await this.smtpVerify(fakeEmail, await this.getMXServer(domain));
    results.push(result.accepted);

    // Small delay between probes to avoid rate limiting
    await new Promise(resolve => setTimeout(resolve, 500));
  }

  // Analyze results
  const acceptedCount = results.filter(r => r).length;

  if (acceptedCount === probeCount) {
    return { isCatchAll: true, confidence: 'high' };
  } else if (acceptedCount === 0) {
    return { isCatchAll: false, confidence: 'high' };
  } else {
    return { isCatchAll: null, confidence: 'low', note: 'Inconsistent server behavior' };
  }
}

2. Detekcja Oparta na Wzorcach

Niektóre serwery catch-all są skonfigurowane ze wzorcami. Testuj adresy w różnych formatach:

const testPatterns = [
  `nonexistent${Date.now()}@${domain}`,           // Random with timestamp
  `zzz-fake-user-zzz@${domain}`,                  // Obvious fake pattern
  `test.${crypto.randomUUID()}@${domain}`,        // UUID format
  `admin-backup-${Date.now()}@${domain}`          // Administrative-looking
];

3. Analiza Kodów Odpowiedzi

Analizuj konkretne kody i komunikaty odpowiedzi SMTP dla dodatkowych informacji:

function analyzeResponse(response) {
  const code = parseInt(response.substring(0, 3));
  const message = response.toLowerCase();

  if (code === 250) {
    if (message.includes('accepted for delivery')) {
      return { accepted: true, type: 'explicit_accept' };
    }
    return { accepted: true, type: 'standard_accept' };
  }

  if (code === 550) {
    if (message.includes('user unknown') || message.includes('no such user')) {
      return { accepted: false, type: 'user_not_found' };
    }
    if (message.includes('rejected') || message.includes('denied')) {
      return { accepted: false, type: 'policy_rejection' };
    }
  }

  if (code === 451 || code === 452) {
    return { accepted: null, type: 'temporary_failure' };
  }

  return { accepted: code < 400, type: 'unknown' };
}

Najlepsze Praktyki Obsługi E-maili Catch-All

Po wykryciu domeny catch-all potrzebujesz strategii obsługi tych adresów w procesie weryfikacji e-mail.

Strategia 1: Klasyfikacja Oparta na Ryzyku

Wdróż system klasyfikacji ryzyka, który przypisuje różne poziomy pewności:

function classifyEmailRisk(verificationResult) {
  const { valid, catchAll, domain } = verificationResult;

  if (!valid) {
    return { risk: 'high', action: 'reject', reason: 'Invalid email address' };
  }

  if (!catchAll) {
    return { risk: 'low', action: 'accept', reason: 'Verified deliverable' };
  }

  // Catch-all domain - assess additional risk factors
  const riskFactors = [];

  // Check domain age and reputation (would need external data)
  // Check if domain is a known business domain
  // Check email pattern (role-based, random, etc.)

  const localPart = verificationResult.email.split('@')[0];

  if (isRoleBasedAddress(localPart)) {
    riskFactors.push('role_based');
  }

  if (looksRandomlyGenerated(localPart)) {
    riskFactors.push('random_looking');
  }

  if (riskFactors.length >= 2) {
    return { risk: 'high', action: 'reject', reason: 'Catch-all with multiple risk factors' };
  }

  if (riskFactors.length === 1) {
    return { risk: 'medium', action: 'flag', reason: 'Catch-all with one risk factor' };
  }

  return { risk: 'medium', action: 'accept_with_caution', reason: 'Catch-all domain' };
}

function isRoleBasedAddress(localPart) {
  const rolePatterns = [
    'admin', 'info', 'support', 'sales', 'contact',
    'help', 'webmaster', 'postmaster', 'noreply', 'no-reply'
  ];
  return rolePatterns.some(pattern =>
    localPart.toLowerCase().includes(pattern)
  );
}

function looksRandomlyGenerated(localPart) {
  // Check for high entropy (random-looking strings)
  const consonants = localPart.match(/[bcdfghjklmnpqrstvwxyz]/gi) || [];
  const vowels = localPart.match(/[aeiou]/gi) || [];

  if (consonants.length > 0 && vowels.length === 0) {
    return true; // No vowels suggests random
  }

  if (localPart.length > 20) {
    return true; // Very long local parts are suspicious
  }

  // Check for number sequences
  if (/\d{5,}/.test(localPart)) {
    return true; // Long number sequences
  }

  return false;
}

Strategia 2: Filtrowanie Oparte na Zaangażowaniu

W celach marketingowych rozważ użycie danych o zaangażowaniu do filtrowania adresów catch-all:

function shouldIncludeInCampaign(email, engagementData, catchAllStatus) {
  // Always include if we have positive engagement history
  if (engagementData.hasOpened || engagementData.hasClicked) {
    return { include: true, reason: 'Previous engagement confirmed' };
  }

  // Non-catch-all verified emails are safe
  if (!catchAllStatus.isCatchAll && catchAllStatus.verified) {
    return { include: true, reason: 'Verified deliverable' };
  }

  // Catch-all with no engagement history - be cautious
  if (catchAllStatus.isCatchAll) {
    // Check if we've successfully delivered before
    if (engagementData.previousDeliveries > 0 && engagementData.bounceRate < 0.1) {
      return { include: true, reason: 'Previous successful deliveries' };
    }

    // New catch-all address with no history
    return {
      include: false,
      reason: 'Catch-all domain with no engagement history',
      recommendation: 'Send verification email first'
    };
  }

  return { include: true, reason: 'Default include' };
}

Strategia 3: Stopniowe Rozgrzewanie

Mając do czynienia z adresami catch-all, wdróż stopniową strategię wysyłki:

class CatchAllWarmingStrategy {
  constructor() {
    this.warmingGroups = {
      verified: { dailyLimit: 1000, priority: 1 },
      catchAllEngaged: { dailyLimit: 500, priority: 2 },
      catchAllNew: { dailyLimit: 100, priority: 3 }
    };
  }

  categorizeAddress(email, verification, engagement) {
    if (!verification.catchAll) {
      return 'verified';
    }

    if (engagement.hasInteracted) {
      return 'catchAllEngaged';
    }

    return 'catchAllNew';
  }

  buildSendingQueue(emails, verifications, engagements) {
    const categorized = {
      verified: [],
      catchAllEngaged: [],
      catchAllNew: []
    };

    emails.forEach(email => {
      const category = this.categorizeAddress(
        email,
        verifications[email],
        engagements[email] || {}
      );
      categorized[category].push(email);
    });

    // Build queue respecting daily limits
    const queue = [];

    Object.entries(this.warmingGroups)
      .sort((a, b) => a[1].priority - b[1].priority)
      .forEach(([category, config]) => {
        const addresses = categorized[category].slice(0, config.dailyLimit);
        queue.push(...addresses.map(email => ({
          email,
          category,
          priority: config.priority
        })));
      });

    return queue;
  }
}

Studia Przypadków z Praktyki

Studium Przypadku 1: Czyszczenie Listy w Firmie E-commerce

Średniej wielkości firma e-commerce z 500 000 subskrybentów e-mail chciała poprawić wskaźniki dostarczalności. Ich analiza ujawniła:

Stan Początkowy:

  • 500 000 subskrybentów łącznie
  • 12% wskaźnik odrzuceń w kampaniach
  • 45 000 adresów (9%) w domenach catch-all

Wyniki Weryfikacji:

  • 425 000 zweryfikowanych dostarczalnych (nie-catch-all)
  • 45 000 zidentyfikowanych adresów catch-all
  • 30 000 usuniętych nieprawidłowych adresów

Strategia Obsługi Catch-All:

Zamiast usuwać wszystkie adresy catch-all, wdrożyli podejście warstwowe:

  1. Warstwa 1 - Zatrzymaj: 15 000 adresów catch-all z wcześniejszym zaangażowaniem (otwarcia lub kliknięcia w ciągu 6 miesięcy)
  2. Warstwa 2 - Zweryfikuj: 20 000 adresów catch-all wysłano kampanię reaktywacyjną
  3. Warstwa 3 - Usuń: 10 000 adresów catch-all bez historii zaangażowania i podejrzanych wzorców

Wyniki Po 3 Miesiącach:

  • Wskaźnik odrzuceń spadł do 2,1%
  • Wskaźniki otwarć wzrosły o 18%
  • Znacząco poprawił się wynik reputacji nadawcy
  • Dostarczalność e-maili osiągnęła 98,5%

Studium Przypadku 2: Walidacja Leadów B2B SaaS

Firma B2B SaaS otrzymująca 10 000 nowych leadów miesięcznie wdrożyła wykrywanie catch-all w procesie rejestracji:

Wyzwanie: Wiele leadów B2B pochodziło z domen firmowych skonfigurowanych jako catch-all, co utrudniało weryfikację. Nie mogli po prostu odrzucić wszystkich adresów catch-all bez utraty wartościowych leadów.

Rozwiązanie:

async function validateB2BLead(email, companyInfo) {
  const verification = await verifyEmail(email);
  const catchAllResult = await detectCatchAll(email.split('@')[1]);

  if (!verification.valid) {
    return { accept: false, reason: 'Invalid email' };
  }

  if (!catchAllResult.isCatchAll) {
    return { accept: true, reason: 'Verified deliverable', confidence: 'high' };
  }

  // Catch-all domain - use company info to validate
  const domainMatchesCompany = email.split('@')[1].includes(
    companyInfo.name.toLowerCase().replace(/\s+/g, '')
  );

  if (domainMatchesCompany) {
    // Email domain matches company name - likely legitimate
    return {
      accept: true,
      reason: 'Catch-all but matches company domain',
      confidence: 'medium',
      requireVerification: true
    };
  }

  // Catch-all with unrelated domain
  return {
    accept: true,
    reason: 'Catch-all domain',
    confidence: 'low',
    requireVerification: true,
    sendDoubleOptIn: true
  };
}

Wyniki:

  • Wskaźnik akceptacji leadów utrzymany na poziomie 95%
  • Fałszywe odrzucenia zmniejszone o 60%
  • Wskaźnik potwierdzenia podwójnej zgody dla catch-all: 72%
  • Ogólna jakość leadów poprawiona o 25%

Używanie BillionVerify do Wykrywania Catch-All

Choć budowanie własnego wykrywania catch-all jest możliwe, korzystanie z profesjonalnej usługi weryfikacji e-mail, takiej jak BillionVerify, zapewnia znaczące korzyści:

Przykład Integracji API

const axios = require('axios');

async function verifyWithBillionVerify(email) {
  const response = await axios.post(
    'https://api.billionverify.com/v1/verify',
    { email },
    {
      headers: {
        'Authorization': `Bearer ${process.env.BV_API_KEY}`,
        'Content-Type': 'application/json'
      }
    }
  );

  const result = response.data;

  return {
    email: result.email,
    deliverable: result.deliverable,
    isCatchAll: result.is_catch_all,
    isDisposable: result.is_disposable,
    isRoleBased: result.is_role_address,
    qualityScore: result.quality_score,
    recommendation: result.recommendation
  };
}

// Bulk verification with catch-all handling
async function bulkVerifyWithStrategy(emails) {
  const results = await Promise.all(
    emails.map(email => verifyWithBillionVerify(email))
  );

  return {
    safe: results.filter(r => r.deliverable && !r.isCatchAll),
    catchAll: results.filter(r => r.deliverable && r.isCatchAll),
    invalid: results.filter(r => !r.deliverable),
    stats: {
      total: results.length,
      safeCount: results.filter(r => r.deliverable && !r.isCatchAll).length,
      catchAllCount: results.filter(r => r.deliverable && r.isCatchAll).length,
      invalidCount: results.filter(r => !r.deliverable).length
    }
  };
}

Zalety Używania BillionVerify

  1. Wyższa Dokładność: Nasze wykrywanie catch-all wykorzystuje wiele technik weryfikacji i utrzymuje obszerną bazę danych znanych domen catch-all.

  2. Dodatkowa Inteligencja: Poza wykrywaniem catch-all otrzymujesz wykrywanie jednorazowych adresów e-mail, identyfikację adresów rolowych i ocenę jakości.

  3. Zarządzanie Limitami Szybkości: Obsługujemy limitowanie szybkości i rotację IP, zapewniając spójną weryfikację bez blokad.

  4. Dane Historyczne: Dostęp do historycznych danych weryfikacji pomaga identyfikować wzorce i poprawiać podejmowanie decyzji.

  5. Aktualizacje w Czasie Rzeczywistym: Nasza baza danych catch-all jest stale aktualizowana w miarę zmiany konfiguracji domen.

Podsumowanie

Wykrywanie e-maili catch-all jest krytycznym komponentem każdej kompleksowej strategii weryfikacji e-mail. Choć te serwery stanowią wyzwanie dla weryfikacji, zrozumienie, jak działają, i wdrożenie odpowiednich strategii wykrywania i obsługi pozwala utrzymać wysokie wskaźniki dostarczalności bez utraty wartościowych kontaktów.

Kluczowe wnioski z tego przewodnika:

  1. Serwery catch-all akceptują całą pocztę niezależnie od tego, czy konkretna skrzynka pocztowa istnieje
  2. Detekcja obejmuje testowanie adresami, które definitywnie nie istnieją
  3. Nie odrzucaj automatycznie adresów catch-all—wdróż strategie oparte na ryzyku
  4. Używaj danych o zaangażowaniu do podejmowania świadomych decyzji o kontaktach catch-all
  5. Rozważ profesjonalne usługi takie jak BillionVerify dla systemów produkcyjnych

Gotowy do wdrożenia wykrywania catch-all w swoim procesie? Wypróbuj nasze narzędzie sprawdzania e-mail, aby przetestować pojedyncze adresy, lub poznaj API BillionVerify, aby bezproblemowo zintegrować je ze swoimi aplikacjami.

Prawidłowo obsługując domeny catch-all, poprawisz dostarczalność e-maili, ochronisz reputację nadawcy i podejmiesz lepsze decyzje dotyczące swoich kontaktów e-mailowych.

Zespoły korzystające z Instantly lub Smartlead poprawiają dostarczalność, czyszcząc listy z BillionVerify przed każdą kampanią.

Porównaj BillionVerify z ZeroBounce pod kątem dokładności i szybkości przed wyborem dostawcy weryfikacji.

Leo
LeoFounder, BillionVerify
Informacje o weryfikacji e-mail

Rozpocznij weryfikację dzisiaj

Zacznij weryfikować adresy e-mail z BillionVerify już dziś. Otrzymaj 100 darmowych kredytów po rejestracji - nie wymagana karta kredytowa. Dołącz do tysięcy firm poprawiających ROI z marketingu e-mailowego dzięki dokładnej weryfikacji e-mail.

Nie wymagana karta kredytowa · 100+ darmowych kredytów dziennie · Rozpocznij w 30 sekund

99.9%
Dokładność
Real-time
Szybkość API
$0.00014
Za e-mail
100/day
Darmowe na zawsze