---
name: "Sisimai::Fact"
section: "3pm"
platform: "linux"
package: "libsisimai-perl"
version: "5.3.0-1"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/Sisimai::Fact"
---

# Sisimai::Fact(3pm)

Decoded data object

## NAME

Sisimai::Fact - Decoded data object

## SYNOPSIS

```
    use Sisimai::Fact;
    my $args = { 'data' => 'entire-email-text-including-all-the-headers' };
    my $fact = Sisimai::Fact->rise($args);
    for my $e ( @$fact ) {
        print $e->reason;               # userunknown, mailboxfull, and so on.
        print $e->recipient->address;   # (Sisimai::Address) envelope recipient address
        print $e->bonced->ymd           # (Sisimai::Time) Date of bounce
    }
```

## DESCRIPTION

`"Sisimai::Fact"` generates a decoded bounce email data structure from `"Sisimai::Message"` object.

## CLASS METHODS

### "rise(Hash)"

`rise()` method generate decoded data and returns an array reference which are including `"Sisimai::Fact"` objects.

```
    my $mail = Sisimai::Mail->new('/var/mail/root');
    while( my $r = $mail->read ) {
        my $fact = Sisimai::Fact->make('data' => $r);
        for my $e ( @$fact ) {
            print $e->reason;               # userunknown, mailboxfull, and so on.
            print $e->recipient->address;   # (Sisimai::Address) envelope recipient address
            print $e->timestamp->ymd        # (Sisimai::Time) Date of the email bounce
        }
    }
```

If you want to get bounce records which reason is `"delivered"`, set `"delivered"` option to `rise()` method like the following:

```
    my $fact = Sisimai::Fact->rise('data' => $r, 'delivered' => 1);
```

## INSTANCE METHODS

### "damn()"

`"damn"` method converts the object to a hash reference.

```
    my $hash = $self->damn;
    print $hash->{'recipient'}; # user@example.jp
    print $hash->{'timestamp'}; # 1393940000
```

## PROPERTIES

`"Sisimai::Fact"` have the following properties:

### "action" (*String*)

`"action"` is the value of `"Action:"` field in a bounce email message such as `"failed"` or `"delayed"`.

```
    Action: failed
```

### "addresser" (*Sisimai::Address)*

`"addressser"` is Sisimai::Address object generated from the sender address. When `"Sisimai::Fact"` object is dumped as JSON, this value converted to an email address. `"Sisimai::Address"` object have the following accessors:

- \- user() - the local part of the address

  - \- host() - the domain part of the address

  - \- address() - email address

  - \- verp() - variable envelope return path

  - \- alias() - alias of the address

  ```
    From: "Kijitora Cat" <kijitora@example.org>
```

### "alias" (*String*)

`"alias"` is an alias address of the recipient. When the `"Original-Recipient:"` field or `"expanded from "address""` string did not exist in a bounce message, this value is empty.

```
    Original-Recipient: rfc822;kijitora@example.org
    "|IFS=' ' && exec /usr/local/bin/procmail -f- || exit 75 #kijitora"
        (expanded from: <kijitora@neko.example.edu>)
```

### "command" (*String*)

`"command"` is a SMTP command name picked from the error message or the value of `"Diagnostic-Code:"` field in a bounce message. When there is no SMTP command in the bounce message, this value will be empty. The list of values is `"HELO"`, `"EHLO"`, `"MAIL"`, `"RCPT"`, `"DATA"`, and `"CONN"`. Until v5.2.0, this accessor name was `"smtpcommand"`.

```
    <kijitora@example.go.jp>: host mx1.example.go.jp[192.0.2.127] said: 550 5.1.6 recipient
        no longer on server: kijitora@example.go.jp (in reply to RCPT TO command)
```

### "decodedby" (*String*)

`"decodedby"` is a module name to be used for decoding a bounce message. For example, when the value is `"Sendmail"`, Sisimai used Sisimai::Lhost::Sendmail to decode the bounce message, to find the recipient address, and collect error messages for deciding a bounce reason. Until v5.2.0, this accessor name was `"smtpagent"`.

### "deliverystatus" (*String*)

`"deliverystatus"` is the value of `"Status:"` field in a bounce message. When the message has no `"Status:"` field, Sisimai set pseudo value like `"5.0.9XX"` to this value. The range of values only `"4.x.x"` or `"5.x.x"`.

```
    Status: 5.0.0 (permanent failure)
```

### "destination" (*String*)

`"destination"` is the domain part of the recipient address. This value is the same as the return value from `host()` method of `"recipient"` accessor.

### "diagnosticcode" (*String*)

`"diagnosticcode"` is an error message picked from `"Diagnostic-Code:"` field or message body in a bounce message. This value and the value of `"diagnostictype"`, `"action"`, `"deliverystatus"`, `"replycode"`, and `"command"` will be referred by Sisimai::Reason to decide the bounce reason.

```
    Diagnostic-Code: SMTP; 554 5.4.6 Too many hops
```

### "diagnostictype" ("String")

`"diagnostictype"` is a type like `"SMTP"` or `"X-Unix"` picked from `"Diagnostic-Code:"` field in a bounce message. When there is no `"Diagnostic-Code:"` field in the bounce message, this value will be empty.

```
    Diagnostic-Code: X-Unix; 255
```

### "feedbacktype" (*String*)

