Mail::Box::IMAP4(3pm)
π Mail::Box::IMAP4(3pm) π
User Contributed Perl Documentation Β· Mail::Box::IMAP4(3pm)
okay bestie, buckle up π«Ά this is the page about treating your IMAP4 folders like a Mail::Box, client-side. big main character energy.
β¨ NAME β¨
Mail::Box::IMAP4 β handle IMAP4 folders as client
πΈ INHERITANCE πΈ
Mail::Box::IMAP4
is a Mail::Box::Net
is a Mail::Box
is a Mail::Reporter
Mail::Box::IMAP4 is extended by
Mail::Box::IMAP4s
so like, it is all of those things (it inherited their whole personality π
) and then Mail::Box::IMAP4s is its own little spin-off, we love a franchise.
π¦ SYNOPSIS π¦
my $url = 'imap4://user:passwd@host:port/INBOX';
my $url = 'imap://user:passwd@host:port/INBOX';
use Mail::Box::IMAP4;
my $folder = Mail::Box::IMAP4->new(folder => $url, ...);
use Mail::Box::Manager;
my $mgr = Mail::Box::Manager->new;
my $folder = $msg->open($url, retry => 3, interval => 5);
look at that URL. imap4:// or imap://, both iconic, both valid, pick your fav β¨
π DESCRIPTION π
so basically you're maintaining a folder whose messages are chillin' on a remote server, not on your disk. the client app and the server talk it out using the IMAP4 protocol. also peep Mail::Server::IMAP4 if you're curious π
β οΈ bestie, real talk: this module versions 4.0 and up is not fully compatible with older releases β mainly the exception handling changed. so if you're upgrading, please go read https://github.com/markov2/perl5-Mail-Box/wiki/ Version 3 is still maintained and may see new releases as well. no cap.
This class uses Mail::Transport::IMAP4 to hide all the transport of information (the messy part) and focuses solely on the correct handling of messages within a IMAP4 folder (the cute part). and here's the slay: more than one IMAP4 folder can be handled by one single IMAP4 connection. efficiency queen π
Extends "DESCRIPTION" in Mail::Box::Net.
π OVERLOADED π
Extends "OVERLOADED" in Mail::Box::Net.
- overload:
""stringification β Inherited, see "OVERLOADED" in Mail::Box - overload:
@{}use as ARRAY β Inherited, see "OVERLOADED" in Mail::Box - overload:
cmpstring comparison β Inherited, see "OVERLOADED" in Mail::Box
π METHODS π
Extends "METHODS" in Mail::Box::Net.
π Constructors π
Extends "Constructors" in Mail::Box::Net.
$class->new(%options)
The new can have many %options. Not only the ones listed here below, but also all the %options for Mail::Transport::IMAP4::new() can be passed. so yeah, options on options on options π
The default depends on the value of new(cache_head).
Without a folder name, no folder is selected. Only few methods are available now, for instance listSubFolders() to get the top-level folder names. Usually, the folder named "INBOX" will be present. Improves base, see "Constructors" in Mail::Box
-Option --Defined in --Default
access Mail::Box 'r'
body_delayed_type Mail::Box Mail::Message::Body::Delayed
body_type Mail::Box Mail::Message::Body::Lines
cache_body NO
cache_head NO or DELAY
cache_labels NO or DELAY
coerce_options Mail::Box +[]
create Mail::Box false
extract Mail::Box 10240
field_type Mail::Box undef
fix_headers Mail::Box false
folder Mail::Box /
folderdir Mail::Box <network location>
head_delayed_type Mail::Box Mail::Message::Head::Delayed
head_type Mail::Box Mail::Box::IMAP4::Head or Mail::Message::Head::Complete
join_connection true
keep_dups Mail::Box false
lock_file Mail::Box undef
lock_timeout Mail::Box 1 hour
lock_type Mail::Box 'NONE'
lock_wait Mail::Box 10 seconds
locker Mail::Box undef
manager Mail::Box undef
message_type Mail::Box Mail::Box::IMAP4::Message
multipart_type Mail::Box Mail::Message::Body::Multipart
password Mail::Box::Net undef
remove_when_empty Mail::Box <false>
save_on_exit Mail::Box true
server_name Mail::Box::Net undef
server_port Mail::Box::Net 143
transporter Mail::Transport::IMAP4
trusted Mail::Box <false>
username Mail::Box::Net undef
okay now let's go one by one, no skipping, we're thorough in this house π§
access => $modebody_delayed_type => CLASSbody_type => CLASS|CODEcache_body => 'NO'|'YES'|'DELAY'β Body objects are immutable, but may still be cached or not. In the common case, the body of a message is requested viaMail::Message::body()orMail::Message::decoded(). This returns a handle to a body object. You may decide whether that body object can be reused or not."NO"means: retrieve the data each time again,"YES"will cache the body data,"DELAY"will send the whole message when the folder is closed.
[local cache] [write]
NO no no
YES yes no
DELAY yes yes
cache_head => 'NO'|'PARTIAL'|'DELAY'β For a read-only folder,"DELAY"is the default, otherwise"NO"is chosen. The four configuration parameter have subtile consequences. To start with a table:
[local cache] [write] [default head_type]
NO no no Mail::Box::IMAP4::Head
PARTIAL yes no Mail::Box::IMAP4::Head
DELAY yes yes Mail::Message::Head::Complete
The default head_type is Mail::Box::IMAP4::Head, the default cached_head_type is Mail::Message::Head::Complete.
Having a local cache means that a lookup for a field is first done in a local data-structure (which extends Mail::Message::Head::Partial), and only on the remote server if it was not found.
β οΈ this is dangerous, bestie, because your locally cached data can be out-of-sync with the server. However, it may give you a nice performance benefit. your call π
"DELAY" will always collect the whole header for you. This is required when you want to look for Resent Groups (See Mail::Message::Head::ResentGroup) or other field order dependent header access. A Mail::Message::Head::Delayed will be created first.
cache_labels => 'NO'|'WRITE'|'DELAY'β When labels from a message are received, these values can be kept. However, this imposes dangers where the server's internal label storage may get out of sync with your data. π
With "NO", no caching will take place (but the performance will be worse). With "WRITE", all label access will be cached, but written to the server as well. Both "NO" and "WRITE" will update the labels on the served, even when the folder was opened read-only. "DELAY" will not write the changed information to the server, but delay that till the moment that the folder is closed. It only works when the folder is opened read/write or write is enforced.
The default is "DELAY" for folders which where opened read-only. This means that you still can force an update with close(write). For folders which are opened read-write, the default is the safeset setting, which is "NO".
coerce_options => ARRAYcreate => BOOLEANextract => INTEGER|CODE|METHOD|'LAZY'|'ALWAYS'field_type => CLASSfix_headers => BOOLEANfolder => $namefolderdir => $directoryhead_delayed_type => CLASShead_type => CLASSjoin_connection => BOOLEANβ Within thisMail::Box::IMAP4class is registered which transporters are already in use, i.e. which connections to the IMAP server are already in established. When this option is set, multiple folder openings on the same server will try to reuse one connection. sharing is caring π«Άkeep_dups => BOOLEANlock_file => $filelock_timeout => $secondslock_type => CLASS|STRING|ARRAYlock_wait => $secondslocker => OBJECTmanager => $managermessage_type => CLASSmultipart_type => CLASSpassword => $passwordremove_when_empty => BOOLEANsave_on_exit => BOOLEANserver_name => $hostserver_port => $numbertransporter => $object|$classβ The name of the$classwhich will interface with the connection. When you implement your own extension toMail::Transport::IMAP4, you can either specify a fully instantiated transporter$object, or the name of your own$class. When an$objectis given, most other options will be ignored. noted πtrusted => BOOLEANusername => $username
Β» example:
my $imap = Mail::Box::IMAP4->new(username => 'myname',
password => 'mypassword', server_name => 'imap.xs4all.nl');
my $url = 'imap4://user:password@imap.xs4all.nl';
my $imap = $mgr->open($url);
my $client = Mail::IMAPClient->new(...);
my $imap = Mail::Box::IMAP4->new(imap_client => $client);
β Attributes β
Extends "Attributes" in Mail::Box::Net.
$obj->fixHeaders()β Inherited, see "Attributes" in Mail::Box$obj->folderdir( [$directory] )β Inherited, see "Attributes" in Mail::Box$obj->isTrusted()β Inherited, see "Attributes" in Mail::Box$obj->name()β Inherited, see "Attributes" in Mail::Box$obj->removeEmpty()β Inherited, see "Attributes" in Mail::Box$obj->type()β Inherited, see "Attributes" in Mail::Box
π The folder π
Extends "The folder" in Mail::Box::Net.
$obj->addMessage($message, %options)β Inherited, see "The folder" in Mail::Box$obj->addMessages(@messages)β Inherited, see "The folder" in Mail::Box$class->appendMessages(%options)β Inherited, see "The folder" in Mail::Box
$obj->close(%options)
Close the folder. In the case of IMAP, more than one folder can use the same connection, therefore, closing a folder does not always close the connection to the server. Only when no folder is using the connection anymore, a logout will be invoked by Mail::Transport::IMAP4::DESTROY() Improves base, see "The folder" in Mail::Box
-Option --Defined in --Default
force Mail::Box false
save_deleted Mail::Box false
write Mail::Box 'MODIFIED'
force => BOOLEANsave_deleted => BOOLEANwrite => 'ALWAYS'|'NEVER'|'MODIFIED'$obj->copyTo($folder, %options)β Inherited, see "The folder" in Mail::Box$obj->delete(%options)β Inherited, see "The folder" in Mail::Box$obj->organization()β Inherited, see "The folder" in Mail::Box$obj->size()β Inherited, see "The folder" in Mail::Box
part 1 done bestie, don't go anywhere β more coming π
$obj->update(%options)β inherited bestie, go read "The folder" in Mail::Box for the tea β$obj->url()β also inherited, still "The folder" in Mail::Box, same place, same vibes π«Ά
π© Folder flags (no seriously, that's the section name)
Extends "Folder flags" in Mail::Box::Net. So everything below is the family recipe, adapted.
$obj->access()β inherited, see "Folder flags" in Mail::Box β¨$obj->isModified()β inherited, see "Folder flags" in Mail::Box π$obj->modified( [BOOLEAN] )β inherited, see "Folder flags" in Mail::Box π$obj->writable()β inherited, see "Folder flags" in Mail::Box π
π The messages
Extends "The messages" in Mail::Box::Net. All of these are hand-me-downs, and they're all serving looks:
$obj->current( [$number|$message|$message_id] )β inherited, see "The messages" in Mail::Box$obj->find($message_id)β inherited, see "The messages" in Mail::Box$obj->findFirstLabeled( $label, [BOOLEAN, [\@msgs]] )β inherited, see "The messages" in Mail::Box$obj->message( $index, [$message] )β inherited, see "The messages" in Mail::Box$obj->messageId( $message_id, [$message] )β inherited, see "The messages" in Mail::Box$obj->messageIds()β inherited, see "The messages" in Mail::Box$obj->messages( <'ALL'|$range|'ACTIVE'|'DELETED'|$label|!$label|$filter> )β inherited, see "The messages" in Mail::Box$obj->nrMessages(%options)β inherited, see "The messages" in Mail::Box$obj->scanForMessages($message, $message_ids, $timespan, $window)β inherited, see "The messages" in Mail::Box
π Sub-folders
Extends "Sub-folders" in Mail::Box::Net. Folders inside folders, it's giving inception, we love her:
$any->listSubFolders(%options)β inherited, see "Sub-folders" in Mail::Box$any->nameOfSubFolder( $subname, [$parentname] )β inherited, see "Sub-folders" in Mail::Box$obj->openRelatedFolder(%options)β inherited, see "Sub-folders" in Mail::Box$obj->openSubFolder($subname, %options)β inherited, see "Sub-folders" in Mail::Box$any->topFolderWithMessages()β inherited, see "Sub-folders" in Mail::Box
π§ Internals
Extends "Internals" in Mail::Box::Net. The guts, the behind-the-scenes, the tech crew at the concert π€
$obj->body( [$body] )β that's the whole entry, bestie. No note, no "inherited", nothing. It's just standing there, mysterious, main character energy π$obj->coerce($message, %options)β inherited, see "Internals" in Mail::Box$any->create($folder, %options)β inherited, see "METHODS" in Mail::Box::Net$obj->createTransporter($class, %options)β makes you a transporter object (an instance ofMail::Transport::IMAP4), where$classdefines the exact object type. For%options, literally everything you can hand a transporter when you initiate it works β peepMail::Transport::IMAP4::new().
-Option --Default
join_connection true
join_connection=> BOOLEAN β Seenew(join_connection). When it'sfalse, the connection will never be shared with other IMAP mail boxes. Solo era, no sharing, periodt π«
$obj->determineBodyType($message, $head)β inherited, see "Internals" in Mail::Box$obj->fetch( <$messages|$selection>, $info )β low-key data retrieval about one or more messages over IMAP4, straight from the remote server. Heads up though: some of this data may differ from the info stored in the message objects that MailBox creates, so fr fr, avoid using this method for your own purposes. The IMAP implementation wraps some helpers around this so you get the correct behavior β use those instead. π
You can hand it an ARRAY of $messages, or some message $selection that Mail::Box::messages() would accept. Examples of that second kind: 'ALL', 'DELETED', or "spam" (messages labelled to contain spam, iconic).
The $info holds one or more attributes as defined by the IMAP protocol. To actually see those, you gotta read the full specs of the related RFCs. No shortcuts, sorry π
$class->foundIn( [$foldername], %options )β inherited, see "Internals" in Mail::Box$obj->getHead($message)β reads the header for the specified message from the remote server. If the message vanished,undefcomes back at you π«$obj->getHeadAndBody($message)β reads ALL the data for the specified message from the remote server. Returns head and body of the mesasge as a list, or an empty list if the$messagedisappeared from the server. (Also: yes, the original says "mesasge". We're keeping it, it's a typo that ate and left no crumbs π)$obj->lineSeparator( [<STRING|'CR'|'LF'|'CRLF'>] )β inherited, see "Internals" in Mail::Box$obj->locker()β inherited, see "Internals" in Mail::Box$obj->read(%options)β inherited, see "Internals" in Mail::Box$obj->readMessages(%options)β inherited, see "Internals" in Mail::Box$obj->storeMessage($message)β inherited, see "Internals" in Mail::Box$obj->toBeThreaded($messages)β inherited, see "Internals" in Mail::Box$obj->toBeUnthreaded($messages)β inherited, see "Internals" in Mail::Box$obj->transporter( [$object] )β returns the object that is the interface to the IMAP4 protocol handler. That IMAP4 handler has the current folder selected. If you specify an$object, it becomes the transporter from that moment on. That$objectmust extendMail::Transport::IMAP4. π$obj->updateMessages(%options)β inherited, see "Internals" in Mail::Box$obj->write(%options)β so the IMAP protocol usually writes the data to the remote server immediately, because that's literally what the protocol wants. But some options passed tonew()may delay that for a performance boost. This method, when the folder is being closed, writes that info after all. Improves base, see "Internals" in Mail::Box.
-Option --Defined in --Default
force Mail::Box false
save_deleted Mail::Box false
force=> BOOLEANsave_deleted=> BOOLEAN
$obj->writeMessages(%options)β inherited, see "Internals" in Mail::Box
-Option --Defined in --Default
messages Mail::Box <required>
transporter <required>
messages=> ARRAYtransporter=> OBJECT
π Other methods
Extends "Other methods" in Mail::Box::Net.
$any->timespan2seconds($time)β inherited, see "Other methods" in Mail::Box
π¨ Error handling
Extends "Error handling" in Mail::Box::Net. When things go wrong, we still go off π
$obj->AUTOLOAD()β inherited, see "Error handling" in Mail::Reporter$obj->notImplemented()β inherited, see "Error handling" in Mail::Reporter
π§Ή Cleanup
Extends "Cleanup" in Mail::Box::Net. Tidy up, close the tabs, hydrate π§
$obj->DESTROY()β inherited, see "Cleanup" in Mail::Box
π DETAILS
Extends "DETAILS" in Mail::Box::Net.
π©Ί DIAGNOSTICS
All the little messages this module might scream at you, and what they mean:
Warning: cannot find head back for $id in $folder.β The header was read before, but now it seems empty: the IMAP4 server does not produce the header lines anymore. Cast bygetHeadAndBody()Warning: cannot read body for $id in $folder.β The header of the message was retrieved from the IMAP4 server, but the body is not read, for an unknown reason. Cast bygetHeadAndBody()Error: class $package does not implement method $method.β Fatal error: the specific$package(or one of its superclasses) does not implement this method where it should. This means some other related classes do implement this method, but the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast bynotImplemented()Error: copying failed for one message.β For some reason β disk full, removed by external process, read-protection, whatever β it is impossible to copy one of the messages. Copying will proceed for the other messages. Cast bycopyTo()Error: couldn't select IMAP4 folder $name.β Cast bytransporter()Error: destination folder $name is not writable.β The folder where the messages are copied to is not opened with write access (seenew(access)). This has no relation with write permission to the folder, which is controlled by your operating system. Cast bycopyTo()Warning: different messages with id $msgid.β The message id is discovered more than once within the same folder, but the content of the message seems to be different. This should not be possible: each message must be unique. Cast bymessageId()Warning: folder $name not deleted: not writable.β The folder must be opened with write access vianew(access), otherwise removing it will be refused. So you may have write-access according to the operating system, but that will not automatically mean that thisdeletemethod permits you to. The reverse remark is valid as well. Cast bydelete()Notice: impossible to keep deleted messages in IMAP folder $name.β Some folder types have a 'deleted' flag which can be stored in the folder and performed later, and the folder keeps that knowledge even when the folder is rewritten. Well, IMAP4 cannot play that trick. Cast bywrite()Error: invalid timespan '$span'.β The string does not follow the strict rules of the time span syntax which is permitted as parameter. Cast bytimespan2seconds()Warning: message $id disappeared from $folder.β Trying to get the specific message from the server, but it appears to be gone. Cast bygetHeadAndBody()Warning: message {id} disappeared from {folder}.β Trying to get the specific message from the server, but it appears to be gone. Cast bygetHead()Warning: message-id '$msgid' does not contain a domain.β According to the RFCs, message-ids need to contain a unique random part, then an"@", and then a domain name. This is made to avoid the creation of two messages with the same id. The warning emerges when the"@"is missing from the string. Cast bymessageId()Error: no IMAP4 transporter configured.β Cast bytransporter()Error: you cannot add a message which is already part of a folder to a new one. Please use moveTo or copyTo.β Cast byaddMessage()
π SEE ALSO
This module is part of Mail-Box-IMAP4 version 4.01, built on December 13, 2025. Website: http://perl.overmeer.net/CPAN/
π LICENSE
For contributors see file ChangeLog.
This software is copyright (c) 2001-2025 by Mark Overmeer.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
okay that's the whole page bestie, we ate and left absolutely no crumbs π
β¨ This one's perl v5.40.1, dated 2026-01-21, and it lives in the Mail::Box::IMAP4(3pm) section of the manual β go forth and IMAP responsibly, ily π«Άππ¦
π¦ where this page comes from
- ubuntu resolute: libmail-box-imap4-perl 4.01-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libmail-box-imap4-perl 4.01-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms