Archive

Kategorien

Postfix Autoreply mit MySQL

Das Autoreply Script für Postfix besteht aus 2 Scripten. Es wird eine mysql-Tabelle mit folgendem Aufbau erwartet.
WICHTIG: Sowohl title (Betreff) als auch content (Inhalt) müssen quoted-printable codiert sein. Die automatische Antwort erfolgt im UTF-8 Format (8bit). In Mails sind jedoch nur Zeichen nach ASCII (7bit) erlaubt. Daher müssen sowohl Betreff als auch Inhalt codiert werden.

1
2
Ich wünsche einen schönen Tag
Ich w=C3=BCnsche einen sch=C3=B6nen Tag
 CREATE TABLE `autoreply` (
  `email` VARCHAR(255) COLLATE utf8_unicode_ci NOT NULL,
  `title` VARCHAR(255) CHARACTER SET utf8 NOT NULL,
  `content` text CHARACTER SET utf8 NOT NULL,
  `active` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`email`),
  KEY `email` (`email`)
) ENGINE=Innodb DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='Blahblahblah'

Die Länge von 255 für title ist etwas viel 😉 Eigentlich sind im Betreff einer Mail nur 72 Zeichen erlaubt. Das Problem ist die Codierung des Betreffs. Mit vielen nicht-ASCII Zeichen wird der String beim Codieren deutlich länger als wenn der String ohne Sonderzeichen ist.
Ein Betreff wird mindestens um ?UTF-8?Q? und ? und zwei Zeilenendzeichen ergänzt d.h. ein reiner ASCII Betreff darf maximal 60 Zeichen lang sein. Wenn nicht-ASCII Zeichen vorkommen dann kürzer

Das autoreply.sh Script stellt die Autoreply-Funktion bereit. Diese wird dann in /etc/postfix/master.cf als Postfix-Handler eingebunden.

1
2
autoreply   unix    -   n   n   -   -   pipe
 flags= user=nobody argv=/etc/postfix/autoreply/autoreply.sh ${sender} ${mailbox}

Die weiteren Schritte wie man einen Autoreply in Postfix einbindet lasse ich hier weg. Mehr kann man hier oder direkt im Postfix-Manual nachlesen

#!/bin/bash
 
if test "$1" = "-h"; then
 echo "*************************************************************"
 echo "*                                                           *"
 echo "* Usage:    autoreply sender reciever                       *"
 echo "* sender:   the original sender of the mail                 *"
 echo "* reciever: the original reciever of the mail               *"
 echo "* stdin:    on stdin the content of the mail is expected    *"
 echo "*                                                           *"
 echo "*************************************************************"
 exit
fi
 
# config variables
 
# logpath MUST be writable for the user running autoreply (check master.cf where the user can be specified)
# the script tries to create the file but depending from the specified position it will be impossible
# for the script to create it. 
# The easiest way is to manually create the file and chmod it so the user running autoreply has write privileges on the file
LOG=/var/log/autoreply.log
 
# exclude list for autoreply. must be valid syntax for <egrep>
# if the sender of the mail or the receiver of the autoreply match expression then NO autoreply will be sent
EXCLUDE=''
 
# path to sendmail program
# for diskstation users /usr/syno/mailstation/sbin/sendmail
MAIL=/usr/sbin/sendmail
 
 
touch $LOG > /dev/null 2>&1
[[ $? -ne 0 || ! -w $LOG ]] && echo "$LOG could not be statet. Check path and permissions" && exit 1
 
while read x1
do
 [ "x$x1" = "x" ] && break
 MSG="$MSG\n$x1"
done
 
