Validator email sederhana yang menggunakan SMTP verification untuk keperluan non-komersial. Tidak perlu bayar ke ZeroBounce atau useBouncer!

πŸ“‹ Daftar Isi


πŸ”§ Cara Kerja

Tahap-tahap Validasi

Email Input
    ↓
[1] Cek Format (Regex)
    ↓
[2] Extract Domain
    ↓
[3] Lookup MX Record (DNS)
    ↓
[4] Terhubung ke Mail Server
    ↓
[5] Kirim Perintah SMTP: RCPT TO <email>
    ↓
[6] Analisis Response Code
    - 250 = βœ“ VALID (Email diterima)
    - 550 = βœ— INVALID (User tidak ditemukan)
    - 421/452 = ? UNKNOWN (Server sibuk/tidak bisa)

Respons SMTP yang Mungkin:

CodeArtiKesimpulan
250AcceptedValid βœ“
550User not foundInvalid βœ—
551User not localInvalid βœ—
421Service unavailableUnknown ?
452Insufficient storageUnknown ?
500+Server errorUnknown ?

πŸ’» Setup

Opsi 1: Script CLI (Standalone)

# Cukup Node.js, tidak perlu install apa-apa
node email-validator.js

Kelebihan:

  • Tidak perlu install dependencies
  • Cepat untuk quick test
  • Pure Node.js

Opsi 2: API Server dengan Express.js

# Install dependencies
npm install express cors

# Jalankan server
node email-validator-api.js

Server akan berjalan di http://localhost:3000

Opsi 3: Minimal HTTP Server (Zero Dependencies)

# Tidak perlu install apa-apa
node email-validator-minimal.js

Server akan berjalan di http://localhost:3000


πŸš€ Penggunaan

1. Script CLI (email-validator.js)

node email-validator.js

Output contoh:

Validating: user@gmail.com
──────────────────────────────────────────────
βœ“ Syntax valid
βœ“ Domain: gmail.com
βœ“ MX Records found: aspmx.l.google.com, alt1.aspmx.l.google.com
β—Œ Verifying with mail server...

Result: {
  email: 'user@gmail.com',
  valid: null,
  reason: 'Could not verify with any mail server',
  step: 'smtp'
}
Status: ? UNKNOWN

2. API Server

Start Server:

node email-validator-api.js
# atau
node email-validator-minimal.js

Validasi Single Email (GET):

curl "http://localhost:3000/validate?email=user@example.com"

Response:

{
  "email": "user@example.com",
  "valid": true,
  "mailServer": "mail.example.com",
  "code": 250,
  "timestamp": "2024-04-20T10:30:00.000Z"
}

Validasi Single Email (POST):

curl -X POST http://localhost:3000/validate \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com"}'

Validasi Batch:

curl -X POST http://localhost:3000/validate-batch \
  -H "Content-Type: application/json" \
  -d '{
    "emails": [
      "user1@example.com",
      "user2@gmail.com",
      "user3@outlook.com"
    ]
  }'

Response:

{
  "total": 3,
  "valid": 2,
  "invalid": 1,
  "unknown": 0,
  "results": [
    {
      "email": "user1@example.com",
      "valid": true,
      "mailServer": "mail.example.com",
      "code": 250
    },
    {
      "email": "user2@gmail.com",
      "valid": null,
      "reason": "Could not verify with any mail server",
      "code": null
    },
    {
      "email": "user3@outlook.com",
      "valid": false,
      "mailServer": "outlook.com",
      "code": 550
    }
  ],
  "timestamp": "2024-04-20T10:30:00.000Z"
}

3. Web Interface

Buka email-validator.html di browser:

# Jika server API berjalan di port 3000
open email-validator.html
# atau buka manual di browser: file:///path/to/email-validator.html

πŸ“‘ API Reference

Endpoints

GET /validate?email=<email>

Validasi email via query parameter.

Parameter:

  • email (required) – Email untuk divalidasi

Response:

{
  "email": "user@example.com",
  "valid": true|false|null,
  "reason": "Deskripsi alasan",
  "mailServer": "mail.server.com",
  "code": 250,
  "timestamp": "ISO-8601"
}

POST /validate

Validasi email via request body.

Body:

{
  "email": "user@example.com"
}

Response: Sama seperti GET

POST /validate-batch

Validasi multiple emails sekaligus.

Body:

{
  "emails": [
    "user1@example.com",
    "user2@gmail.com"
  ]
}

Response:

{
  "total": 2,
  "valid": 1,
  "invalid": 0,
  "unknown": 1,
  "results": [...],
  "timestamp": "ISO-8601"
}

GET /health

Health check endpoint.

Response:

{
  "status": "ok",
  "uptime": 3600,
  "timestamp": "ISO-8601"
}

GET /stats (API version only)

Lihat cache statistics.

Response:

