logo
Программирование на языке Ruby

18.2.5. Взаимодействие с imap-сервером

Протокол IMAP нельзя назвать вершиной совершенства, но во многих отношениях он превосходит POP3. Сообщения могут храниться на сервере сколь угодно долго (с индивидуальными пометками «прочитано» и «не прочитано»). Для хранения сообщений можно организовать иерархию папок. Этих возможностей уже достаточно для того, чтобы считать протокол IMAP более развитым, чем POP3.

Для взаимодействия с IMAP-сервером предназначена стандартная библиотека net/imap. Естественно, вы должны сначала установить соединение с сервером, а затем идентифицировать себя с помощью имени и пароля:

require 'net/imap'

host = "imap.hogwarts.edu"

user, pass = "lupin", "riddikulus"

imap = Net::IMAP.new(host)

begin

 imap.login(user, pass)

 # Или иначе:

 # imap.authenticate("LOGIN", user, pass)

rescue Net::IMAP::NoResponseError

 abort "He удалось аутентифицировать пользователя #{user}"

end

# Продолжаем работу...

imap.logout # Разорвать соединение.

Установив соединение, можно проверить почтовый ящик методом examine; по умолчанию почтовый ящик в IMAP называется INBOX. Метод responses возвращает информацию из почтового ящика в виде хэша массивов (наиболее интересные данные находятся в последнем элементе массива). Показанный ниже код показывает общее число сообщений в почтовом ящике ("EXISTS") и число непрочитанных сообщений ("RESENT"):

imap.examine("INBOX")

total = imap.responses["EXISTS"].last  # Всего сообщений.

recent = imap.responses["RECENT"].last # Непрочитанных сообщений.

imap.close                             # Закрыть почтовый ящик.

Отметим, что метод examine позволяет только читать содержимое почтового ящика. Если нужно удалить сообщения или произвести какие-то другие изменения, пользуйтесь методом select.

Почтовые ящики в протоколе IMAP организованы иерархически, как имена путей в UNIX. Для манипулирования почтовыми ящиками предусмотрены методы create, delete и rename:

imap.create("lists")

imap.create("lists/ruby")

imap.create("lists/rails")

imap.create("lists/foobar")

# Уничтожить последний созданный ящик:

imap.delete("lists/foobar")

Имеются также методы list (получить список всех почтовых ящиков) и lsub (получить список «активных» ящиков, на которые вы «подписались»). Метод status возвращает информацию о состоянии ящика.

Метод search находит сообщения, удовлетворяющие заданному критерию, а метод fetch возвращает запрошенное сообщение:

msgs = imap.search("ТО","lupin")

msgs.each do |mid|

 env = imap.fetch(mid, "ENVELOPE")[0].attr["ENVELOPE"]

 puts "От #{env.from[0].name} #{env.subject}"

end

Команда fetch в предыдущем примере выглядит так сложно, потому что возвращает массив хэшей. Сам конверт тоже представляет собой сложную структуру; некоторые методы доступа к нему возвращают составные объекты, другие — просто строки.

В протоколе IMAP есть понятия UID (уникального идентификатора) и порядкового номера сообщения. Обычно методы типа fetch обращаются к сообщениям по номерам, но есть и варианты (например, uid_fetch) для обращения по UID. У нас нет места объяснять, почему нужны обе системы идентификации, но если вы собираетесь серьезно работать с IMAP, то должны понимать различие между ними (и никогда не путать одну с другой).

Библиотека net/imap располагает разнообразными средствами для работы с почтовыми ящиками, сообщениями, вложениями и т.д. Дополнительную информацию поищите в онлайновой документации на сайте ruby-doc.org.