Merhaba,

Şu an geliştirmekte olduğum kişisel bir TypeScript projemde kaydolan kullanıcılara üyelik onaylama e-postası gönderme işlevi için Nodemailer kütüphanesini ve Gmail SMTP sunucusunu kullanıyorum. Bu işlevi nasıl sağladığımı anlatmak istedim.

Şunu belirteyim: Anlatacağım yöntem kişisel projeler dışında pek seçilesi bir yöntem olmayabilir, emin değilim. Bu konuya çok hakim olmamakla birlikte bahsettiğim projem için biraz araştırma sonrası bulduğum en kolay yöntemi seçtim.

İyi okumalar. :)

Gereksinimler​

NodeJS kurulumu​

Bilgisayarımızda tarayıcı olmadan JavaScript kodlarını çalıştırabilmek için bir JavaScript çalıştırma ortamına ihtiyaç duyarız. Ben bunun için şimdiye kadar hep en popülerlerinden biri olan NodeJS'i tercih ettim fakat başka alternatifler de mevcut. Örneğin en son bildiğim kadarıyla Bun çıktı, onu da inceleyebilirsiniz. NodeJS'ten çok daha hızlı olduğu söyleniyor.

NodeJS'i kurmak için resmi sitesine başvurmanız yeterli: Download | Node.js
LTS versiyonunu kurmanızı öneririm. Sayfada belirtilene göre npm de NodeJS'in yanında geliyor.

Gmail SMTP sunucusunu kullanabilmek için yapılması gerekenler​

Gmail'ı kullanarak e-posta göndermenin başka yolları da var ama ben kendi kullandığım yöntemi anlatacağım. Bunun için bir kişisel hesapta birkaç gerekli işlem yapmak gerekiyor:
  1. Önerim, yeni bir kişisel Gmail hesabı açmanız. Halihazırda hesabınız varsa onu da kullanabilirsiniz ama önermem; asıl hesabınızı bence kullanmayın. Buradaki "Hesap oluştur" butonuna basarak hesap oluşturma sayfasına ulaşabilirsiniz.
    Sanırım bu buton aslında oturum açmaya yönlendiriyor, oradan "Hesap oluşturun"a tıklayıp "Kişisel kullanımım için" seçeneğine tıklayabilirsiniz:
    1703944985148.webp
  2. Google, 30 Mayıs 2022'den itibaren üçüncü taraf uygulamalar için "Güvenliği düşük uygulamalar" ismi altında yeni bir kısıt getirmiş. Detaylara buradan ulaşabilirsiniz.
    Kısaca olay şu ki uygulamamızın e-posta gönderebilmesi için direkt hesap şifremizi kullanamayacağız. Benim bulduğum tek yöntem, uygulama şifresi kullanma. Bunun için hesap ayarlarından bir uygulama şifresi oluşturmamız gerekiyor ve bu işlem, hesapta 2 Adımlı Doğrulama'nın etkinleştirilmiş olmasını gerektiriyor:
    1703945774677.webp

    Gösterdiğim yerden, aşamaları takip ederek bu özelliği etkinleştirebilirsiniz.
    Uygulama şifresi oluşturmayı bir sonraki adımda anlatayım.
  3. 2 Adımlı Doğrulama'yı etkinleştirdikten sonra "Uygulama şifreleri" sayfasına erişmeniz gerekiyor. Buraya, 2 Adımlı Doğrulama sayfasının en altından erişebilirsiniz veya arama çubuğuna "uygulama" yazdığınızda önerilerde çıkacak (ikinci seçenek):
    1703946116260.webp
    1703946170305.webp
  4. "Uygulama şifreleri" sayfasında sizden direkt uygulama adı isteyecek. Buraya istediğiniz herhangi bir ad yazabilirsiniz. Ben "techolay-nodemailer-gmail-smtp" yazdım:
    1703946319899.webp
  5. "Oluştur"a basınca direkt oluşturulan 16 haneli şifreyi gösterecek size. Ben ne olur ne olmaz sansürledim fakat şifre "4-4-4-4" formatında, aralarda birer boşlukla veriliyor (örneğin tech olay uygu lama):
    1703946375599.webp

    Bu şifreyi bir yere kaydedin. "Tamamlandı" butonuna bastıktan sonra tekrar göremiyorsunuz galiba. Bir aksilik çıkarsa yeni şifre oluşturursunuz.
    Açıklamada "Şifreyi bir yere not etmeyin." denilmiş ama ben projemde e-posta göndermek için hep bu şifreyi kullandım, yani bir yere kaydedip kullandım.

