Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I send HTML email via Celery? It keeps sending in text/plain

I setup a system Django/Celery/Redis. And I used EmailMultiAlternatives to send my HTML and Text email.

When I send email as part of the request process, the email is sent in HTML. All runs well and it wraps around a function. Here's the code:

def send_email(email, email_context={}, subject_template='', body_text_template='',
    body_html_template='', from_email=settings.DEFAULT_FROM_EMAIL):

    # render content
    subject = render_to_string([subject_template], context).replace('\n', ' ')
    body_text = render_to_string([body_text_template], context)
    body_html = render_to_string([body_html_template], context)

    # send email
    email = EmailMultiAlternatives(subject, body_text, from_email, [email])
    email.attach_alternative(body_html, 'text/html')
    email.send()

However, when I tried to run it as a Celery Task, like below, it just sent as "text/plain". What could be the problem? Or what can I do to find out more? Any hint or solution are greatly appreciated.

@task(name='tasks.email_features', ignore_result=True)
def email_features(user):
    email.send_email(user.email,
        email_context={'user': user},
        subject_template='emails/features_subject.txt',
        body_text_template='emails/features_body.txt',
        body_html_template='emails/features_body.html')
like image 408
Mickey Cheong Avatar asked Oct 07 '22 05:10

Mickey Cheong


1 Answers

Celery does not affect the executing results of tasks. Have you restarted celeryd after make change to the task? It's important for celery to reload the Python code.

When you were using EmailMultiAlternatives and email.attach_alternative(body_html, 'text/html'), the email was sent in the Content-Type: multipart/alternative; and the text/html is an alternative one, it depends on mail receipts to choose the content type of the mail during the rendering. So is the receipt same one between the view procedure and celery procedure?

You could output the sending mail directly, through python -m smtpd -n -c DebuggingServer localhost:25 to find out the actual messages. I've tested on my mac w/ redis-backed Celery, the outputs of the examples taken from the official doc are same as expected.

like image 110
okm Avatar answered Oct 13 '22 10:10

okm