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
Use Mailgun.
You'll need to give MailGun a URL that it would POST to and you can parse the email message.
http://documentation.mailgun.net/quickstart.html#receiving-and-parsing-email
Django doesn't provide any email receiving support.
Lamson may be a good alternative if you need something more advanced than checking out email using poplib, or something more pythonic than interacting with postfix.
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 <recipient>"
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 messagerecipient - 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.