I'm setting up on a Django site the elegant forum application Spirit, but having just a bit of trouble getting it to send emails on the Heroku installation. This is undoubtedly because I'm a novice, a little unsteady about sending emails in Django, and not quite sure how to get the relevant debugging info. Some help would be much appreciated.
I installed the Postmark addon plus the Python-Postmark library. On the local installation, everything is perfectly fine: registration emails get delivered as they should when using the installation on my machine. The problem is only with the deployment version.
Also, when I enter
heroku run python
from django.config import settings
from django.core.mail import send_mail
send_mail('this is a test from the heroku server','body',settings.DEFAULT_FROM_EMAIL, ['the.robot#example.com'],fail_silently=False)
then the Postmark server sends the message and it is received. So... it seems like the Postmark installation, and the Django command send_mail at least sort of work on the Heroku server. It's just when I request e.g. a user activation message through the browser while using the forum application itself, on the Heroku server, that the mail is not sent.
Postmark is configured in the site's settings.py files like this.
EMAIL_BACKEND = 'postmark.django_backend.EmailBackend'
POSTMARK_API_KEY = os.environ['POSTMARK_API_KEY']
POSTMARK_SENDER = 'the.robot#example.com'
POSTMARK_TEST_MODE = False
POSTMARK_TRACK_OPENS = False
DEFAULT_FROM_EMAIL = POSTMARK_SENDER
SERVER_EMAIL = POSTMARK_SENDER
Here is the (slightly modified) code which is supposed to be sending the email.
def sender(request, subject, template_name, context, to):
site = 'example.com'
context.update({'site_name': 'example',
'domain': 'example.com',
'protocol': 'https' if request.is_secure() else 'http'})
message = render_to_string(template_name, context)
from_email = "the.robot#example.com"
if len(to) > 1:
kwargs = {'bcc': to, }
else:
kwargs = {'to': to, }
email = EmailMessage(subject, message, from_email, **kwargs)
def send_activation_email(request, user):
subject = _("User activation")
template_name = 'spirit/user/activation_email.html'
token = UserActivationTokenGenerator().generate(user)
context = {'user_id': user.pk, 'token': token}
sender(request, subject, template_name, context, [user.email, ])
I also tried using gmail as a mail server, as suggested in this answer, and the same problem recurred. That is, mail gets sent perfectly fine from the local installation, but is apparently not sent by the Heroku version. Likewise, the command send_mail then still works on Heroku.
Related
I'm attempting to send email from a very simple Django app. The app is hosted on Heroku, and I have the Mailgun add-on installed. However, whenever I attempt to actually send an email using Mailgun, I get a SMTPServerDisconnected error, with the message Connection unexpectedly closed.
I've gone through almost every tutorial that I can find on the subject, and have still had no luck. My settings.py is exactly as described in the Heroku Mailgun documentation:
EMAIL_USE_TLS = True
EMAIL_HOST = os.environ.get('MAILGUN_SMTP_SERVER')
EMAIL_PORT = os.environ.get('MAILGUN_SMTP_PORT', '')
EMAIL_HOST_USER = os.environ.get('MAILGUN_SMTP_LOGIN', '')
EMAIL_HOST_PASSWORD = os.environ.get('MAILGUN_SMTP_PASSWORD', '')
The os environment variables referenced are managed by Heroku. When I've searched for similar problems, every other question has been using Port 465, however, my port is on 587, which shouldn't have this issue as far as I know.
Currently, I'm using the sandbox domain provided by Mailgun just to attempt to send a test email to a verified recipient email. The following code is used in my views.py to actually send the email, using the django django.core.mail.send_mail() function.
subject = "Thank you for RSVP-ing!"
message = f'Hello World!'
email_from = "mailgun#blannholley.com"
recipient_list = [request.POST.get('email'), ]
send_mail(subject, message, email_from, recipient_list, fail_silently=False)
Any help would be greatly appreciated, as this is my first time attempting to send email over SMTP, so I'm very lost here and feel like I've tried everything.
guys!
I have an issue with my Django project.
About project:
Django version: 3.0.7
Django hosting provider: Digitalocean
E-mail hosting provider: Beget.com
OS: Ubuntu 18.04.6
Here is my settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.beget.com'
EMAIL_PORT = 465
EMAIL_HOST_USER = 'my#email.com'
EMAIL_HOST_PASSWORD = 'MyVerySecretPassword'
DEFAULT_FROM_EMAIL='my#email.com'
Here is my views.py
from django.core.mail import send_mail
def register(request):
if request.method == 'POST':
form = UserRegistrationForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.save()
current_site = get_current_site(request)
mail_subject = 'Please, activate your account by clicking the link below.'
message = render_to_string('acc_active_email.html', {
'user': user,
'domain': current_site.domain,
'uid':urlsafe_base64_encode(force_bytes(user.pk)),
'token':account_activation_token.make_token(user),
})
to_email = form.cleaned_data.get('email')
send_mail(mail_subject, message, settings.DEFAULT_FROM_EMAIL, [to_email])
What I have tried to solve my problem:
Using gmail account (yes, with anabled 'Allow less secure apps')
Sending via Django shell (nope, it returns code '1', the mailbox is as empty as my ideas:( )
I have opened 587 and 465 ports in ufw
I tried to write and run simple python smtp script to send e-mail via Django shell (spoiler: it worked perfectly on my server via shell), but when I tried to implement this code into my Django code, it failed just like Django send_mail() function:
here is the code:
import smtplib
def send_email(user, pwd, recipient, subject, body):
FROM = user
TO = recipient if isinstance(recipient, list) else [recipient]
SUBJECT = subject
TEXT = body
message = """From: %s\nTo: %s\nSubject: %s\n\n%s""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
print(message)
try:
server_ssl = smtplib.SMTP_SSL("smtp.beget.com", 465)
server_ssl.ehlo()
server_ssl.login(user, pwd)
server_ssl.sendmail(FROM, TO, message)
server_ssl.close()
print('successfully sent the mail')
except:
print("failed to send mail")
usn='sender#email.com'
pwd='MyVerySecretPassword'
rc=['reciever#email.com']
subj='HoHoHo'
body='Hello, world'
send_email(usn,pwd,rc,subj,body)
I checked all the variables (rendered them on the screen) which I tried to send via e-mail, all of them are correct.
Sorry, I am not interested in third party projects like Sendgrid. I just want to understand what I am doing wrong.
Hope someone could help me to find the bug. Thank you very much!
I have found the solution. Thank to Solarissmoke for answering to my question.
The real thing was in fact that my hosting provider blocked outgoing traffic. So the best solution is to user third-party mail delivery provider like Google or Sendinblue. After I changed my settings, everything worked.
Hope my post could help anyone.
I am deploying my django site soon!! In debug=True mode, there is an error page that comes up when there is some bug in the code.
When in debug=False mode, after I deploy, I want to set up something so that I am alerted whenever anyone on the prod site reaches this page. Is there any way to do this? Thanks!
This setup would send an email after someone make a request. Here is the documention on sending emails through Django. https://docs.djangoproject.com/en/3.0/topics/email/
def home_page(request):
send_mail(
'Site Visitor',
'someone visted the site.',
'from#example.com',
['to#example.com'],
fail_silently=False,
)
return render(request, 'template')
For an "error alert system," you can look into Sentry. https://sentry.io/for/django/
In my settings I have this...
ADMINS = (
('Me', 'me#me.com'),
)
MANAGERS = ADMINS
DEBUG = False
ALLOWED_HOSTS = ['*']
and then in my views/urls I have these...
url(r'^test/$', 'main.views.test', name='page'),
def test(request):
return render(request, '500.html', status=500)
I have the email settings configured and I know they work because I have emails working from that server in other parts of my site. I have everything that is said to be required in the docs, but it is still not working and IDK where to go from here. I have tried it in my live environment too with no luck...
It turns out that my email settings were correct, but there was a new setting added for error reporting titled 'SERVER_EMAIL' that was supposed to be the default from email. I had a nonexistant email address in there and that is what was causing the emails to not be sent.
I am trying to send account activation link in my Django project, but it cannot work. So I try the very basic send_mail() function in shell and see if it is sending.
in the settin.py
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend', # necessary for django.auth
'survey.modelbackend.EmailBackend' # custom backend to authenticate using the email field
)
#settings for the email
EMAIL_HOST = 'localhost'
EMAIL_PORT = 25
DEFAULT_FROM_EMAIL = 'webmaster#localhost'
(I am using all the default values in the settings for email)
in the shell I typed
>>> from django.core.mail import send_mail
>>> send_mail('Subject here', 'Here is the message.', 'from#example.com',
... ['myemailaddress#gmail.com'], fail_silently=False)
and it return 1 after the above line, but I cannot get the email in my own email
Can anyone help with this problem and explain why the email is not sent to my email?
Thank you very much.
I'm going to go ahead and say that the mail is probably being sent, but it is hitting your spam filter.
Unless you have something other than django.core.mail.backends.smtp.EmailBackend set as your settings.EMAIL_BACKEND, you will only get a return of True (or 1) if the backend has successfully connected to the server and told the server to send the message. If fail_silently=False, that means that send_mail will either return True or raise an exception. This means that the error either lies in your SMTP or it is being sent directly to "spam".
But, in the off chance that you have already checked spam, there are ways to make an SMTP server fail silently. Check out this article for Sendmail (one of the most common *nix applications), or this one for Mercury (one of the SMTP servers available for Windows). If you're using IIS, this site looks like it addresses some potential issues.
Hy, I've tried asking and this can successfully send email without any setting in the settings.py
first, add these two imports
import smtplib
from email.mime.text import MIMEText as text
then the code to send email could be like this
def send_email(sender,receiver,message,subject):
sender = sender
receivers = receiver
m = text(message)
m['Subject'] = subject
m['From'] = sender
m['To'] = receiver
# message = message
try:
smtpObj = smtplib.SMTP('localhost')
smtpObj.sendmail(sender, receivers, str(m))
print "Successfully sent email"
except SMTPException:
print "Error: unable to send email"
This works just as expected.