SMTP 郵箱驗證:無需發送郵件驗證郵箱地址的完整指南

Leo
LeoFounder, BillionVerify

通過這份全面指南掌握 SMTP 郵箱驗證技術。學習如何使用 SMTP 握手、RCPT TO 命令等方法驗證郵箱地址,無需實際發送郵件,構建可靠的郵件驗證器。

Cover Image for SMTP 郵箱驗證:無需發送郵件驗證郵箱地址的完整指南

SMTP 郵箱驗證是確認郵箱地址是否能夠實際接收郵件的黃金標準。與基本的語法驗證或網域檢查不同,SMTP 驗證直接與收件人的郵件伺服器通訊,以驗證特定郵箱是否存在並能夠接收電子郵件。這種強大的電子郵件驗證技術構成了專業郵箱驗證服務的基礎,幫助企業維護乾淨的郵件清單、保護寄件人聲譽並提高郵件可達性。

理解 SMTP 郵箱驗證

SMTP(簡單郵件傳輸協定)是電子郵件傳輸的網際網路標準。每次您發送電子郵件時,您的郵件用戶端或伺服器都使用 SMTP 將該郵件傳遞給收件人的郵件伺服器。SMTP 郵箱驗證利用這同一協定來檢查郵箱地址是否存在——但實際上並不發送任何郵件。

SMTP 驗證的優勢在於其能夠從源頭驗證郵箱地址。與其根據格式或網域猜測地址是否有效,SMTP 驗證直接詢問郵件伺服器:「您會接受發送到此地址的郵件嗎?」伺服器的回應會告知郵箱是否存在、是否已滿或是否已被停用。

SMTP 郵箱驗證的工作原理

SMTP 驗證流程遵循一系列特定的命令序列,模擬郵件傳遞的開始階段,但在實際發送任何郵件內容之前停止。以下是逐步分解:

步驟 1:DNS 查找 MX 記錄

在連接到任何郵件伺服器之前,驗證流程必須確定哪個伺服器處理該網域的電子郵件。這涉及查詢 DNS 中的郵件交換 (MX) 記錄。一個網域可能有多個具有不同優先順序的 MX 記錄,如果主伺服器不可用,則允許使用備用伺服器。

步驟 2:建立 TCP 連接

一旦確定了郵件伺服器,驗證器就會在埠 25(標準 SMTP 埠)或 587、465 等替代埠上建立 TCP 連接。

步驟 3:SMTP 握手 (HELO/EHLO)

連接從問候開始。驗證器發送 EHLO(擴充 HELO)或 HELO 命令向郵件伺服器介紹自己。伺服器回應其功能並確認已準備好繼續。

步驟 4:MAIL FROM 命令

驗證器使用 MAIL FROM 命令指定寄件人地址。雖然此地址不需要是最終寄件人,但如果 MAIL FROM 網域缺少適當的 DNS 記錄或看起來可疑,郵件伺服器可能會拒絕驗證嘗試。

步驟 5:RCPT TO 命令(關鍵步驟)

這是實際驗證發生的地方。驗證器使用要檢查的郵箱地址發送 RCPT TO 命令。郵件伺服器對此命令的回應表明郵箱是否存在:

  • 250 OK:郵箱存在且可以接收郵件
  • 550 User unknown:郵箱不存在
  • 551 User not local:伺服器知道該使用者但建議使用其他地址
  • 552 Mailbox full:郵箱存在但無法接收郵件
  • 553 Mailbox name not allowed:地址語法被拒絕

步驟 6:QUIT

在收到 RCPT TO 回應後,驗證器發送 QUIT 以優雅地關閉連接,而不實際發送任何郵件。

SMTP 回應代碼解釋

理解 SMTP 回應代碼對於構建準確的郵箱驗證系統至關重要。這些三位數代碼承載著決定驗證結果的特定含義。

2xx 成功代碼

  • 250:請求的操作成功完成(郵箱存在)
  • 251:使用者不在本地;將轉寄到指定路徑

