### Install Sisimai via Shell Source: https://github.com/sisimai/rb-sisimai/blob/5-stable/README.md Commands to install the Sisimai library from RubyGems or by cloning the repository from GitHub and building locally. ```shell $ sudo gem install sisimai $ git clone https://github.com/sisimai/rb-sisimai.git $ cd ./rb-sisimai $ sudo make depend install-from-local ``` -------------------------------- ### Install Sisimai from GitHub Source: https://context7.com/sisimai/rb-sisimai/llms.txt Installs Sisimai by cloning the GitHub repository and building from the local source. This method is useful for development or when using the latest unreleased version. ```bash git clone https://github.com/sisimai/rb-sisimai.git cd rb-sisimai make depend install-from-local ``` -------------------------------- ### Install Sisimai from RubyGems Source: https://context7.com/sisimai/rb-sisimai/llms.txt Installs the Sisimai Ruby gem, providing the library for bounce email analysis. This is the standard method for adding Sisimai to your Ruby project. ```ruby gem install sisimai ``` -------------------------------- ### List Detectable Bounce Reasons Source: https://context7.com/sisimai/rb-sisimai/llms.txt Shows how to get a hash of all detectable bounce reasons and their corresponding descriptions using Sisimai.reason. This helps in understanding the various categories of email delivery failures that Sisimai can identify. ```ruby require 'sisimai' # Get list of all bounce reasons reasons = Sisimai.reason reasons.each do |reason_name, description| puts "#{reason_name}: #{description}" end # Key bounce reasons include: # AuthFailure: Email rejected due to SPF/DKIM/DMARC failure # BadReputation: Blocked due to bad sender reputation # Blocked: Blocked by recipient server # ContentError: Message content rejected # EmailTooLarge: Message size exceeds limit # Expired: Delivery time expired # Filtered: Filtered by recipient rules # HostUnknown: Destination domain does not exist # MailboxFull: Recipient mailbox is full # NoRelaying: Relaying denied # NotAccept: Server not accepting messages # RateLimited: Sending rate exceeded ``` -------------------------------- ### Parse and Validate Email Addresses with Sisimai::Address Source: https://context7.com/sisimai/rb-sisimai/llms.txt Provides examples of using the Sisimai::Address utility class to validate email addresses, check for mailer-daemon addresses, parse addresses with names and comments, extract clean email addresses, expand VERP and alias addresses, and create Address objects. ```ruby require 'sisimai/address' # Check if string is valid email address Sisimai::Address.is_emailaddress('user@example.org') # => true Sisimai::Address.is_emailaddress('invalid-email') # => false # Check if address is mailer-daemon Sisimai::Address.is_mailerdaemon('MAILER-DAEMON@example.org') # => true Sisimai::Address.is_mailerdaemon('postmaster@example.org') # => true # Parse email address from string with name and comment addresses = Sisimai::Address.find('Neko Cat ') # => [{ address: "neko@example.org", name: "Neko Cat", comment: "(comment)" }] # Parse multiple addresses addresses = Sisimai::Address.find('user1@example.org, user2@example.org') # Extract clean email address (like sendmail ruleset 3,4) Sisimai::Address.s3s4('') # => "neko@example.org" # Expand VERP address Sisimai::Address.expand_verp('bounce+user=example.org@mail.example.org') # => "user@example.org" # Expand alias address Sisimai::Address.expand_alias('user+tag@example.org') # => "user@example.org" # Create Address object addr = Sisimai::Address.new(address: 'user@example.org', name: 'User Name') addr.address # => "user@example.org" addr.user # => "user" addr.host # => "example.org" addr.name # => "User Name" addr.to_s # => "user@example.org" ``` -------------------------------- ### Convert Bounce Data to JSON and YAML Strings Source: https://context7.com/sisimai/rb-sisimai/llms.txt Demonstrates how to convert bounce message data into JSON or YAML string formats using the dump method. The JSON conversion is a built-in feature, while YAML conversion requires the 'yaml' gem to be installed. ```ruby json_string = bounce.dump('json') # Convert to YAML string (requires yaml gem) yaml_string = bounce.dump('yaml') ``` -------------------------------- ### Initialize Sisimai Message Source: https://github.com/sisimai/rb-sisimai/blob/5-stable/ChangeLog.md Demonstrates the standard way to initialize a new Sisimai message object for parsing bounce email content. ```ruby require 'sisimai/message' # Create a new message object message = Sisimai::Message.new(data: email_content) # Alternatively, use the make method parsed_data = Sisimai::Message.make(data: email_content) ``` -------------------------------- ### Implement Custom Callback for Email Processing in Ruby Source: https://github.com/sisimai/rb-sisimai/blob/5-stable/README.md Demonstrates how to use the callback feature in Sisimai.rise to process email files, extract metadata, modify content, and perform file operations like deletion or saving. ```ruby path = '/path/to/maildir' code = lambda do |args| kind = args['kind'] mail = args['mail'] path = args['path'] fact = args['fact'] fact.each do |e| e.catch ||= {} e.catch['size'] = mail.size e.catch['kind'] = kind.capitalize if cv = mail.match(/^Return-Path: (.+)$/) e.catch['return-path'] = cv[1] end e.catch['parsedat'] = Time.new.localtime.to_s a = sprintf("X-Sisimai-Parsed: %d", fact.size) p = sprintf("/path/to/another/directory/sisimai-%s.eml", e.token) v = mail.sub(/^(From:.+?)$/, '\\1' + "\n" + a) f = File.open(p, 'w:UTF-8') f.write(v) f.close File.delete(path) if kind == 'maildir' end end list = Sisimai.rise(path, c___: [nil, code]) puts list[0].catch['size'] puts list[0].catch['kind'] puts list[0].catch['return-path'] ``` -------------------------------- ### Dump email data with delivery and vacation options Source: https://github.com/sisimai/rb-sisimai/blob/5-stable/README.md Demonstrates how to invoke the Sisimai.dump method while enabling delivered and vacation status tracking. This allows the parser to include these specific email states in the output. ```ruby puts Sisimai.dump('/path/to/mbox', delivered: true, vacation: true) ``` -------------------------------- ### Implement callback feature for custom header and body processing Source: https://github.com/sisimai/rb-sisimai/blob/5-stable/README.md Shows how to use the c___ parameter in Sisimai.rise and Sisimai.dump to execute custom Proc objects. The first callback processes headers and message bodies, allowing for the extraction of custom fields like Queue-ID and X-Mailer. ```ruby #! /usr/bin/env ruby require 'sisimai' code = lambda do |args| head = args['headers'] # (*Hash) Email headers body = args['message'] # (String) Message body adds = { 'x-mailer' => '', 'queue-id' => '' } if cv = body.match(/^X-Postfix-Queue-ID:\s*(.+)$/) adds['queue-id'] = cv[1] end r['x-mailer'] = head['x-mailer'] || '' return adds end data = Sisimai.rise('/path/to/mbox', c___: [code, nil]) json = Sisimai.dump('/path/to/mbox', c___: [code, nil]) puts data[0].catch['x-mailer'] # "Apple Mail (2.1283)" puts data[0].catch['queue-id'] # "43f4KX6WR7z1xcMG" ``` -------------------------------- ### Parse Bounce Emails with Sisimai Source: https://github.com/sisimai/rb-sisimai/blob/5-stable/README.md Demonstrates how to use Sisimai.rise() to parse bounce emails from file paths or strings. It also shows how to access parsed data attributes and convert results to JSON. ```ruby require 'sisimai' # Parse from file path v = Sisimai.rise('/path/to/mbox') # Parse from string content f = File.open('/path/to/mbox', 'r') v = Sisimai.rise(f.read) # Parse with options v = Sisimai.rise('/path/to/mbox', delivered: true, vacation: true) # Accessing data if v.is_a? Array v.each do |e| puts e.reason puts e.dump('json') end end ``` -------------------------------- ### Execute Sisimai Dump via Command Line Source: https://github.com/sisimai/rb-sisimai/blob/5-stable/README.md A one-liner shell command to parse an email file using the Sisimai Ruby library and output the results. ```shell ruby -rsisimai -e 'puts Sisimai.dump($*.shift)' /path/to/mbox ``` -------------------------------- ### List Available MTA/MDA/ESP Decoder Modules Source: https://context7.com/sisimai/rb-sisimai/llms.txt Demonstrates how to retrieve a hash of all available MTA, MDA, and ESP decoder modules along with their descriptions using Sisimai.engine. This is useful for understanding which email delivery agents Sisimai can parse. ```ruby require 'sisimai' # Get list of all decoding engines engines = Sisimai.engine engines.each do |module_name, description| puts "#{module_name}: #{description}" end # Output includes: # Sisimai::Lhost::Postfix: Postfix # Sisimai::Lhost::Sendmail: V8Sendmail: /usr/sbin/sendmail # Sisimai::Lhost::Qmail: qmail # Sisimai::Lhost::Gmail: Gmail # Sisimai::Lhost::AmazonSES: Amazon SES(Sending) # Sisimai::Lhost::Exchange2007: Microsoft Exchange Server 2007 # Sisimai::ARF: Abuse Arrow Format # Sisimai::RFC3464: Fallback Module for DSN # ... ``` -------------------------------- ### Implement Custom Email Processing with Callbacks Source: https://context7.com/sisimai/rb-sisimai/llms.txt Illustrates how to use the `:c___` parameter in Sisimai.rise and Sisimai.dump to define custom callback functions for processing email headers/body during parsing and for handling each email file after parsing. This allows for custom data extraction and file manipulation. ```ruby require 'sisimai' # Callback for email headers and body (called during message parsing) header_callback = lambda do |args| headers = args['headers'] # Hash of email headers body = args['message'] # Message body string custom_data = {} # Extract custom header custom_data['x-mailer'] = headers['x-mailer'] || '' # Extract queue ID from body if match = body.match(/^X-Postfix-Queue-ID:\s*(.+)$/) custom_data['queue-id'] = match[1] end custom_data # Return hash to be stored in bounce.catch end # Callback for each email file (called after parsing each file) file_callback = lambda do |args| kind = args['kind'] # "mailbox", "maildir", or "memory" mail = args['mail'] # Entire email content path = args['path'] # File path fact = args['fact'] # Array of Sisimai::Fact objects fact.each do |bounce| bounce.catch ||= {} bounce.catch['size'] = mail.size bounce.catch['kind'] = kind.capitalize bounce.catch['parsed_at'] = Time.now.to_s # Save processed email to different location new_path = "/archive/#{bounce.token}.eml" File.write(new_path, mail) # Delete original file from Maildir after processing File.delete(path) if kind == 'maildir' end end # Use callbacks with rise() results = Sisimai.rise('/path/to/Maildir/', c___: [header_callback, file_callback]) # Access custom data results.each do |bounce| puts "Queue ID: #{bounce.catch['queue-id']}" puts "X-Mailer: #{bounce.catch['x-mailer']}" puts "Email Size: #{bounce.catch['size']}" end # Use callbacks with dump() json = Sisimai.dump('/path/to/mbox', c___: [header_callback, nil]) ``` -------------------------------- ### Process bounce emails with Sisimai in Ruby Source: https://context7.com/sisimai/rb-sisimai/llms.txt This snippet demonstrates how to initialize a bounce processor, use a custom callback hook to extract specific headers, and parse bounce emails into a structured JSON report. It tracks hard and soft bounce statistics and categorizes failures by reason. ```ruby require 'sisimai' require 'json' class BounceProcessor def initialize(source_path) @source = source_path @stats = { total: 0, hard: 0, soft: 0, by_reason: Hash.new(0) } end def process custom_hook = lambda do |args| headers = args['headers'] { 'received_date' => headers['date'], 'return_path' => headers['return-path'] } end results = Sisimai.rise(@source, c___: [custom_hook, nil], delivered: false, vacation: false) return { error: 'No bounce emails found' } if results.nil? bounces = [] results.each do |bounce| @stats[:total] += 1 @stats[:hard] += 1 if bounce.hardbounce @stats[:soft] += 1 unless bounce.hardbounce @stats[:by_reason][bounce.reason] += 1 bounces << { recipient: bounce.recipient.address, sender: bounce.addresser.address, reason: bounce.reason, hard_bounce: bounce.hardbounce, status: bounce.deliverystatus, reply_code: bounce.replycode, diagnostic: bounce.diagnosticcode[0..200], timestamp: bounce.timestamp.to_time.iso8601, mta: bounce.decodedby, custom: bounce.catch } end { bounces: bounces, statistics: @stats } end def export_json(output_path) result = process File.write(output_path, JSON.pretty_generate(result)) puts "Exported #{@stats[:total]} bounces to #{output_path}" end end processor = BounceProcessor.new('/var/mail/bounces/') processor.export_json('/tmp/bounce_report.json') ``` -------------------------------- ### Accessing Mail Data Source: https://github.com/sisimai/rb-sisimai/blob/5-stable/ChangeLog.md Shows the updated approach for accessing mail data, replacing deprecated methods with the new 'data' accessor pattern. ```ruby # Use data instead of mail mail_object = Sisimai::Mail.new(path) content = mail_object.data.payload # Use kind instead of type kind = mail_object.kind ``` -------------------------------- ### Handle Email Sources with Sisimai::Mail Source: https://context7.com/sisimai/rb-sisimai/llms.txt A wrapper class that provides a unified interface for reading email data from various sources, including mbox files, Maildir directories, strings, and standard input. ```ruby require 'sisimai/mail' # Open mbox file mail = Sisimai::Mail.new('/path/to/mbox') mail.path # => "/path/to/mbox" mail.kind # => "mailbox" # Open Maildir directory mail = Sisimai::Mail.new('/path/to/Maildir/') mail.kind # => "maildir" # Read from string email_string = "From: sender@example.org\nTo: ..." mail = Sisimai::Mail.new(email_string) mail.kind # => "memory" mail.path # => "MEMORY" # Read from STDIN mail = Sisimai::Mail.new('') mail.kind # => "stdin" # Iterate through emails while content = mail.read puts "Processing email: #{mail.data.path}" # Process content... end ``` -------------------------------- ### Convert Bounce Data to JSON Source: https://github.com/sisimai/rb-sisimai/blob/5-stable/README.md Uses the Sisimai.dump() method to directly retrieve bounce analysis data as a JSON-formatted string from a mailbox or Maildir path. ```ruby puts Sisimai.dump('/path/to/mbox') ``` -------------------------------- ### Sisimai::Fact Object Attributes and Methods (Ruby) Source: https://context7.com/sisimai/rb-sisimai/llms.txt Demonstrates accessing attributes and converting data from a Sisimai::Fact object, which is returned by Sisimai.rise(). It provides methods to retrieve sender/recipient details, bounce reasons, timestamps, and convert the data to a Hash. ```ruby require 'sisimai' results = Sisimai.rise('/path/to/bounce.eml') bounce = results.first # Access bounce attributes bounce.recipient # Sisimai::Address object bounce.recipient.address # "user@example.jp" bounce.recipient.host # "example.jp" bounce.recipient.user # "user" bounce.addresser # Sisimai::Address object (sender) bounce.addresser.address # "sender@example.org" bounce.timestamp # Sisimai::Time object bounce.reason # "userunknown", "mailboxfull", "blocked", etc. bounce.deliverystatus # "5.1.1" bounce.replycode # "550" bounce.diagnosticcode # Error message from MTA bounce.diagnostictype # "SMTP" or "X-UNIX" bounce.action # "failed", "delayed", "delivered" bounce.command # Last SMTP command: "RCPT", "DATA", etc. bounce.hardbounce # true or false bounce.origin # Path to original email file bounce.decodedby # MTA module name that decoded the bounce # Convert to Hash hash_data = bounce.damn # => { "recipient" => "user@example.jp", "reason" => "userunknown", ... } ``` -------------------------------- ### Parse SMTP Session Transcripts with Sisimai::SMTP::Transcript Source: https://context7.com/sisimai/rb-sisimai/llms.txt Decodes raw SMTP session logs into structured Ruby objects, allowing for programmatic analysis of client-server exchanges during delivery attempts. ```ruby require 'sisimai/smtp/transcript' # SMTP session transcript transcript = <<~LOG >>> EHLO mail.example.org <<< 250-mx.recipient.com Hello <<< 250 OK >>> MAIL FROM: SIZE=1024 <<< 250 2.1.0 Ok >>> RCPT TO: <<< 550 5.1.1 User unknown >>> QUIT <<< 221 Bye LOG # Parse transcript (>>> = client, <<< = server) session = Sisimai::SMTP::Transcript.rise(transcript, '>>>', '<<<') session.each do |exchange| puts "Command: #{exchange['command']}" puts "Argument: #{exchange['argument']}" puts "Response Code: #{exchange['response']['reply']}" puts "Status: #{exchange['response']['status']}" puts "Text: #{exchange['response']['text'].join(' ')}" puts "---" end ``` -------------------------------- ### Manage SMTP Enhanced Status Codes with Sisimai::SMTP::Status Source: https://context7.com/sisimai/rb-sisimai/llms.txt Provides utilities for mapping DSN codes to reason names, retrieving internal status codes, validating formats, and extracting codes from error strings. ```ruby require 'sisimai/smtp/status' # Get reason name from status code Sisimai::SMTP::Status.name('5.1.1') # => "userunknown" Sisimai::SMTP::Status.name('5.2.2') # => "mailboxfull" Sisimai::SMTP::Status.name('4.4.7') # => "expired" # Get internal status code from reason Sisimai::SMTP::Status.code('userunknown') # => "5.9.213" Sisimai::SMTP::Status.code('mailboxfull') # => "5.9.220" Sisimai::SMTP::Status.code('expired', true) # => "4.9.340" (temporary) # Validate status code format Sisimai::SMTP::Status.test('5.1.1') # => true Sisimai::SMTP::Status.test('5.0.0') # => true Sisimai::SMTP::Status.test('invalid') # => false # Extract status code from error message error = "550 5.1.1 User unknown" Sisimai::SMTP::Status.find(error) # => "5.1.1" error = "host mx.example.com said: 452 4.2.2 Mailbox full" Sisimai::SMTP::Status.find(error) # => "4.2.2" # Check if status code is ambiguous (like X.0.0) Sisimai::SMTP::Status.is_ambiguous('5.0.0') # => true Sisimai::SMTP::Status.is_ambiguous('5.1.1') # => false ``` -------------------------------- ### Export Bounce Emails as JSON with Sisimai.dump (Ruby) Source: https://context7.com/sisimai/rb-sisimai/llms.txt Converts bounce emails directly into a JSON string. This is useful for data storage or integration with other systems. It also supports options to include delivered and vacation messages. ```ruby require 'sisimai' # Get JSON string from a mailbox json_output = Sisimai.dump('/path/to/bounce-mail.eml') puts json_output # Include delivered and vacation messages json_output = Sisimai.dump('/path/to/mbox', delivered: true, vacation: true) # One-liner from command line # ruby -rsisimai -e 'puts Sisimai.dump(ARGV.shift)' /path/to/mbox ``` -------------------------------- ### Parse Bounce Emails with Sisimai.rise (Ruby) Source: https://context7.com/sisimai/rb-sisimai/llms.txt The primary function to parse bounce emails. It accepts file paths, directory paths, or email strings and returns an array of Sisimai::Fact objects. Options like `delivered: true` and `vacation: true` can be used to include specific message types. ```ruby require 'sisimai' # Parse from a mailbox file results = Sisimai.rise('/path/to/bounce-mail.eml') # Parse from a Maildir directory results = Sisimai.rise('/path/to/Maildir/') # Parse from an email string email_content = File.read('/path/to/bounce.eml') results = Sisimai.rise(email_content) # Include successfully delivered messages (normally excluded) results = Sisimai.rise('/path/to/mbox', delivered: true) # Include vacation auto-replies (excluded by default in v5) results = Sisimai.rise('/path/to/mbox', vacation: true) # Process parsed results if results.is_a?(Array) results.each do |bounce| puts "Recipient: #{bounce.recipient.address}" # kijitora@example.jp puts "Sender: #{bounce.addresser.address}" # sender@example.org puts "Reason: #{bounce.reason}" # userunknown puts "Status: #{bounce.deliverystatus}" # 5.1.1 puts "Reply Code: #{bounce.replycode}" # 550 puts "Diagnostic: #{bounce.diagnosticcode}" # User unknown puts "Hard Bounce: #{bounce.hardbounce}" # true puts "Timestamp: #{bounce.timestamp}" # 2024-01-15 10:30:00 puts "Origin: #{bounce.origin}" # /path/to/bounce.eml puts "Decoded By: #{bounce.decodedby}" # Postfix puts "---" end end ``` -------------------------------- ### Detect Bounce Reason from Error Text using Sisimai Source: https://context7.com/sisimai/rb-sisimai/llms.txt Uses the Sisimai.match method to identify the specific bounce reason from a raw error message string. This is useful for quick classification without parsing the entire email structure. ```ruby require 'sisimai' # Detect reason from error message error_msg = "550 5.1.1 The email account that you tried to reach does not exist" reason = Sisimai.match(error_msg) puts reason # => "userunknown" error_msg = "452 4.2.2 Mailbox full" reason = Sisimai.match(error_msg) puts reason # => "mailboxfull" error_msg = "550 Message rejected: spam detected" reason = Sisimai.match(error_msg) puts reason # => "spamdetected" error_msg = "421 Too many connections from your IP" reason = Sisimai.match(error_msg) puts reason # => "ratelimited" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.