
- README(English)
- シシマイ? | What is Sisimai
- シシマイを使う準備 | Setting Up Sisimai
- 使い方 | Usage
- シシマイの仕様 | Sisimai Specification
- Contributing
- その他の情報 | Other Information
- 作者 | Author
- 著作権 | Copyright
- ライセンス | License
What is sisimai
Sisimai(シシマイ)はRFC5322準拠のエラーメールを解析し、解析結果をデータ構造に変換するインターフェイス を提供するPerlモジュールです。シシマイ はbounceHammer version 4として開発していたものであり、 bounceHammerの後継となるライブラリです。

Key features
- エラーメールをデータ構造に変換
- Perlのデータ形式(HashとArray)とJSON(文字列)に対応
- インストールも使用も簡単
cpan,cpanm,cpm install- git clone & make
- 高い解析精度
- 解析精度はbounceHammerの2倍
- 68種類のMTA/MDA/ESPに対応
- Feedback Loopにも対応
- 32種類のエラー理由を検出
- bounceHammer 2.7.13p3よりも高速に解析
- 2.0倍程高速
Command line demo
次の画像のように、Perl版シシマイ(p5-sisimai)もRuby版シシマイ(rb-sisimai)も、コマンドラインから簡単に
バウンスメールを解析することができます。

Setting Up Sisimai
System requirements
シシマイの動作環境についての詳細はSisimai | シシマイを使ってみる をご覧ください。
Install
From CPAN
$ cpanm --sudo Sisimai
--> Working on Sisimai
Fetching http://www.cpan.org/authors/id/A/AK/AKXLIX/Sisimai-4.25.5.tar.gz ... OK
...
1 distribution installed
$ perldoc -l Sisimai
/usr/local/lib/perl5/site_perl/5.30.0/Sisimai.pm
From GitHub
$ cd /usr/local/src
$ git clone https://github.com/sisimai/p5-sisimai.git
$ cd ./p5-sisimai
$ sudo make install-from-local
--> Working on .
Configuring Sisimai-4.25.5 ... OK
1 distribution installed
Usage
Basic usage
下記のようにSisimaiのrise()メソッドをmboxかMaildir/のPATHを引数にして実行すると解析結果が配列
リファレンスで返ってきます。v4.25.6から元データとなった電子メールファイルへのPATHを保持するorigin
が利用できます。
#! /usr/bin/env perl
use Sisimai;
my $v = Sisimai->rise('/path/to/mbox'); # or path to Maildir/
# Beginning with v4.23.0, both rise() and dump() method of Sisimai class can read bounce messages
# from variable instead of a path to 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 want to get bounce records which reason is "delivered", set "delivered" option to rise()
# method like the following:
my $v = Sisimai->rise('/path/to/mbox', 'delivered' => 1);
# Beginning with v5.0.0, sisimai does not return the reulst which "reason" is "vaction" by default.
# If you want to get bounce records which reason is "vacation", set "vacation" option to rise()
# method like the following:
my $v = Sisimai->rise('/path/to/mbox', 'vacation' => 1);
if( defined $v ) {
for my $e ( @$v ) {
print ref $e; # Sisimai::Data
print ref $e->recipient; # Sisimai::Address
print ref $e->timestamp; # Sisimai::Time
print $e->addresser->address; # shironeko@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; # 0
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
}
}
Convert to JSON
下記のようにSisimaiのdump()メソッドをmboxかMaildir/のPATHを引数にして実行すると解析結果が文字列
(JSON)で返ってきます。
# Get JSON string from parsed mailbox or Maildir/
my $j = Sisimai->dump('/path/to/mbox'); # or path to Maildir/
# dump() is added in v4.1.27
print $j; # parsed data as JSON
# dump() method also accepts "delivered" option like the following code:
my $j = Sisimai->dump('/path/to/mbox', 'delivered' => 1);
Callback feature
Sisimai->riseとSisimai->dumpのc___引数はコールバック機能で呼び出されるコードリファンレンスを
保持する配列リファレンスです。c___の1番目の要素にはSisimai::Message->parseで呼び出されるコード
リファレンスでメールヘッダと本文に対して行う処理を、2番目の要素には、解析対象のメールファイルに対して
行う処理をそれぞれ入れます。
各コードリファレンスで処理した結果はSisimai::Data->catchを通して得られます。
[0] メールヘッダと本文に対して
c___に渡す配列リファレンスの最初の要素に入れたコードリファレンスはSisimai::Message->parse()で
呼び出されます。
#! /usr/bin/env perl
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"
各メールのファイルに対して
Sisimai->rise()とSisimai->dump()の両メソッドに渡せる引数c___(配列リファレンス)の2番目に入れた
コードリファレンスは解析したメールのファイルごとに呼び出されます。
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 $sisi = $args->{'sisi'}; # (*Array) List of Sisimai::Data
for my $e ( @$sisi ) {
# Insert custom fields into the parsed results
$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;
}
# Append X-Sisimai-Parsed: header and save into other path
my $a = sprintf("X-Sisimai-Parsed: %d\n", scalar @$sisi);
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 parsed
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>"
コールバック機能のより詳細な使い方は Sisimai | 解析方法 - コールバック機能をご覧ください。
One-Liner
Sisimai 4.1.27から登場したdump()メソッドを使うとワンライナーでJSON化した解析結果が得られます。
$ perl -MSisimai -lE 'print Sisimai->dump(shift)' /path/to/mbox
Output example

