Email

Uygulamadan Mail Gönderme Rehberi: SMTP, API ve Doğru Yol

Şifre sıfırlama, doğrulama ve fatura bildirimleri için mail göndermek göründüğü kadar basit değil. SMTP mi API mi, neden mailler spam'e düşer, kendi domaininiz neden önemli — uygulamacı gözüyle anlattık.

Yazar: Skyversal Ekibi

Bir uygulama yazdınız, kullanıcı kaydı çalışıyor, her şey yolunda. Sonra şifre sıfırlama özelliğini ekliyorsunuz ve işler karışıyor: mail gidiyor mu, spam'e mi düşüyor, kullanıcı hiç aldı mı?

Bu yazı, "mail gönderme" işini çalışan bir hâle getirmek için bilinmesi gerekenleri anlatıyor. Kütüphane seçiminden çok, neden kısmına odaklanıyoruz — çünkü sorunların çoğu kodda değil, altyapıda çıkıyor.

Önce şunu netleştirelim: mail göndermek = itibar yönetimi

Bir HTTP isteği atıp 200 alıyorsanız iş bitmiştir. Mail öyle değil. Sunucunuzun maili kabul edilmesi için alıcı tarafın sizi tanıması gerekir:

  • Bu IP gerçekten o domain adına mı gönderiyor? (SPF)
  • Mail gerçekten o domainden mi çıktı, yolda değişti mi? (DKIM)
  • Bu domain "ben bu maili gönderdim" diyor mu? (DMARC)

Üçü de yoksa Gmail ve Outlook maili reddeder — spam'e atması bile lüks. 2024'ten beri Gmail, kimlik doğrulaması olmayan toplu gönderimi doğrudan 550 5.7.26 ile geri çeviriyor:

550-5.7.26 Gmail requires all senders to authenticate with either SPF or DKIM.
  DKIM = did not pass
  SPF [example.com] with ip [203.0.113.10] = did not pass

Yani "mail gönderme" özelliği eklerken aslında DNS yapılandırması yapıyorsunuz. Bu, mimari kararın kendisi.

SMTP mi, API mi?

Teknik olarak ikisi de aynı işi yapar. Fark, kimin neyi yönettiğinde:

SMTPHTTP API
EntegrasyonHer dilde hazır kütüphaneSağlayıcıya özel SDK
Hata ayıklamatelnet ile elle konuşabilirsinizYanıt gövdesine bakarsınız
Özellik setiStandart (RFC 5321)Şablon, webhook, analytics
KilitlenmeDüşük — her sağlayıcı desteklerSağlayıcıya bağlı

Pratik kural: işlem maili (transactional — şifre sıfırlama, fatura) için SMTP yeterli ve taşınabilir. Pazarlama maili (kampanya, segmentasyon) için API daha zengin.

Çoğu proje SMTP ile başlar ve orada kalır. Bu doğru bir tercih — smtplib, nodemailer, System.Net.Mail gibi kütüphaneler her dilde var ve davranışları öngörülebilir.

Kendi domaininiz neden önemli

İki seçenek var:

  1. Paylaşımlı subdomain — projeniz.saglayici.com. Hızlı başlar, DNS derdi yok.
  2. Kendi domaininiz — no-reply@sirketiniz.com.

Birincisi cazip görünüyor ama gizli bir maliyeti var: itibarı paylaşıyorsunuz. Aynı domainden gönderen başka bir müşteri spam kampanyası yaparsa, o domain kara listeye girer ve sizin şifre sıfırlama mailiniz de düşer. Sizin kodunuzda hiçbir şey değişmemiştir ama sistem çalışmıyordur.

Kendi domaininizde ise itibar size aittir. Kötü giderse düzeltmeniz gereken tek şey kendi gönderim alışkanlığınızdır.

Bu yüzden Skyversal PaaS mail servisinde kendi domaininizi bağlamak ücretsiz: platformun çıkarı da bunu gerektiriyor.

Kod: üç dilde çalışan örnek

Aşağıdaki örnekler aynı env değişkenlerini kullanır — böylece sağlayıcı değişse kod değişmez:

MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=no-reply@sirketiniz.com
MAIL_PASSWORD=********

Python

import smtplib
from email.message import EmailMessage
from email.utils import make_msgid, formatdate
import os

