Skip to main content

Mail Rules

Complete guide to configuring Mail Rules for automated email processing.

Mail rules define how inbound email is processed after a Mailbox fetches it. Rules are processed in priority order (lower number = higher priority). Each mailbox can have multiple rules; rules can be enabled or disabled without deleting them.

What are Mail Rules?

When an email matches a rule's conditions, the system executes actions such as:

  • Extracting images from attachments and adding them to your picture database
  • Parsing spreadsheet files (CSV/XLSX) and triggering EDI destinations
  • Searching for pictures by container code and sending them via EDI
  • Sending processing reports via email

Rule structure

Every rule has three main parts:

  1. When — Conditions that must be met for the rule to trigger
  2. Extract (optional) — Variables to extract from the email (e.g. container codes from subject)
  3. Then — Actions to execute when conditions match
{
"when": {
"type": "sender_email",
"value": "operations@example.com"
},
"extract": {
"variables": {
"container_code": {
"from": "subject",
"regex": "([A-Z]{4}[0-9]{7})",
"group": 1
}
}
},
"then": [
{
"action": "ingest_images",
"config": {
"target": {
"container_code": "{container_code}",
"terminal": "MAIN"
}
}
}
]
}

Conditions (When)

Basic conditions

Sender email — Match a specific sender:

{ "type": "sender_email", "value": "operations@example.com" }

Sender domain — Match any address in a domain:

{ "type": "sender_domain", "value": "@example.com" }

Subject contains — Case-insensitive substring:

{ "type": "subject_contains", "value": "Container Report" }

Subject regex — Regular expression on subject:

{ "type": "subject_regex", "regex": "^(BEANR0F|NLRTM08|NLRTM10)$" }

Body contains:

{ "type": "body_contains", "value": "urgent" }

Has attachment type:

{ "type": "has_attachment_type", "value": ["image/jpeg", "image/png"] }

Field comparison — Operators: eq, ne, contains, matches, in, gt, gte, lt, lte:

{ "field": "subject", "op": "contains", "value": "CAIU" }

Combining conditions

All (AND):

{
"all": [
{ "type": "sender_domain", "value": "@example.com" },
{ "type": "subject_contains", "value": "Container" }
]
}

Any (OR):

{
"any": [
{ "type": "subject_contains", "value": "BEANR0F" },
{ "type": "subject_contains", "value": "NLRTM08" }
]
}

Not (negation):

{
"not": { "type": "sender_domain", "value": "@spam.com" }
}

Variable extraction

Extract values from email fields to use in actions:

{
"extract": {
"variables": {
"container_code": {
"from": "subject",
"regex": "([A-Z]{4}[0-9]{7})",
"group": 1,
"required": true
},
"terminal": {
"from": "subject",
"regex": "Terminal: ([A-Z]+)",
"group": 1,
"default": "MAIN"
}
}
}
}
FieldDescription
fromField to extract from (subject, body, sender, etc.)
regexPattern with capture groups
groupCapture group index (1 = first group)
requiredRule fails if variable cannot be extracted
defaultValue if extraction fails

Actions (Then)

1. Ingest images

Extract image attachments and add them to the picture database:

{
"action": "ingest_images",
"config": {
"target": {
"container_code": "{container_code}",
"terminal": "MAIN",
"case_date": "{case_date}",
"picture_source": "Mailbox",
"picture_creator": "Mailbox: Operations"
},
"attachment_filter": {
"content_types": ["image/jpeg", "image/png"],
"max_size_bytes": 10485760
},
"processing": {
"max_resolution": 1280,
"jpeg_quality": 90
}
}
}

2. Parse spreadsheet

Parse CSV or XLSX attachments and process each row via Code mappings:

