Расскажите о протоколе POP3. В чем его ключевые отличия от IMAP и как с ним работать в Go?

Ответ

POP3 (Post Office Protocol version 3) — это простой протокол прикладного уровня для получения электронной почты с сервера. Его основная идея — «скачать и удалить».

В стандартной библиотеке Go нет встроенного клиента для работы с POP3. Для этого необходимо использовать сторонние библиотеки, например, популярную github.com/emersion/go-pop3.

Ключевые отличия POP3 от IMAP:

Характеристика POP3 IMAP
Состояние Работает в "офлайн" режиме. Письма загружаются на клиентское устройство и (обычно) удаляются с сервера. Работает в "онлайн" режиме. Письма остаются на сервере, клиент синхронизирует их состояние.
Доступ с устройств Рассчитан на доступ с одного устройства. Идеален для доступа с нескольких устройств (ПК, телефон), так как состояние (прочитано/не прочитано) синхронизируется.
Работа с папками Не поддерживает папки на сервере. Есть только "Входящие". Полная поддержка создания, удаления и переименования папок на сервере.
Загрузка писем Обычно загружает письмо целиком (заголовок и тело). Позволяет выборочно загружать части письма, например, только заголовки или текст без вложений.
Порты по умолчанию 110 (нешифрованный), 995 (SSL/TLS) 143 (нешифрованный), 993 (SSL/TLS)
Сценарий «Проверить почту»: скачать все новое, сохранить локально и очистить ящик на сервере. «Управлять почтой»: работать с письмами на сервере, как с файлами в облаке.

Пример простого клиента на Go с emersion/go-pop3:

package main

import (
    "log"

    "github.com/emersion/go-pop3"
)

func main() {
    // Устанавливаем соединение с сервером (для SSL/TLS используйте pop3.DialTLS)
    client, err := pop3.Dial("mail.example.com:110")
    if err != nil {
        log.Fatal(err)
    }
    defer client.Quit()

    // Аутентификация
    if err := client.Auth("user", "password"); err != nil {
        log.Fatal(err)
    }

    // Получаем количество сообщений и общий размер
    count, size, err := client.Stat()
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Всего сообщений: %d, общий размер: %d байт", count, size)

    // Можно пройтись по письмам и получить их
    // for i := 1; i <= count; i++ {
    //     msg, err := client.Retr(i)
    //     // ... обработка письма ...
    // }
}

Таким образом, POP3 — более старый и простой протокол, подходящий для простых задач, в то время как IMAP — более гибкий и современный стандарт для управления почтой на сервере.

Ответ 18+ 🔞

А, слушай, про POP3, да? Ну это ж классика, старый добрый протокол, как дедовский "Москвич". Суть его проще пареной репы: пришёл, скачал всё что есть в ящике на свой комп, и — бац! — по умолчанию ещё и удалил с сервера, чтоб не мозолило глаза. Всё, точка. Оффлайн-режим в чистом виде.

И вот тут, блядь, главный подвох: в стандартной библиотеке Go этого клиента — нихуя нет! Совсем! Как будто его и не было. Приходится лезть за сторонними библиотеками, типа github.com/emersion/go-pop3. Ну, она норм, проверенная.

А теперь, чтобы ты понял разницу, вот тебе краткий разбор полётов, почему все сейчас орут про IMAP, а POP3 считается древним:

Что сравниваем POP3 (старичок) IMAP (продвинутый)
Философия "Скачай и забудь". Как будто принёс газету из почтового ящика, прочитал и выкинул. "Работай в облаке". Все письма живут на сервере, ты просто подключаешься и смотришь, как в Гугл Доке.
Много устройств Полный пиздец. Скачал на ноут — на телефоне уже пусто. Или наоборот. Идеально. Открыл на телефоне, прочитал — на ноуте тоже "прочитано". Красота.
Папки на сервере Не, не слышал. У тебя там одна "Входящие" и хватит. Да хоть "Спам от тёщи" создавай, "Письма счастья" — полная власть.
Что качаем Всё письмо разом, от заголовка до вложений. Даже если тебе нужна только тема. Умный. Можешь стянуть только заголовки, потом решить, что скачивать. Экономия трафика, мать его.
Порты 110 (голый, как сокол) или 995 (упакованный в SSL). 143 (голый) или 993 (в бронеке).
Для кого Для того, кто проверяет почту раз в неделю с одного старенького компа и хочет, чтобы всё было у него на жёстком диске. Для всех остальных, кто живёт в 21 веке с кучей устройств.

Ну и кусочек кода, чтобы было понятно, как это выглядит в жизни. Смотри, ничего сложного:

package main

import (
    "log"

    "github.com/emersion/go-pop3"
)

func main() {
    // Цепляемся к серверу (для защищённого канала используй pop3.DialTLS)
    client, err := pop3.Dial("mail.example.com:110")
    if err != nil {
        log.Fatal(err) // Если не вышло — всё, пиши пропало
    }
    defer client.Quit() // Главное — не забыть вежливо попрощаться

    // Предъявляем логин и пароль
    if err := client.Auth("user", "password"); err != nil {
        log.Fatal(err)
    }

    // Спрашиваем: "Ну чё там по письмам?"
    count, size, err := client.Stat()
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Всего сообщений: %d, общий размер: %d байт", count, size)

    // Дальше можно каждое письмо по одному вытаскивать
    // for i := 1; i <= count; i++ {
    //     msg, err := client.Retr(i)
    //     // ... и тут уже разбирать его, как душе угодно
    // }
}

Короче, POP3 — это как одноразовая зажигалка: использовал и выкинул. Удобно, просто, но в современном мире уже как-то не очень. А IMAP — это уже как полноценная газовая плита, с духовкой и всеми режимами. Выбор, как говорится, за тобой, но если не хочешь через год охуевать от того, что вся переписка только на одном сдохшем ноуте — лучше сразу смотреть в сторону IMAP.