Search code examples
bashemailpdfattachmentqmail

Save an email attachment automatically to map with qmail and reformime


Save an email attachment automatically to map with qmail and reformime

I'm trying to move attachment automatically to another locatie with the dot-qmail file.

My .qmail file

#------------------------------------------------------------
| condredirect pdf-junkmail headermatch 'X-Spam-Status: Yes'
| reformime -X /bin/sh -c "if [ "\${FILENAME#*.}" == "pdf" ];  then cat > /home/users/name/home/$(date +%Y%m%d)_\$FILENAME; fi"
# Forward not set
# Vacation Message not set
./Maildir/

This works for a simple mail with one attachment. My questions:

  1. How can I also move the mailmessage that belongs to this attachment to a mailbox named "done".
  2. Above command doesn't work with multiple attachments in one mailmessage? How can I ajust this line to work for multiple attachments?
  3. This doesn't work if the filename contains multiple dots like "how.areyou.pdf"

Thanks for the help


Solution

  • Here is a featured implementation for your problem.

    First save and set permissions to this bash script for your user.
    You will need to call it from your .qmail file:

    extract-pdf-attachments.sh

    #!/usr/bin/env bash
    
    # This script process mail message attachments from stdin MIME message
    # Extract all PDF files attachments
    # and return the MIME message to stdout for further processing
    
    # Ensure all locale settings are set to C, to prevent
    # reformime from failing MIME headers decode with
    # [unknown character set: ANSI_X3.4-1968]
    # See: https://bugs.gentoo.org/304093
    export LC_ALL=C LANG=C LANGUAGE=C
    
    # Setting the destination path for saved attachments
    attachements='/home/users/name/home'
    
    trap 'rm -f -- "$mailmessage"' EXIT # Purge temporary mail message
    
    # Create a temporary message file
    mailmessage="$(mktemp)"
    
    # Save stdin message to tempfile
    cat > "$mailmessage"
    
    # Iterate all MIME sections from the message
    while read -r mime_section; do
    
      # Get all section info headers
      section_info="$(reformime -s "$mime_section" -i <"$mailmessage")"
    
      # Parse the Content-Type header
      content_type="$(grep 'content-type' <<<"$section_info" | cut -d ' ' -f 2-)"
    
      # Parse the Content-Name header (if available)
      content_name="$(grep 'content-name' <<<"$section_info" | cut -d ' ' -f 2-)"
    
      # Decode the value of the Content-Name header
      content_name="$(reformime -c UTF-8 -h "$content_name")"
    
      if [[ $content_type = "application/pdf" || $content_name =~ .*\.[pP][dD][fF] ]]; then
        # Attachment is a PDF
        if [ -z "$content_name" ]; then
          # The attachment has no name, so create a random name
          content_name="$(mktemp --dry-run unnamed_XXXXXXXX.pdf)"
        fi
        # Prepend the date to the attachment filename
        filename="$(date +%Y%m%d)_$content_name"
    
        # Save the attachment to a file
        reformime -s "$mime_section" -e <"$mailmessage" >"$attachements/$filename"
      fi
    
    done < <(reformime < "$mailmessage") # reformime list all mime sections
    
    cat <"$mailmessage" # Re-inject the message to stdout for further processing
    

    Then in you .qmail:

    #------------------------------------------------------------
    | condredirect pdf-junkmail headermatch 'X-Spam-Status: Yes'
    | bash /path/to/extract-pdf-attachments.sh | condredirect done true
    # Forward not set
    # Vacation Message not set
    ./Maildir/