[{"listid": "","senderdomain": "example.com","replycode": "550","origin": "set-of-emails/maildir/bsd/lhost-office365-13.eml","smtpagent": "Office365","smtpcommand": "","timestamp": 1493541285,"diagnostictype": "SMTP","action": "failed","feedbacktype": "","lhost": "omls-1.kuins.neko.example.jp","timezoneoffset": "+0000","recipient": "kijitora-nyaan@neko.kyoto.example.jp","token": "3ea52cc68fa4ce73b0489a01e33f53477968252f","destination": "neko.kyoto.example.jp","addresser": "neko@example.com","diagnosticcode": "Error Details Reported error: 550 5.1.10 RESOLVER.ADR.RecipientNotFound; Recipient not found by SMTP address lookup DSN generated by: NEKONYAAN0022.apcprd01.prod.exchangelabs.com","hardbounce": 1,"catch": {"x-mailer": "","sender": "","queue-id": ""},"messageid": "","deliverystatus": "5.1.10","rhost": "nekonyaan0022.apcprd01.prod.exchangelabs.com","subject": "にゃーん","alias": "","reason": "userunknown"}]
Sisimai Specification
Differences between bounceHammer and Sisimai
bounceHammer 2.7.13p3とSisimai(シシマイ)は下記のような違いがあります。違いの詳細については Sisimai | 違いの一覧をご覧ください。
| 機能 | bounceHammer | Sisimai | |------------------------------------------------|---------------|-------------| | 動作環境(Perl) | 5.10 - 5.14 | 5.10 - 5.30 | | コマンドラインツール | あり | 無し | | 商用MTAとMSP対応解析モジュール | 無し | あり(同梱) | | WebUIとAPI | あり | 無し | | 解析済バウンスデータを保存するDBスキーマ | あり | 無し[1] | | 解析精度の割合(2000通のメール)[2] | 0.61 | 1.00 | | メール解析速度(1000通のメール) | 4.24秒 | 1.35秒[3] | | 検出可能なバウンス理由の数 | 19 | 29 | | 解析エンジン(MTAモジュール)の数 | 15 | 68 | | 2件以上のバウンスがあるメールの解析 | 1件目だけ | 全件解析可能| | FeedBack Loop/ARF形式のメール解析 | 非対応 | 対応済 | | 宛先ドメインによる分類項目 | あり | 無し | | 解析結果の出力形式 | YAML,JSON,CSV | JSON | | インストール作業が簡単かどうか | やや面倒 | 簡単で楽 | | cpan, cpanm, cpmコマンドでのインストール | 非対応 | 対応済 | | 依存モジュール数(Perlのコアモジュールを除く) | 24モジュール | 2モジュール | | LOC:ソースコードの行数 | 18200行 | 10500行 | | テスト件数(t/,xt/ディレクトリ) | 27365件 | 311000件 | | ライセンス | GPLv2かPerl | 二条項BSD | | 開発会社によるサポート契約 | 終売(EOS) | 提供中 |
- DBIまたは好きなORMを使って自由に実装してください
- ./ANALYTICAL-PRECISIONを参照
- Xeon E5-2640 2.5GHz x 2 cores | 5000 bogomips | 1GB RAM | Perl 5.24.1
Other spec of Sisimai
Contributing
Bug report
もしもSisimaiにバグを発見した場合はIssuesにて連絡を いただけると助かります。
Emails could not be parsed
Sisimaiで解析できないバウンスメールは set-of-emails/to-be-debugged-because/sisimai-cannot-parse-yetリポジトリに追加してPull-Requestを送ってください。
Other Information
Related sites
- @libsisimai | Sisimai on Twitter (@libsisimai)
- libSISIMAI.ORG | Sisimai | The Successor To bounceHammer, Library to parse bounce mails
- Sisimai Blog | blog.libsisimai.org
- Facebook Page | facebook.com/libsisimai
- GitHub | github.com/sisimai/p5-sisimai
- CPAN | Sisimai - Mail Analyzing Interface for bounce mails. - metacpan.org
- CPAN Testers Reports | CPAN Testers Reports: Reports for Sisimai
- Ruby verson | Ruby version of Sisimai
- Fixtures | set-of-emails - Sample emails for "make test"
- bounceHammer.JP | bounceHammer will be EOL on February 29, 2016
See also
- README.md - README.md in English
- RFC3463 - Enhanced Mail System Status Codes
- RFC3464 - An Extensible Message Format for Delivery Status Notifications
- RFC3834 - Recommendations for Automatic Responses to Electronic Mail
- RFC5321 - Simple Mail Transfer Protocol
- RFC5322 - Internet Message Format
Author
Copyright
Copyright (C) 2014-2023 azumakuniyuki, All Rights Reserved.
License
This software is distributed under The BSD 2-Clause License.