Reputation: 88429
How can I properly send batch/bulk/mass emails using MailGun in Django using SMTP protocol?
django.core.mail.backends.smtp.EmailBackend
as my EMAIL_BACKEND
and this is the code snippet that I have tried to send the emails.
from django.core.mail import EmailMultiAlternatives
import json
to_emails = [
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
]
mail = EmailMultiAlternatives(
subject="Hey - %recipient.name%",
body="Hey %recipient.name%,\n\nThis is just a batch email test!!!",
from_email="JPG <[email protected]>",
to=to_emails,
)
recipient_variables = {
address: {"name": address} for address in to_emails
}
mail.extra_headers["X-Mailgun-Recipient-Variables"] = json.dumps(recipient_variables)
response = mail.send()
print(response)
and I've got the mail as below,
As we can see, the to
attribute is filled with all email addresses, which is not what I am expecting.
So, how can I tell the Mailgun/Django to parse my variables properly in order to make the emails looks more personal?
Notes
to
argument to to="%recipient%"
But, got
TypeError: "to" argument must be a list or tuple
to
argument to to=["%recipient%"]
But, got
smtplib.SMTPRecipientsRefused: {'=?utf-8?q?=25recipient=25?=': (501, b'Invalid command or cannot parse to address')}
Upvotes: 2
Views: 927
Reputation: 43073
As we can see, the
to
attribute is filled with all email addresses, which is not what I am expecting.
It is not properly supported with SMTP by Mailgun.
However, relying on the (unintuitive) implementation of BCC in Mailgun, there is a workaround:
mail = EmailMultiAlternatives(
subject="Hey - %recipient.name%",
body="Hey %recipient.name%,\n\nThis is just a batch email test!!!",
from_email="JPG <[email protected]>",
# to=to_emails, # Replace this
bcc=to_emails, # with this
)
recipient_variables = {
address: {"name": address} for address in to_emails
}
mail.extra_headers["To"] = "%recipient%" # Add this
mail.extra_headers["X-Mailgun-Recipient-Variables"] = json.dumps(recipient_variables)
to=["%recipient%"]
not work with SMTP?It's the standard in the protocol.
From https://documentation.mailgun.com/_/downloads/en/latest/pdf/:
SMTP send will error with “cannot parse to address” or “cannot parse from address” if the provided email address fails syntax checks in accordance with RFC5321, RFC5322, RFC6854.
Use the API.
From https://stackoverflow.com/questions/30787399/laravel-5-sending-group-emails (multiposted to https://laracasts.com/discuss/channels/laravel/sending-email-to-1000s-of-reciepents):
So far, I have created an array of recipient email addresses, sent the email to a webmaster type address, and included the end recipients in BCC
While this works, it's not ideal.
Rather than using Laravel's built in
This also allows me to access unique recipient variables within my email template
(It's not specific to Laravel/PHP, but to SMTP via Mailgun.)
Mailgun effectively personalises the email for each BCC recipient using recipient-variables.
From https://github.com/mailgun/mailgun-js-boland/issues/89:
the bcc person is receiving the email as it was addressed to them instead of being part of the bcc
This causes a separate issue when you actually want BCC recipients to get the same content.
In the copy sent to the bcc address, the recip_vars substitution has not been made.
According to the good people at Mailgun, this is not possible, at least in the current release of the service.
Upvotes: 1