Send email to address getting from HTML input via Django - python

I'm searching for solution to this problem for many hours but can't find anything related. I want to get user's email from input and send mail from admin to that email address. Here are my codes:
views.py:
def index(request):
context = {
'questions': Question.objects.all(),
'applicants': Applicant.objects.filter(status=1),
'empty_cards': range(4 - Applicant.objects.filter(status=1).count())
}
if request.method == "POST":
if request.POST.get('message_text'):
Message.objects.create(
sender_name = request.POST.get('sender_name'),
sender_email = request.POST.get('sender_email'),
message_text = request.POST.get('message_text'))
if request.method == 'POST':
subject = 'Welcome !'
message = 'We will back to you.'
from_email = settings.EMAIL_HOST_USER
recipient_list = 'don't know how to get email'
send_mail(subject, message, from_email, recipient_list)
return render(request, 'index.html', context)

from your code I assume that you already have access to the user's mail
inside the request.
so you can try this:
sender_email = sender_request.POST.get('sender_email')
recipient_list = [sender_email]

Related

How to merge a function into another

Sorry for asking a basic thing. new to Python and Django ,
I want to resend email if the OTP from PUT request is incorrect.
I have a function which send email with otp automatically on Register.
But if user PUT incorrect OTP I want to resend that email with new otp, So I want to merge sent_email_otp into verifyEmail function.
So how could I achieve that?
#receiver(post_save, sender=CustomUser)
def send_email_otp(sender, instance, created, **kwargs):
if created:
try:
subject = "Your email needs to be verified to use site"
message = f'Hi, Dear {instance.name} use this following OTP to Get verified your email : OTP({instance.otpForEmail})'
email_from = settings.EMAIL_HOST_USER
recipient_list = [instance.email]
send_mail(subject, message, email_from, recipient_list)
print(f"Email Sent to {instance.email}")
except Exception as e:
print(e)
print("Something Wrong at send_email_otp")
#api_view(['PUT'])
#permission_classes([IsAuthenticated])
def verifyEmail(request, pk):
user = CustomUser.objects.get(id=pk)
data = request.data
otp_to_verify = data['otpForEmail']
if otp_to_verify == user.otpForEmail:
user.isEmailVerified = True
user.save()
message = {'detail': 'Your email is now verified'}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
else:
message = {
'detail': 'OTP is not valid and expired, Use New OTP which we have sent you on the email'}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
Edit:
If I simply call the send_email_otp() inside else statement of verifyEmail then this error comes :
TypeError: send_email_otp() missing 3 required positional arguments: 'sender', 'instance', and 'created'
You cant call the signal directly unless you provide it the expected input.
You will need to create another function for sending the otp. and call it in the post_save signal and in the view
def send_otp(name, email, otpForEmail):
subject = "Your email needs to be verified to use site"
message = f'Hi, Dear {name} use this following OTP to Get verified your email : OTP({otpForEmail})'
email_from = settings.EMAIL_HOST_USER
recipient_list = [email]
send_mail(subject, message, email_from, recipient_list)
print(f"Email Sent to {email}")
#receiver(post_save, sender=CustomUser)
def send_email_otp_on_post_save(sender, instance, created, **kwargs):
if created:
try:
send_otp(instance.name, instance.email, instance.otpForMail)
except Exception as e:
print(e)
print("Something Wrong at send_email_otp")
#api_view(['PUT'])
#permission_classes([IsAuthenticated])
def verifyEmail(request, pk):
user = CustomUser.objects.get(id=pk)
data = request.data
otp_to_verify = data['otpForEmail']
if otp_to_verify == user.otpForEmail:
user.isEmailVerified = True
user.save()
message = {'detail': 'Your email is now verified'}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
else:
message = {
'detail': 'OTP is not valid and expired, Use New OTP which we have sent you on the email'}
send_otp(user.name, user.email, user.otpForEmail)
return Response(message, status=status.HTTP_400_BAD_REQUEST)
It would be hard for you to configure the same function to send_mail again to send OTP, as you said this sends the email when the user gets registered. So why not modify the verifyEmail itself.
First, you don't need a user instance here as the user is already authenticated and you already have the User Id.
So in the else statement of verifyEmail, you can send_email without calling send_email_otp() function.
Update the verifyEmail to.
#api_view(['PUT'])
#permission_classes([IsAuthenticated])
def verifyEmail(request, pk):
user = CustomUser.objects.get(id=pk)
data = request.data
otp_to_verify = data['otpForEmail']
if otp_to_verify == user.otpForEmail:
user.isEmailVerified = True
user.save()
message = {'detail': 'Your email is now verified'}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
else:
subject = "Your email needs to be verified to use site "
message = f'Hi, Dear {user.name} use this following OTP to Get verified your email : OTP({user.otpForEmail})'
email_from = settings.EMAIL_HOST_USER
recipient_list = [user.email]
send_mail(subject, message, email_from, recipient_list)
print(f"Email Sent to {user.email}")
message = {
'detail': 'OTP is not valid and expired, Use New OTP which we have sent you on the email'}
return Response(message, status=status.HTTP_400_BAD_REQUEST)

