Ответ
Да, приходилось. Для работы с 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).