sendReply ()
{
 MSGID=''
 MSGID=$(echo -e $MSG | grep -i ^Message-Id | awk -F': ' '{print $2}')
 TXT="$(php /etc/postfix/autoreply/autoreply.php $2 $1 $MSGID)" 
 [ "$TXT" = '0' ] && echo -e $(date +"%b %_d %T")" autoreply failure: msg to $1 in response to mail to $2 could not be sent because of missing mysql dataset for forwaring" >> $LOG && exit 0
 printf "$TXT" | $MAIL -f "$2" -t "$1"
 if [ $? -eq 0 ] ; then
  SHOW=$(cat /var/log/mail.log | grep '<'$1'>' | awk '{print $6}' | awk -F: '{print $1}')
  OUT=$(echo $SHOW | awk '{print $NF}')
  IN=$(echo $SHOW | awk '{print $(NF-1)}')
  echo -e $(date +"%b %_d %T")" autoreply success: msg to $1 ("$OUT") in response to mail to $2 ("$IN") sent" >> $LOG  && exit 0
 fi
 echo -e $(date +"%b %_d %T")" autoreply error: msg to $1 in response to mail to $2 could NOT  be sent." >> $LOG && exit 1
}
#[ ! "x$(echo -e $1 | egrep $EXCLUDE)" = 'x' ] && echo -e $(date +"%b %_d %T")" autoreply dunno: domain in exclude list found in sender-envelope sender=$1 rcpt=$2" >> $LOG 2>&1 && exit 0
#[ ! "x$(echo -e $MSG | grep ^From: | egrep $EXCLUDE)" = 'x' ] && echo -e $(date +"%b %_d %T")" autoreply dunno: domain in exclude list found in From-header sender=$1 rcpt=$2" >> $LOG 2>&1 && exit 0
[ "x$(echo -e $MSG | grep -i 'X-Spam-Flag: YES')" != 'x' ] && echo -e $(date +"%b %_d %T")" autoreply dunno: no autoreply because of spam flag sender=$1 rcpt=$2" >> $LOG 2>&1 && exit 0 
[ "$1" = "$2" ] && echo -e $(date +"%b %_d %T")" autoreply dunno: sender and receiver are the same sender=$1 rcpt=$2" >> $LOG && exit 0
[ "x$(echo -e $MSG | grep -i ^From:.*$1)" = 'x' ] && echo -e $(date +"%b %_d %T")" autoreply dunno: envelop sender not found in From-header sender=$1 rcpt=$2" >> $LOG && exit 0
[ ! "x$(echo -e $MSG | grep -i ^Auto-Submitted: | grep -iv no)" = 'x' ] && echo -e $(date +"%b %_d %T")" autoreply dunno: msg has auto-submitted headers with a value other than \"no\" sender=$1 rcpt=$2" >> $LOG && exit 0
[ ! "x$(echo -e $MSG | egrep -i '^Precedence: junk\|bulk\|list')" = 'x' ] && echo -e $(date +"%b %_d %T")" autoreply dunno: msg has precedence \"junk\" or \"bulk\" or \"list\" header sender=$1 rcpt=$2" >> $LOG && exit 0
[ ! "x$(echo $1 | egrep -i mailer-daemon\|listserv\|majordomo\|owner-\|\-request)" = 'x' ] &&  echo -e $(date +"%b %_d %T")" autoreply dunno: msg seems to be from a mailing list sender=$1 rcpt=$2" >> $LOG && exit 0
 
[ ! "x$(echo -e $MSG | grep -i ^To: | grep $2)" = 'x' ] &&  sendReply $1 $2
[ ! "x$(echo -e $MSG | grep -i ^Cc: | grep $2)" = 'x' ] &&  sendReply $1 $2
[ ! "x$(echo -e $MSG | grep -i ^Bcc: | grep $2)" = 'x' ] &&  sendReply $1 $2
echo -e $(date +"%b %_d %T")" autoreply dunno: rcpt not found in headers (To, Cc or Bcc) sender=$1 rcpt=$2" >> $LOG && exit 0

Das autoreply.php Script stellt die automatische Mail zusammen und gibt sie zum Versand wieder an autoreply.sh zurück. Die Zugangsdaten zum mysql müssen natürlich angepasst werden

<?php
error_reporting('E_NONE');
ini_set('display_errors','0');
$db = mysql_connect(mysql_server','mysql_user','mysql_password') OR die('0');
mysql_select_db('mysql_db',$db) OR die('0');
$email = mysql_real_escape_string($argv[1],$db);
$reciever = $argv[2];
$sql = 'SELECT `title`,`content` FROM `autoreply` WHERE `email`=\''.$email.'\' AND `active`=1 LIMIT 1;';
$res = mysql_query($sql,$db) OR die('0');
$row = mysql_fetch_array($res,MYSQL_ASSOC) OR die('0');
if ( count ( $row ) == 2){
	$str = "From: $email <$email>\n";
	$str .= "To: <".$reciever.">\n";
	$str .= "Auto-Submitted: auto-replied\n";
	if(isset($argv[3]) && !empty($argv[3])){
	 $str .= "In-Reply-To: $argv[3]\n";
	 $str .= "References: $argv[3]\n";
	}
	$str .= "Content-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: quoted-printable\n";
	$str .= "Subject: =?UTF-8?Q?". str_replace(array("=\r\n","=\n","=\r"), "", $row['title']) ."?=\n\n";
	$str .= $row['content'];
	echo "$str";
} else {
	echo "0";
}
?>

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">

  

  

  

eleven + seven =

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie mehr darüber, wie Ihre Kommentardaten verarbeitet werden .