How to process mail using "deliver"


This page outlines how to process incoming mail using Chip Salzenberg's deliver program. The program is similar to the procmail program in that it processes incoming mail messages via a pipe from the mail transfer agent (sendmail, exim, etc.), but its use is somewhat the reverse. Whereas procmail uses its own internal syntax language to parse the parts of the message and then take actions using more built-in syntax, deliver uses simple built-in variables from within a language of your choice to do whatever you like with it. In simpler terms, deliver pipes the message to your script and you do whatever you like using the few variables that are set in the environment for that script by deliver.

Let's use a simple example to see deliver in action. Let's assume you want to parse the email sent to an address called "testmail". This will be piped to deliver by way of sendmail's aliases mechanism.

In /etc/mail/aliases:

testmail:"| /usr/local/bin/deliver testmail"
The deliver program will then look for a series of files but for system aliases such as this, the important file will be the "system" deliver file; in this case /usr/local/lib/deliver.sys. In this file will be a "case" statement that will determine what action is taken based on the value of argument 1.

In /usr/local/lib/deliver.sys:
case $1 in 
somestring)
	/usr/local/bin/some_script
;;
testmail)
	/usr/local/bin/testmail
;;
*)
	echo $1
;;
esac
This essentially will have sendmail call the program /usr/local/bin/deliver with an argument of testmail and the mail message as standard input. Then deliver looks for a matching argument in /usr/local/lib/deliver.sys (or $HOME/.deliver if present) runs whatever is in the case statement, in this case a simple shell called /usr/local/bin/testmail. This script can then use deliver's built-in special variables to parse the mail and then you basically do what you want from there; i.e. break up the fields and run through a Perl script, SQL*Plus or whatever. As an example, the script testmail will write out the headers and message body of the mail (defined internally in deliver with the $HEADER and $BODY variables) to a file if the Subject field matches a predetermined string.
#!/bin/sh
# Write mail out if Subject matches and respond to sender

SUBJECT=`grep "^Subject: " $HEADER | sed -e 's/^Subject: //' | tr '[A-Z]' '[a-z]'`

if [ "$SUBJECT" = "test mail" ]
then
	cat $HEADER $BODY > /tmp/workfile
	echo "Subject received: $SUBJECT" | mailx -s "Mail received" $SENDER
fi
echo DROP
You can then do as you wish with the contents of the file. You parse the message further, autorespond using your own code, whatever you want. The beauty is that it's up to you what you want to use as a language to parse with as you're not tied to a built-in syntax as you are with procmail's recipes. One important caveat to remembert with deliver. *ANY* output created by your script to stdout will be construed as an address to attempt delivery to (Hence the default case statement in deliver.sys). So it is imperative that you redirect command output; like from greps; to /dev/null or other. Also, at the end of the script you'll see a "echo DROP" statement. This is a special keyword to deliver which tells it to finish processing and looking for addresses.

See the deliver man page for details.