NodeJS'i de kurduk, yeni bir Gmail hesabı oluşturup uygulama şifremizi de oluşturduk. Geriye denemek kaldı!​

Deneme projesi oluşturma​

  1. Bilgisayarınızda, tercih ettiğiniz bir yerde yeni bir klasör açın. Ben masaüstünde "nodemailer-gmail" ismiyle açtım. Sonrasında tercihe bağlı olarak bu klasörü bir IDE'de açın. Ben VS Code kullanıyorum. Çok beğendiğim için tavsiye ederim.
  2. Komut satırında aşağıdaki komutu çalıştırın. Bunu yapmadan önce, komut satırında proje klasöründe olduğunuza emin olun:
    [CODE lang="bash" title="Proje oluşturma komutu"]npm init -y[/CODE]
    Bu komut, bir NodeJS projesi için gerekli package.json dosyasını oluşturacak.
  3. Oluşturulan package.json dosyası şu şekilde gözükecektir:
    [CODE lang="json" title="package.json dosyasının ilk hali"]{
    "name": "nodemailer-gmail",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
    },
    "keywords": [],
    "author": "",
    "license": "ISC"
    }
    [/CODE]
    name'e klasör ismi atanıyor. Sizin klasör isminiz farklıysa orası da farklı olacaktır.
  4. package.json dosyasında, süslü parantezlerin içine "type": "module" özelliğini ekleyin:
    [CODE lang="json" title="type özelliğinin eklenmiş hali"]{
    "type": "module",
    "name": "nodemailer-gmail",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
    },
    "keywords": [],
    "author": "",
    "license": "ISC"
    }[/CODE]
  5. Yine komut satırında, Nodemailer kütüphanesini projeye eklemek için şu komutu çalıştırın:
    [CODE lang="bash" title="Nodemailer kütüphanesini ekleme komutu"]npm i nodemailer[/CODE]
  6. Yeni bir .env dosyası oluşturup, Gereksinimler kısmında oluşturduğunuz yeni Gmail hesabının e-posta adresini ve uygulama şifresini ekleyin:
    [CODE title=".env içeriği"]
    GMAIL_SMTP_EMAIL_ADDRESS="[email protected]"
    GMAIL_SMTP_APP_PASSWORD="16 haneli uygulama şifresi"
    [/CODE]
    Bu aşama tercihe bağlı. Kodunuzda direkt bulunmaması gereken değerleri ayrı bir dosyada bulundurmuş oluyoruz.
  7. Yeni bir index.js dosyası oluşturup içine aşağıda paylaştığım kodu yapıştırın:
    [CODE lang="javascript" title="Uygulama kodu"]
    import { createTransport } from "nodemailer";
    import readline from "readline";

    function main() {
    // https://nodemailer.com/about/#example
    /*
    const transporter = nodemailer.createTransport({
    host: "smtp.ethereal.email",
    port: 587,
    secure: false, // `true` for port 465, `false` for all other ports
    auth: {
    user: "[email protected]",
    pass: "jn7jnAPss4f63QBp6D",
    },
    });
    */

    const transporter = createTransport({
    host: "smtp.gmail.com",
    port: 465,
    secure: true,
    auth: {
    user: process.env.GMAIL_SMTP_EMAIL_ADDRESS,
    pass: process.env.GMAIL_SMTP_APP_PASSWORD,
    },
    });

    // https://stackoverflow.com/questions/61394928/get-user-input-through-node-js-console
    const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    });

    let mailTo = null;
    let subject = "Deneme e-postası";
    let content = "Selam!";

    rl.question(`E-posta hangi adrese gönderilsin? (Gerekli)\n`, (mailToInput) => {
    if (mailToInput) mailTo = mailToInput;
    rl.question(`Başlığı ne olsun? ("${subject}")\n`, (subjectInput) => {
    if (subjectInput) subject = subjectInput;
    rl.question(`Ne yazsın? ("${content}")\n`, (contentInput) => {
    if (contentInput) content = contentInput;
    rl.close();
    });
    });
    });

    rl.on("close", () => {
    console.log("E-posta gönderiliyor, bekleyiniz...");
    transporter
    .sendMail({
    from: process.env.GMAIL_SMTP_EMAIL_ADDRESS,
    to: mailTo,
    subject,
    html: content,
    })
    .then((value) => {
    // `value`yu şu şekilde yazdırıp detaylı bilgileri görebilirsiniz:
    // console.log(value);
    console.log(`${mailTo} e-posta adresine "${subject}" başlıklı, "${content}" içerikli e-posta gönderildi!`);
    })
    .catch((e) => {
    console.error("Maalesef bir hata meydana geldi :( Şu şekilde:");
    console.error(e);
    });
    });
    }

    main();
    [/CODE]
    Burada process.env ile başlayan ortam değişkenlerinin değerlerini dilerseniz direkt koda gömebilirsiniz. Bu haliyle .env dosyasındaki değişkenler alınıyor.
  8. Komut satırında şu komutu çalıştırarak uygulamayı çalıştırabilirsiniz:
    [CODE lang="bash" title="Uygulamayı çalıştırma komutu"]node --env-file='.env' index.js[/CODE]
    Eğer 6. adımı uygulamayıp Gmail ile ilgili bilgileri direkt koda yazmayı tercih ettiyseniz --env-file='.env' kısmını yazmanıza gerek yok.
  9. Uygulamayı çalıştırdığınızda sizden şu bilgileri komut satırından girmenizi isteyecek:
    • E-postanın gönderileceği adres: Gerekli, girmeniz gerekiyor.
    • E-posta başlığı: Gerekli değil. Hiçbir şey yazmadan Enter'a basarsanız varsayılan başlık şu: "Deneme e-postası".
    • E-posta içeriği: Gerekli değil. Hiçbir şey yazmadan Enter'a basarsanız varsayılan içerik şu: "Selam!"
  10. Bilgileri girdiğiniz takdirde eğer sorun çıkmazsa kısa bir süre sonra e-posta belirttiğiniz adrese ulaşmış olacak.
