Sisimai(3pm)
π NAME π
Sisimai β the Mail Analyzing Interface for bounce mails, and honestly? she ate π
β¨ SYNOPSIS β¨
use Sisimai;
That's it. That's the whole entrance. Main character energy from line one π
π¦ DESCRIPTION π¦
Okay so bestie, picture this: bounce emails are chaos. Every mail server on earth writes them differently, like they all went to different schools and never compared notes π
Sisimai (pronounced /Ιi.Ιi.ma.i/) is the library that decodes complex and diverse bounce emails and outputs the results of the delivery failure β stuff like the reason for the bounce and the recipient email address β in structured data. And if you want it as JSON? Yeah, she does that too. Obsessed π
πΈ BASIC USAGE πΈ
rise('/path/to/mbox')
The rise() method provides the feature for getting decoded data as a Perl Hash reference from bounced email messages, like this. And heads up: beginning with v4.25.6, there's a new accessor called origin which keeps the path to the email file as a data source β¨
use Sisimai;
my $v = Sisimai->rise('/path/to/mbox'); # or path to Maildir/
# In v4.23.0, the rise() and dump() methods of the Sisimai class can now read the entire bounce
# email as a string, in addition to the PATH to the email file or mailbox.
use IO::File;
my $r = '';
my $f = IO::File->new('/path/to/mbox'); # or path to Maildir/
{ local $/ = undef; $r = <$f>; $f->close }
my $v = Sisimai->rise(\$r);
# If you also need analysis results that are "delivered" (successfully delivered), please
# specify the "delivered" option to the rise() method as shown below.
my $v = Sisimai->rise('/path/to/mbox', 'delivered' => 1);
# From v5.0.0, Sisimai no longer returns analysis results with a bounce reason of "vacation" by
# default. If you also need analysis results that show a "vacation" reason, please specify the
# "vacation" option to the rise() method as shown in the following code.
my $v = Sisimai->rise('/path/to/mbox', 'vacation' => 1);
if( defined $v ) {
for my $e ( @$v ) {
print ref $e; # Sisimai::Fact
print ref $e->recipient; # Sisimai::Address
print ref $e->timestamp; # Sisimai::Time
print $e->addresser->address; # "michitsuna@example.org" # From
print $e->recipient->address; # "kijitora@example.jp" # To
print $e->recipient->host; # "example.jp"
print $e->deliverystatus; # "5.1.1"
print $e->replycode; # "550"
print $e->reason; # "userunknown"
print $e->origin; # "/var/spool/bounce/new/1740074341.eml"
print $e->hardbounce; # 1
my $h = $e->damn(); # Convert to HASH reference
my $j = $e->dump('json'); # Convert to JSON string
print $e->dump('json'); # JSON formatted bounce data
}
}
Look at all those accessors. She's thriving π«Ά
dump('/path/to/mbox')
The dump() method provides the feature for getting decoded data as a JSON string from bounced email messages, like the following code:
use Sisimai;
# Get JSON string from path of a mailbox or a Maildir/
my $j = Sisimai->dump('/path/to/mbox'); # or path to Maildir/
# dump() is added in v4.1.27
print $j; # decoded data as JSON
# dump() method also accepts "delivered" and "vacation" option like the following code:
my $j = Sisimai->dump('/path/to/mbox', 'delivered' => 1, 'vacation' => 1);
π‘ dump() was added in v4.1.27, so if you're on something ancient, no JSON for you bestie.
π OTHER WAYS TO DECODE π
Read email data from STDIN
Wanna pipe email data straight in from STDIN? Just specify STDIN at the first argument of the dump() and rise() method, like this command:
% cat ./path/to/bounce.eml | perl -MSisimai -lE 'print Sisimai->dump(STDIN)'
Callback Feature
Okay so this is the fun one πͺ The c___ argument β that's c and three _s, looks like a fishhook, iykyk β of Sisimai->rise and Sisimai->dump() is an array reference, and it's the parameter that receives code references for the callback feature.
Here's how the two slots work:
- The first element of the
c___argument is called atSisimai::Message->sift()for dealing with email headers and the entire message body. - The second element of the
c___argument is called at the end of each email file processing.
The result generated by the callback method is accessible via Sisimai::Fact->catch β¨
[0] For email headers and the body
The callback method set in the first element of c___ is called at Sisimai::Message->sift().
use Sisimai;
my $code = sub {
my $args = shift; # (*Hash)
my $head = $args->{'headers'}; # (*Hash) Email headers
my $body = $args->{'message'}; # (String) Message body
my $adds = { 'x-mailer' => '', 'queue-id' => '' };
if( $body =~ m/^X-Postfix-Queue-ID:\s*(.+)$/m ) {
$adds->{'queue-id'} = $1;
}
$adds->{'x-mailer'} = $head->{'x-mailer'} || '';
return $adds;
};
my $data = Sisimai->rise('/path/to/mbox', 'c___' => [$code, undef]);
my $json = Sisimai->dump('/path/to/mbox', 'c___' => [$code, undef]);
print $data->[0]->catch->{'x-mailer'}; # "Apple Mail (2.1283)"
print $data->[0]->catch->{'queue-id'}; # "43f4KX6WR7z1xcMG"
[1] For each email file
The callback method set in the second element of c___ is called at the Sisimai->rise() method for dealing with each email file.
my $path = '/path/to/maildir';
my $code = sub {
my $args = shift; # (*Hash)
my $kind = $args->{'kind'}; # (String) Sisimai::Mail->kind
my $mail = $args->{'mail'}; # (*String) Entire email message
my $path = $args->{'path'}; # (String) Sisimai::Mail->path
my $fact = $args->{'fact'}; # (*Array) List of Sisimai::Fact
for my $e ( @$fact ) {
# Store custom information in the "catch" accessor.
$e->{'catch'} ||= {};
$e->{'catch'}->{'size'} = length $$mail;
$e->{'catch'}->{'kind'} = ucfirst $kind;
if( $$mail =~ /^Return-Path: (.+)$/m ) {
# Return-Path: <MAILER-DAEMON>
$e->{'catch'}->{'return-path'} = $1;
}
# Save the original email with an additional "X-Sisimai-Decoded:" header to a different PATH.
my $a = sprintf("X-Sisimai-Decoded: %d\n", scalar @$fact);
my $p = sprintf("/path/to/another/directory/sisimai-%s.eml", $e->token);
my $f = IO::File->new($p, 'w');
my $v = $$mail; $v =~ s/^(From:.+)$/$a$1/m;
print $f $v; $f->close;
}
# Remove the email file in Maildir/ after decoding
unlink $path if $kind eq 'maildir';
# Need to not return a value
};
my $list = Sisimai->rise($path, 'c___' => [undef, $code]);
print $list->[0]->{'catch'}->{'size'}; # 2202
print $list->[0]->{'catch'}->{'kind'}; # "Maildir"
print $list->[0]->{'catch'}->{'return-path'}; # "<MAILER-DAEMON>"
β οΈ Note the comment: Need to not return a value. She means it, bestie. Don't return anything π
More information about the callback feature is available at <https://libsisimai.org/en/usage/#callback>
π OTHER METHODS π
engine()
The engine method provides a table including the decoding engine list and its description.
use Sisimai;
my $v = Sisimai->engine();
for my $e ( keys %$v ) {
print $e; # Sisimai::MTA::Sendmail
print $v->{ $e }; # V8Sendmail: /usr/sbin/sendmail
}
reason()
The reason method provides a table including all the reasons Sisimai can detect π₯
use Sisimai;
my $v = Sisimai->reason();
for my $e ( keys %$v ) {
print $e; # Blocked
print $v->{ $e }; # 'Email rejected due to client IP address or a hostname'
}
match()
The match method receives an error message as a string and returns a reason name, like the following:
use Sisimai;
my $v = '550 5.1.1 User unknown';
my $r = Sisimai->match($v);
print $r; # "userunknown"
version()
The version method returns the version number of Sisimai.
use Sisimai;
print Sisimai->version; # 5.0.1
β SEE ALSO β
Sisimai::Mailβ Mailbox or Maildir objectSisimai::Factβ Decoded data object- <https://libsisimai.org/> β Sisimai - Mail Analyzing Interface Library
- <https://tools.ietf.org/html/rfc3463> β RFC3463: Enhanced Mail System Status Codes
- <https://tools.ietf.org/html/rfc3464> β RFC3464: An Extensible Message Format for Delivery Status Notifications
- <https://tools.ietf.org/html/rfc5321> β RFC5321: Simple Mail Transfer Protocol
- <https://tools.ietf.org/html/rfc5322> β RFC5322: Internet Message Format
π REPOSITORY π
- <https://github.com/sisimai/p5-sisimai> β Sisimai on GitHub
π WEB SITE π
- <https://libsisimai.org/> β Mail Analyzing Interface Library
- <https://github.com/sisimai/rb-sisimai> β Ruby version of Sisimai
π AUTHOR π
azumakuniyuki
π COPYRIGHT π
Copyright (C) 2014-2026 azumakuniyuki, All rights reserved.
π§ LICENSE π§
This software is distributed under The BSD 2-Clause License π
And that's the whole page, bestie! This tea was served to you via User Contributed Perl Documentation β page generated by perl v5.40.1, dated 2026-07-05. Go decode some bounces, you absolute legend πΈπ¦β¨
π¦ where this page comes from
- ubuntu stonking: libsisimai-perl 5.7.0-1 Β· BSD-2-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms