author Ahmad Muhardian

Belajar Nodejs #09: Bagaimana Cara Mengirim Email di Nodejs?


Cara Mengirim Email dengan Nodejs

Coba perhatikan.

Ada beberapa aplikasi atau layanan yang kamu gunakan dan layanan tersebut sering kali mengirim email.

Bahkan ada yang sampai memenuhi kotak suratmu.

Contoh:

Saat kamu jarang buka facebook, maka facebook akan mengirimkan email.

Saat kamu mendaftar sebuah layanan, maka kamu akan menerima email dari layanan tersebut.

Apakah mereka mengirim secara manual?

Jawabanya: Tidak.

Siapa yang akan mampu mengirim email ke ribuan atau jutaan pengguna?

Kamu mampu?

Ya, mampu dengan menggunakan program.

Program inilah yang akan kita buat pada tutorial ini.

Program pengirim email biasanya dibutuhkan untuk beberapa studi kasus seperti:

  • Reset Password;
  • Email Marketing;
  • Contact Form;
  • Verifikasi Akun;
  • dan sebagainya.

Pada tutorial ini, kita akan belajar cara mengirim email di nodejs dengan menggunakan modul nodemailer dan layanan gmail.

Mari kita mulai…

Persiapan Awal

Silahkan buat project baru dengan membuat direktori bernama 📁 nodejs-email.

mkdir nodejs-email && cd nodejs-email

Kemudian install nodemailer di sana.

npm install nodemailer

Tunggulah sampai proses instalasi selesai.

Instalasi Nodemailer

Membuat Program Nodejs untuk Kirim Email

Silahkan buat file baru bernama 📄 send_email.js, kemudian isi dengan kode berikut:

var nodemailer = require('nodemailer');

var transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: '[email protected]',
        pass: 'your password'
    }
});

var mailOptions = {
    from: '[email protected]',
    to: '[email protected]',
    subject: 'Sending Email using Nodejs',
    text: 'That was easy!'
};

transporter.sendMail(mailOptions, (err, info) => {
    if (err) throw err;
    console.log('Email sent: ' + info.response);
});

Penjelasan:

Pertama, kita membutuhkan modul nodemailer. Lalu kita impor dengan fungsi reqiuire().

var nodemailer = require('nodemailer');

Lalu setelah itu, kita buat sebuah objek transporter:

var transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: '[email protected]',
        pass: 'your password'
    }
});

Objek ini nantinya yang akan bertugas mengirim email.

Perhatikan parameter yang diberikan pada objek transporter.

Silahkan ubah alamat email dan password-nya sesuai dengan email dan password yang kamu miliki.

Berikutnya, kita membuat objek mailOptions.

var mailOptions = {
    from: '[email protected]',
    to: '[email protected]',
    subject: 'Sending Email using Nodejs',
    text: 'That was easy!'
};

Objek ini akan menampung data email yang akan kita kirim.

Seperti alamat asal, alamat tujuan, subjek, teks, dan lampiran yang akan dikirim.

Terakhir…

Kita kirim emailnya dengan fungsi sendMail().

transporter.sendMail(mailOptions, (err, info) => {
    if (err) throw err;
    console.log('Email sent: ' + info.response);
});

Percobaan Kirim Email

Sekarang coba eksekusi programnya…

Apabila kamu mendapatkan error seperti ini:

Error kirim email dengan gmail dan nodejs

Ini artinya, kita gagal login ke akun gmail.

Ada beberapa kemungkinan:

  1. Passwordnya salah;
  2. Pengaturan Keamanan di Gmail yang tidak mengizinkan aplikasi pihak ketiga.
  3. Koneksi internet;

Coba periksa kembali…

Untuk point yang nomer 2, coba ubah pengaturan keamanan di akun Google.

Aktifkan bagian ini:

Pengaturan Gmail

Setelah beberapa menit, coba lagi…

Sukses kirim email dengan gmail dan nodejs

Kirim email berhasil. 🎉

Untuk memastikan, coba periksa inbox email tujuan.

Inbox kirim email dengan gmail dan nodejs

Kirim Email Tingkat Lanjut