4xx 臨時失敗代碼

  • 421:服務不可用,關閉傳輸通道
  • 450:請求的郵件操作未執行:郵箱不可用(忙碌/臨時阻止)
  • 451:請求的操作被中止:處理中的本地錯誤
  • 452:請求的操作未執行:系統儲存空間不足

5xx 永久失敗代碼

  • 550:請求的操作未執行:郵箱不可用(不存在)
  • 551:使用者不在本地;請嘗試其他路徑
  • 552:請求的郵件操作被中止:超出儲存分配
  • 553:請求的操作未執行:郵箱名稱不允許
  • 554:事務失敗

4xx 和 5xx 代碼之間的區別非常重要。4xx 回應表示臨時問題——郵箱可能稍後變為可用。5xx 回應表示永久失敗——該地址應被視為無效。

實作 SMTP 郵箱驗證

構建 SMTP 驗證系統需要仔細關注協定細節、錯誤處理和速率限制。以下是實用的實作指南。

基本 SMTP 驗證流程

以下偽代碼說明了核心驗證邏輯:

function verifyEmail(email):
    domain = extractDomain(email)

    // 步驟 1:取得 MX 記錄
    mxRecords = getMXRecords(domain)
    if mxRecords is empty:
        return INVALID_DOMAIN

    // 按優先順序排序(數字越小 = 優先順序越高)
    sortByPriority(mxRecords)

    // 嘗試每個 MX 伺服器
    for mx in mxRecords:
        try:
            // 步驟 2:連接
            connection = connectSMTP(mx.host, 25)

            // 步驟 3:EHLO
            response = sendCommand("EHLO verifier.example.com")
            if response.code != 250:
                continue  // 嘗試下一個 MX

            // 步驟 4:MAIL FROM
            response = sendCommand("MAIL FROM:<verify@example.com>")
            if response.code != 250:
                continue

            // 步驟 5:RCPT TO
            response = sendCommand("RCPT TO:<" + email + ">")

            // 步驟 6:QUIT
            sendCommand("QUIT")
            closeConnection()

            // 解釋結果
            if response.code == 250:
                return VALID
            else if response.code >= 500:
                return INVALID
            else:
                return UNKNOWN

        catch ConnectionError:
            continue  // 嘗試下一個 MX

    return UNABLE_TO_VERIFY

Node.js 實作

這是一個使用原生 netdns 模組的實用 Node.js 實作:

const dns = require('dns');
const net = require('net');

async function verifyEmailSMTP(email) {
  const domain = email.split('@')[1];

  // 取得 MX 記錄
  const mxRecords = await new Promise((resolve, reject) => {
    dns.resolveMx(domain, (err, addresses) => {
      if (err) reject(err);
      else resolve(addresses.sort((a, b) => a.priority - b.priority));
    });
  });

  if (!mxRecords || mxRecords.length === 0) {
    return { valid: false, reason: 'No MX records found' };
  }

  // 嘗試每個 MX 伺服器
  for (const mx of mxRecords) {
    try {
      const result = await checkMailbox(mx.exchange, email);
      return result;
    } catch (err) {
      continue; // 嘗試下一個 MX 伺服器
    }
  }

  return { valid: null, reason: 'Unable to verify' };
}

function checkMailbox(mxHost, email) {
  return new Promise((resolve, reject) => {
    const socket = net.createConnection(25, mxHost);
    let step = 0;
    let response = '';

    socket.setTimeout(10000);

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

      switch (step) {
        case 0: // 伺服器問候
          if (code === 220) {
            socket.write('EHLO verifier.example.com\r\n');
            step++;
          } else {
            socket.end();
            reject(new Error('Server rejected connection'));
          }
          break;

        case 1: // EHLO 回應
          if (code === 250) {
            socket.write('MAIL FROM:<verify@example.com>\r\n');
            step++;
          } else {
            socket.end();
            reject(new Error('EHLO failed'));
          }
          break;

        case 2: // MAIL FROM 回應
          if (code === 250) {
            socket.write(`RCPT TO:<${email}>\r\n`);
            step++;
          } else {
            socket.end();
            reject(new Error('MAIL FROM rejected'));
          }
          break;

        case 3: // RCPT TO 回應 - 驗證結果
          socket.write('QUIT\r\n');
          socket.end();

          if (code === 250) {
            resolve({ valid: true, reason: 'Mailbox exists' });
          } else if (code >= 500) {
            resolve({ valid: false, reason: 'Mailbox does not exist', code });
          } else {
            resolve({ valid: null, reason: 'Unable to determine', code });
          }
          break;
      }
    });

    socket.on('timeout', () => {
      socket.end();
      reject(new Error('Connection timeout'));
    });

    socket.on('error', (err) => {
      reject(err);
    });
  });
}

