Personal Blog of Thomas Hampel - Creative Mythbusting in Development and Collaboration

Previous Document Next Document

Print Email Attachments automatically with a RaspberryPI

Thomas Hampel
 23 June 2015

I am tired of printing email attachments. Yes, I still need to print some of them e.g. invoices for tax computation or travel reimbursement needs, or credit card balance sheets for archiving them offline.
Most of them are e-mails with PDF file attachments which I need to print on a regular basis. In order to print them I need to be at home, using a device with apropriate printer drivers installed and connected to my home network.

There must be a more simple method, so lets see how to allow mobile or remote printing.


What options do we have for remote printing?
  • Google Cloud Print - would be the easiest option but who wants to forward personal data to Google?
  • Using web-connected printers like those from HP or EPSON or Canon, but my current printer(s) do work fine and I see no reason to replace them.
    Furthermore any mail would be routed to the vendors environment which I dont trust.
    • VPN - probably the best approach, but still requires printer drivers and VPN software to be installed.
      Since none of the options above satisfied my needs, lets see if we can build a solution ourselfes...maybe using a Raspberry Pi
      Main idea is to poll an IMAP account on a regular basis and if new mail will meet certain criteria then print the PDF file attachment.

      Image:Print Email Attachments automatically with a RaspberryPI

      Step 1 - Preparations

      Obviously you need to
      buy a Raspberry PI, the Model B+ is enough. You also need some further equipment like a memory card, power adapter, keyboard, etc.
      Beside
      installing and configuring the operating system you need to:
    • Enable SSH
    • Apply latest patches by running update and Upgrade
      $ sudo apt-get update -y && apt-get upgrade -y
    • Install updates automatically by using apt-cron
      $ sudo apt-get install apt-cron
    • Configure your network adapter preferably assign a static IP
    • Change system locale and keyboard layout to fit your needs
    • Don't forget to Change the default password
    • When using a WiFi dongle disable WiFi Adapter Power Saving Mode
      Step 2 - Set up a new IMAP (or POP3) account

      Contact your provider for a description how to do that. Make sure your provider supports SSL/TLS connections and make sure to enable antivirus/antispam control for your IMAP account.
      Remark: SmartCloud Notes / Connections Cloud users need to enable IMAP access first (
      see details)

      Step 3 - Import SSL Root certificate(s)

      SSH into your Raspberry PI and start by creating a new directory for this project
      mkdir pimailprint
      cd pimailprint
       

      For
      verification of SSL certificates we would like to store SSL certificates of our mail provider locally, preferably in another subdirectory.
      mkdir sslcerts
      wget {url-of-provider certificate} -O ./sslcerts/provider-name.cer
      c_rehash ./sslcerts/

      You can verify the functionality
      using OpenSSL

      Step 4 - Install Prerequisites

      Install the required packages

      sudo apt-get install fetchmail procmail uudeview

      Create a configuration file for fetchmail, in our case the file will be located in the project directory instead of the users home folder.
      With this configuration I'm using procmail as mail delivery agent in order to further process the inbound mail.

      nano ./fetchmail.conf

      using this configuration:

      set no bouncemail
      poll IMAP.YOUR-DOMAIN.COM

      service 993

      protocol imap

      user "YOUR-USERNAME"

      password "YOUR-PASSWORD"

      ssl

      sslcertck

      sslproto TLS1

      no keep

      mda "/usr/bin/procmail -m './procmail.conf'"

      Change file permissions so only you can open and see the file.

      chmod 700 ./fetchmail.conf

      Create a configuration file for procmail...

      nano ./procmail.conf

      and use this configuration which will store mails that contain an attachment in the folder ./maildata

      MAIL_DIR=./maildata
      VERBOSE=off

      LOGFILE=./logs/printmail.log

      :0

      *^content-Type:

      $MAIL_DIR/


      Step 5 - Install and Configure CUPS

      CUPS (Common Unix Printing System) allows any computer to act as a print server.
      Just refer to
      this page for installation and configuration instructions
      Remark: Make sure to set this printer to be your default printer.
      Once completed you can manage the printer queue remotely using https://[ip-address-or-dns-name-of-your-raspberrypi]:631

      Image:Print Email Attachments automatically with a RaspberryPI

      Step 4 - Build your Script

      Create a new shell script...

      touch ./printmail.sh
      chmod +x ./printmail.sh

      nano ./printmail.sh

      using the following code
      #!/bin/bash
      # Parameters

      BASEDIR=$(dirname $0)

      CURDIR=$(pwd)

      MAILDIR=./maildata

      LOGFILE=./logs/printmail.log

      ATTACH_DIR=./attachments

      # change directory

      echo "Switching directory to : $BASEDIR"

      cd $BASEDIR

      # create log file if it does not exist

      touch $LOGFILE

      date +%r-%-d/%-m/%-y >> $LOGFILE

      # fetch mail

      echo "Checking for new mail..."

      fetchmail -f ./fetchmail.conf -L $LOGFILE

      # process new mails

      shopt -s nullglob

      for i in $MAILDIR/new/*

      do

       echo "Processing : $i" | tee -a $LOGFILE

       uudeview $i -i -p $ATTACH_DIR/

      # process file attachments with space
        cd $ATTACH_DIR

        for e in ./*

            do

                mv "$e" "${e// /_}"

        done

        for f in *.PDF

            do

            mv $f ${f%.*}.pdf

        done

        cd $BASEDIR
      # end of patch
       echo "Printing PDFs" | tee -a $LOGFILE

       for x in $ATTACH_DIR/*.pdf

       do

               echo "Printing : $x" | tee -a $LOGFILE

               lpr $x

               echo "Deleting file : $x" | tee -a $LOGFILE

               rm $x | tee -a $LOGFILE

       done

       echo "Clean up and remove any other attachments"

       for y in $ATTACH_DIR/*

       do

               rm $y

       done

       # delete mail

       echo "Deleting mail : $i" | tee -a $LOGFILE

       rm $i | tee -a $LOGFILE

      done

      shopt -u nullglob

      echo "Job finished." | tee -a $LOGFILE

      cd $CURDIR


      Step 5 - Test and Scheduling

      in order to test the whole script, just run it :)

      ./printmail.sh
      To run it on a schedule, just add the whole path to crontab.
      crontab -e -u pi

      in my case it is enough to run this script once per hour, feel free to customize it to your needs

      @hourly  /home/pi/pimailprint/printmail.sh

      Image:Print Email Attachments automatically with a RaspberryPI

      Results

      By forwarding a mail to a specific email address I can now print attachments automatically. Back home all the documents I wanted have already been printed or will be printed when switching on my printer and I can quickly process them further on, e.g. for claiming travel expenses back.
      In my case I am forwarding mails manually to a new account if I want to print them. Of course it is also possible to use mail rules for processing mails automatically.

      Enhancement requests / what needs to be done:
      • End to end encryption with S/MIME
    • Reply to sender when print job has completed
    • Define printer settings based on acronym in subject line
      Remark: Feel free to use this script at your own risk.
  • Tagged with: Code Linux RaspberryPI
    Comments

    1.) Untitled

    Rodrigo http:// 23.09.2015 15:43:22

    Hi I wonder if would rather print the attachments of the email I could print the body of the email?

    2.) Untitled

    Christian http:// 14.12.2015 11:57:34

    Thanks, Thomas. This ist working perfect on a Ubuntu 14.04.3 LTS virtual machine...

    I only had to change "lpr $x" to "lp -d PrinterName $x -o fit-to-page -o media=a4"

    I agree to @rodrigo that it would be nice to print the email body too.

    Christian

    3.) Untitled

    André Husken 16.05.2016 12:57:44

    Hi Thomas. I love your script. Is it also possible to print the mail body and not the attachments? How to i have to modify the fetchmail shell script? Hope you can help me.

    4.) Untitled

    Joachim http:// 29.01.2017 20:16:39

    Good article which helped my build my own Intel-based brick PC for automatically printing mail. However the script does not work with files that have a space in their name.

    5.) Untitled

    maurits http:// 24.09.2018 23:35:22

    I love this work, but unfortunately the pdf attachments are not stored on my raspi and can therefore not be printed. I dont understand what' going wrong :(

    This is when it goes wrong:

    Processing : ./maildata/new/1537820739.910_0.raspberrypi

    Loaded from ./maildata/new/1537820739.910_0.raspberrypi: 'test5' (test5): test.txt part 1 Base64

    Found 'test.txt' State 16 Base64 Parts 1 OK

    Opened file ./maildata/new/1537820739.910_0.raspberrypi

    ERROR: Could not open target file ./attachments/test.txt for writing: No such file or directory

    ERROR: while writing ./attachments/test.txt (test5): File I/O Error

    0 files decoded from 1 input file, 1 failed

    tee: ./logs/printmail.log: No such file or directory

    Printing PDFs

    anyone has any ideas?

    Go ElsewhereSubscribe to RSSAboutStay ConnectedAnd More
    Thomas Hampel, All rights reserved.