The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

LICENSE AND COPYRIGHT

THIS PROGRAM IS SUBJECT TO THE TERMS OF THE ARTISTIC LICENSE, VERSION 2.0.

THE FOLLOWING DISCLAIMER APPLIES TO ALL SOFTWARE CODE AND OTHER MATERIALS CONTRIBUTED IN CONNECTION WITH THIS PROGRAM:

THIS SOFTWARE IS LICENSED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY WARRANTY OF NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE MAY BE REDISTRIBUTED TO OTHERS ONLY BY EFFECTIVELY USING THIS OR ANOTHER EQUIVALENT DISCLAIMER IN ADDITION TO ANY OTHER REQUIRED LICENSE TERMS.

ONLY THE SOFTWARE CODE AND OTHER MATERIALS CONTRIBUTED IN CONNECTION WITH THIS SOFTWARE, IF ANY, THAT ARE ATTACHED TO (OR OTHERWISE ACCOMPANY) THIS SUBMISSION (AND ORDINARY COURSE CONTRIBUTIONS OF FUTURES PATCHES THERETO) ARE TO BE CONSIDERED A CONTRIBUTION. NO OTHER SOFTWARE CODE OR MATERIALS ARE A CONTRIBUTION.

Copyright (c) 2012 Contributor All rights reserved.

NAME

Mail::IMAPQueue - IMAP client extension to watch and process a mailbox as a queue

VERSION

Version 0.04

SYNOPSIS

Basic usage

    use Mail::IMAPClient;
    use Mail::IMAPQueue;
    
    my $imap = Mail::IMAPClient->new(
        ... # See Mail::IMAPClient documentation
    ) or die $@;
    
    $imap->select('INBOX') or die $@;
    
    my $queue = Mail::IMAPQueue->new(
        client => $imap
    ) or die $@;
    
    while (defined(my $msg = $queue->dequeue_message())) {
        # Do something with $msg (sequence number or UID)
    }
    
    $imap->close();

DESCRIPTION

This module provides a way to access a mailbox with IMAP protocol, regarding the mailbox as a FIFO queue so that the client code can continuously process incoming email messages.

The module utilizes Mail::IMAPClient as an IMAP client interface.

The instance of Mail::IMAPQueue maintains a buffer internally, and loads the message sequence numbers (or UIDs) into the buffer as necessary. When there are no messages in the mailbox while the buffer is empty, it will wait until new messages are received in the mailbox.

For the purpose of this module, one single mailbox (or a folder) must be selected at all times (Mail::IMAPClient::select()).

It is assumed that the UID assigned to each message is strictly ascending as stated in RFC 3501 2.3.1.1. and that the order for any messages to start appearing in the result of the SEARCH command is always consistent with the order of UIDs.

It is also assumed that the IMAP server provides the IDLE extension (RFC 2177), for real-time updates from the server.

EXAMPLES

Dumping messages into files

    while (defined(my $msg = $queue->dequeue_message())) {
        $imap->message_to_file("/tmp/mails/$msg", $msg) or die $@;
        $imap->delete_message($msg) or die $@;
        $imap->expunge() or die $@ if $queue->is_empty;
    }

Managing messages with each buffer

    while (my $msg_list = $queue->dequeue_messages()) {
        for my $msg (@$msg_list) {
           # Do something with $msg
           $imap->delete_message($msg) or die $@;
        }
        $imap->expunge() or die $@;
    }

Controlling timing of fetching and waiting

    while ($queue->reload_messages()) { # non-blocking
        my $msg_list = $queue->peek_messages or die $@; # non-blocking
        if (@$msg_list) {
            for my $msg (@$msg_list) {
                # Do something with $msg
            }
        } else {
            $queue->attempt_idle or die $@;
                # blocking wait for new messages, up to 30 sec.
        }
    }

METHODS

$class->new(client => $imap, ...)

Instanciate a queue object, with the required field client set to a Mail::IMAPClient object.

    my $queue = Mail::IMAPQueue->new(
        client       => $imap,
        uidnext      => $known_next_uid, # default = undef
        skip_initial => $true_or_false,  # default = 0
        idle_timeout => $seconds,        # default = 30
    ) or die $@;

No IMAP requests are invoked with the client object during the initialization. The buffer maintained by this object is initially empty.

  • client => $imap

    The underlying client object. It is assumed to be an instance of Mail::IMAPClient, although the type of the object is not enforced.

  • uidnext => $known_next_uid

    If the next message UID (the smallest UID to be used) is known (e.g. from a previous execution), specify the value here.

  • skip_initial => $true_or_false

    Specify a true value to skip all the messages initially in the mailbox. If uidnext option is set, this option will be ignored effectively.

  • idle_timeout => $seconds

    Specify the timeout in seconds for the IDLE command (RFC 2177), which allows the IMAP client to receive updates from the server in real-time. It does not mean the method call will give up when there are no updates after the timeout, but it means how frequently it will reset the IDLE command (with any blocking methods except for attempt_idle() method, which is for one timeout round).

$queue->is_empty()

Return 1 if the current buffer is empty, and 0 otherwise.

$queue->dequeue_message()

Dequeue the next message from the mailbox. If the current buffer is non-empty, the next message will be removed from the buffer and returned. Otherwise, the call will be blocked until there is at least one message found in the mailbox, and then the first message will be removed from the loaded buffer and returned.

The method returns the sequence number of the message (or UID if the Uid option is turned on for the underlying client). undef is returned if the attempt to load the messages was failed.

$queue->dequeue_messages()

Dequeue the next list of messages. If the current buffer is non-empty, all the messages will be removed from the buffer and returned. Otherwise, the call will be blocked until there is at least one message found in the mailbox, and then all the loaded messages will be removed and returned.

In the list context, the method returns an array of the message sequence numbers (or UIDs if the Uid option is turned on for the underlying client). In the scalar context, a reference to the array is returned. undef is returned if the attempt to load the messages was failed.

$queue->peek_message()

Retrieve the first message in the current buffer without removing the message.

The method returns the sequence number of the message (or UID if the Uid option is turned on for the underlying client). undef is returned if the current buffer is empty.

$queue->peek_messages()

Retrieve all the messages in the current buffer without removing the messages.

In the list context, the method returns an array of the message sequence numbers (or UIDs if the Uid option is turned on for the underlying client). In the scalar context, a reference to the array is returned.

$queue->ensure_messages()

The call is blocked until there is at least one message loaded into the buffer.

The method returns the object itself if successful, and undef otherwise.

$queue->attempt_idle()

Attempt the IDLE command so that the call is blocked until there are any updates in the mailbox or the timeout (default = 30 sec.) has elapsed.

The method returns the object itself if successful, and undef otherwise. If the timeout has elapsed gracefully, it is considered to be a success.

$queue->reload_messages()

Discard the current buffer, and attempt to load any messages from the mailbox to the buffer. The call is not blocked (except for the usual socket wait for any server response).

The method returns the object itself if successful, and undef otherwise.

Note: Even if no new messages are loaded, it is a success as long as the server has responded properly. In order to test the last result of loading, the is_empty() method can be used.

AUTHOR

Mahiro Ando, <mahiro at cpan.org>

BUGS

Please report any bugs or feature requests to bug-mail-imapqueue at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Mail-IMAPQueue. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc Mail::IMAPQueue

You can also look for information at:

ACKNOWLEDGEMENTS

The initial package was created by Module::Starter v1.58.

This module utilizes Mail::IMAPClient as a client library interface for IMAP.