I am trying to send email via Django Rest framework application. The mail should be sent to the user who would register to our system using Gmail.
I am also using docker images python:3.7-slim and MySql:5.6
First I have created email configurations inside the Django project setting.py file as stated below.
# Email Settings.
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 456
EMAIL_HOST_USER = 'steinnlabs#gmail.com'
EMAIL_HOST_PASSWORD = '*****'
EMAIL_USE_TLS = 1
EMAIL_USE_SSL = 0
This is how view.py file of application looks like.
from __future__ import unicode_literals
from django.shortcuts import render
from . import views
from rest_framework.views import APIView
from django.db import IntegrityError
from rest_framework import status
from . import models, serializers
from rest_framework.response import Response
from django.core.mail import send_mail
class UserAPIViews(APIView):
"""
"""
def post(self, request, format=None):
"""
"""
print(request.data)
serialized_data = serializers.UserSerializer(data=request.data)
if serialized_data.is_valid():
try:
user_id = serialized_data.save()
except IntegrityError as error:
message = f"Email already exist."
return Response ({
'error_message' : message,
'status' : status.HTTP_226_IM_USED
})
subject = 'Eitan - Case Manager Account Credentials'
body = f"Hi {serialized_data.validated_data.get('first_name')} Your case manager account is ready. Please use following credentials to login. Email - {serialized_data.validated_data.get('email')}, Password - {serialized_data.validated_data.get('password')} Thank You! Team Eitan."
sender = "steinnlabs#gmail.com"
to = serialized_data.validated_data.get('email')
send_mail(subject, body, sender, [to], fail_silently=False)
success_message = f"User has been created."
return Response({
'success_message' : success_message,
'status' : status.HTTP_201_CREATED
})
else:
return Response (serialized_data.error_messages)
I don't understand what is wrong with my configuration. Whenever I call this API user is created but send_mail() functions fails with an error.
OSError at /user/create/
[Errno 99] Cannot assign requested address
It might be a connection issue related to Docker based on this question.
Check that smtp.gmail.com:587 is open to connection from your docker container.
I was using incorrect EMAIL_PORT i.e 456 in setting.py file. Gmail's EMAIL_PORT is 587. It works fine for me now.
Related
I just started using python and django , I'm trying to send an email from a page directy to my email but the moment i send it the page gives me this error "SMTPAuthenticationError" , i already Less secure apps and disable captcha code
this is how i configured my setting
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = '587'
EMAIL_HOST_USER = 'mymail#gmail.com'
EMAIL_HOST_PASSWORD = 'mypassword'
EMAIL_USE_TLS = True
and this is the function i coded in the views file
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.views import View
from django.core.mail import send_mail
from TatooPage.models import UserRequest
def email_request(request):
name = request.POST['name']
email = request.POST['email']
message = request.POST['message']
send_mail(
'Message from' + name,
message,
email,
['mymail#gmail.com'],
)
user_details = UserRequest(
name=name,
email=email,
message=message
)
user_details.save()
return HttpResponseRedirect('/contact-us/')
Don't know if there would be anything else i should add .
Nvm I found the problem just had to add this line in the setting , leaving this here in case someone else has the same problem :P
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
I'm working on a project hosted on Google App Engine, and using Django-allauth for my user system.
Right now I'm just using the following setup in settings.py
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = DEFAULT_FROM_EMAIL = 'myMail#gmail.com'
EMAIL_HOST_PASSWORD = 'password'
But I would like to use GAE's Mail API instead, so that I can take use of all the quotas available.
To send an email with GAE's API I can do as follows:
sender_address = "myMail#gmail.com"
subject = "Subject"
body = "Body."
user_address = "user#gmail.com"
mail.send_mail(sender_address, user_address, subject, body)
As I understand it from the allauth documentation, I can "hook up your own custom mechanism by overriding the send_mail method of the account adapter (allauth.account.adapter.DefaultAccountAdapter)."
But I'm really confusing about how to go about doing this.
Does it matter where I place the overridden function?
Any additional tips would be greatly appreciated.
My Solution
What I did to get Django-allauth email system to work with Google App Engine mail API
Created a file auth.py in my 'Home' app:
from allauth.account.adapter import DefaultAccountAdapter
from google.appengine.api import mail
class MyAccountAdapter(DefaultAccountAdapter):
def send_mail(self, template_prefix, email, context):
msg = self.render_mail(template_prefix, email, context)
sender_address = "myEmailAddress#gmail.com"
subject = msg.subject
body = msg.body
user_address = email
mail.send_mail(sender_address, user_address, subject, body)
In order to use your email as sender with GAE's mail API, it is important to remember to authorize the email as a sender
Lastly, as e4c5 pointed out, allauth has to know that this override exists, which is done as so in settings.py
ACCOUNT_ADAPTER = 'home.auth.MyAccountAdapter'
You have to tell django-allauth about your custom adapter by adding the following line to settings.py
ACCOUNT_ADAPTER = 'my_app.MyAccountAdapter'
taking care to replace my_app with the correct name
Currently I have a working implementation of sending emails with Amazon SES in Django.
My setup looks like this. In settings.py I have:
EMAIL_HOST = 'email-smtp....'
EMAIL_PORT = 25
EMAIL_HOST_USER = 'my-email-host-user'
EMAIL_HOST_PASSWORD = 'my-email-host-password'
EMAIL_USE_TLS = True
In my view I have:
from django.shortcuts import render
from django.http import HttpResponse
from django.conf import settings
from django.contrib import messages
from django.core.mail import send_mail
from django.core.mail import EmailMessage
def index(request):
email_message = EmailMessage('This is a title', 'This is a message body', 'FromEmail#example.com', ['ToEmail#example.com'])
email_message.send()
return HttpResponse("You just sent an email message.")
When I open the message I get this in the header:
FromEmail#example.com via amazonses.com
I would like to customize this so that I can do something like this:
UserFirstName UserLastName via amazonses.com
How would I go about doing this?
I doubt that you can, but you should be able to use from addresses like this:
email_message = EmailMessage('This is a title', 'This is a message body', 'UserFirstName UserLastName <FromEmail#example.com>', ['ToEmail#example.com'])
which should result in email clients displaying the from address like this:
UserFirstName UserLastName <FromEmail#example.com>
I use this settings to send email:
settings.py
EMAIL_HOST = "mail.xxxxxx.ir"
EMAIL_PORT = "25"
EMAIL_HOST_USER = "xxxxx#xxx.ir"
EMAIL_HOST_PASSWORD = "xxxxxxxx"
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
DEFAULT_FROM_EMAIL = 'xxxxx#xxx.ir'
and in python shell:
from django.core.mail import send_mail
send_mail('test', 'hello', 'xxxxx#xxx.ir', ['myEmail#gmail.com'])
And its successfully sent But when i use that two line code in view, i got this error:
gaierror at /userforget/
[Errno -3] Temporary failure in name resolution
Please help me.
Update:
this is my view code:
def userforget(request):
from django.core.mail import send_mail
send_mail('test', 'hello', 'xxxxxx#xxxx.ir', ['myEmail#gmail.com'])
t = get_template('Finalauth/login.html')
html = t.render(Context({"userbody" : "<p>Email sent.</p>"}))
return HttpResponse(html)
I run your code and find there is no error except
t = get_template('Finalauth/login.html')
I mean, maybe, send_email is OK, however get_template is nor correct.
Then, please check the file 'Finalauth/login.html' and import for get_template, Context and HttpResponse.
I use the IP rather than the name for EMAIL_HOST and its worked and its probably DNS problem for me.
I am having difficulties in configuring my settings.py so that I can send email from a webserver with any sender name
This is what I have done:
EMAIL_USE_TLS = True
EMAIL_HOST = 'mail.wservices.ch'
HOSTNAME = 'localhost'
DEFAULT_FROM_EMAIL = 'info#domain.com'
And sending email like this:
html_content = render_to_string('htmlmail.html', {})
text_content = strip_tags(html_content)
msg = EmailMultiAlternatives('subject!',text_content,'info#domain.com',['to#domain.com'])
msg.attach_alternative(html_content, "text/html")
msg.send()
But I am getting:
{('to#domain.com': (554, '5.7.1 <to#domain.com>: Relay access denied')}
In one function, I have two msg.send() calls, BTW.
What am I doing wrong?
this is the answer webmaster when i asked how to send mails from webserver programmatically:
It is possible to send mails from E-Mail-Server "mail.wservices.ch".I suggest to
use the local installed Mail-Server. Hostname: localhost
There you can set any sender name, they just have to exist.
https://docs.djangoproject.com/en/dev/ref/settings/#default-from-email
Make sure first you have properly install django-sendmail
$ sudo apt-get install sendmail
in the settings.py :
from django.core.mail import send_mail
DEFAULT_FROM_EMAIL='webmaster#localhost'
SERVER_EMAIL='root#localhost'
EMAIL_HOST = 'localhost'
EMAIL_HOST_USER=''
EMAIL_BACKEND ='django.core.mail.backends.smtp.EmailBackend'
EMAIL_PORT = 25 #587
EMAIL_USE_TLS = False
in views.py:
from project.apps.contact import ContactForm
def contactnote(request):
if request.method=='POST':
form =ContactForm(request.POST)
if form.is_valid():
topic=form.cleaned_data['topic']
message=form.cleaned_data['message']
sender=form.cleaned_data.get('sender','email_address')
send_mail(
topic,
message,
sender,
['myaddress#gmail.com'],fail_silently=False
)
#return HttpResponseRedirect(reverse('games.views.thanks', {},RequestContext(request)))
return render_to_response('contact/thanks.html', {},RequestContext(request)) #good for the reverse method
else:
form=ContactForm()
return render_to_response('contact.html',{'form':form},RequestContext(request))
contact.py:
from django import forms as forms
from django.forms import Form
TOPIC_CHOICES=(
('general', 'General enquiry'),
('Gamebling problem','Gamebling problem'),
('suggestion','Suggestion'),
)
class ContactForm(forms.Form):
topic=forms.ChoiceField(choices=TOPIC_CHOICES)
sender=forms.EmailField(required=False)
message=forms.CharField(widget=forms.Textarea)
#the widget here would specify a form with a comment that uses a larger Textarea widget, rather than the default TextInput widget.
def clean_message(self):
message=self.cleaned_data.get('message','')
num_words=len(message.split())
if num_words <4:
raise forms.ValidationError("Not enough words!")
return message
Try it , this is a whole working example apps, modify it
to be send to to mailserver like a reply when it got an mail, very simple to modify it