`"feedbacktype"` is the value of `"Feedback-Type:"` field like `"abuse"`, `"fraud"`, `"opt-out"` in a bounce message. When the message is not ARF format or the value of `"reason"` is not `"feedback"`, this value will be empty.

```
    Content-Type: message/feedback-report
    Feedback-Type: abuse
    User-Agent: SMP-FBL
```

### "hardbounce" (*Integer*)

The value of `"hardbounce"` indicates whether the reason of the bounce is a hard bounce or not. This accessor has added in Sisimai 5.0.0. The range of the values are the followings:

- 1 = Hard bounce

  - 0 = Not a hard bounce

  ### "lhost" (*String*)

`"lhost"` is a local MTA name to be used as a gateway for sending email message or the value of `"Reporting-MTA:"` field in a bounce message. When there is no `"Reporting-MTA:"` field in a bounce message, Sisimai try to get the value from `"Received:"` headers.

```
    Reporting-MTA: dns; mx4.smtp.example.co.jp
```

### "listid" (*String*)

`"listid"` is the value of `"List-Id:"` header of the original message. When there is no `"List-Id:"` field in the original message or the bounce message did not include the original message, this value will be empty.

```
    List-Id: Mailman mailing list management users
```

### "messageid" (*String*)

`"messageid"` is the value of `"Message-Id:"` header of the original message. When the original message did not include `"Message-Id:"` header or the bounce message did not include the original message, this value will be empty.

```
    Message-Id: <201310160515.r9G5FZh9018575@smtpgw.example.jp>
```

### "origin" (*Path to the original email file*)

`"origin"` is the path to the original email file of the decoded results. When the original email data were input from STDIN, the value is `"<STDIN"`\>, were input from a variable, the value is `"<MEMORY"`\>. This accessor method has been implemented at v4.25.6.

### "recipient" (*Sisimai::Address)*

`"recipient"` is Sisimai::Address object generated from the recipient address.  When `"Sisimai::Fact"` object is dumped as JSON, this value converted to an email address. `"Sisimai::Address"` object have the following accessors:

- \- user() - the local part of the address

  - \- host() - the domain part of the address

  - \- address() - email address

  - \- verp() - variable envelope return path

  - \- alias() - alias of the address

  ```
    Final-Recipient: RFC822; shironeko@example.ne.jp
    X-Failed-Recipients: kijitora@example.ed.jp
```

### "reason" (*String*)

`"reason"` is the value of bounce reason Sisimai detected. When this value is `"undefined"` or `"onhold"`, it means that Sisimai could not decide the reason. All the reasons Sisimai can detect are available at Sisimai::Reason or web site \<https://libsisimai.org/en/reason/\>.

### "replycode" (*Integer*)

`"replycode"` is the value of SMTP reply code picked from the error message or the value of `"Diagnostic-Code:"` field in a bounce message. The range of values is only `"4xx"` or `"5xx"`.

```
       ----- The following addresses had permanent fatal errors -----
    <userunknown@libsisimai.org>
        (reason: 550 5.1.1 <userunknown@libsisimai.org>... User Unknown)
```

### "rhost" (*String*)

`"rhost"` is a remote MTA name which has rejected the message you sent or the value of `"Remote-MTA:"` field in a bounce message. When there is no `"Remote-MTA:"` field in the bounce message, Sisimai try to get the value from `"Received:"` headers.

```
    Remote-MTA: DNS; g5.example.net
```

### "senderdomain" (*String*)

`"senderdomain"` is the domain part of the sender address. This value is the same as the return value from `host()` method of addresser accessor.

### "subject" (*String*)

`"subject"` is the value of `"Subject:"` header of the original message. When the original message which is included in a bounce email contains no `"Subject:"` header (removed by remote MTA), this value will be empty. If the value of `"Subject:"` header of the original message contain any multibyte character (non-ASCII character), such as MIME encoded Japanese or German and so on, the value of `"subject"` in decoded data is encoded with UTF-8 again.

### "token" (*String*)

`"token"` is an identifier of each email-bounce. The token string is created from the sender email address (`"addresser"`) and the recipient email address (`"recipient"`) and the machine time of the date in a bounce message as an MD5 hash value. The token value is generated at `token()` method of Sisimai::String class.

If you want to get the same token string at command line, try to run the following command:

```
    % printf "\x02%s\x1e%s\x1e%d\x03" sender@example.jp recipient@example.org `date '+%s'` | md5
    714d72dfd972242ad04f8053267e7365
```

### "timestamp" (*Sisimai::Time*)

`"timestamp"` is the date which email has bounced as a Sisima::Time (Child class of `"Time::Piece"`) object. When `"Sisimai::Fact"` object is dumped as JSON, this value will be converted to an UNIX machine time (32 bits integer).

```
    Arrival-Date: Thu, 29 Apr 2009 23:45:33 +0900
```

### "timezomeoffset" (*String*)

`"timezoneoffset"` is a time zone offset of a bounce email which its email has bounced. The format of this value is String like `+0900`, `-0200`.  If Sisimai has failed to get a value of time zone offset, this value will be set as `+0000`.

## SEE ALSO

\<https://libsisimai.org/en/data/\>

## AUTHOR

azumakuniyuki

## COPYRIGHT

Copyright (C) 2014-2025 azumakuniyuki, All rights reserved.

## LICENSE

This software is distributed under The BSD 2-Clause License.
