Отправка email на Go (Golang): обзор библиотек и инструментов
Go (Golang) — современный компилируемый язык, который отлично подходит для создания бэкенд-сервисов, микросервисов и автоматизации. Одной из частых задач является программная отправка электронных писем. В этой статье мы подробно разберём стандартные средства Go для работы с SMTP, популярные сторонние библиотеки, а также примеры отправки простых и HTML-писем с вложениями.
Стандартный пакет net/smtp
В стандартной библиотеке Go есть пакет net/smtp, который предоставляет базовые возможности для отправки email через SMTP-сервер. Он простой, но требует ручного формирования тела письма (включая заголовки, MIME-типы).
Простой пример отправки текстового письма
package main
import (
"fmt"
"net/smtp"
)
func main() {
// Данные для аутентификации
from := "your_email@gmail.com"
password := "your_app_password"
to := []string{"recipient@example.com"}
// SMTP-сервер (например, Gmail)
smtpHost := "smtp.gmail.com"
smtpPort := "587"
// Тело письма (обязательно с заголовками)
subject := "Subject: Привет из Go!\n"
body := "Это тестовое письмо, отправленное с помощью net/smtp."
message := []byte(subject + "\n" + body)
// Аутентификация
auth := smtp.PlainAuth("", from, password, smtpHost)
// Отправка
err := smtp.SendMail(smtpHost+":"+smtpPort, auth, from, to, message)
if err != nil {
fmt.Println("Ошибка отправки:", err)
return
}
fmt.Println("Письмо отправлено успешно!")
}
Важно: Для Gmail потребуется пароль приложения, а не обычный пароль.
Отправка HTML-письма и письма с вложениями
Пакет net/smtp не умеет автоматически формировать MIME-сообщения. Для HTML-писем или вложений придётся вручную составлять заголовки Content-Type и кодировать вложения в base64. Это громоздко, поэтому для сложных писем лучше использовать сторонние библиотеки.
Популярные сторонние библиотеки для отправки email на Go
Существует несколько зрелых библиотек, которые значительно упрощают работу:
- go-gomail/gomail — одна из самых популярных. Поддерживает HTML, вложения, встраивание изображений, несколько получателей.
- jordan-wright/email — лёгкая библиотека с удобным API.
- sendgrid/sendgrid-go — официальный клиент для сервиса SendGrid (подходит для массовых рассылок).
Пример с go-gomail
package main
import (
"fmt"
"gopkg.in/gomail.v2"
)
func main() {
m := gomail.NewMessage()
m.SetHeader("From", "your_email@gmail.com")
m.SetHeader("To", "recipient@example.com")
m.SetHeader("Subject", "HTML письмо с вложением")
m.SetBody("text/html", "<h1>Привет!</h1><p>Это <b>HTML</b> письмо.</p>")
m.Attach("/path/to/file.pdf") // Вложение
d := gomail.NewDialer("smtp.gmail.com", 587, "your_email@gmail.com", "your_app_password")
if err := d.DialAndSend(m); err != nil {
fmt.Println("Ошибка:", err)
return
}
fmt.Println("Письмо отправлено!")
}
Асинхронная отправка и пул соединений
Если требуется отправлять много писем (например, после регистрации пользователей), важно не блокировать основной поток. Go отлично справляется с конкурентностью:
package main
import (
"fmt"
"gopkg.in/gomail.v2"
"sync"
)
func sendEmail(wg *sync.WaitGroup, to, subject, body string) {
defer wg.Done()
m := gomail.NewMessage()
m.SetHeader("From", "noreply@example.com")
m.SetHeader("To", to)
m.SetHeader("Subject", subject)
m.SetBody("text/plain", body)
d := gomail.NewDialer("smtp.example.com",