Sisimai(シシマイ)はPerlまたはRuby (JRubyの一部バージョンも含む) あるいはGoでビルドしたバイナリが実行可能なシステムで動作します。
SisimaiはCPAN (Perl版)とRubyGems.org (Ruby版)と、 そしてGitHub (Perl版/Ruby版/Go版) からダウンロードできます。 Go版はgo getでもインストール可能です。
Maildir/やUNIX mboxにあるバウンスメールの解析、構造化された解析済みデータの取得と 各項目の参照方法、JSON化など簡単な使い方を紹介します。
標準入力(STDIN)からの読み込み、配信成功や自動応答メッセージ(Vaction)も 解析結果に含める方法、コールバック機能で独自の処理を組み込む方法について。
Sisimai(シシマイ)は*BSDやmacOSやLinuxのようなPerlまたは Ruby(JRubyを含む)、あるいはGoでビルドしたバイナリが動作するOSで動きます。
Sisimai 5.0.0では、互換性のない破壊的な変更がいくつか入っています。 インストールやアップグレードをする前にリリースノート とSisimai 4との違いを確認してください。
Sisimaiは GitHub, CPAN, RubyGems.org, go get からそれぞれダウンロード・インストールが可能です。 また、Perl版SisimaiはFreeBSDのportsコレクション やDebianパッケージ からでもインストールすることができます。
Sisimai 5.0.0で互換性のない、破壊的な変更がいくつか入っています。 インストールやアップグレードをする前にリリースノート とSisimai 4との違いを確認してください。
開発版を含む最新バージョンと安定版のSisimaiは
GitHub
の5-stableブランチまたは4-stable
ブランチからダウンロード出来ます。Perl版・Ruby版・Go版ともにこのリポジトリにあります。
2024年2月2日からリポジトリのデフォルトブランチは 5-stableになりました。
Perl版Sisimaiのリポジトリ名は
sisimai/p5-sisimai
です。Sisimai 5.0.0からPerl 5.26以上が必要になりますので、
インストールの前にシステムに入っているPerlのバージョンを確認してください。
% perl -v
This is perl 5, version 30, subversion 0 (v5.30.0) built for darwin-2level
Copyright 1987-2019, Larry Wall
...
% git clone https://github.com/sisimai/p5-sisimai.git
% cd ./p5-sisimai
% make install-from-local
./cpanm --sudo . || ( make cpm && ./cpm install --sudo -v . )
--> Working on .
Configuring Sisimai-v5.0.0 ... OK
Building and testing Sisimai-v5.0.0 ... Password: <sudo password here>
OK
Successfully installed Sisimai-v5.0.0
1 distribution installed
% perl -MSisimai -lE 'print Sisimai->version'
5.0.0
2024年2月2日よりリポジトリのデフォルトブランチは5-stable になっています。もしSisimaiを使いたい場合は4-stable をブランチ名に指定してください。
% git clone -b 4-stable https://github.com/sisimai/p5-sisimai.git
Ruby版Sisimaiのリポジトリ名は
sisimai/rb-sisimai
です。Sisimai 5.0.0からRuby 2.4以上が必要になりますので、
インストールの前にシステムに入っているRubyのバージョンを確認してください。
% ruby -v
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin21]
% git clone https://github.com/sisimai/rb-sisimai.git
% cd ./rb-sisimai
% sudo make depend install-from-local
gem install bundle rake minitest
...
3 gems installed
if [ -d "/usr/local/jr" ]; then \
PATH="/usr/local/jr/bin:$PATH" /usr/local/jr/bin/gem install bundle rake minitest; \
fi
...
3 gems installed
/opt/local/bin/rake install
sisimai 5.0.0 built to pkg/sisimai-5.0.0.gem.
sisimai (5.0.0) installed.
if [ -d "/usr/local/jr" ]; then \
PATH="/usr/local/jr/bin:$PATH" /usr/local/jr/bin/rake install; \
fi
sisimai 5.0.0 built to pkg/sisimai-5.0.0-java.gem.
sisimai (5.0.0) installed.
2024年2月2日よりリポジトリのデフォルトブランチは5-stable になっています。もしSisimaiを使いたい場合は4-stable をブランチ名に指定してください。
% git clone -b 4-stable https://github.com/sisimai/rb-sisimai.git
Go版Sisimaiはgo getコマンドで $GOMODCACHE
へインストールされます。
libsisimai.org/sisimai には
main パッケージを宣言したファイルは入っていませんので
以下のようにディレクトリを作成して依存パッケージとして導入してください。
$ mkdir ./sisimai
$ cd ./sisimai
$ go mod init example.com/sisimaicli
go: creating new go.mod: module example.com/sisimaicli
$ go get -u libsisimai.org/sisimai/v5@latest
go: added libsisimai.org/sisimai/v5 v5.4.0
$ cat ./go.mod
module example.com/sisimaicli
go 1.24
require (
libsisimai.org/sisimai/v5 v5.4.0 // indirect
)
% cpanm --sudo Sisimai
--> Working on Sisimai
Fetching http://www.cpan.org/authors/id/A/AK/AKXLIX/Sisimai-5.0.0.tar.gz ... OK
...
1 distribution installed
% perldoc -l Sisimai
/usr/local/lib/perl5/site_perl/5.30.0/Sisimai.pm
古いバージョンをインストールしたい場合は、以下のようにURLを指定してください。
% cpanm --sudo https://cpan.metacpan.org/authors/id/A/AK/AKXLIX/Sisimai-v4.25.16.tar.gz
% sudo cpm install https://cpan.metacpan.org/authors/id/A/AK/AKXLIX/Sisimai-v4.25.16.tar.gz
Ruby版Sisimaiのリリース版のみ
RubyGems.org
からダウンロードが可能で、gemコマンドでインストールが出来ます。
JRubyを使用する場合はjgemでのインストールも可能です。
% sudo gem install sisimai
Fetching: sisimai-5.0.0.gem (100%)
Successfully installed sisimai-5.0.0
Parsing documentation for sisimai-5.0.0
Installing ri documentation for sisimai-5.0.0
Done installing documentation for sisimai after 6 seconds
1 gem installed
古いバージョンをインストールしたい場合は、以下のように-vオプションで 任意のバージョンを指定してください。
% sudo gem install sisimai -v 4.25.16
Perl版SisimaiはFreeBSD
のPortsコレクション
(mail/p5-Sisimai)
からインストールができます。makeコマンド一発でインストールが可能ですが、
Perl版SisimaiがPortsコレクションに取り込まれるタイミングによっては、
最新版ではないSisimaiがインストールされる点に注意してください。
# cd /usr/ports/mail/p5-sisimai
# make install
===> License BSD2CLAUSE accepted by the user
===> p5-sisimai-4.25.16 depends on file: /usr/local/sbin/pkg - found
=> Sisimai-v4.25.16.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
...
# apt install libsisimai-perl
Reading package lists... Done
Building dependency tree
Reading state information... Done
...
Need to get 366 kB/563 kB of archives.
After this operation, 1892 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://jp.archive.ubuntu.com/ubuntu focal/universe amd64 libclass-accessor-lite-perl all 0.08-1 [8136 B]
Get:2 http://jp.archive.ubuntu.com/ubuntu focal/universe amd64 libsisimai-perl all 4.25.5-1 [358 kB]
Fetched 366 kB in 2s (171 kB/s)
...
Setting up libjson-perl (4.02000-2) ...
Setting up libsisimai-perl (4.25.5-1) ...
Setting up libjson-xs-perl (4.020-1build1) ...
Processing triggers for man-db (2.9.1-1) ...
下記のコードはSisimaiのrise()
メソッドを使ってバウンスメールを解析し解析結果のデータを得る例です。
rise()メソッドに指定できる他の引数については
シシマイでの解析方法をご覧ください。
従来のmake()メソッドはSisimai 5.0.0で廃止になりました。
#! /usr/bin/env perl
use Sisimai;
my $v = Sisimai->rise('/path/to/mbox'); # or Path to Maildir
if( defined $v ) {
for my $e ( @$v ) {
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
}
} else {
# There is no bounce message in the mailbox
# or Sisimai could not decode
}
#! /usr/bin/env ruby
require 'sisimai'
v = Sisimai.rise('/path/to/mbox') # or Path to Maildir
if v.is_a? Array
v.each do |e|
puts e.class # Sisimai::Fact
puts e.recipient.class # Sisimai::Address
puts e.timestamp.class # Sisimai::Time
puts e.addresser.address # "michitsuna@example.org" # From
puts e.recipient.address # "kijitora@example.jp" # To
puts e.recipient.host # "example.jp"
puts e.deliverystatus # "5.1.1"
puts e.replycode # "550"
puts e.reason # "userunknown"
puts e.origin # "/var/spool/bounce/Maildir/new/1740074341.eml"
puts e.hardbounce # true
end
else
# There is no bounce message in the mailbox
# or Sisimai could not decode
end
下記のコードはSisimaiのRise()
関数を使ってバウンスメールを解析し解析結果のデータを得る例です。
Rise()関数に指定できる他の引数については
シシマイでの解析方法をご覧ください。
Sisimai 5.4.0からRise()関数はポインターではなく スライスを返すようになりました。
$ vi ./sisid.go
package main
import "os"
import "fmt"
import "libsisimai.org/sisimai/v5"
func main() {
path := os.Args[1] // go run ./sisid /path/to/mailbox or maildir/
args := sisimai.Args() // sis.DecodingArgs{}
// sisi is a pointer to []sis.Facti
sisi, nyaan := sisimai.Rise(path, args)
if len(sisi) > 0 {
for _, e := range sisi {
// e is a sis.Fact struct
fmt.Printf("- Sender is %s\n", e.Addresser.Address)
fmt.Printf("- Recipient is %s\n", e.Recipient.Address)
fmt.Printf("- Recipient host is %s\n", e.Recipient.Host)
fmt.Printf("- Delivery status is %s\n", e.DeliveryStatus)
fmt.Printf("- SMTP reply code is %s\n", e.ReplyCode)
fmt.Printf("- Bounced due to %s\n", e.Reason)
fmt.Printf("- Email file is %s\n", e.Origin)
fmt.Printf("- Hard bounce is %t\n", e.HardBounce)
}
}
// nyaan is a pointer to []sis.NotDecoded
if len(nyaan) > 0 { fmt.Fprintf(os.Stderr, "%v\n", nyaan) }
}
$ CGO_ENABLED=0 go build -o ./sisid ./sisid.go
$ ./sisid /path/to/mailbox
Perl版Sisimai v4.1.27から登場したdump()メソッドは解析結果を
JSONで得るのに便利です。下記のように解析したいメールのPATHを渡すだけの
簡単なコードで済みます。
#! /usr/bin/env perl
use Sisimai;
print Sisimai->dump('/home/postmaster/Maildir/cur');
#! /usr/bin/env ruby
require 'sisimai'
puts Sisimai.dump('/home/postmaster/Maildir/cur')
package main
import "fmt"
import "libsisimai.org/sisimai/v5"
func main() {
args := sisimai.Args()
json, _ := sisimai.Dump("/home/postmaster/Maildir/cur", args)
if json != nil && *json != "" { fmt.Printf("%s\n", *json) }
}
解析結果のJSONデータを目で確認したい場合は
jqコマンドが便利です。
下記のようにdump()メソッドの出力が読みやすく表示されます。
% perl -MSisimai -lE 'print Sisimai->dump(shift)' path/to/mbox | jq .
% ruby -rsisimai -e 'puts Sisimai.dump($*.shift)' path/to/mbox | jq .
% go build -o sisid ./sisid.go && ./sisid path/to/mbox | jq .
[
{
"destination": "google.example.com",
"lhost": "gmail-smtp-in.l.google.com",
"hardbounce": 0,
"reason": "authfailure",
"catch": null,
"addresser": "michitsuna@example.jp",
"alias": "nekochan@example.co.jp",
"decodedby": "Postfix",
"smtpcommand": "DATA",
"senderdomain": "example.jp",
"listid": "",
"action": "failed",
"feedbacktype": "",
"messageid": "hwK7pzjzJtz0RF9Y@relay3.example.com",
"origin": "./gmail-5.7.26.eml",
"recipient": "kijitora@google.example.com",
"rhost": "gmail-smtp-in.l.google.com",
"subject": "Nyaan",
"timezoneoffset": "+0900",
"replycode": 550,
"token": "84656774898baa90660be3e12fe0526e108d4473",
"diagnostictype": "SMTP",
"timestamp": 1650119685,
"diagnosticcode": "host gmail-smtp-in.l.google.com[64.233.187.27] said: This mail has been blocked because the sender is unauthenticated. Gmail requires all senders to authenticate with either SPF or DKIM. Authentication results: DKIM = did not pass SPF [relay3.example.com] with ip: [192.0.2.22] = did not pass For instructions on setting up authentication, go to https://support.google.com/mail/answer/81126#authentication c2-202200202020202020222222cat.127 - gsmtp (in reply to end of DATA command)",
"deliverystatus": "5.7.26"
}
]