Python 實作

Python 使用其 smtplib 模組提供簡潔的 SMTP 驗證:

import dns.resolver
import smtplib
import socket

def verify_email_smtp(email):
    domain = email.split('@')[1]

    # 取得 MX 記錄
    try:
        mx_records = dns.resolver.resolve(domain, 'MX')
        mx_hosts = sorted([(r.preference, str(r.exchange).rstrip('.'))
                          for r in mx_records])
    except dns.resolver.NXDOMAIN:
        return {'valid': False, 'reason': 'Domain does not exist'}
    except dns.resolver.NoAnswer:
        return {'valid': False, 'reason': 'No MX records found'}

    # 嘗試每個 MX 伺服器
    for priority, mx_host in mx_hosts:
        try:
            result = check_mailbox(mx_host, email)
            if result['valid'] is not None:
                return result
        except Exception as e:
            continue

    return {'valid': None, 'reason': 'Unable to verify'}

def check_mailbox(mx_host, email):
    try:
        # 連接到 SMTP 伺服器
        smtp = smtplib.SMTP(timeout=10)
        smtp.connect(mx_host, 25)

        # EHLO
        code, message = smtp.ehlo('verifier.example.com')
        if code != 250:
            smtp.quit()
            return {'valid': None, 'reason': 'EHLO failed'}

        # MAIL FROM
        code, message = smtp.mail('verify@example.com')
        if code != 250:
            smtp.quit()
            return {'valid': None, 'reason': 'MAIL FROM rejected'}

        # RCPT TO - 驗證步驟
        code, message = smtp.rcpt(email)
        smtp.quit()

        if code == 250:
            return {'valid': True, 'reason': 'Mailbox exists'}
        elif code >= 500:
            return {'valid': False, 'reason': 'Mailbox does not exist', 'code': code}
        else:
            return {'valid': None, 'reason': 'Temporary failure', 'code': code}

    except socket.timeout:
        return {'valid': None, 'reason': 'Connection timeout'}
    except smtplib.SMTPServerDisconnected:
        return {'valid': None, 'reason': 'Server disconnected'}
    except Exception as e:
        return {'valid': None, 'reason': str(e)}

SMTP 郵箱驗證的挑戰

雖然 SMTP 驗證功能強大,但幾個挑戰可能會使實作複雜化並影響準確性。

全捕獲網域

某些郵件伺服器被設定為全捕獲,接受發送到其網域下任何地址的郵件,無論特定郵箱是否存在。當您發送 RCPT TO 任何地址時——即使是隨機字元——伺服器都會以 250 OK 回應。

全捕獲設定使 SMTP 驗證無法區分該網域上的有效和無效地址。BillionVerify 等專業郵箱驗證服務實施了專門的全捕獲檢測演算法來識別這些網域並提供適當的置信度分數。

灰名單

灰名單是一種反垃圾郵件技術,郵件伺服器會臨時拒絕來自未知寄件人的電子郵件。首次 SMTP 連接嘗試回傳 4xx 臨時錯誤。合法的郵件伺服器會重試傳遞,而許多垃圾郵件系統則不會。

對於郵箱驗證,灰名單顯示為臨時失敗。正確的實作需要:

  • 識別灰名單回應(通常是 450 或 451)
  • 實施帶有適當延遲的重試邏輯
  • 追蹤哪些伺服器使用灰名單