{
  "cacheSize": 42,
  "cacheEntries": ["user@example.com", "...]
}

⚠️ Limitation & Tips

Keterbatasan

  1. Gmail, Outlook, Yahoo: Sering REJECT
    • Provider besar sering memblock SMTP verification demi privacy
    • Hasil: UNKNOWN (tidak bisa dipastikan valid/invalid)
    • Ini adalah bug provider, bukan bug validator
  2. Catch-all Domains Beberapa domain (terutama hosting shared) menerima SEMUA email Contoh: server@somehost.com β†’ diterima random12345@somehost.com β†’ juga diterima! Status: UNKNOWN (tidak bisa dipastikan)
  3. Rate Limiting
    • Jangan validasi ribuan email sekaligus ke domain yang sama
    • Mail server akan block/slow down Anda
    • Tambahkan delay antara request (minimal 1-2 detik)
  4. Timeout Issues
    • Beberapa mail server slow respond
    • Default timeout: 8 detik
    • Bisa disesuaikan di constructor: new EmailValidator({ timeout: 10000 })

Tips Penggunaan

1. Batch Processing dengan Delay

const emails = ['a@test.com', 'b@test.com', 'c@test.com'];

for (const email of emails) {
  const result = await validator.validate(email);
  console.log(result);
  
  // Tunggu 2 detik sebelum validasi berikutnya
  await new Promise(r => setTimeout(r, 2000));
}

2. Caching Hasil

const cache = new Map();

async function validateWithCache(email) {
  if (cache.has(email)) {
    return cache.get(email);
  }
  
  const result = await validator.validate(email);
  cache.set(email, result);
  return result;
}

3. Error Handling

try {
  const result = await validator.validate(email);
  
  if (result.valid === true) {
    console.log('βœ“ Email valid');
  } else if (result.valid === false) {
    console.log('βœ— Email invalid');
  } else {
    console.log('? Tidak bisa dipastikan');
  }
} catch (error) {
  console.log('Server error:', error.message);
}

4. Kombinasi dengan Format Validation

// Jangan langsung SMTP check jika format sudah jelek
if (!email.includes('@') || !email.includes('.')) {
  return { valid: false, step: 'syntax' };
}

// Baru SMTP check kalau format OK
const result = await validator.verifyWithSMTP(email, mxRecords);

5. Integration dengan Form

<form>
  <input type="email" id="email" />
  <button type="button" onclick="validateOnBlur()">
    Cek Email
  </button>
  <span id="feedback"></span>
</form>

<script>
async function validateOnBlur() {
  const email = document.getElementById('email').value;
  const feedback = document.getElementById('feedback');
  
  // Show loading
  feedback.textContent = 'Sedang cek...';
  feedback.style.color = 'orange';
  
  const result = await fetch(`/validate?email=${email}`).then(r => r.json());
  
  if (result.valid) {
    feedback.textContent = 'βœ“ Email valid';
    feedback.style.color = 'green';
  } else {
    feedback.textContent = 'βœ— Email tidak valid';
    feedback.style.color = 'red';
  }
}
</script>

πŸ”’ Security Considerations

Untuk Penggunaan Production

  1. Rate Limiting // Tambahkan rate limiter middleware const rateLimit = require('express-rate-limit'); const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 menit max: 100 // max 100 request per IP }); app.use('/validate', limiter);
  2. Authentication
    • Jangan expose tanpa authentication
    • Add API key untuk production:
    const apiKey = req.headers['x-api-key']; if (apiKey !== process.env.VALIDATOR_API_KEY) { return res.status(401).json({ error: 'Unauthorized' }); }
  3. Timeout & Resource
    • Set timeout untuk batch requests
    • Limit batch size (max 100 emails per batch)
    • Monitor server resource usage
  4. Logging const fs = require('fs'); function logValidation(email, result) { fs.appendFileSync('validations.log', JSON.stringify({ email, result, timestamp: new Date() }) + '\n' ); }

πŸ“Š Comparison vs Commercial Services

FeatureValidator LokalZeroBounceuseBouncer
CostGratis$0.5-1 per 1000$0.3-0.8 per 1000
Setup5 menitAPI keyAPI key
Accuracy~95%~98%~97%
Speed5-10 detikReal-timeReal-time
BulkOK (dengan delay)ExcellentExcellent
SupportSelf-serviceEmail supportEmail support
PrivacyLokal 100%Cloud (tergantung mereka)Cloud

❓ FAQ

Q: Kenapa Gmail selalu “unknown”? A: Gmail block SMTP verification. Gunakan Gmail API atau accept “unknown” untuk Gmail.

Q: Apakah bisa detect disposable email? A: Tidak included. Bisa add list dari: https://github.com/disposable-email-domains/disposable-email-domains

Q: Berapa banyak email bisa divalidasi per hari? A: Tidak ada limit, tapi jangan spam. Tambahkan delay 1-2 detik per email.

Q: Bagaimana kalau mail server tidak respond? A: Akan timeout. Increase timeout atau accept hasilnya “unknown”.

Q: Bisa jalan di VPS? A: Ya, asal:

  • Port 25 (SMTP) tidak diblock provider
  • Node.js terinstall
  • Cukup resource (minimal 256MB RAM)

πŸ“ License & Usage

Kode ini untuk penggunaan non-komersial. Untuk commercial use, gunakan service yang sudah mature seperti ZeroBounce atau useBouncer.

Jangan gunakan untuk:

  • Bulk spam
  • Harvesting email
  • Selling email lists
  • Mengganggu mail servers

Boleh digunakan untuk:

  • Validasi form di website Anda sendiri
  • Membersihkan database email lokal
  • Internal tools
  • Learning purpose

Happy validating! πŸ“§