{
"action": "parse_spreadsheet",
"config": {
"attachment_filter": {
"content_types": ["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],
"filename_pattern": "*.xlsx"
},
"parser": {
"type": "xlsx",
"sheet": 0,
"skip_rows": 0,
"max_rows": 0
},
"column_map": {
"customer": "client_name",
"containerno": "container_code"
}
}
}

Key configuration notes:

  • parser.typecsv or xlsx
  • column_map — Maps spreadsheet columns to internal fields
  • use_code_mappings: true (default) — EDI destination and days_back come from each code mapping
  • fallback_enabled — Use tenant fallback destination when no mapping matches
  • use_code_mappings: false — Each row must include days_back (1–365)
  • reporting — Optional summary email with CSV/JSONL attachments after all chunks finish
  • Legacy rule fields days_back and send_when_no_pictures on parse_spreadsheet are ignored — use code mappings instead

3. Search pictures and send EDI

Search by container code and send via EDI (useful when email has no attachments):

{
"action": "search_pictures_and_send_edi",
"config": {
"container_code": "{container_code}",
"days_back": 30,
"terminals": ["MAIN", "GATE"],
"destination": "EOS"
}
}

4. Send report

Email a processing report:

{
"action": "send_report",
"config": {
"to": "operations@example.com",
"subject": "Processed: {container_code}",
"include_logs": true
}
}

Complete examples

Example 1: Extract images from specific sender

{
"when": {
"all": [
{ "type": "sender_email", "value": "operations@example.com" },
{ "type": "subject_contains", "value": "Container" }
]
},
"extract": {
"variables": {
"container_code": {
"from": "subject",
"regex": "([A-Z]{4}[0-9]{7})",
"group": 1,
"required": true
}
}
},
"then": [
{
"action": "ingest_images",
"config": {
"target": {
"container_code": "{container_code}",
"terminal": "MAIN",
"case_date": "2026-01-20",
"picture_source": "Mailbox",
"picture_creator": "Mailbox: Operations"
},
"attachment_filter": {
"content_types": ["image/jpeg", "image/png"]
}
}
}
]
}

Example 2: Process spreadsheet from company domain

{
"when": {
"all": [
{ "type": "sender_domain", "value": "@example.com" },
{
"type": "has_attachment_type",
"value": ["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"]
}
]
},
"then": [
{
"action": "parse_spreadsheet",
"config": {
"parser": { "type": "xlsx", "sheet": 0 },
"column_map": {
"customer": "client_name",
"containerno": "container_code"
}
}
}
]
}

Example 3: EDI for specific subject patterns

{
"when": {
"all": [
{
"any": [
{ "type": "sender_email", "value": "operations@depot1.example.com" },
{ "type": "sender_email", "value": "notifications@depot2.example.com" }
]
},
{ "type": "subject_regex", "regex": "^(BEANR0F|NLRTM08|NLRTM10)$" },
{ "type": "subject_contains", "value": "CAIU" }
]
},
"extract": {
"variables": {
"container_code": {
"from": "subject",
"regex": "([A-Z]{4}[0-9]{7})",
"group": 1,
"required": true
}
}
},
"then": [
{
"action": "search_pictures_and_send_edi",
"config": {
"container_code": "{container_code}",
"days_back": 30,
"terminals": ["*"],
"destination": "EOS"
}
}
]
}

Best practices

  • Use specific conditions — Combine sender and subject checks when possible
  • Validate before saving — Use the Validate button in the Admin UI
  • Set priorities — Specific rules: lower numbers; general rules: higher numbers
  • Use variable extraction — Reuse rules across senders
  • Start simple — Add complexity incrementally
  • Monitor Processing state
  • Use descriptive rule names

Troubleshooting

Rule not triggering?

  • Check the rule is active (is_active: true)
  • Verify conditions match the test email exactly
  • Check rule priority — a higher-priority rule may match first
  • Review Processing state for other rules on the same message

Variable extraction failing?

  • Test regex with an online regex tester
  • Ensure capture group numbering is correct (group: 1 = first parentheses)
  • Set "required": false and provide a "default" for optional variables

Actions not executing?

  • Check Processing state for error messages
  • Verify required fields (container_code, terminal, etc.)
  • Ensure Code mappings exist for parse_spreadsheet
  • Verify EDI destinations are configured for search_pictures_and_send_edi

See also: Mailboxes, Processing state, Code mappings