速率限制和阻止

郵件伺服器透過限制連接速率來保護自己免受濫用。短時間內從單一 IP 位址進行太多驗證嘗試可能會觸發:

  • 臨時阻止(4xx 回應)
  • 永久黑名單
  • 連接逾時
  • 驗證碼或挑戰

專業郵箱驗證服務將驗證請求分散在多個 IP 位址上,並實施複雜的速率限制以避免觸發這些保護措施。

誤報和漏報

SMTP 驗證並非 100% 準確。幾種情況可能會產生不正確的結果:

誤報(將無效報告為有效)

  • 全捕獲網域接受一切
  • 伺服器在 SMTP 期間接受但稍後退回
  • 仍接受連接的完整郵箱

漏報(將有效報告為無效)

  • 灰名單拒絕首次嘗試
  • 速率限制阻止合法檢查
  • 伺服器設定錯誤
  • 臨時中斷

SMTP 伺服器變體

不同的郵件伺服器使用影響驗證的變體實作 SMTP:

Microsoft Exchange/Office 365

  • 通常需要驗證才能取得詳細回應
  • 可能在 SMTP 期間接受但稍後拒絕傳遞
  • 實施複雜的反垃圾郵件措施

Gmail/Google Workspace

  • 接受/拒絕通常很可靠
  • 可能會對激進的驗證嘗試進行速率限制
  • 回傳一致的回應

Yahoo Mail

  • 以嚴格的速率限制而聞名
  • 可能需要解決挑戰
  • 實施灰名單

自訂郵件伺服器

  • 行為差異很大
  • 可能具有非標準設定
  • 安全設定影響驗證準確性

SMTP 郵箱驗證的最佳實務

構建可靠的 SMTP 驗證需要遵循經過驗證的最佳實務。

正確的 EHLO/HELO 設定

您的 EHLO 主機名稱應該:

  • 解析到您的驗證伺服器的 IP
  • 具有有效的反向 DNS(PTR 記錄)
  • 不出現在黑名單上
  • 是您控制的合法網域
EHLO verify.yourdomain.com

避免使用觸發垃圾郵件篩選器的通用或可疑主機名稱。

MAIL FROM 地址選擇

MAIL FROM 地址對驗證接受度很重要:

  • 使用具有有效 MX 記錄的真實網域
  • 確保 SPF 記錄允許您的驗證伺服器
  • 考慮使用專用於驗證的網域
  • 避免已知的垃圾郵件陷阱網域

連接管理

高效的連接管理可提高驗證速度和可靠性:

// 連接池範例
class SMTPConnectionPool {
  constructor(maxConnections = 10) {
    this.pools = new Map(); // 網域 -> 連接
    this.maxConnections = maxConnections;
  }

  async getConnection(mxHost) {
    if (!this.pools.has(mxHost)) {
      this.pools.set(mxHost, []);
    }

    const pool = this.pools.get(mxHost);

    // 如果可用,重用現有連接
    if (pool.length > 0) {
      return pool.pop();
    }

    // 建立新連接
    return await this.createConnection(mxHost);
  }

  releaseConnection(mxHost, connection) {
    const pool = this.pools.get(mxHost);
    if (pool && pool.length < this.maxConnections) {
      pool.push(connection);
    } else {
      connection.end();
    }
  }
}

逾時設定

設定適當的逾時以避免在無回應伺服器上掛起:

const TIMEOUT_CONFIG = {
  connection: 10000,    // 10 秒建立連接
  greeting: 30000,      // 30 秒等待伺服器問候
  command: 30000,       // 每個命令回應 30 秒
  total: 60000          // 每次驗證最多 60 秒
};

錯誤處理和重試邏輯

實施帶有智慧重試的強健錯誤處理:

