Process received email with Python or Django?

后端 未结 3 873
迷失自我
迷失自我 2021-02-10 07:50

I understand how sending email works through Django, but I want users to be able to respond to the email. If the email they send (and I receive) contains a message that matches

3条回答
  •  梦如初夏
    2021-02-10 08:36

    We are doing something similar with plone by configuring postfix to do a HTTP request to plone when receiving an email to a specific domain. This should also easily be possible with django, so that you just have to configure your server and write a view in django which receives the email.

    That's how you can do it:

    1) Set up your DNS so that a MX record for the domain points to your server.

    2) Configure a postfix virtual alias /etc/postfix/virtual:

    example.com anything
    django@example.com django-mail-in
    

    3) and /etc/aliases:

    django-mail-in: "|/usr/local/bin/mta2django.py http://127.0.0.1:8000/mail-inbound"
    

    4) The /usr/local/bin/mta2django.py is called by postscript and sends the mail to the mail-inbound django view. This mta2django.py should work:

    #!/usr/bin/python
    
    import sys, urllib
    import os
    
    
    def post_message(url, recipient, message_txt):
        """ post an email message to the given url
        """
    
        if not url:
            print "Invalid url."
            print "usage: mta2django.py url "
            sys.exit(64)
    
        data = {'mail': message_txt}
        if recipient and len(recipient) > 0:
            data ['recipient'] = recipient
    
        try:
            result = urllib.urlopen(url, urllib.urlencode(data)).read()
        except (IOError,EOFError),e:
            print "error: could not connect to server",e
            sys.exit(73)
    
        try:
            exitcode, errormsg = result.split(':')
            if exitcode != '0':
                print 'Error %s: %s' % (exitcode, errormsg)
                sys.exit(int(exitcode))
        except ValueError:
            print 'Unknown error.'
            sys.exit(69)
    
        sys.exit(0)
    
    
    if __name__ == '__main__':
        # This gets called by the MTA when a new message arrives.
        # The mail message file gets passed in on the stdin
    
        # Get the raw mail
        message_txt = sys.stdin.read()
    
        url = ''
        if len(sys.argv)>1:
            url = sys.argv[1]
    
        recipient = ''
        # If mta2django is executed as external command by the MTA, the
        # environment variable ORIGINAL_RECIPIENT contains the entire
        # recipient address, before any address rewriting or aliasing
        recipient = os.environ.get('ORIGINAL_RECIPIENT')
    
        if len(sys.argv)>2:
            recipient = sys.argv[2]
    
        post_message(url, recipient, message_txt)
    

    5) Write a django view /mail-inbound which receives the mail and does the things you need it to do. In the request you have:

    • mail - the full email message
    • recipient - the original recipient (useful when you do not catch a specific email address but the whole domain / subdomain)

    You can parse the email using the python email module:

    import email
    
    msg = email.message_from_string(request.get('mail'))
    

    As I'm no postfix expert, I'm not sure if editing /etc/postfix/virtual and /etc/aliases is sufficient. Please consult the postfix documentation for details.

提交回复
热议问题