Hi all,
Answering a FAQ here: using dbmail you can now provide a functional
autoreplier with the same features as the famous vacation script.
Since dbmail's autoreply functionality is less than useful, I decided to
whip up a script to mimic the vacation functionality without having to
provide posix users as required by vacation itself.
howto:
0) make sure you have installed python on your system
1) install the attached script in your path, i.e. /usr/bin/autoreplier
2) run:
install -d -o dbmail -g root -m 2750 /var/cache/dbmail/
install -d -o dbmail -g root -m 2750 /var/lib/dbmail/
3) create a reply message file, i.e.
/var/lib/dbmail/messages/johndoe.msg
this message should be a well-formed email message, including a
From and a Subject line.
"""
From: [EMAIL PROTECTED] (J.Doe)
Subject: Out-of-Office message
Hi there,
I'm off for the duration...
please call our office at 0800-12345 for urgent issues.
--
J.Doe.
"""
4) add an alias using dbmail-adduser to activate:
dbmail-adduser f [EMAIL PROTECTED] "|/usr/bin/autoreplier \
-u johndoe -a [EMAIL PROTECTED] \
-m /var/lib/dbmail/johndoe.msg"
Now the reply message will be sent back no more than once a week to the
same recipient. Messages from postmaster, mailer-daemon, or daemon are
ignored. Only message sent directly to [EMAIL PROTECTED] (To or Cc
headers are checked) will be replied to.
5) to deactivate:
dbmail-adduser x [EMAIL PROTECTED] "|/usr/bin/autoreplier \
-u johndoe -a [EMAIL PROTECTED] \
-m /var/lib/dbmail/johndoe.msg"
There are some loose ends in the code:
- extend the options to resemble vacation a bit more.
- add an X-Loop header to prevent unnecessary loops.
Some ideas for additional features I still have:
- control (de)activation through the tool itself
- store the reply message in the dbmail database (use the auto_replies
table if possible)
what do you think?
--
________________________________________________________________
Paul Stevens mailto:[EMAIL PROTECTED]
NET FACILITIES GROUP PGP: finger [EMAIL PROTECTED]
The Netherlands________________________________http://www.nfg.nl
#!/usr/bin/python
#
# Copyright: NFG, Paul Stevens <[EMAIL PROTECTED]>, 2004
# License: GPL
#
# $Id: autoreplier.py,v 1.2 2004/06/30 18:17:40 paul Exp $
#
# Reimplementation of the famous vacation tool for dbmail
#
#
import os,sys,string,email,getopt,shelve,time,re,smtplib
def usage():
print """autoreplier: dbmail autoreply replacement
-u <username> --username=<username> specify recipient
-a <alias> --alias=<alias> specify matching destination address
-m <file> --message-file=<file> file containing reply message
"""
error='AutoReplyError'
class AutoReplier:
CACHEDIR="/var/cache/dbmail"
TIMEOUT=60*24*7
OUTHOST="localhost"
OUTPORT=25
_username=None
_messagefile=None
def __init__(self):
self.setMessage(email.message_from_file(sys.stdin))
def setUsername(self,_username): self._username=_username
def getUsername(self): return self._username
def setMessage(self,_message): self._message=_message
def getMessage(self): return self._message
def setReply(self,_messagefile): self._messagefile=_messagefile
def getReply(self): return email.message_from_file(open(self._messagefile))
def setAlias(self,_alias): self._alias=_alias
def getAlias(self): return self._alias
def openCache(self):
file=os.path.join(self.CACHEDIR,"%s.db" % self.getUsername())
self.cache=shelve.open(file,writeback=True)
def closeCache(self): self.cache.close()
def checkSender(self,bounce_senders=[]):
for f in ('From',):
if self.getMessage().has_key(f):
header=string.lower(self.getMessage()[f])
for s in bounce_senders:
if string.find(header,s) >= 0:
return True
return False
def checkDestination(self):
for f in ('To','Cc'):
if self.getMessage().has_key(f):
header=string.lower(self.getMessage()[f])
if string.find(header,self.getAlias()) >=0:
return True
return False
def send_message(self,msg):
server=smtplib.SMTP(self.OUTHOST,self.OUTPORT)
server.sendmail(msg['From'],msg['To'],msg.as_string())
server.quit()
def _reply(self):
m=self.getMessage()
u=self.getUsername()
if m.has_key('Reply-to'): to=m['Reply-to']
elif m.has_key('From'): to=m['From']
else: raise error, "No return address"
if self.checkSender(['daemon','mailer-daemon','postmaster']):
return
if not self.checkDestination():
return
if not self.cache.has_key(u):
self.cache[u]={}
if not self.cache[u].has_key(to) or self.cache[u][to] < int(time.time())-self.TIMEOUT:
reply=self.getReply()
del reply['To']
reply['To']=to
self.send_message(reply)
self.cache[u][to]=int(time.time())
def reply(self):
self.openCache()
self._reply()
self.closeCache()
if __name__ == '__main__':
try:
opts,args = getopt.getopt(sys.argv[1:],"u:m:a:",
["username=","message-file=","alias="])
except getopt.GetoptError:
usage()
sys.exit(0)
replier=AutoReplier()
for o,a in opts:
if o in ('-u','--username'):
replier.setUsername(a)
if o in ('-a','--alias'):
replier.setAlias(a)
if o in ('-m','--message-file'):
replier.setReply(a)
replier.reply()