async function verifyWithRetry(email, maxRetries = 3) {
  const delays = [1000, 5000, 15000]; // 指數退避

  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const result = await verifyEmailSMTP(email);

      // 如果我們得到了確定的答案,不要重試
      if (result.valid !== null) {
        return result;
      }

      // 檢查錯誤是否可重試
      if (isGreylisting(result) || isTemporaryError(result)) {
        await sleep(delays[attempt]);
        continue;
      }

      return result;

    } catch (err) {
      if (attempt === maxRetries - 1) {
        return { valid: null, reason: err.message };
      }
      await sleep(delays[attempt]);
    }
  }
}

function isGreylisting(result) {
  return result.code === 450 || result.code === 451;
}

function isTemporaryError(result) {
  return result.code >= 400 && result.code < 500;
}

速率限制實作

保護您的驗證基礎設施並維持良好聲譽:

class RateLimiter {
  constructor() {
    this.domainLimits = new Map();
    this.globalCounter = 0;
    this.globalLimit = 100; // 每秒
    this.domainLimit = 10;  // 每個網域每秒
  }

  async waitForSlot(domain) {
    // 檢查全域限制
    while (this.globalCounter >= this.globalLimit) {
      await sleep(100);
    }

    // 檢查網域限制
    const domainCount = this.domainLimits.get(domain) || 0;
    while (domainCount >= this.domainLimit) {
      await sleep(100);
    }

    // 預留插槽
    this.globalCounter++;
    this.domainLimits.set(domain, domainCount + 1);

    // 1 秒後釋放
    setTimeout(() => {
      this.globalCounter--;
      this.domainLimits.set(domain,
        (this.domainLimits.get(domain) || 1) - 1);
    }, 1000);
  }
}

SMTP 驗證與其他方法對比

了解 SMTP 驗證與其他電子郵件驗證技術的比較有助於您選擇正確的方法。

語法驗證

語法驗證使用正規表達式模式檢查電子郵件是否遵循正確的格式。它速度快,可以在用戶端完成,但只能捕獲明顯的格式錯誤。

優勢:

  • 即時結果
  • 無需網路請求
  • 捕獲拼寫錯誤

局限性:

  • 無法驗證存在性
  • 許多無效電子郵件通過語法檢查

網域/MX 驗證

MX 記錄驗證透過檢查郵件伺服器記錄來確認網域可以接收電子郵件。

優勢:

  • 捕獲不存在的網域
  • 快速 DNS 查找
  • 無需 SMTP 連接

局限性:

  • 無法驗證特定郵箱
  • 網域可能有 MX 但沒有有效使用者

SMTP 驗證

SMTP 驗證確認特定郵箱存在並可以接收郵件。

優勢:

  • 郵箱存在性的最高準確性
  • 直接與郵件伺服器通訊
  • 捕獲許多無效地址

局限性:

  • 比其他方法慢
  • 受全捕獲網域影響
  • 可能被速率限制阻止

驗證層次結構

全面的郵箱驗證策略分層使用這些方法:

  1. 語法驗證 - 過濾明顯無效的格式
  2. 網域驗證 - 確認網域存在且有 MX 記錄
  3. SMTP 驗證 - 驗證特定郵箱
  4. 附加檢查 - 一次性郵箱檢測、角色郵箱檢測、全捕獲檢測

BillionVerify 等專業郵箱驗證服務實施了這一完整的層次結構,處理 SMTP 驗證的複雜性,同時提供有關電子郵件品質的額外情報。

使用專業 SMTP 驗證服務

雖然構建自己的 SMTP 驗證系統具有教育意義,但生產應用程式通常受益於處理複雜性的專業郵箱驗證 API。

專業服務的優勢

基礎設施

  • 全球分散式驗證伺服器
  • 乾淨的 IP 聲譽管理
  • 高可用性和冗餘

智慧

  • 全捕獲網域檢測
  • 一次性郵箱識別
  • 角色郵箱標記
  • 垃圾郵件陷阱檢測

合規性

  • 符合隱私的處理
  • 安全的資料處理
  • 稽核追蹤

BillionVerify API 整合

BillionVerify 提供包括 SMTP 檢查在內的全面郵箱驗證:

