Ön Hazırlık ve Gereksinimler
Çalışmaya başlamadan önce sisteminizde Node.js'in güncel bir sürümünün (LTS 2026 sürümü önerilir) kurulu olması gerekmektedir. Projenizi başlatmak için bir klasör oluşturun ve terminal üzerinden gerekli paketleri yükleyin.
mkdir toplu-posta-sistemi
cd toplu-posta-sistemi
npm init -y
npm install nodemailer dotenv
Burada nodemailer e-posta gönderimini sağlayan ana kütüphanemiz, dotenv ise hassas SMTP bilgilerimizi (şifre, port vb.) çevresel değişkenlerde saklamamıza yarayan güvenlik aracımızdır.
SMTP Yapılandırması ve Güvenlik
E-posta gönderimi yaparken SMTP bilgilerini kod içerisinde doğrudan yazmak büyük bir güvenlik zafiyetidir. Bunun yerine .env dosyası kullanmalıyız. Proje kök dizininde bir .env dosyası oluşturun.
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=eposta@adresiniz.com
SMTP_PASS=uygulama-ozel-sifreniz
Güvenlik uyarısı: Gmail gibi servisler için normal şifrenizi değil, "Uygulama Şifreleri" (App Passwords) kısmından oluşturulan özel şifreyi kullanmalısınız. Aksi takdirde kimlik doğrulama hataları alırsınız.
Nodemailer Taşıyıcı (Transporter) Kurulumu
Nodemailer'ın e-postaları gönderebilmesi için bir "transporter" yani taşıyıcı nesneye ihtiyacı vardır. Bu nesne, sunucu ile bağlantıyı yönetir.
require('dotenv').config();
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: process.env.SMTP_PORT,
secure: false, // 587 portu için false, 465 için true olmalı
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
});
Bu kod bloğu, SMTP sunucusu ile bağlantı kurmak için yapılandırmayı hazırlar. secure parametresi, bağlantının SSL/TLS üzerinden mi yoksa STARTTLS üzerinden mi yapılacağını belirler.
Toplu E-Posta Gönderim Mantığı
Toplu e-posta gönderirken tüm alıcıları "To" kısmına eklemek, kullanıcıların birbirlerinin e-posta adreslerini görmesine neden olur (Gizlilik ihlali). Bunun yerine, her alıcı için ayrı bir gönderim yapmalı veya "BCC" (Gizli Kopya) alanını kullanmalısınız.
const alicilar = ['kullanici1@test.com', 'kullanici2@test.com', 'kullanici3@test.com'];
async function topluGonderim() {
for (const alici of alicilar) {
try {
await transporter.sendMail({
from: '"Sistem Adı" ',
to: alici,
subject: 'Haftalık Bültenimiz',
text: 'Merhaba, bu haftaki güncellemelerimiz aşağıdadır...',
html: 'Merhaba
Bültenimize hoş geldiniz.
'
});
console.log(`${alici} adresine gönderildi.`);
} catch (error) {
console.error(`${alici} adresine gönderilemedi:`, error);
}
}
}
Bu yöntem, her alıcıya özel bir e-posta gitmesini sağlar. Ancak çok büyük listeler için (1000+ kullanıcı), bu işlem "Queue" (kuyruk) yapısı gerektirir.
E-Posta Gönderim Yöntemlerinin Karşılaştırılması
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| SMTP (Nodemailer) | Ücretsiz, kontrol tamamen sizde. | Spam filtrelerine takılma riski yüksek. |
| API (SendGrid/Mailgun) | Yüksek teslimat oranı, analiz. | Maliyetli olabilir. |
Kritik Güvenlik Uyarısı: E-posta gönderim sistemlerinde asla kullanıcıdan gelen veriyi (örneğin e-posta içeriği) doğrudan HTML olarak render etmeyin. XSS (Cross-Site Scripting) saldırılarına karşı verileri mutlaka temizleyin (sanitize) ve doğruluğunu kontrol edin.
Hata Yönetimi ve Loglama
Toplu gönderim sırasında ağ hataları veya SMTP limitleri nedeniyle kesintiler yaşanabilir. Bu yüzden her gönderimi bir hata bloğu (try-catch) içerisinde yönetmek hayati önem taşır.
// Basit bir gecikme ekleyerek sunucuyu yormayın
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
async function guvenliGonderim(liste) {
for (const alici of liste) {
await transporter.sendMail({ /* ... */ });
await sleep(1000); // Her gönderim arasında 1 saniye bekle
}
}
Bu gecikme, SMTP sağlayıcınızın sizi "spam" olarak işaretlemesini engellemeye yardımcı olan bir "rate limiting" (hız sınırlama) stratejisidir.
Sorumluluk Reddi: Bu rehberdeki kodlar eğitim amaçlıdır. Ticari ölçekli ve yüksek hacimli e-posta gönderimlerinde, teslimat oranlarını korumak için profesyonel e-posta servisleri (SES, SendGrid vb.) kullanmanız önerilir.
Sıkça Sorulan Sorular
Nodemailer ile günde kaç e-posta gönderebilirim?
Bu tamamen kullandığınız SMTP sağlayıcısının limitlerine bağlıdır. Gmail kişisel hesaplarının günlük gönderim limiti oldukça düşüktür; profesyonel işler için SMTP relay servisleri tercih edilmelidir.
E-postalarım neden "Spam" kutusuna düşüyor?
SPF, DKIM ve DMARC kayıtlarınızın DNS ayarlarınızda doğru yapılandırılmamış olması, e-postalarınızın spam olarak algılanmasına neden olur.
Toplu gönderimde "BCC" kullanmalı mıyım?
BCC kullanmak teknik olarak mümkündür ancak kişiselleştirilmiş (isimle hitap etme gibi) içerikler sunmak istiyorsanız, her kullanıcıya ayrı gönderim yapmak daha profesyoneldir.
HTML e-posta tasarımı nasıl olmalı?
E-posta istemcileri modern CSS'i tam desteklemez. Tasarımlarınızda tablo (table) tabanlı yapılar ve inline (satır içi) CSS kullanmanız en yüksek uyumluluğu sağlar.
Nodemailer ile ek dosya (attachment) gönderebilir miyim?
Evet, sendMail fonksiyonu içerisindeki attachments dizisini kullanarak dosya yolları veya buffer verileri üzerinden kolayca dosya ekleyebilirsiniz.
Performans ve Ölçeklendirme İçin "Queue" (Kuyruk) Yapısı
Toplu e-posta gönderimlerinde, e-postaları doğrudan bir döngü içerisinde await ile göndermek, sisteminizin yanıt süresini ciddi oranda düşürür. Node.js'in olay döngüsünü (event loop) bloklamamak ve hata durumunda gönderimi tekrar denemek (retry) için BullMQ veya Bee-Queue gibi bir kuyruk sistemi kullanmalısınız.
Kuyruk sistemi, gönderim görevlerini arka plana atarak ana uygulamanızın kesintisiz çalışmasını sağlar. Aşağıdaki örnek, bir işin kuyruğa nasıl ekleneceğini göstermektedir:
const Queue = require('bull');
const emailQueue = new Queue('email-sending');
// Gönderim görevini kuyruğa ekle
async function addToQueue(userData) {
await emailQueue.add({
to: userData.email,
subject: 'Bültenimize Hoş Geldiniz!',
text: `Merhaba ${userData.name}, içeriğimiz aşağıdadır...`
}, { attempts: 3 }); // Hata durumunda 3 kez tekrar dene
}
// Kuyruktaki işi işleyen worker
emailQueue.process(async (job) => {
await transporter.sendMail({
from: '"Sistem" ',
to: job.data.to,
subject: job.data.subject,
text: job.data.text
});
});
Gönderim Süreçlerinde Hata Ayıklama (Debugging) İpuçları
E-posta sistemlerinde yaşanan sorunların çoğu ağ bağlantısı, kimlik doğrulama hataları veya yanlış yapılandırılmış SMTP sunucularından kaynaklanır. Nodemailer'ın kendi içerisinde sunduğu hata ayıklama modunu aktif ederek, arka planda dönen tüm SMTP trafiğini konsolda görebilirsiniz.
SMTP Trafiğini İzleme
Geliştirme aşamasında debug: true ve logger: true parametrelerini transporter yapılandırmanıza ekleyerek, sunucu ile kurulan iletişimi adım adım takip edebilirsiniz.
const transporter = nodemailer.createTransport({
host: 'smtp.example.com',
port: 587,
secure: false,
debug: true, // SMTP trafiğini konsola döker
logger: true // İşlemleri loglar
});
Yaygın Hata Kodları ve Çözümleri
| Hata Kodu | Anlamı | Çözüm |
|---|---|---|
| ETIMEDOUT | Sunucuya ulaşılamadı. | Güvenlik duvarı (Firewall) ayarlarını ve portu kontrol edin. |
| EAUTH | Kimlik doğrulama başarısız. | Kullanıcı adı veya şifrenin doğruluğunu, 2FA aktifse uygulama şifresini kontrol edin. |
| ESOCKET | Bağlantı kopması. | Sunucu limitlerinizi (rate limit) kontrol edin, gönderim hızını düşürün. |
Unutmayın ki, yüksek hacimli gönderimlerde DKIM (DomainKeys Identified Mail) ve SPF (Sender Policy Framework) kayıtlarınızın DNS ayarlarınızda tanımlı olması, e-postalarınızın teslim edilebilirlik oranını doğrudan etkileyen kritik bir güvenlik katmanıdır.
Sonuç
Node.js ve Nodemailer kullanarak kendi toplu e-posta gönderim sisteminizi kurmak, projenizin iletişim altyapısını güçlendirmenin en hızlı yoludur. Bu rehberde öğrendiğiniz SMTP yapılandırması, döngüsel gönderim mantığı ve hata yönetimi teknikleri, profesyonel bir sistemin temel yapı taşlarıdır. Bir sonraki adım olarak, gönderimlerinizi bir veritabanı (MongoDB veya PostgreSQL) ile entegre ederek "kuyruğa alma" (Queue) sistemlerini araştırmanızı öneririm.


Yorumlar (0)
Yorum Yaz