Oke, kita sudah berhasil kirim email…

Namun, ada beberapa hal lagi yang perlu kita bahas:

Mengirim Email ke Banyak Orang

Untuk mengirim email ke banyak orang atau penerima, kita cukup isi alamat email penerima di properti to pada mailOptions: 1

var mailOptions = {
  from: '[email protected]',
  to: '[email protected], [email protected]',
  subject: 'Sending Email using Node.js',
  text: 'That was easy!'
} 

Pisahkan alamat penerima dengan tanda koma.

Mengirim Email yang berisi HTML

Untuk mengirim email dengan konten HTML, kita cukup menggnati properti text menjadi html.

var mailOptions = {
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Sending Email using Node.js',
  html: '<h1>Welcome</h1><p>That was easy!</p>'
}

Tips: Kita juga bisa menggunakan template HTML dari file eksternal. Gunakan modul fs untuk membaca file HTML.

Coba pelajar di: Tutorial Nodejs #5: Baca Tulis File dengan Modul File System

Mengirim Lampiran

Untuk mengirim lampiran (attachment), kita bisa menambahkan properti attachments pada mailOptions.

Isi dari properti attachments berupa array dari objek file yang akan dilampirkan.

Berikut ini contah kodenya yang saya dapatkan dari dokuemntasi Nodemailer. 2

let message = {
    ...
    attachments: [
        {   // utf-8 string as an attachment
            filename: 'text1.txt',
            content: 'hello world!'
        },
        {   // binary buffer as an attachment
            filename: 'text2.txt',
            content: new Buffer('hello world!','utf-8')
        },
        {   // file on disk as an attachment
            filename: 'text3.txt',
            path: '/path/to/file.txt' // stream this file
        },
        {   // filename and content type is derived from path
            path: '/path/to/file.txt'
        },
        {   // stream as an attachment
            filename: 'text4.txt',
            content: fs.createReadStream('file.txt')
        },
        {   // define custom content type for the attachment
            filename: 'text.bin',
            content: 'hello world!',
            contentType: 'text/plain'
        },
        {   // use URL as an attachment
            filename: 'license.txt',
            path: 'https://raw.github.com/nodemailer/nodemailer/master/LICENSE'
        },
        {   // encoded string as an attachment
            filename: 'text1.txt',
            content: 'aGVsbG8gd29ybGQh',
            encoding: 'base64'
        },
        {   // data uri as an attachment
            path: 'data:text/plain;base64,aGVsbG8gd29ybGQ='
        },
        {
            // use pregenerated MIME node
            raw: 'Content-Type: text/plain\r\n' +
                 'Content-Disposition: attachment;\r\n' +
                 '\r\n' +
                 'Hello world!'
        }
    ]
}

Mari kita coba mengirim sebuah file txt yang berisi Hello World.

Berikut ini kodenya:

var nodemailer = require('nodemailer');

var transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: '[email protected]',
        pass: 'your password'
    }
});

var mailOptions = {
    from: '[email protected]',
    to: '[email protected]',
    subject: 'Sending Email using Nodejs',
    html: '<h1>Welcome</h1><p>That was easy!</p>',
    attachments: [
        {
            filename: 'text1.txt',
            content: 'hello world!'
        }
    ]
};

transporter.sendMail(mailOptions, (err, info) => {
    if (err) throw err;
    console.log('Email sent: ' + info.response);
});

Coba eksekusi:

Kirim email dengan nodejs

Hasilnya:

Inbox yang berisi lampiran

Mantap 👍

Bonus: Membuat Aplikasi Contact Form

Nah, sekarang mari kita coba kirim email untuk studi kasus di dunia nyata.

Yaitu: membuat contact form.

Silahkan buat file baru dengan nama contact_form.html dengan isi sebagai berikut:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Contact Us</title>

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
        crossorigin="anonymous">
</head>

