Panduan langkah demi langkah mengintegrasikan Gmail SMTP dengan Go — pengaturan app password, paket mailer yang bisa dipakai ulang dengan template HTML, dan contoh pengiriman yang berfungsi.
Kalau Anda perlu mengirim email dari aplikasi Go, server SMTP milik Gmail adalah salah satu opsi paling sederhana untuk dijalankan. Tidak perlu akun layanan email pihak ketiga — cukup akun Google dan app password yang dibuat sendiri.
Menyiapkan App Password Gmail
Google mensyaratkan app password, bukan password akun biasa Anda, saat login lewat SMTP. Untuk membuatnya:
- Buka Akun Google → Keamanan → App password (Verifikasi 2 Langkah harus aktif).
- Buat app password baru untuk "Mail".
- Salin password yang dihasilkan — Anda akan memakainya di konfigurasi di bawah. Hapus spasi apa pun sebelum menyimpannya.
Struktur Proyek
Kita letakkan semuanya dalam paket mailer di dalam folder mail/:
mail/
setup.go — konfigurasi SMTP, inisialisasi singleton
usecase.go — struct Mailer, pembangun body, method Send
sample.template — template email HTML
Pengaturan SMTP (mail/setup.go)
Pengaturannya diinisialisasi sekali memakai sync.Once, sehingga objek auth SMTP hanya dibuat satu kali berapa pun banyak email yang Anda kirim:
package mailer
import (
"fmt"
"net/smtp"
"sync"
)
type SMTPMailSetup struct {
Server string
Port string
Address string
Sender string
Password string
Auth smtp.Auth
}
var mailSetup *SMTPMailSetup
var once sync.Once
func getSetup() *SMTPMailSetup {
once.Do(func() {
mailSetup = &SMTPMailSetup{
Server: "smtp.gmail.com",
Port: "587",
Sender: "your_email@gmail.com",
Password: "your_app_password",
}
mailSetup.Address = fmt.Sprintf("%s:%s", mailSetup.Server, mailSetup.Port)
mailSetup.Auth = smtp.PlainAuth("", mailSetup.Sender, mailSetup.Password, mailSetup.Server)
})
return mailSetup
}
Di proyek sungguhan, ambil Sender dan Password dari environment variable — jangan pernah menuliskan kredensial langsung di file sumber.
Usecase Mailer (mail/usecase.go)
Struct Mailer menyediakan satu method Send. Di dalamnya ia membangun body HTML dari file template Go sebelum menyerahkannya ke smtp.SendMail:
package mailer
import (
"bytes"
"fmt"
"net/smtp"
"text/template"
)
type Mailer struct {
Body []byte
Setup *SMTPMailSetup
}
func NewSMTPMailer() *Mailer {
return &Mailer{Setup: getSetup()}
}
func (m *Mailer) createBody(subject, htmlTemplate string, data any) (err error) {
var body bytes.Buffer
const mime = "MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n"
body.Write([]byte(fmt.Sprintf("Subject: %s\n%s\n\n", subject, mime)))
t, err := template.ParseFiles(htmlTemplate)
if err != nil {
return
}
err = t.Execute(&body, data)
if err != nil {
return
}
m.Body = body.Bytes()
return nil
}
func (m *Mailer) Send(recipient, subject, tmpl string, data any) (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("error on sending email: %v", r)
}
}()
err = m.createBody(subject, tmpl, data)
if err != nil {
return
}
err = smtp.SendMail(m.Setup.Address, m.Setup.Auth, m.Setup.Sender, []string{recipient}, m.Body)
return
}
Parameter data any diteruskan ke template Go, jadi Anda bisa menyuntikkan nilai dinamis — nama pengguna, tautan verifikasi, ringkasan pesanan — dengan mendefinisikan field di sebuah struct lalu merujuknya memakai {{ .FieldName }} di template.
Template HTML (mail/sample.template)
<!DOCTYPE html>
<html>
<body>
Sending email from a Go app!
</body>
</html>
Ganti bagian ini dengan HTML email Anda yang sebenarnya. Anda bisa merujuk field mana pun dari struct data memakai sintaks template Go standar.
Menyatukan Semuanya (main.go)
package main
import (
"log"
"time"
mailer "yourmodule/mail"
)
func main() {
mail := mailer.NewSMTPMailer()
err := mail.Send(
"recipient@example.com",
"Test Email",
"./mail/sample.template",
nil,
)
if err != nil {
log.Println(err)
}
time.Sleep(30 * time.Second)
}
Catatan untuk Penggunaan Produksi
- Pakai environment variable untuk
SenderdanPassword— jangan pernah menaruh kredensial di version control. - Cache template —
template.ParseFilesmembaca dari disk setiap kali dipanggil. Untuk pengiriman bervolume tinggi, parse template sekali saat startup dan simpan di structMailer. - Batas harian Gmail — akun Gmail gratis dibatasi sekitar 500 email per hari lewat SMTP. Untuk email transaksional dalam skala besar, pertimbangkan layanan khusus seperti SendGrid atau Amazon SES.
- TLS —
smtp.SendMailpada port 587 memakai STARTTLS secara otomatis, jadi koneksinya terenkripsi saat transit.
Kode sumber lengkapnya tersedia di github.com/uhkrowi/go-gmail-mailer.