Umarım işinize yarar. :)
 
Böyle bir hata aldım.
Node: Bad option: --env-file=.env

Bunu tahmin ediyordum. Sanırım Node'u siz önceden kurmuşsunuz.

Bu, Node'a 20 versiyonuyla (?) yeni gelmiş bir özellik. Şu komutu çalıştırarak Node versiyonunuzu söyleyebilir misiniz?

[CODE lang="bash" title="Node versiyon öğrenme komutu"]node -v[/CODE]

Şuradan öğrendiğim kadarıyla şu komutla .env dosyasına gerek duymadan ortam değişkenlerini programa sağlayabiliyorsunuz:

Bash:
GMAIL_SMTP_EMAIL_ADDRESS="..." GMAIL_SMTP_APP_PASSWORD="..." node index.js
 
Sürüm v18.17.1
Bu arada sorunu çözdüm.
Env dosyasını silip gerekli bilgileri Index'in içine koyunca başarılı şekilde gönderebildim.

Eskiden bayağı uğraşmıştım Google ile mail için çözüm şimdiyeymiş, ben bunu daha da geliştiririm umarım bu da kaldırılmaz teşekkürler.
 
Env dosyasını silip gerekli bilgileri Index'in içine koyunca başarılı şekilde gönderebildim.

Bu genelde tavsiye edilen bir yol olmadığı için bunu sadece alternatif olarak sundum rehberde.

Sorunu çözmenize sevindim :)

Umarım istediğiniz aşamaya kadar geliştirme yapabilirsiniz.

Tekrar etmem gerekir ki bu rehberde anlattığım yöntem pek tercih edilesi olmayabilir. Konuya çok hakim olmayıp sadece kişisel projem için bulduğum çözümü aktardım.
 
Bu genelde tavsiye edilen bir yol olmadığı için bunu sadece alternatif olarak sundum rehberde.

Sorunu çözmenize sevindim :)

Umarım istediğiniz aşamaya kadar geliştirme yapabilirsiniz.

Tekrar etmem gerekir ki bu rehberde anlattığım yöntem pek tercih edilesi olmayabilir. Konuya çok hakim olmayıp sadece kişisel projem için bulduğum çözümü aktardım.

Diğer yollar biraz uzun ve sıkıcı ben yarıda bırakmıştım bu iş kısa ve güzel.
Mail atamadığım zaman Telegram webhook ile yapıyordum en azından ikisini de koyayım:D