Django - how to get email links to work on mobile?

My Django site sends out an email confirmation link, and everything seems to work fine on desktop. On mobile devices, however, the link text is highlighted blue and underlined (i.e. it looks like a link) but nothing happens when the user clicks it. It should open a browser tab and say, "you have confirmed your email, etc"
Thanks for any tips!
views.py:
def signup(request):
if request.method == 'POST':
#send signup form
email_address = request.POST['email']
if request.POST['password1'] == request.POST['password2']:
try:
user = User.objects.get(email=email_address)
return render(request, 'accounts/signup.html', {'error': "Email already in use."})
except User.DoesNotExist:
user = User.objects.create_user(request.POST['email'], password=request.POST['password1'])
#auth.login(request, user)
#send email confirmation link then redirect:
#user = User.objects.get(email=email_address)
current_site = get_current_site(request)
mail_subject = 'Welcome to My Site'
plain_msg = 'Thank you for signing up to My Site! Click this link to activate your account:\n\n'+current_site.domain+'/accounts/activated/'+urlsafe_base64_encode(force_bytes(user.pk)).decode()+'/'+account_activation_token.make_token(user)+'/'
msg = '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>title</title></head><body>Confirm your email address to continue:<br/>Confirm my email address</body></html>'
print(msg)
send_mail(mail_subject, plain_msg, 'my_email#gmail.com', [email_address], html_message=msg)
return render(request, 'accounts/activation-link-sent.html', {'email': email_address})
#truncated for Stack Overflow post
You should use build_absolute_uri to create fully qualified links that include the current domain and protocol, then use this link in your email
link = request.build_absolute_uri('/accounts/activated/'+urlsafe_base64_encode(force_bytes(user.pk)).decode()+'/'+account_activation_token.make_token(user)+'/')
Do you have a url pattern that matches this URL? You should consider using reverse for building URLs
path = reverse('activate', kwargs={
'pk': user.pk,
'token': account_activation_token.make_token(user)
})
link = request.build_absolute_uri(path)

Django restframe work send email from posted data

I'm using Django rest framework, I have a contact us table.. in views, I use class based view i want to send email when user post data .. this's my function
def post(self, request):
return self.create(request)
return send_email(request)
def send_email(request):
if request.method == 'POST':
subject = request.POST.get('subject', '')
message = request.POST.get('message', '')
from_email = request.POST.get('email', '')
send_mail(subject, message, from_email, ['haguwanax#l0real.net'], fail_silently=False)
return Response (status=status.HTTP_200_OK)
it saves the data but there's nothing being sent.
this's my settings.py
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
EMAIL_PORT = 587
EMAIL_HOST_USER = '*****#gmail.com'
EMAIL_HOST_PASSWORD = '*******'
EMAIL_USE_TLS = True
You can not use two return at a time in a same block of code. Your second return statement will not execute.
I don't think your create method need return something. It's just storing some values.
And your send email might return true or false if email send is successful or not
Please use only one return statement in your post function.
You can rewrite the code following:
def post(self, request):
self.create(request)
check_mail=send_email(request)
if check_mail:
return Response (status=status.HTTP_200_OK)
def send_email(request):
if request.method == 'POST':
subject = request.POST.get('subject', '')
message = request.POST.get('message', '')
from_email = request.POST.get('email', '')
send_mail(subject, message, from_email, ['haguwanax#l0real.net'],
fail_silently=False)
return True
The send_email function is not being called because you're calling it after return self.create(request). Your code for send_email is hence unreachable.
Please use only one return statement in your post function.
You can call email method without the return statement and then call return self.create(request)
send_email(request)
return self.create(request)

Django from_email defaulting to recipient

