При верификации email адресов одним из самых сложных сценариев, с которым вы столкнётесь, является catch-all email сервер. Эти серверы принимают почту для любого адреса в своём домене, что делает невозможным определение через стандартную SMTP верификацию, существует ли конкретный почтовый ящик на самом деле. Понимание обнаружения catch-all email имеет решающее значение для всех, кто серьёзно относится к поддержанию качества списков рассылки и максимизации показателей доставляемости.
В этом подробном руководстве мы рассмотрим всё, что вам нужно знать о catch-all email: что это такое, почему они существуют, как их обнаружить и, что важнее всего, как обрабатывать их в процессе верификации email. Независимо от того, являетесь ли вы разработчиком, создающим систему валидации email, или маркетологом, пытающимся очистить свой список рассылки, это руководство даст вам знания и инструменты, необходимые для эффективной работы с catch-all доменами.
Надёжная стратегия верификации email должна учитывать catch-all серверы. Без правильного обнаружения и обработки результаты вашей верификации могут создать у вас ложную уверенность в доставляемости email. Давайте погрузимся в технические детали и практические решения.
Что такое Catch-All Email сервер?
Catch-all email сервер, также известный как accept-all сервер, настроен на приём входящей почты для любого адреса в своём домене, независимо от того, существует ли этот конкретный почтовый ящик. Когда вы отправляете email на anyaddress@catchall-domain.com, сервер принимает его без возврата, даже если почтовый ящик с именем "anyaddress" никогда не создавался.
Как работает конфигурация Catch-All
В типичной конфигурации email сервера, когда приходит сообщение для несуществующего почтового ящика, сервер отвечает сообщением об отклонении "550 User not found" или подобным. Такое поведение позволяет системам верификации email определять, существует ли адрес, проверяя ответ сервера.
Catch-all серверы ведут себя иначе. Они настроены на приём всей входящей почты независимо от адреса получателя. Затем почта может быть:
- Направлена в специальный почтовый ящик - один администратор получает все сообщения
- Сохранена в общей очереди - сообщения хранятся для последующей сортировки
- Молча удалена - принята, но удалена без доставки
- Переадресована в другую систему - отправлена на другой сервер для обработки
Вот пример того, как это выглядит в конфигурации почтового сервера Postfix:
# /etc/postfix/main.cf # Стандартная конфигурация - отклоняет неизвестных получателей local_recipient_maps = proxy:unix:passwd.byname $alias_maps # Конфигурация Catch-all - принимает всех получателей local_recipient_maps =
Почему организации используют Catch-All серверы
Существует несколько законных причин, по которым организации настраивают catch-all email:
1. Предотвращение потери деловой переписки
Малые предприятия часто беспокоятся о пропуске важных писем из-за опечаток или вариаций в именах сотрудников. Если кто-то отправит письмо на john.smith@company.com, но настоящий адрес jsmith@company.com, конфигурация catch-all гарантирует, что сообщение не будет потеряно.
2. Гибкая маршрутизация email
Некоторые организации используют catch-all как часть сложной системы маршрутизации email. Вся входящая почта поступает в центральную очередь, где автоматически сортируется и распределяется на основе правил.
3. Мониторинг безопасности
Команды безопасности иногда настраивают catch-all для мониторинга того, какие адреса атакуют злоумышленники или спамеры. Эта информация помогает выявлять попытки фишинга или утечки данных.
4. Совместимость со старыми системами
Организации, переходящие с одной email системы на другую, могут временно включить catch-all, чтобы гарантировать, что никакие сообщения не будут потеряны во время перехода.
5. Защита конфиденциальности
Некоторые организации, заботящиеся о конфиденциальности, используют catch-all домены для создания уникальных email адресов для каждого сервиса, на который они регистрируются, что упрощает отслеживание, какие компании передают или публикуют их данные.
Проблема для верификации Email
Для целей верификации email catch-all серверы представляют значительную проблему. Когда вы выполняете SMTP верификацию на catch-all домене, сервер отвечает с подтверждением "250 OK" для каждого адреса, который вы тестируете — будь то реальный или полностью вымышленный.
Рассмотрим этот пример SMTP сессии:
> MAIL FROM:<test@verify.local> < 250 OK > RCPT TO:<real.user@catchall-domain.com> < 250 OK > RCPT TO:<completely.fake.address@catchall-domain.com> < 250 OK > RCPT TO:<asdfghjkl12345@catchall-domain.com> < 250 OK
Все три адреса получают одинаковый положительный ответ, что делает невозможным отличить реального пользователя от поддельных адресов только через SMTP верификацию.
Как обнаружить Catch-All Email серверы
Обнаружение того, настроен ли почтовый сервер как catch-all, требует умного подхода: тестирование с адресом, который определённо не должен существовать, и наблюдение за ответом сервера.
Алгоритм обнаружения
Базовый алгоритм обнаружения catch-all работает следующим образом:
- Сгенерируйте случайный, несуществующий адрес в целевом домене
- Выполните SMTP верификацию этого поддельного адреса
- Проанализируйте ответ:
- Если сервер принимает поддельный адрес → Вероятно, это catch-all
- Если сервер отклоняет поддельный адрес → Применяется обычная верификация
Реализация на Node.js
Вот полная реализация на Node.js для обнаружения catch-all:
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);
Реализация на Python
Вот эквивалентная реализация на Python:
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}")
Продвинутые техники обнаружения
Базовое обнаружение catch-all можно улучшить с помощью этих продвинутых техник:
1. Тестирование несколькими проверками
Вместо тестирования только с одним поддельным адресом, протестируйте несколько случайно сгенерированных адресов. Это помогает выявить серверы с непоследовательным поведением:
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. Обнаружение на основе паттернов
Некоторые catch-all серверы настроены с паттернами. Тестируйте адреса с различными форматами:
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. Анализ кодов ответа
Анализируйте конкретные коды и сообщения ответа SMTP для получения дополнительной информации:
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' };
}
Лучшие практики обработки Catch-All Email
Как только вы обнаружили catch-all домен, вам нужна стратегия для обработки этих адресов в процессе верификации email.
Стратегия 1: Классификация на основе риска
Внедрите систему классификации рисков, которая присваивает различные уровни уверенности:
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;
}
Стратегия 2: Фильтрация на основе вовлечённости
Для маркетинговых целей рассмотрите использование данных о вовлечённости для фильтрации 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' };
}
Стратегия 3: Постепенная подготовка
При работе с catch-all адресами внедрите стратегию постепенной отправки:
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;
}
}
Реальные примеры из практики
Пример 1: Очистка списка e-commerce компании
E-commerce компания среднего размера с 500 000 подписчиков email хотела улучшить показатели доставляемости. Их анализ показал:
Начальное состояние:
- 500 000 всего подписчиков
- 12% показатель возврата в кампаниях
- 45 000 адресов (9%) на catch-all доменах
Результаты верификации:
- 425 000 проверенных доставляемых (не catch-all)
- 45 000 идентифицированных catch-all адресов
- 30 000 удалённых недействительных адресов
Стратегия обработки Catch-All:
Вместо удаления всех catch-all адресов они применили многоуровневый подход:
- Уровень 1 - Сохранить: 15 000 catch-all адресов с предыдущей вовлечённостью (открытия или клики в течение 6 месяцев)
- Уровень 2 - Проверить: 20 000 catch-all адресов отправили кампанию повторного вовлечения
- Уровень 3 - Удалить: 10 000 catch-all адресов без истории вовлечённости и подозрительными паттернами
Результаты через 3 месяца:
- Показатель возврата снизился до 2.1%
- Показатели открытия увеличились на 18%
- Оценка репутации отправителя значительно улучшилась
- Доставляемость email достигла 98.5%
Пример 2: Валидация лидов B2B SaaS
B2B SaaS компания, получающая 10 000 новых лидов ежемесячно, внедрила обнаружение catch-all в процесс регистрации:
Проблема: Многие B2B лиды приходили с доменов компаний, настроенных как catch-all, что усложняло верификацию. Они не могли просто отклонить все catch-all адреса без потери ценных лидов.
Решение:
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
};
}
Результаты:
- Показатель принятия лидов сохранился на уровне 95%
- Ложное положительное отклонение сократилось на 60%
- Показатель подтверждения двойной подписки для catch-all: 72%
- Общее качество лидов улучшилось на 25%
Использование BillionVerify для обнаружения Catch-All
Хотя создание собственной системы обнаружения catch-all возможно, использование профессионального сервиса верификации email, такого как BillionVerify, предоставляет значительные преимущества:
Пример интеграции 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.BILLIONVERIFY_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
}
};
}
Преимущества использования BillionVerify
Более высокая точность: Наше обнаружение catch-all использует несколько техник верификации и поддерживает обширную базу данных известных catch-all доменов.
Дополнительная аналитика: Помимо обнаружения catch-all, вы получаете обнаружение одноразовых email, идентификацию ролевых адресов и оценку качества.
Управление ограничениями скорости: Мы управляем ограничениями скорости и ротацией IP, обеспечивая стабильную верификацию без блокировок.
Исторические данные: Доступ к историческим данным верификации помогает выявлять паттерны и улучшать принятие решений.
Обновления в реальном времени: Наша база данных catch-all постоянно обновляется по мере изменения конфигураций доменов.
Заключение
Обнаружение catch-all email является критически важным компонентом любой комплексной стратегии верификации email. Хотя эти серверы представляют проблемы для верификации, понимание того, как они работают, и внедрение правильных стратегий обнаружения и обработки позволяет поддерживать высокие показатели доставляемости без потери ценных контактов.
Ключевые выводы из этого руководства:
- Catch-all серверы принимают всю почту независимо от того, существует ли конкретный почтовый ящик
- Обнаружение включает тестирование с адресами, которые определённо не существуют
- Не отклоняйте автоматически catch-all адреса — внедряйте стратегии на основе риска
- Используйте данные о вовлечённости для принятия обоснованных решений о catch-all контактах
- Рассмотрите профессиональные сервисы такие как BillionVerify для производственных систем
Готовы внедрить обнаружение catch-all в свой процесс? Попробуйте наш инструмент проверки email для тестирования отдельных адресов или изучите BillionVerify API для бесшовной интеграции в ваши приложения.
Правильно обрабатывая catch-all домены, вы улучшите доставляемость email, защитите репутацию отправителя и будете принимать более взвешенные решения о своих контактах email.