Django is not sending e-mails - django

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.

Related

SMTPServerDisconnected when sending email from a Django App on Heroku with Mailgun

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.

I get this django error 421, b'service not available (connection refused, too many connections when signing up for my account, i dont really know?

SMTPConnectError at /investor/signup
(421, b'service not available (connection refused, too many connections)')
This Error has been delaying for days now, i'm really stuck while sending email with django and i'm a beginner in django that why i do not have many idea on how to solve this issue please can anyone help?
Setting.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'xxxxxxxxxxxxxxxx#gmail.com'
EMAIL_HOST_PASSWORD = 'xxxxxxxxxxxxxxxxxxxx'
EMAIL_USE_TLS = True
I don't know if you've found the solution to this bug but coincidentally, I encountered the same issue recently... Here is the solution that worked for me. My assumption is that you already know how to generate secret password from gmail smpt.
I tried this using the EmailMessage class and the send_mail function. Both worked perfectly.
I'll share portions of both my settings.py and views.py files.Hope it works for you too... cheers!
settings.py
# smtp configuration
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'xxxxxxxxxx#gmail.com'
EMAIL_HOST_PASSWORD = 'xxxxxxxxxxxxxxxx'
EMAIL_USE_TLS = True
views.py
# user activation
current_site = get_current_site(request)
email_subject = 'Please activate your account',
message = render_to_string('accounts/account_verification_email.html', {
'user': user,
'domain': current_site,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': default_token_generator.make_token(user)
})
from_email = settings.EMAIL_HOST_USER
recipient = [email]
send_email = EmailMessage( email_subject, message, from_email, recipient)
send_email.send(fail_silently=False)
Alternate method using send_mail function:
subject = 'This is a mail from IfeCog'
message = f'hi {firstname}, this mail is about your registration'
from_email = settings.EMAIL_HOST_USER
recipient_list = [email]
send_mail(subject, message, from_email, recipient_list, fail_silently=False)
Have you tried enabling 'Less secure app access' , go to your gmail host 'manage account' -> 'security', make sure you have 'Less secure app access' enabled.
To Fix this issue, the easiest way to is use to SendGrid as thier server doesn't throw all the regular error gmail Simple Mail Transfer Protocol Throws. To get started using SendGrid in django, this is the best tutorial Article 1 and Official SendGrid X Django Docs

Could not send email in django rest framework

I am developing password reset part of the project. I am using django_rest_passwordreset to get the password reset. I am using mailjet smtp. I could not send the email to the user.
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'in-v3.mailjet.com'
# EMAIL_PORT = 465
EMAIL_PORT = 587
EMAIL_USE_TLS = True
# EMAIL_USE_SSL = True
EMAIL_HOST_USER = '5e4329460b3c88f1d24d19c3e7374548aa213da%asasd1asd'
EMAIL_HOST_PASSWORD = 'a6c5ab2515d6ae761253a396453530ba$42asasdasdaasdasd'
If I change the EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' to the EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' it is printing it to the console. I have no idea why it is not working.
the part of the code where I am trying to send an email.
#receiver(reset_password_token_created)
def password_reset_token_created(sender, instance, reset_password_token, *args, **kwargs):
# send an e-mail to the user
context = {
'current_user': reset_password_token.user,
'username': reset_password_token.user.firstname,
'email': reset_password_token.user.email,
'reset_password_url': "{}?token={}".format(reverse('password_reset:reset-password-request'), reset_password_token.key)
}
# just checking if it works
send_mail('Hello from something', 'hello there', 'abdukhashimov#yandex.ru',
[reset_password_token.user.email, ], fail_silently=False)
# render email text
email_html_message = render_to_string('user_reset_password.html', context)
email_plaintext_message = render_to_string(
'user_reset_password.txt', context)
msg = EmailMultiAlternatives(
# title:
"Password Reset for {title}".format(title="Some website title"),
# message:
email_plaintext_message,
# from:
"noreply#somehost.local",
# to:
[reset_password_token.user.email]
)
msg.attach_alternative(email_html_message, "text/html")
msg.send()
I came up with a different solution. I used the google smtp service. I have followed the steps from this kinsta.com - steps to setup up google smtp.
Step1: The very first thing you will need to do is ensure that you have 2-step verification enabled on your primary Gmail account. Important: If you don’t do this you will get an invalid password error further below when trying to authenticate your email address. So first go and enable 2-step verification.
Step2: Next, you will need to generate an App password. You then use the app password in place of your personal Gmail password further below. This is the only way this process will work.
Step3: Now back in Gmail, go to settings, and can click on “Accounts and Import.” Then click on “Add another email address you own.”. Basically to the gmail and sign in with your account and go to the settings.
Step4: Enter your additional business name and business email that is on the custom domain.
(Extra Info). I usually use yandex mail and added it then it generated the followings.
Step5: It will then send an email confirmation code to the email you just added. You will need to click the link in the email to confirm it or manually enter the code (this proves that you are in fact the owner of the additional email account). And that’s it!
From my experience, you might need to tweak some settings from google if it did not work for you. For example, I read from other source, you might need to allow less secure apps from google. I have not done it as I was using yandex mail, I guess.
In case if you are not sure what to put in settings.py
EMAIL_HOST = 'smtp.yandex.ru' # in my case
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'added account'
EMAIL_HOST_PASSWORD = 'your password'
Credits to kinsta.com

'from_email' not showing with 'send_mail' smtp

I have set up smtp with gmail. When I use send_mail the from email is not showing up in the account receiving the email.
Django settings.py
# DEFAULT_FROM_EMAIL = 'sendTo#gmail.com'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'sendTo#gmail.com'
EMAIL_HOST_PASSWORD = '**********'
EMAIL_USE_TLS = True
Using
$ python manage.py shell
I send the mail as follows,
>>> from django.core.mail import send_mail
>>> send_mail('subject is', 'message is and is not 12342', 'fromEmail#gmail.com', ['sendTo#gmail.com'])
1
>>>
I am receiving this email in my gmail account, (which is the same gmail account used for the smtp), but the from email is showing up as the sendTo#gmail.com and should be fromEmail#gmail.com
When you send emails through google's SMTP servers you cannot change the from email field. It uses the same address that you provided for authentication.
If you want to change it you have to use either your own mail server or one of the numerous mail apis/servers available. Sendgrid, MailGun etc come to mind.
I solved the problem using this view:
def contact(request):
form = ContactForm(data=request.POST or None)
if form.is_valid():
subject = form.cleaned_data['sujet']
message = form.cleaned_data['message']
sender = form.cleaned_data['envoyeur']
msg_mail = str(message) + " " + str(sender)
send_mail(sujet, msg_mail, sender, ['corbin.julien#gmail.com'], fail_silently=False)
return render(request, 'blog/contact.html', locals())
I actually append the email of the sender to the message. You could even remove the sender argument from send_mail. You just have to make your EmailField mandatory to make sure you'll get the sender's email address.

Sending email on Heroku with the Django application Spirit

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.