<body>
    <div class="container p-5">
        <div class="row justify-content-center">
            <div class="col-6">
                <h4 class="text-center my-4">Contact Us</h4>
                <div class="card">

                    <div class="card-body">
                        <form action="/contact/" method="POST">

                            <div class="form-group">
                                <label for="email">Email</label>
                                <input type="email" class="form-control" name="email" placeholder="email..." required />
                            </div>
                            <div class="form-group">
                                <label for="subject">Subject</label>
                                <input type="text" class="form-control" name="subject" placeholder="subject..."
                                    required />
                            </div>
                            <div class="form-group">
                                <label for="message">Message</label>
                                <textarea class="form-control" name="message" placeholder="your messages..." required></textarea>
                            </div>
                            <div class="form-group">
                                <input type="submit" class="btn btn-primary w-100" value="Send" />
                            </div>

                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>

</html>

Pada kode kode HTML ini, kita menggunakan Bootstrap melalui CDN. Sehingga nanti tampilannya akan seperti ini:

Contact Form App

Setelah membuat form, selanjutnya buat satu lagi file javascript dengan nama app_contact.js dan isi sebagai berikut:

var http = require('http');
var fs = require('fs');
var qs = require('querystring');
var nodemailer = require('nodemailer');

http.createServer((req, res) => {

    if(req.url === "/") {
        // redirect ke halaman contact form
        res.writeHead(302, {
            'Location': '/contact/'
          });
        res.end();
    }

    // load the contact form
    if(req.url === "/contact/" && req.method === "GET"){
        fs.readFile("contact_form.html", (err, data) => {
            if (err) throw err;
            res.end(data);
        });
    }

    // send the email
    if(req.url === "/contact/" && req.method === "POST"){

        var requestBody = '';
        req.on('data', function(data) {
            // tangkap data dari form
            requestBody += data;

            // kirim balasan jika datanya terlalu besar
            if(requestBody.length > 1e7) {
              res.writeHead(413, 'Request Entity Too Large', {'Content-Type': 'text/html'});
              res.end('<!doctype html><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>');
            }
        });

        req.on('end', function() {
            let formData = qs.parse(requestBody);

            // send the email
            let transporter = nodemailer.createTransport({
                service: 'gmail',
                auth: {
                    user: '[email protected]',
                    pass: 'your password'
                }
            });
            
            let mailOptions = {
                from: formData.email,
                replyTo: formData.email,
                to: '[email protected]',
                subject: formData.subject,
                text: formData.message
            };
            
            transporter.sendMail(mailOptions, (err, info) => {
                if (err) throw err;
                console.log('Email sent: ' + info.response);
                res.end("Thank you!");
            }); 
        });
               
    }

}).listen(8000);

console.log('server listening on http://localhost:8000/');

Yang perlu kamu perhatikan pada kode ini adalah di bagian mailOptions:

let mailOptions = {
    from: formData.email,
    replyTo: formData.email,
    to: '[email protected]',
    subject: formData.subject,
    text: formData.message
};

Isi dari objek formData adalah data yang kita inputkan dari form.

Kalau belum paham, silahkan pelajari: Tutorial Nodejs #7: Cara Mengambil Data dari Form

Properti replyTo pada mailOptions berfungsi untuk menentukan alamat email yang akan digunakan untuk membalas.

Untuk lebih jelasnya, mari kita coba…

Mengirim email dengan contact form nodejs

Maka email yang akan masuk pada inbox akan seperti ini:

Email dari contact form
Email dari contact form

Lalu, ketika kita menekan tombol reply, maka email ini akan langsung dibalas ke email yang kita berikan pada properti replyTo.

Membalas email dari concact form
Membalas email dari concact form

Apa Selanjutnya?

Kita baru hanya mencoba mengirim email menggunakan layanan Gmail saja. Kita masih belum coba yang menggunakan layanan lain seperti SMTP dan Web Service.

Mengirim email menggunakan layanan Gmail, masih terdapat beberapa kekurangan.

Seperti, email gampang di tandai sebagai spam dan kita juga harus pathui kebijakan dan aturan Google.

Agar tidak mengirim email secara berlebihan.

Untuk coba-coba, tidak apa-apa pakai gmail. Namun untuk produksi, disarankan menggunakan layanan email yang lain. Seperti SendGrid, Mailgun, atau server email sendiri.

Selamat mencoba.