Im using Django, anymail API & mailgun to send emails from my site.
I have a form where users can subscribe,
At present when the email is send to the subscriber's email address, the FROM address default to a combination of their and my email domain.
As an exmample:
User enters test#test.com an receives email from test=test.com#mail.mydomain.com and not the one I specified of info#mydomain.com
I am pretty sure the problem is within my views.py, but im not sure how to resolve.
views.py
def send_email(subject, html_content, text_content=None, from_email=None, recipients=[], attachments=[], bcc=[], cc=[]):
# send email to user with attachment
if not from_email:
from_email = settings.DEFAULT_FROM_EMAIL
if not text_content:
text_content = ''
email = EmailMultiAlternatives(
subject, text_content, from_email, recipients, bcc=bcc, cc=cc
)
email.attach_alternative(html_content, "text/html")
for attachment in attachments:
# Example: email.attach('design.png', img_data, 'image/png')
email.attach(*attachment)
email.send()
def send_mass_mail(data_list):
for data in data_list:
template = data.pop('template')
context = data.pop('context')
html_content = get_rendered_html(template, context)
data.update({'html_content': html_content})
send_email(**data)
# Contact Form - home.html
def HomePage(request, template='home.html'):
form = ContactForm(request.POST or None)
if form.is_valid():
from_email = form.cleaned_data['from_email']
# Create message1 to send to poster
message1 = {
'subject': 'Test',
'from_email': from_email,
'recipients': [from_email],
'template': "marketing/welcome.html",
'context': {
"from_email": from_email,
}
}
# Create message1 to send to website admin
message2 = {
'subject': 'Test - Contact',
'from_email': from_email,
'recipients': ['info#mydomain.com'],
'template': "marketing/admin.html",
'context': {
"from_email": from_email,
}
}
try:
send_mass_mail([message1, message2])
except BadHeaderError:
return HttpResponse('Invalid header found.')
return redirect('/thanks/')
context = {
"form": form,
}
return render(request, template, context)
It looks as if you are using the from_email from the user, not info#mydomain.com. In two places you have:
'from_email': from_email,
Many mail providers will limit the addresses that you can send mail from (to stop you sending spam using someone else's address.
Therefore you can't use a from_email that the user gives you. The usual approach is to use your own address as the from_email, but set a reply-to header so that any replies go to the address that the user specified.

How can my user upload an image to email to me [Django]

I've got a simple website for a Screenprinting company built using Django 1.10 and Python 3.5.2, but I am having issues with my "Get a Quote" page.
The idea is a user can go to www.example.com/quote/ and they are presented with a form. Here they put in their Name, Email Address, a Brief Message, and most importantly they can upload an image.
When they click submit, this data gets sent to my email address as an email using the EmailMessage method. I have set up a simple email form plenty of times in the past so I know my settings.py file is fine.
Here is my forms.py:
class QuoteForm(forms.Form):
name = forms.CharField(required=True)
from_email = forms.EmailField(required=True)
subject = "Quote"
uploaded_image = forms.ImageField()
message = forms.CharField(widget=forms.Textarea)
Here is my views.py:
def quote(request):
form = QuoteForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
from_email = form.cleaned_data['from_email']
message = form.cleaned_data['message']
message = "From: " + name + "\n" + "Return Email: " + from_email + "\n" + "Subject: " + subject + "\n" + "Message: " + message
uploaded_image = form.cleaned_data['uploaded_image']
msg = EmailMessage(subject, message, from_email, ['example#email.com'], reply_to=[from_email])
msg.attach_file(uploaded_image)
try:
msg.send()
except BadHeaderError:
return HttpResponse('Invalid header found')
return HttpResponseRedirect('thankyou')
return render(request, "quote.html", {'form': form})
When I test this on 127.0.0.1 I click submit and the form refreshes with the same info, except the image is no longer there.
Also, When I test it using the console.EmailBackend there are no errors. In fact, clicking submit doesn't seem to have any effect other than it reloads a few css files.
Any ideas?
A file is not in the request.POST attribute, it is in request.FILES. Your views.py should look like this:
def quote(request):
form = QuoteForm(request.POST, request.FILES)
if form.is_valid():
...
uploaded_image = request.FILES.getlist('uploaded_image')
...
Please note that this is a raw draft. I haven't tested it. Also note that you might have to sanitize the file for your own safety. For example: checking on the maximum filesize and contenttype.
More information about all of this: https://docs.djangoproject.com/en/1.10/topics/http/file-uploads/

Categories

Resources