async function verifyWithBillionVerify(email) {
  const response = await fetch('https://api.billionverify.com/v1/verify', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ email })
  });

  const result = await response.json();

  return {
    isValid: result.is_valid,
    isDeliverable: result.is_deliverable,
    isCatchAll: result.is_catch_all,
    isDisposable: result.is_disposable,
    isRoleBased: result.is_role_based,
    smtpCheck: result.smtp_check,
    mxRecords: result.mx_records,
    riskScore: result.risk_score
  };
}

該 API 在內部處理所有 SMTP 複雜性,同時提供需要大量基礎設施才能複製的額外情報。

批次 SMTP 驗證

對於驗證大型郵件清單,批次驗證最佳化了流程:

async function bulkVerify(emails) {
  // 上傳檔案進行批次處理
  const formData = new FormData();
  formData.append('file', createCSV(emails));

  const uploadResponse = await fetch('https://api.billionverify.com/v1/bulk/upload', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    },
    body: formData
  });

  const { jobId } = await uploadResponse.json();

  // 輪詢完成
  let status = 'processing';
  while (status === 'processing') {
    await sleep(5000);
    const statusResponse = await fetch(
      `https://api.billionverify.com/v1/bulk/status/${jobId}`,
      { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
    );
    const job = await statusResponse.json();
    status = job.status;
  }

  // 下載結果
  const resultsResponse = await fetch(
    `https://api.billionverify.com/v1/bulk/download/${jobId}`,
    { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
  );

  return await resultsResponse.json();
}

註冊表單的即時 SMTP 驗證

在使用者註冊期間實施即時郵箱驗證從一開始就提高了資料品質。

前端實作

// 輸入時的防抖郵箱驗證
const emailInput = document.getElementById('email');
let verificationTimeout;

emailInput.addEventListener('input', (e) => {
  clearTimeout(verificationTimeout);

  const email = e.target.value;
  if (!isValidSyntax(email)) {
    showError('請輸入有效的郵箱格式');
    return;
  }

  verificationTimeout = setTimeout(async () => {
    showLoading();

    try {
      const result = await verifyEmail(email);

      if (result.isValid) {
        showSuccess('郵箱已驗證');
      } else if (result.isCatchAll) {
        showWarning('無法完全驗證此郵箱');
      } else {
        showError('此郵箱地址似乎無效');
      }
    } catch (err) {
      // 驗證錯誤時不要阻止註冊
      clearStatus();
    }
  }, 500); // 停止輸入後等待 500 毫秒
});

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

後端 API 端點

// Express.js 端點
app.post('/api/verify-email', async (req, res) => {
  const { email } = req.body;

  // 首先進行快速語法檢查
  if (!isValidEmailSyntax(email)) {
    return res.json({ isValid: false, reason: 'Invalid syntax' });
  }

  try {
    // 呼叫 BillionVerify API 進行完整驗證
    const result = await emailVerify.verify(email);

    res.json({
      isValid: result.is_valid && result.is_deliverable,
      isCatchAll: result.is_catch_all,
      isDisposable: result.is_disposable,
      suggestion: result.did_you_mean // 拼寫建議
    });
  } catch (err) {
    // 失敗時保持開放 - API 錯誤時不要阻止註冊
    res.json({ isValid: true, verified: false });
  }
});

SMTP 驗證的安全考慮

SMTP 驗證涉及需要安全意識的網路連接。

保護您的基礎設施

防火牆設定

  • 僅允許來自驗證伺服器的出站 SMTP 連接
  • 監控異常連接模式
  • 阻止已知的惡意 IP 範圍

TLS/SSL 使用

  • 在可用時使用 STARTTLS
  • 驗證伺服器憑證
  • 優雅地處理憑證錯誤

避免黑名單

如果您的驗證伺服器看起來像在發送垃圾郵件或濫用郵件伺服器,它們可能會被列入黑名單:

  • 實施嚴格的速率限制
  • 使用專用 IP 進行驗證
  • 定期監控黑名單狀態
  • 維護適當的反向 DNS
  • 及時回應濫用投訴

資料隱私

郵箱地址是需要保護的個人資料:

  • 不必要地不記錄完整的郵箱地址
  • 加密儲存的驗證結果
  • 實施資料保留政策
  • 遵守 GDPR 和其他法規
  • 對 API 呼叫使用安全連接

衡量 SMTP 驗證效能

追蹤關鍵指標以確保您的驗證系統效能良好。

關鍵指標

準確性指標

  • 真陽性率(正確識別有效)
  • 假陽性率(無效標記為有效)
  • 全捕獲檢測準確性
  • 未知/無法驗證率

效能指標

  • 平均驗證時間
  • 第 95 百分位回應時間
  • 連接成功率
  • 按網域的逾時率

營運指標

  • 每日驗證量
  • 按類型的錯誤率
  • 黑名單事件
  • API 可用性

監控儀表板範例

class VerificationMetrics {
  constructor() {
    this.counters = {
      total: 0,
      valid: 0,
      invalid: 0,
      catchAll: 0,
      unknown: 0,
      errors: 0
    };
    this.timings = [];
  }

  record(result, duration) {
    this.counters.total++;
    this.timings.push(duration);

    if (result.valid === true) this.counters.valid++;
    else if (result.valid === false) this.counters.invalid++;
    else if (result.isCatchAll) this.counters.catchAll++;
    else this.counters.unknown++;
  }

  recordError() {
    this.counters.errors++;
  }

  getStats() {
    const sortedTimings = this.timings.sort((a, b) => a - b);

    return {
      counts: this.counters,
      accuracy: {
        validRate: this.counters.valid / this.counters.total,
        unknownRate: this.counters.unknown / this.counters.total
      },
      performance: {
        avgTime: average(this.timings),
        p95Time: sortedTimings[Math.floor(sortedTimings.length * 0.95)],
        errorRate: this.counters.errors / this.counters.total
      }
    };
  }
}

結論

SMTP 郵箱驗證提供了驗證郵箱地址是否能夠接收郵件的最準確方法。透過使用 SMTP 協定直接與郵件伺服器通訊,您可以確定郵箱是否存在,而無需實際發送任何電子郵件。

構建有效的 SMTP 驗證需要了解協定細節、處理各種挑戰(如全捕獲網域和灰名單)以及實施適當的速率限制和錯誤處理。對於大多數生產應用程式,BillionVerify 等專業郵箱驗證服務提供了所需的基礎設施、智慧和可靠性,而無需構建和維護驗證基礎設施的複雜性。

無論您是為了學習目的實作自己的 SMTP 驗證,還是整合專業郵箱驗證 API,本指南涵蓋的原則都將幫助您了解在大規模驗證郵箱地址時幕後發生的事情。

請記住,SMTP 驗證只是全面電子郵件驗證的一個組成部分。將其與語法驗證、網域驗證、一次性郵箱檢測和全捕獲識別相結合,可以建立完整的郵箱驗證策略,保護您的寄件人聲譽、提高郵件可達性並維護郵件清單的品質。

從基本的語法和網域檢查開始獲得即時回饋,分層使用 SMTP 驗證進行徹底驗證,並在需要專用郵箱驗證基礎設施帶來的可靠性、準確性和額外情報時考慮使用 BillionVerify 等專業服務。

使用 InstantlySmartlead 的團隊,在每次活動前透過 BillionVerify 清洗名單,可顯著提升送達率。

在選擇驗證服務商之前,比較 BillionVerify 與 ZeroBounce 在準確率和速度方面的差異。

Leo
LeoFounder, BillionVerify
電子郵件驗證洞察

立即開始驗證

立即使用 BillionVerify 開始驗證電子郵件。註冊即可獲得 100 個免費積分——無需信用卡。加入數千家企業的行列,透過精準的電子郵件驗證提升電子郵件行銷的投資報酬率。

無需信用卡 · 每日 100+ 免費積分 · 30 秒後開始

99.9%
準確率
Real-time
API 速度
$0.00014
每封郵件費用
100/day
永久免費