Ответ
Да, приходилось. Для работы с IMAP в Go я бы использовал стандартную де-факто библиотеку github.com/emersion/go-imap
и ее экосистему.
Процесс работы с почтой обычно состоит из следующих шагов:
- Подключение к серверу: Установка безопасного соединения с IMAP-сервером, обычно через TLS (
client.DialTLS
). - Аутентификация: Вход в систему с использованием логина и пароля (
client.Login
). - Выбор почтового ящика (Mailbox): Выбор папки для работы, например,
INBOX
(client.Select
). - Поиск и получение писем (Search & Fetch): Сначала можно найти ID нужных писем (например, все непрочитанные) с помощью
client.Search
, а затем запросить их содержимое (client.Fetch
). При запросе можно указать, какие части письма нужны:ENVELOPE
(метаданные),BODY[]
(содержимое),UID
и т.д. - Парсинг MIME-содержимого: Тело письма — это сложная структура (MIME). Для его разбора на текст, HTML и вложения понадобится дополнительная библиотека, например,
net/mail
из стандартной библиотеки илиgithub.com/emersion/go-message
.
Пример кода (чтение темы последнего письма):
package main
import (
"log"
"github.com/emersion/go-imap"
"github.com/emersion/go-imap/client"
)
func main() {
c, err := client.DialTLS("imap.example.com:993", nil)
if err != nil { log.Fatal(err) }
defer c.Logout()
if err := c.Login("user@example.com", "password"); err != nil {
log.Fatal(err)
}
mbox, err := c.Select("INBOX", true) // true - read-only
if err != nil { log.Fatal(err) }
if mbox.Messages == 0 {
log.Fatal("No messages in inbox")
}
// Берем последнее письмо
seqset := new(imap.SeqSet)
seqset.AddNum(mbox.Messages)
// Запрашиваем его конверт (тема, отправитель и т.д.)
messages := make(chan *imap.Message, 1)
go func() {
if err := c.Fetch(seqset, []imap.FetchItem{imap.FetchEnvelope}, messages); err != nil {
log.Fatal(err)
}
}()
msg := <-messages
log.Println("Subject:", msg.Envelope.Subject)
}
Дополнительные возможности:
Библиотека также поддерживает продвинутые функции, такие как команда IDLE
, которая позволяет получать уведомления о новых письмах в реальном времени без необходимости постоянно опрашивать сервер (polling).