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:
| Code | Arti | Kesimpulan |
|---|---|---|
| 250 | Accepted | Valid β |
| 550 | User not found | Invalid β |
| 551 | User not local | Invalid β |
| 421 | Service unavailable | Unknown ? |
| 452 | Insufficient storage | Unknown ? |
| 500+ | Server error | Unknown ? |
π» 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
- 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
- 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) - 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)
- 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
- 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); - 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' }); } - Timeout & Resource
- Set timeout untuk batch requests
- Limit batch size (max 100 emails per batch)
- Monitor server resource usage
- 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
| Feature | Validator Lokal | ZeroBounce | useBouncer |
|---|---|---|---|
| Cost | Gratis | $0.5-1 per 1000 | $0.3-0.8 per 1000 |
| Setup | 5 menit | API key | API key |
| Accuracy | ~95% | ~98% | ~97% |
| Speed | 5-10 detik | Real-time | Real-time |
| Bulk | OK (dengan delay) | Excellent | Excellent |
| Support | Self-service | Email support | Email support |
| Privacy | Lokal 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! π§