If your Django site sends emails and they are getting blocked, you might want to consider using Postmark. These are my notes for getting it to work on Webfaction.
On Postmark, you need to create a sender signature. This involves setting up DKIM and SPF on Webfaction. To setup SPF, go to the Webfaction control panel and select the domain name for your web site. This will pull up a panel that will allow you to add a DNS record. When you create the Postmark signature, it gave you text for the SPF record. Postmark says to add it as a TXT record. On Webfaction, I got it to work adding it as a SPF record. When that is done, click verify on Postmark. The first time I did this, it took several hours before verify would work.
Postmark also gave you a DKIM domain name and TXT. On Webfaction, create that domain name, select DNS record TXT and paste in the text from Postmark. Pretty straight forward, except the first time I did this, it took about 12 hours before Postmark could verify this record. That’s a long time to wait when you are not sure you did it right.
**** Jan 2015 Update*************************************
Below, I describe how to use Postmark with Django using the Postmark API. Now you can skip the API and use Postmark’s SMTP server. I tried it and it works. Here are the Django settings:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.postmarkapp.com' EMAIL_HOST_PASSWORD = 'my Postmark Server API key' # From Postmark credentials field EMAIL_HOST_USER = 'my Postmark Server API key' # this is intentionally repeated EMAIL_PORT = '587' # encrypted EMAIL_USE_TLS = True SERVER_EMAIL = 'my server email address, setup on Postmark'
***** End Jan 2015 Update ********************************
To get things working in Django, install python-postmark. I installed version 0.4.2 using:
pip install python-postmark
Add these lines to your Django settings file:
EMAIL_BACKEND = 'postmark.django_backend.EmailBackend' POSTMARK_API_KEY = 'my api key' POSTMARK_SENDER = 'email@example.com' POSTMARK_TEST_MODE = False POSTMARK_TRACK_OPENS = False DEFAULT_FROM_EMAIL = POSTMARK_SENDER SERVER_EMAIL = POSTMARK_SENDER
Here is a view for testing email:
from django.http import HttpResponse from django.core.mail import send_mail from django.conf import settings def sendmail_test(request): to = ['the email address'] send_mail('the subject', 'test message', settings.DEFAULT_FROM_EMAIL, to, fail_silently=False) return HttpResponse('Mail was sent to %s' % to)
Sending a CSV file was a little more tricky. I thought I could send it as a text file. But when I tried, got this error:
PMMailUnprocessableEntityException: u'Unprocessable Entity: Invalid attachment content - illegal base64 string.
Base 64 encoding of the CSV file solved that problem:
import csv import base64 from django.http import HttpResponse from django.core.mail import EmailMessage from django.conf import settings def sendmail_test_w_attachment(request): """Send mail with attachment """ # Make csv file filename = 'test.csv' fp = open(filename, 'wb') writer = csv.writer(fp) writer.writerow(['data 1', 'data 2']) writer.writerow([1, 2]) fp.close() to = ['to email address'] email = EmailMessage('TimeSheet CSV File', 'The CSV is attached.', to=to) # Load file and Base64 encode csv data data = open(filename, 'rb').read() encoded = base64.b64encode(data) email.attach('test.csv', encoded, mimetype='application/octet-stream') # Send it email.send(fail_silently=False) return HttpResponse('Mail was sent to %s' % to)
Postmark works from the development server (http://127.0.0.1:8000/), so you can do all your tests before going live.