msg = EmailMessage()
msg["Subject"]  = "Şifre sıfırlama"
msg["From"]     = "no-reply@sirketiniz.com"
msg["To"]       = kullanici_email
# Message-ID ZORUNLU: eksikse Gmail 550 ile reddeder
msg["Message-ID"] = make_msgid(domain="sirketiniz.com")
msg["Date"]     = formatdate(localtime=True)
msg.set_content("Sıfırlama bağlantısı: https://...")

with smtplib.SMTP(os.environ["MAIL_HOST"], 587, timeout=30) as s:
    s.ehlo()
    s.starttls()                                    # STARTTLS şart
    s.login(os.environ["MAIL_USERNAME"], os.environ["MAIL_PASSWORD"])
    s.send_message(msg)

Node.js

const nodemailer = require("nodemailer");

const transport = nodemailer.createTransport({
  host: process.env.MAIL_HOST,
  port: 587,
  secure: false,          // 587 = STARTTLS, 465 = implicit TLS
  auth: {
    user: process.env.MAIL_USERNAME,
    pass: process.env.MAIL_PASSWORD,
  },
});

await transport.sendMail({
  from: "no-reply@sirketiniz.com",
  to: kullaniciEmail,
  subject: "Şifre sıfırlama",
  text: "Sıfırlama bağlantısı: https://...",
});

.NET

using System.Net;
using System.Net.Mail;

// DIKKAT: .NET SmtpClient yalnız STARTTLS destekler.
// EnableSsl = true → STARTTLS (port 587).
// Implicit TLS (port 465) DESTEKLENMEZ.
using var client = new SmtpClient(host, 587)
{
    EnableSsl   = true,
    Credentials = new NetworkCredential(user, pass),
};

var mail = new MailMessage("no-reply@sirketiniz.com", kullaniciEmail)
{
    Subject = "Şifre sıfırlama",
    Body    = "Sıfırlama bağlantısı: https://...",
};
await client.SendMailAsync(mail);

Dikkat: .NET'in SmtpClient'ı 465 portunu (implicit TLS) desteklemez. 465 kullanmaya çalışırsanız bağlantı kurulur ama el sıkışma başarısız olur. 587 + EnableSsl = true doğru kombinasyon.

Spam'e düşmenin gerçek sebepleri

Kimlik doğrulaması doğruysa mail gönderilir. Spam'e düşmesi ayrı bir konu — ve sıklıkla şunlardan biri:

  • Eksik Message-ID — Gmail bunu doğrudan reddeder (550 5.7.1). Kütüphanelerin çoğu ekler, ama elle kurduğunuz EmailMessage'da eklemeniz gerekir.
  • Ters DNS (PTR) yok — gönderen IP'nin bir hostname'e çözülmesi ve o hostname'in aynı IP'ye dönmesi (FCrDNS) beklenir.
  • İçerik ve başlık uyumsuzluğu — "Faturanız" konusu, içerikte tek satır link.
  • Ani hacim artışı — yeni IP'den bir günde 10.000 mail. Isınma (warm-up) gerekir.
  • Link kısaltıcı — bit.ly gibi servisler spam skorunu yükseltir.

Kontrol listesi

Yayına almadan önce:

  • ☐ SPF kaydı var ve gönderen IP'yi içeriyor
  • ☐ DKIM imzası geçiyor (Authentication-Results başlığında dkim=pass)
  • ☐ DMARC kaydı var (_dmarc TXT)
  • ☐ PTR kaydı gönderen hostname'e çözülüyor
  • ☐ Her mesajda Message-ID ve Date var
  • ☐ 587 + STARTTLS kullanılıyor (465 değil)
  • ☐ Hata yolu var: mail gönderilemezse kullanıcıya anlamlı mesaj dönüyor

Altyapıyı kendiniz mi yöneteceksiniz?

Postfix kurmak, DKIM imzalama servisi çalıştırmak, kota uygulamak ve abuse engellemek ayrı bir üründür. Çoğu uygulama için bu, ürünün kendisinden daha fazla iş çıkarır.

Skyversal PaaS'ta bu katman hazır: her plana günde 200 mail ücretsiz, SPF/DKIM/PTR tarafımızda, kendi domaininizi bağlamak ücretsiz. Kodunuzda yalnız env değişkenlerini okumanız yeterli.

Detaylı teknik doküman: Skyversal dokümantasyonu.

Son güncelleme: 24 Ekim 2026