Send raw email from python and retrieve sendmail queueid

一曲冷凌霜 提交于 2019-12-11 17:15:41

问题


I have a need to take an incoming email that matches a specific ruleset in postfix, send it to an external python process, rewrite the email to multiple delivery recipients based upon the postfix postmap table, and re-inject back into the postfix chain. The included python meets that basic requirement except for one, tracking the queueid of the new re-injected email.

The typical method of re-injecting with /usr/sbin/sendmail does not return a usable queueid for the correct process. This causes loss of visibility of the newly created emails (logs have to be manually parse to generate a delivery confirmation report for 3rd parties).

Since the re-injection process is in python, ideally I would like to use the smtplib.Sendmail for that, but it also does not return a queueid.

What I have tried, and kind of works, is using netcat as a subprocess in python (netcat_msg = "helo myserver\nmail from: " + sender + "\nrcpt to: " + recipient + "\ndata\n" + msg.as_string() + "\n\n.\nquit\n") but I feel that's a hack and I get warnings about command sequences in smtp (which is expected since I'm not waiting on the response before issuing the next command).

Is there a way to expose the queueid returned from the remote SMTP server when the process completes? Any recommended approaches to this?

My goal is to log these queueids to a file/api endpoint/whatever so we can determine that incoming email to a@domain.tld was sent to bob@example.com, chris@example.com and track the return status of the destination server.

(Excuse my crude python)

#!/bin/python
#v 2.7.15

import email
import sys
from email.mime.text import MIMEText
import argparse
from subprocess import Popen
from subprocess import PIPE

#ignore this, it was just for debugging
def dump(obj):
   for attr in dir(obj):
       if hasattr( obj, attr ):
           print( "obj.%s = %s" % (attr, getattr(obj, attr)))

def process_message(data, sender, recipient):
   msg = email.message_from_string(data)

   newaddress = '"{recipient}" <{recipient}>'.format(recipient=recipient)
   oldaddress = ''
   if msg.has_key('To'):
      oldaddress = msg['To']
      msg.replace_header('To', newaddress)
   else:
      msg.add_header('To', newaddress)
      oldaddress = newaddress

   if msg.has_key('X-Original-To'):
      msg.replace_header('X-Original-To', oldaddress)
   else:
      msg.add_header('X-Original-To', oldaddress)

   #print(msg.as_string())
   try:
      # replace this with a re-inject that can return the queueid
      p = Popen(["/usr/sbin/sendmail", "-G", "-i", "-f " + sender, "--", recipient ], stdin=PIPE)
      p.communicate(msg.as_string())
      # end replacement
      # log original queueid, returned queueid and destination email here
   except Exception as ex:
      exit(69)

def main():
   parser = argparse.ArgumentParser(description='To field replacement for Email MIME.')
   parser.add_argument('--from', dest="sender", help="From email address", required=True)
   parser.add_argument('--recipient', dest="recipients", help="Recipient address to replace in To field (N+1)", nargs='+', required=True)
   args = parser.parse_args()

   #dump(args)
   data = sys.stdin.readlines()
   data = ''.join(data)

   for recipient in args.recipients:
      #print(recipient)
      process_message(data, args.sender, recipient)

   exit(0)

main()

来源:https://stackoverflow.com/questions/55907546/send-raw-email-from-python-and-retrieve-sendmail-queueid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!