rnevius
rnevius

Reputation: 27092

Unable to send email via Django contact form

Preface: I can send email via the command line (using send_mail()) on my server. I can also send email from my localhost using the same SMTP settings. Additionally, I'm using django-allauth for user registration...and it's able to send out email verification emails just fine.

Problem: Mail is not sent by my contact form on my server, and no error is thrown. In fact, send_mail() is returning 1 (i.e. success), and the view is redirecting.

My views.py looks like the following:

class ContactFormView(FormView):

    form_class = ContactForm
    template_name = 'contact.html'
    success_url = '/message-sent/'

    def form_valid(self, form):
        subject = form.cleaned_data.get('subject')
        message = "{name} / {email} sent you the following message: ".format(
            name=form.cleaned_data.get('name'),
            email=form.cleaned_data.get('email')
        )
        message += "\n\n{0}".format(form.cleaned_data.get('message'))
        sender = form.cleaned_data.get('email')
        recipients = ['[email protected]', '[email protected]']
        honeypot = form.cleaned_data.get('phone_number')

        if not honeypot:
            send_mail(subject, message, sender, recipients)
        return HttpResponseRedirect(self.get_success_url())

And my relevant forms.py:

class ContactForm(forms.Form):
    phone_number = forms.CharField(required=False, label='Phone Number (keep this empty, or the form won\'t submit)')  # honeypot
    name = forms.CharField(required=True)
    email = forms.EmailField(required=True)
    subject = forms.CharField(required=True)
    message = forms.CharField(widget=forms.Textarea)

Am I missing something super obvious?

EDIT: The credentials are definitely working (as mentioned, they're working from my local development environment, and I'm also able to send an email from the shell on my server using the same credentials). Enabling fail_silently=False doesn't result in an exception.

EDIT_2: I modified the view to look like the following:

def form_valid(self, form):
    send_mail('Test Subject', 'Test Message', '[email protected]', ['[email protected]'])
    return HttpResponseRedirect(self.get_success_url())

And received an email just fine. As you can see, no form data was passed to send_mail() in the above view.

Upvotes: 1

Views: 650

Answers (1)

rnevius
rnevius

Reputation: 27092

Aaaand...the source of my 4 hours of debugging turned out to be my honeypot. More specifically, my browser's auto-complete filling in the honeypot.

I wasn't seeing problems in my local environment, because I don't have autocomplete enabled in my VM's browser. However, testing things on the staging/production server using the main browser of my host machine resulted in the honeypot (which is 5000px off screen) being filled.

This answer is here for anyone who happens upon a similar issue in the future.

If you use a honeypot, and your form isn't sending email, turn off auto-complete! Also be aware that keeping your honeypot visible (albeit, off screen) means that it can still be filled by normal users. It may be a good idea to actually hide it with JS.

Upvotes: 1

Related Questions