',
inline => [
{ path => '/var/www/images/logo.png', type => 'image/png', id => 'logo@yamato-inc' },
],
)
->attach( '/tmp/Q4-Report.pdf' );
my $raw = $mail->as_string || die( $mail->error );
# Scalar-ref form - no string copy, useful for large messages
my $raw_ref = $mail->as_string_ref || die( $mail->error );
print $$raw_ref;
# Write directly to a filehandle - no in-memory buffering
open( my $fh, '>', '/tmp/message.eml' ) or die( $! );
$mail->print( $fh ) || die( $mail->error );
# Hash-based alternative constructor
my $mail2 = Mail::Make->build(
from => 'hello@example.com',
to => [ 'jack@example.jp' ],
subject => 'Hello',
plain => "Hi there.\n",
related => {
html => '
Hi there.
',
inline => [
{ path => '/var/www/images/logo.png', type => 'image/png', id => 'logo@example.com' },
],
},
attach => '/tmp/report.pdf',
) || die( Mail::Make->error );
# Hash-based with automatic asset embedding
my $mail3 = Mail::Make->build(
from => 'hello@example.com',
to => [ 'jack@example.jp' ],
subject => 'Hello',
plain => "Hi there.\n",
html_to_inline => {
html => '
Hi there.
',
base_url => 'https://www.example.com',
},
) || die( Mail::Make->error );
# Direct access to the envelope headers object
my $h = $mail->headers;
$h->set( 'X-Priority' => '1' );
VERSION
v0.23.0
DESCRIPTION
"Mail::Make" is a strict, validating MIME email builder with a fluent
interface.
All RFC 2822 envelope fields ("From", "To", "Cc", "Bcc", "Subject",
"Date", "Message-ID", "In-Reply-To", "References", "Reply-To", "Sender")
are stored in a Mail::Make::Headers instance accessible via "headers",
eliminating any duplication between "Mail::Make"'s own fields and the
final entity's headers.
The MIME structure is assembled lazily when "as_entity", "as_string", or
"print" is called. Structure selection is automatic:
* plain only → "text/plain"
* html only → "text/html"
* plain + html → "multipart/alternative"
* above + inline parts → wrapped in "multipart/related"
* above + attachments → wrapped in "multipart/mixed"
Non-ASCII display names in address fields and non-ASCII subjects are RFC
2047 encoded automatically.
"as_string" returns a plain string, consistent with
"MIME::Entity::stringify".
"as_string_ref" returns a scalar reference to avoid a string copy,
useful for large messages. "print" writes directly to a filehandle
without buffering the message in memory at all, and is the recommended
approach for very large messages.
When "use_temp_file" is set, or the assembled message size would exceed
"max_body_in_memory_size", "as_string_ref" spools to a temporary file
during serialisation and reads it back, keeping peak memory use to a
single copy rather than two overlapping buffers.
CONSTRUCTOR
new( [%opts] )
Creates a new "Mail::Make" object. Takes an hash or hash reference of
options. Supported options are:
* "max_body_in_memory_size"
Sets the byte threshold above which "as_string_ref" spools to a
temporary file rather than building the message in RAM. Set to 0 or
"undef" to disable the threshold entirely. Default:
$Mail::Make::MAX_BODY_IN_MEMORY_SIZE (1 MiB).
* "use_temp_file"
When true, "as_string_ref" always spools to a temporary file
regardless of message size. Useful when you know the message will be
large, or when you want to bound peak memory use unconditionally.
Default: false.
build( %params )
An alternate hash-based constructor.
Takes an hash or hash reference of options.
Recognised parameters are: from, to, cc, bcc, date, reply_to, sender,
subject, in_reply_to, message_id, references, plain, html, "plain_opts",
"html_opts", "attach", "related", "html_to_inline", "url_to_inline",
"headers".
When using the standard mail envelop headers, "build" will call each
respective method, such as from, to, etc.
When passing the "plain" parameter, it will call plain, and passing it
the optional hash reference of parameters provided with "plain_opts"
Likewise when passing the "html" parameter, it will call html, and
passing it the optional hash reference of parameters provided with
"html_opts"
The "attach" parameter accepts one of the following forms:
* A plain scalar or stringifiable object resolving to an existing
file; "path", "type", and "filename" are auto-detected:
attach => 'report.pdf'
* An array reference of plain scalars for multiple attachments;
likewise "path", "type", and "filename" are auto-detected:
attach => [ 'report.pdf', 'log.pdf' ]
* An array reference of hash references for full control over each
attachment:
attach => [
{ path => 'report.pdf', filename => 'Q4 Report.pdf' },
{ path => 'log.pdf', filename => 'Access Log.pdf' },
]
* A mix of both forms is also accepted:
attach => [ 'report.pdf', { path => 'log.pdf', filename => 'Access Log.pdf' } ]
If "type" is not provided in any of the above forms, it is auto-detected
from the file content using Module::Generic::File::Magic.
Each element is forwarded to "attach", so all options supported by
"attach" are available in the hash reference form.
The "related" parameter accepts a hash reference with at least a "html"
key, forwarded to "related":
related => {
html => '
Hello.
',
inline => [
{ path => '/var/www/images/logo.png', type => 'image/png', id => 'logo@example.com' },
],
}
The "html_to_inline" parameter accepts a hash reference with at least
"html" and "base_url" keys, forwarded to "html_to_inline":
html_to_inline => {
html => '
Hello.
',
base_url => 'https://www.example.com',
}
The "url_to_inline" parameter accepts a hash reference with at least a
"url" key, forwarded to "url_to_inline":
url_to_inline => {
url => 'https://www.example.com/newsletter/confirm.html',
}
You can also provide additional mail envelop headers by providing the
parameter "headers" as an hash reference.
For each element of that hash reference, it will call "header" in header
Returns the populated "Mail::Make" object, or upon error, set an error
object, and returns "undef" in scalar context or an empty list in list
context.
FLUENT METHODS
All setter methods return $self to allow chaining. Called without
arguments, they act as getters and return the stored value (delegating
to the internal Mail::Make::Headers object).
attach( %opts )
# Positional shorthand: path, type, and filename are auto-detected
$mail->attach( '/path/to/report.pdf' );
# Explicit form
$mail->attach(
path => $pdf_path,
type => 'application/pdf',
filename => 'report.pdf',
); # returns $mail
Adds a downloadable attachment, and returns the current instance for
chaining.
Takes either a single positional file path as a shorthand, or an hash or
hash reference of parameters.
When a single plain scalar or stringifiable object is provided and it
resolves to an existing file on disk, "path", "type", and "filename" are
set automatically. Additional named options may still be passed after
the path:
$mail->attach( '/path/to/report.pdf', encoding => 'base64' );
Requires either "path" or "data" when using the named-parameter form.
Options are:
* "charset"
The optional charset of the attachment.
* "description"
A short description.
* "encoding"
The encoding of the attachment, such as "zip", "gzip", "bzip2",
etc..
* "filename"
The attachment filename as displayed to the reader.
* "type"
The attachment mime-type.
All parameters are forwarded to "build" in Mail::Make::Entity.
attach_inline( %opts )
$mail->attach_inline(
path => $img_path,
type => 'image/png',
filename => 'Yamato,Inc-Logo.png',
cid => 'logo@yamato-inc',
); # returns $mail
Adds an inline part (e.g. an embedded image referenced via "cid:" in
HTML), and returns the current instance for chaining.
Takes an hash or hash reference of parameters.
Requires either or "data" and either "id" or "cid".
Supported parameters are:
* "boundary"
The boundary used.
* "charset"
The optional charset of the attachment.
* "cid" or "id"
The attachment ID ("Content-ID")
* "data"
The attachement raw data.
* "debug"
An unsigned integer to enable debugging.
* "description"
A short description.
See also "path" for an alternative.
* "disposition"
Can be either "attachment" or "inline"
* "encoding"
The encoding of the attachment, such as "zip", "gzip", "bzip2",
etc..
* "filename"
The attachment filename as displayed to the reader.
* "path"
The attachment file path.
See also "data" for an alternative.
* "type"
The attachment mime-type.
bcc( @addresses )
$mail->bcc( qw( hello@example.com john@example.jp ) );
$mail->bcc( [qw( hello@example.com john@example.jp )] );
Accumulates one or more BCC addresses. May be called multiple times.
This takes either an array reference or a list of e-mail addresses,
encode them if necessary, and add them to the "Bcc" mail envelop header
as a comma-separated value using "push_header" in Mail::Make::Headers
When called as a mutator, it returns the current instance of
Mail::Make::Headers, otherwise, as an accessor, it returns the current
value of the mail envelop header.
cc( @addresses )
$mail->cc( qw( hello@example.com john@example.jp ) );
$mail->cc( [qw( hello@example.com john@example.jp )] );
Accumulates one or more CC addresses.
This takes either an array reference or a list of e-mail addresses,
encode them if necessary, and add them to the "Cc" mail envelop header
as a comma-separated value using "push_header" in Mail::Make::Headers
When called as a mutator, it returns the current instance of
Mail::Make::Headers, otherwise, as an accessor, it returns the current
value of the mail envelop header.
date( [$date_string_or_epoch] )
Gets or sets the "Date" header.
Accepts a Unix epoch integer (converted to RFC 5322 format
automatically) or a pre-formatted RFC 5322 string.
Delegates to "date" in Mail::Make::Headers. If not set explicitly, the
current date and time are used when "as_entity" is first called.
When called as a mutator, it returns the current instance of
Mail::Make::Headers, otherwise, as an accessor, it returns the current
value of the mail envelop header.
from( [$address] )
$mail->from( 'hello@example.com' );
Gets or sets the "From" header by calling "set" in Mail::Make::Headers.
Non-ASCII display names are RFC 2047 encoded automatically.
When called as a mutator, it returns the current instance of Mail::Make,
otherwise, as an accessor, it returns the current value of the mail
envelop header.
header( $name [, $value] )
$mail->header( 'X-Mailer' => 'MySoft/v1.0.0' ); # returns $mail
# or
$mail->header( X_Mailer => 'MySoft/v1.0.0' ); # returns $mail
my $software = $mail->header( 'X-Mailer' );
With two arguments: appends an arbitrary header to the envelope using
push_header semantics (does not replace an existing field of the same
name).
Returns the current instance of "Mail::Make"
With one argument: returns the current value of the named header.
headers()
my $headers = $mail->headers; # Mail::Make::Headers
Returns the internal Mail::Make::Headers object. Use this for operations
not covered by the fluent methods, such as setting "X-*" headers or
reading back any field.
html( $content [, %opts] )
$mail->html( '
Hello world
', {
charset => 'utf-8',
encoding => 'quoted-printable',
}); # returns $mail
Adds a "text/html" body part, and returns the current instance for
chaining.
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
This takes an optional hash or hash reference of the following
parameters:
* "charset"
The character set used for thise HTML data.
Defaults to "utf-8"
* "data"
The HTML data.
* "encoding"
Can be "quoted-printable" or "base64"
Defaults to "quoted-printable"
html_to_inline( %opts )
# Fluent form
$mail->plain( "Hello.\n" )
->html_to_inline(
html => '
Hello.
',
base_url => 'https://www.example.com',
);
# HTML only, no plain text alternative
$mail->html_to_inline(
html => '
Hello.
',
base_url => 'https://www.example.com',
);
Parses the HTML, fetches all external assets (images, body background
images, and optionally CSS), rewrites their URLs to
"cid:UUID.ext@hostname", sets the HTML body via "html", and attaches
each asset as an inline part via "attach_inline". Returns $self for
chaining.
Assets that cannot be fetched are left unchanged and a warning is
emitted (suppressible with "no warnings 'Mail::Make'").
Supported options are:
* "base_url"
The base URL used to resolve relative and absolute-path URLs, such
as "/images/logo.png". Required unless every "src" and "href" in the
HTML is already an absolute URL. A "file:///path" URI is also
accepted as a base.
* "cache_dir"
Path to a directory for persistent caching. Each fetched resource is
stored on disk as "MD5(url).ext", with a sidecar "MD5(url).ext.json"
file holding the "ETag" and "Last-Modified" values used for
subsequent conditional requests ("If-None-Match" or
"If-Modified-Since"). The per-instance in-memory cache is always
active regardless of this option.
* "charset"
Charset for the HTML part. Forwarded to "html". Default: "utf-8".
* "embed_css"
Boolean. When true, "" assets are
also fetched and embedded as inline parts. Default: 0.
* "encoding"
Content-Transfer-Encoding for the HTML part. Forwarded to "html".
Default: "quoted-printable".
* "html"
Required. The raw HTML string to process.
If an error occurs, it sets an exception object, and returns "undef" in
scalar context or an empty list in list context.
in_reply_to( [$mid] )
$mail->in_reply_to( 'dave.null@example.com' ); # Returns $mail
my $email = $mail->in_reply_to;
Gets or sets the "In-Reply-To" header.
In mutator mode, this sets the "In-Reply-To" mail envelop header using
"set" in Mail::Make::Headers, and returns the current instance of
"Mail::Make", and in accessor mode, this returns the current value for
the mail envelop header "In-Reply-To"
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
message_id( [$mid | \%opts] )
$mail->message_id( '2adefb89-a26a-4cf1-91c7-1413b13cfd0f@local' ); # Returns $mail
$mail->message_id( '2adefb89-a26a-4cf1-91c7-1413b13cfd0f@local', { strict => 1 } ); # Returns $mail
$mail->message_id({ generate => 1, domain => 'example.com' });
$mail->message_id( undef ); # remove the message ID
my $msgid = $mail->message_id;
Gets or sets the "Message-ID". Auto-generated when "as_entity" is called
if not explicitly set.
Delegates to "message_id" in Mail::Make::Headers.
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
This takes an optional hash reference of the following parameters:
* "domain"
The domain name to use when generating the message ID.
* "generate"
If set to true, then "message_id" in Mail::Make::Headers will
generate the message ID.
If the option "domain" is not provided, it will use "hostname" in
Sys::Hostname to guess the domain name.
* "strict"
A boolean value (1 or 0).
When this is set to true, message_id|Mail::Make::Headers/message_id>
will call "_validate_message_id_value" in Mail::Make::Headers to
thoroughly validate the value provided. This means, it will reject
the value if:
1. It contains any non-ASCII or spaces/control characters.
2. It is not wrapped in angle brackets: "<" and ">"
3. Does not have exactly one at-mark "@"
4. The local part (the part on the left of the at-mark) contains
characters other than:
[A-Za-z0-9.!#\$%&'\*\+\/=\?\^_`\{\|\}~\-]+
5. The domain part (the part of the right of the at-mark) contains
characters other than:
[A-Za-z0-9](?:[A-Za-z0-9\-\.]*[A-Za-z0-9])?
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
plain( $content [, %opts] )
$mail->plain( 'Hello world', {
charset => 'utf-8',
encoding => 'quoted-printable',
}); # returns $mail
Adds a "text/plain" body part, and returns the current instance for
chaining.
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
This takes an optional hash or hash reference of the following
parameters:
* "charset"
The character set used for thise HTML data.
Defaults to "utf-8"
* "data"
The HTML data.
* "encoding"
Can be "quoted-printable" or "base64"
Defaults to "quoted-printable"
references( @mids )
$mail->references( [ $msg_id1, $msg_id2 ] ); # Returns $mail
$mail->references( $msg_id1, $msg_id2 ); # Returns $mail
# Removes the header
$mail->references( undef ); # Returns $mail
my @message_ids = $mail->references;
my $comma_list = $mail->references;
Accumulates one or more Message-IDs in the "References" header.
In mutator mode, this returns the current instance of Mail::Make
In accessor mode, this returns a list of message IDs, and in scalar
mode, this returns a comma-separate list of message IDs.s
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
related( %opts )
# Fluent form - with plain text alternative
$mail->plain( "Hello.\n" )
->related(
html => '
Hello.
',
inline => [
{ path => '/var/www/images/logo.png', type => 'image/png', id => 'logo@example.com' },
],
);
# HTML only, no plain text alternative
$mail->related(
html => '
Hello.
',
inline => [
{ path => '/var/www/images/logo.png', type => 'image/png', id => 'logo@example.com' },
],
);
Convenience method that sets the HTML body part and attaches all inline
parts in one call. The HTML must already contain "cid:ID" references
matching the "id" values in the "inline" list. Returns $self for
chaining.
This method is suited to the case where you have already processed the
HTML yourself and know the Content-IDs. For automatic URL-to-cid
rewriting, use "html_to_inline" instead.
Supported options are:
* "html"
Required. The HTML string, which must already contain "cid:ID"
references for each inline part.
* "html_opts"
Optional hash reference of options forwarded to "html" (such as
"charset" or "encoding").
* "inline"
An array reference of hash references, each forwarded to
"attach_inline". Each hash reference must supply at least "id" (or
"cid") and one of "path" or "data".
If an error occurs, it sets an exception object, and returns "undef" in
scalar context or an empty list in list context.
reply_to( [$address] )
$mail->reply_to( 'hello@example.com' );
Gets or sets the "Reply-To" header by calling "set" in
Mail::Make::Headers.
Non-ASCII display names are RFC 2047 encoded automatically.
When called as a mutator, it returns the current instance of Mail::Make,
otherwise, as an accessor, it returns the current value of the mail
envelop header.
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
return_path( [$address] )
$mail->return_path( 'dave.null@example.com' );
Gets or sets the "Return-Path" header by calling "set" in
Mail::Make::Headers.
Non-ASCII display names are RFC 2047 encoded automatically.
When called as a mutator, it returns the current instance of Mail::Make,
otherwise, as an accessor, it returns the current value of the mail
envelop header.
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
sender( [$address] )
$mail->sender( 'hello@example.com' );
Gets or sets the "Sender" header by calling "set" in
Mail::Make::Headers.
When called as a mutator, it returns the current instance of Mail::Make,
otherwise, as an accessor, it returns the current value of the mail
envelop header.
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
subject( [$string] )
$mail->subject( '会議議事録' ); # Returns $mail
$mail->subject;
Gets or sets the "Subject" by calling "set" in Mail::Make::Headers.
When called as a mutator, it returns the current instance of Mail::Make,
otherwise, as an accessor, it returns the current value of the mail
envelop header.
Non-ASCII subjects are RFC 2047 encoded before being stored.
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
to( @addresses )
$mail->to( 'hello@example.com' );
Accumulates one or more To addresses. Multiple calls are merged into a
single "To:" field per RFC 5322 §3.6.3 by calling "set" in
Mail::Make::Headers.
Non-ASCII display names are RFC 2047 encoded automatically.
Note that it is up to you to ensure there are no duplicates.
When called as a mutator, it returns the current instance of Mail::Make,
otherwise, as an accessor, it returns the current value of the mail
envelop header.
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
url_to_inline( %opts )
# Fluent form
$mail->plain( "Hello.\n" )
->url_to_inline( url => 'https://www.example.com/newsletter/confirm.html' );
# HTML only, no plain text alternative
$mail->url_to_inline( url => 'https://www.example.com/newsletter/confirm.html' );
Fetches the HTML page at "url", then processes it exactly like
"html_to_inline": external assets are fetched, their URLs rewritten to
"cid:" references, and each asset is attached as an inline part via
"attach_inline". Returns $self for chaining.
The "base_url" for resolving relative asset URLs defaults to the
directory portion of "url" (e.g. "https://www.example.com/newsletter/"
for a page at ".../newsletter/confirm.html"), but can be overridden
explicitly.
Supported options are:
* "url"
Required. The URL of the HTML page to fetch and process.
"file:///path" URIs are also accepted.
* "base_url"
Overrides the base URL used to resolve relative asset URLs. When
omitted, it is deduced from the directory portion of "url".
* "cache_dir"
Same as "html_to_inline". Path to a directory for persistent HTTP
caching of fetched assets.
* "charset"
Charset for the HTML part. Forwarded to "html". Default: "utf-8".
* "embed_css"
Boolean. When true, "" assets are
also fetched and embedded. Default: 0.
* "encoding"
Content-Transfer-Encoding for the HTML part. Forwarded to "html".
Default: "quoted-printable".
If an error occurs, it sets an exception object, and returns "undef" in
scalar context or an empty list in list context.
OUTPUT METHODS
as_entity
my $entity = $mail->as_entity; # Returns a Mail::Make::Entity object
Assembles and returns the top-level Mail::Make::Entity based on the
various content that has been specified, such as plain text, html mail,
attachments, or inline attachments.
The MIME structure is selected automatically (see "DESCRIPTION").
Envelope headers are merged into the entity using "init_header"
semantics: fields already set on the entity ("Content-Type",
"MIME-Version", etc.) are never overwritten.
If no "Message-ID" is set yet, it will compute one.
"MIME-Version" will be set to 1.0 no matter what value may have been set
previously.
The computed value is cached, so repetitive calls will return the cached
value.
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
as_string
my $string = $mail->as_string;
Assembles the message and returns it as a plain string, consistent with
"MIME::Entity::stringify". This is the form suitable for direct
printing, string interpolation, and most downstream consumers.
For large messages, prefer "print" (no buffering) or "as_string_ref" (no
copy on return).
This method calls "as_entity", and returns the value returned by
"as_string" in Mail::Make::Entity, passing it whatever value was
provided.
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
as_string_ref
my $scalar_ref = $mail->as_string_ref;
Assembles the message and returns it as a scalar reference (or a
Module::Generic::Scalar object, which stringifies as needed). No extra
string copy is made during the fast path.
When "use_temp_file" is true, or the serialised entity size returned by
"length" in Mail::Make::Entity exceeds "max_body_in_memory_size", the
message is written to a "Module::Generic::Scalar" buffer via its
in-memory filehandle. This keeps peak RAM use to a single copy of the
assembled message.
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
max_body_in_memory_size( [$bytes] )
Gets or sets the byte threshold above which "as_string_ref" spools to a
temporary file rather than building the message in RAM. Set to 0 or
"undef" to disable the threshold entirely. Default:
$Mail::Make::MAX_BODY_IN_MEMORY_SIZE (1 MiB).
print( $fh )
$mail->print( $fh ) || die( $mail->error );
Writes the fully assembled message to a filehandle without buffering it
in memory. This is the recommended approach for very large messages: the
MIME tree is serialised part by part directly to $fh, keeping memory use
proportional to the largest single part rather than the total message
size.
This returns the current instance of Mail::Make for chaining.
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
smtpsend( %opts )
my @recipients = $mail->smtpsend( Host => $smtp );
my $rv = $mail->smtpsend(
Host => '127.0.0.1',
Port => $port,
Hello => 'test.local',
);
my $recipients_array_ref = $mail->smtpsend(
Host => '127.0.0.1',
Port => $port,
Hello => 'test.local',
MailFrom => 'bounce@example.com',
);
Assembles the message and submits it to an SMTP server via Net::SMTP,
which is a core perl module, and loaded only when this method is called.
This takes a hash or hash reference of options.
Credential and recipient validation is performed before any network
connection is attempted, so configuration errors are reported
immediately without consuming network resources.
Recognised options:
"AuthMechanisms"
Space-separated list of SASL mechanism names in preference order.
Defaults to "PLAIN LOGIN", which are safe and universally supported
over an encrypted channel (STARTTLS or SSL).
The actual mechanism used is the intersection of this list and what
the server advertises. If no intersection exists, deprecated
challenge-response mechanisms ("DIGEST-MD5", "CRAM-MD5", "GSSAPI")
are excluded and the remainder of the server's list is tried.
"Debug"
Boolean. Enables Net::SMTP debug output.
"Hello"
The FQDN sent in the EHLO/HELO greeting.
"Host"
Hostname, IP address, or an already-connected Net::SMTP object. If
an existing object is passed, it is used as-is and not quit on
completion (the caller retains ownership of the connection).
If omitted, the colon-separated list in $ENV{SMTPHOSTS} is tried
first, then "mailhost" and "localhost" in that order.
"MailFrom"
The envelope sender address ("MAIL FROM"). Defaults to the bare
addr-spec extracted from the "From:" header.
"Password"
Password for SMTP authentication. May be:
* A plain string.
* A "CODE" reference called with no arguments at authentication
time.
Useful for reading credentials from a keyring or secrets manager
without storing them in memory until needed:
Password => sub { MyKeyring::get('smtp') }
"Port"
SMTP port number. Common values:
* 25 - plain SMTP (default when "SSL" is false)
* 465 - SMTPS, direct SSL/TLS (use with "SSL => 1")
* 587 - submission, usually STARTTLS (use with "StartTLS => 1")
"SSL"
Boolean. When true, the connection is wrapped in SSL/TLS from the
start (SMTPS, typically port 465).
Requires IO::Socket::SSL.
"StartTLS"
Boolean. When true, a plain connection is established first and then
upgraded to TLS via the SMTP "STARTTLS" extension (typically port
587).
Requires IO::Socket::SSL. Ignored when "Host" is a pre-built
Net::SMTP object.
"SSL_opts"
Hash reference of additional options passed to IO::Socket::SSL
during the SSL/TLS handshake. For example:
SSL_opts => { SSL_verify_mode => 0 } # disable peer cert check
SSL_opts => { SSL_ca_file => '/etc/ssl/ca.pem' }
"Timeout"
Connection and command timeout in seconds, passed directly to
Net::SMTP.
"To", "Cc", "Bcc"
Override the RCPT TO list. Each may be a string or an array
reference of addresses. When omitted, the corresponding message
headers are used.
"Bcc:" is always stripped from the outgoing message headers before
transmission, per RFC 2822 §3.6.3.
"Username"
Login name for SMTP authentication (SASL). Requires Authen::SASL.
Must be combined with "Password". Validated before any connection is
made.
Typical usage examples:
# Plain SMTP, no auth (LAN relay)
$mail->smtpsend( Host => 'mail.example.com' );
# SMTPS (direct TLS, port 465)
$mail->smtpsend(
Host => 'smtp.example.com',
Port => 465,
SSL => 1,
Username => 'jack@example.com',
Password => 'secret',
);
# Submission with STARTTLS (port 587) and password callback
$mail->smtpsend(
Host => 'smtp.example.com',
Port => 587,
StartTLS => 1,
Username => 'jack@example.com',
Password => sub { MyKeyring::get('smtp_pass') },
);
Returns the list of accepted recipient addresses in list context, or a
reference to that list in scalar context.
If an error occurs, it sets an exception object, and returns "undef" in
scalar context, or an empty list in list context.
use_temp_file( [$bool] )
When true, "as_string_ref" always spools to a temporary file regardless
of message size. Useful when you know the message will be large, or when
you want to bound peak memory use unconditionally. Default: false.
GPG METHODS
These methods delegate to Mail::Make::GPG, which requires IPC::Run and a
working "gpg" (or "gpg2") installation. All three methods produce RFC
3156-compliant messages and return a new Mail::Make object suitable for
passing directly to "smtpsend()".
gpg_encrypt( %opts )
Encrypts this message for one or more recipients and returns a new
Mail::Make object whose entity is an RFC 3156 "multipart/encrypted;
protocol="application/pgp-encrypted"" message.
Required options:
Recipients => \@addrs_or_key_ids
Array reference of recipient e-mail addresses or key fingerprints.
Each recipient's public key must already be present in the local
GnuPG keyring, unless "AutoFetch" is enabled.
Optional options:
"AutoFetch => $bool"
When true and "KeyServer" is set, calls "gpg --locate-keys" for each
recipient before encryption. Default: 0.
"Digest => $algorithm"
Hash algorithm for the signature embedded in the encrypted payload.
Default: "SHA256".
"GpgBin => $path"
Full path to the "gpg" executable. Defaults to searching "gpg2" then
"gpg" in "PATH".
"KeyServer => $url"
Keyserver URL for auto-fetching recipient public keys (e.g.
'keys.openpgp.org'). Only consulted when "AutoFetch" is true.
gpg_sign( %opts )
Signs this message and returns a new Mail::Make object whose entity is
an RFC 3156 "multipart/signed; protocol="application/pgp-signature""
message with a detached, ASCII-armoured signature.
Required options:
"KeyId => $fingerprint_or_id"
Signing key fingerprint or short ID (e.g.
'35ADBC3AF8355E845139D8965F3C0261CDB2E752').
Optional options:
"Digest => $algorithm"
Hash algorithm. Default: "SHA256".
Valid values: "SHA256", "SHA384", "SHA512", "SHA1".
"GpgBin => $path"
Full path to the "gpg" executable.
"Passphrase => $string_or_coderef"
Passphrase to unlock the secret key. May be a plain string or a
"CODE" reference called with no arguments at signing time. When
omitted, GnuPG's agent handles passphrase prompting.
gpg_sign_encrypt( %opts )
Signs then encrypts this message. Returns a new Mail::Make object whose
entity is an RFC 3156 "multipart/encrypted" message containing a signed
and encrypted OpenPGP payload.
Accepts all options from both "gpg_sign" and "gpg_encrypt".
Note: "KeyId" and "Recipients" are both required.
Typical usage:
# Sign only
my $signed = $mail->gpg_sign(
KeyId => '35ADBC3AF8355E845139D8965F3C0261CDB2E752',
Passphrase => 'my-passphrase', # or: sub { MyKeyring::get('gpg') }
) || die( $mail->error );
$signed->smtpsend( Host => 'smtp.example.com' );
# Encrypt only
my $encrypted = $mail->gpg_encrypt(
Recipients => [ 'alice@example.com' ],
) || die( $mail->error );
# Sign then encrypt
my $protected = $mail->gpg_sign_encrypt(
KeyId => '35ADBC3AF8355E845139D8965F3C0261CDB2E752',
Passphrase => sub { MyKeyring::get_passphrase() },
Recipients => [ 'alice@example.com', 'bob@example.com' ],
) || die( $mail->error );
S/MIME METHODS
These methods delegate to Mail::Make::SMIME, which requires Crypt::SMIME
(an XS module wrapping OpenSSL "libcrypto"). All certificates and keys
must be supplied in PEM format, either as file paths or as PEM strings.
Memory usage
All three methods load the complete serialised message into memory
before performing any cryptographic operation. This is a fundamental
constraint imposed by two factors: the Crypt::SMIME API accepts only
Perl strings (no filehandle or streaming interface), and the underlying
protocols themselves require the entire content to be available before
the result can be emitted, thus signing requires a complete hash before
the signature can be appended, and PKCS#7 encryption requires the total
payload length to be declared in the ASN.1 DER header before any
ciphertext is written.
For typical email messages this is not a concern. If you anticipate very
large attachments, consider Mail::Make::GPG instead, which delegates to
the "gpg" command-line tool via IPC::Run and can handle arbitrary
message sizes through temporary files. A future "v0.2.0" of
Mail::Make::SMIME may add a similar "openssl smime" backend.
See "MEMORY USAGE AND LIMITATIONS" in Mail::Make::SMIME for a full
discussion.
smime_encrypt( %opts )
$encrypted = $mail->smime_encrypt(
RecipientCert => $smime_rec_cert,
);
Encrypts this message for one or more recipients and returns a new
"Mail::Make" object whose entity is an RFC 5751 "application/pkcs7-mime;
smime-type=enveloped-data" message.
Takes an hash or hash reference of options.
Required options:
"RecipientCert => $pem_string_or_path"
Recipient certificate in PEM format (for encryption). May also be an
array reference of PEM strings or file paths for multi-recipient
encryption.
Optional options:
"CACert => $pem_string_or_path"
CA certificate to include for chain verification.
smime_sign( %opts )
my $signed = $mail->smime_sign(
Cert => $smime_cert,
Key => $smime_key,
CACert => $smime_ca, # optional
);
Signs this message with a detached S/MIME signature and returns a new
"Mail::Make" object whose entity is an RFC 5751 "multipart/signed"
message.
The signature is always detached, which allows non-S/MIME-aware clients
to read the message body.
Required options:
"Cert => $pem_string_or_path"
Signer certificate in PEM format.
"Key => $pem_string_or_path"
Private key in PEM format.
Optional options:
"KeyPassword => $string_or_coderef"
Passphrase for an encrypted private key, or a CODE ref that returns
one.
"CACert => $pem_string_or_path"
CA certificate to include in the signature for chain verification.
smime_sign_encrypt( %opts )
my $result = $mail->smime_sign_encrypt(
Cert => $smime_cert,
Key => $smime_key,
RecipientCert => $smime_rec_cert,
CACert => $smime_ca, # optional
);
Signs this message then encrypts the signed result. Returns a new
"Mail::Make" object whose entity is an RFC 5751 enveloped message
containing a signed payload.
Accepts all options from both "smime_sign" and "smime_encrypt".
Note: "Cert", "Key", and "RecipientCert" are all required.
Typical usage:
# Sign only
my $signed = $mail->smime_sign(
Cert => '/path/to/my.cert.pem',
Key => '/path/to/my.key.pem',
CACert => '/path/to/ca.crt',
) || die( $mail->error );
$signed->smtpsend( Host => 'smtp.example.com' );
# Encrypt only
my $encrypted = $mail->smime_encrypt(
RecipientCert => '/path/to/recipient.cert.pem',
) || die( $mail->error );
# Sign then encrypt
my $protected = $mail->smime_sign_encrypt(
Cert => '/path/to/my.cert.pem',
Key => '/path/to/my.key.pem',
RecipientCert => '/path/to/recipient.cert.pem',
) || die( $mail->error );
PRIVATE METHODS
_default_domain
Returns a FQDN for auto-generated "Message-ID" values. Uses
Sys::Hostname and appends ".local" when the hostname contains no dot.
Falls back to "mail.make.local".
_encode_address( $addr_string )
Encodes the display-name portion of an RFC 2822 address using RFC 2047
when the display name contains non-ASCII characters. The addr-spec is
never modified.
_encode_header( $string )
Encodes an arbitrary header string for the wire using RFC 2047
encoded-words.
Delegates to Mail::Make::Headers::Subject.
_format_date
Returns the current local date and time as an RFC 2822 string.
AUTHOR
Jacques Deguest
SEE ALSO
RFC 2045, RFC 2046, RFC 2047, RFC 2183, RFC 2231, RFC 2822
Mail::Make::Entity, Mail::Make::Headers,
Mail::Make::Headers::ContentType,
Mail::Make::Headers::ContentDisposition,
Mail::Make::Headers::ContentTransferEncoding, Mail::Make::Body::InCore,
Mail::Make::Body::File, Mail::Make::Stream::Base64,
Mail::Make::Stream::QuotedPrint, Mail::Make::Exception, Net::SMTP
COPYRIGHT & LICENSE
Copyright(c) 2026 DEGUEST Pte. Ltd.
All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.