Django send mail back to the user who sends in form - django

I have a contactform on my site.
When submitted a mail is sent to me. But I also want to send the user a mail, letting the user know that I have received the form submission.
When I try to put the email value as a recipient, I get this error: AssertionError: "to" argument must be a list or tuple
Anyone see what is wrong with my code?
def show_contactform(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
f = ContactForm(request.POST)
f.save()
email = form.cleaned_data['email']
subject = "New contact from website"
recipients = ['contact#company.com']
rendered = render_to_string('forms/email_body.html', {'form':form)
to_user_subject = "Contact registred"
to_user_rendered = render_to_string('form/to_user_email_contact.html', {'form_headline':subject})
#Send content to celery worker for asynchronous mail outbox - sending to company
tasks.send_email.delay(subject=subject, rendered=rendered, email=email, recipients=recipients)
#Send content to celery worker for asynchronous mail outbox - sending to the user who sent the form
tasks.send_email.delay(subject=to_user_subject, rendered=to_user_rendered, email=recipients, recipients=email)
return HttpResponseRedirect('/form/contact/success/')
else:
form = ContactForm() # An unbound form
return render(request, 'contact/form.html', {
'form': form,
})
#task()
def send_email(subject, rendered, email, recipients):
msg = EmailMultiAlternatives(subject, rendered, email, recipients)
msg.attach_alternative(rendered, "text/html")
msg.send()

Related

why does Django returns BadHeaderError when adding a new line in my 'Contact' page's 'message' field

Everything works except when I add a new line via 'enter' in the "Message" field. It goes through if I don't add new lines in the message textfield.
What am i missing here? Tried to solve this problem for 2 days, nothing similar on google.
I feel like there could be the problem of my views.py config:
def success(request):
return render(request, 'home/success.html')
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# send email code goes here
sender_name = form.cleaned_data['name']
sender_email = form.cleaned_data['email']
sender_phone = form.cleaned_data['phone']
sender_message = form.cleaned_data['message']
subject = "Enquiry: {0}".format(sender_message[:50])
message = "New message from {0}\n phone number: {1}\n email: {2}\n\n{3}".format(sender_name, sender_phone, sender_email, sender_message)
recipients = ['john.smith#gmail.com']
sender = "{0}<{1}>".format(sender_name, sender_email)
try:
send_mail(subject, message, sender, recipients, fail_silently=False)
except BadHeaderError:
return HttpResponse('Invalid header found')
return HttpResponseRedirect('success')
else:
form = ContactForm()
return render(request, 'home/contact.html', {'form': form})
Any ideas?
As described in the documentation, a BadHeaderError is raised to "protect against header injection by forbidding newlines in header values".
Since you're copying part of sender_message directly into the subject header, you may be including newlines as well. The simple solution is to strip them out first.
sender_message = form.cleaned_data['message']
clean_message = sender_message.replace('\n', '').replace('\r', '')
subject = "Enquiry: {0}".format(clean_message[:50])

Django: send emails to users

I have a list of users with their email adress (only for Staff members), I am trying to send a form to the user.
When I use i.email, I get this error: "to" argument must be a list or tuple
When I use ['i.email'] I don't receive the message.
urls.py
path('users/<int:id>/contact', views.contactUser, name='contact_user'),
views.py
def contactUser(request, id):
i = User.objects.get(id=id)
if request.method == 'POST':
form = ContactUserForm(request.POST)
if form.is_valid():
message = form.cleaned_data['message']
send_mail('Website administration', message, ['website#gmail.com'], ['i.email'])
return redirect('accounts:users')
else:
form = ContactUserForm()
return render(request, 'accounts/contact_user.html', {'form': form, 'username': i})
I am using SendGrid. I have a 'contact us' form which is similar to contactUser and it works fine.
['i.email'] should be [i.email]

Django: How can I send an email with a description that includes all inputs from a contact form?

I have a Django-built website which sends an email to a certain employee after a contact form is submitted. The relevant code in my views.py file that does this is as follows:
def quote_req(request):
submitted = False
if request.method == 'POST':
form = QuoteForm(request.POST, request.FILES)
description = request.POST['company']
if form.is_valid():
form.save()
# assert false
send_mail('Contact Form', description, settings.EMAIL_HOST_USER, ['sample#gmail.com'], fail_silently=False)
return HttpResponseRedirect('/quote/?submitted=True')
else:
form = QuoteForm()
if 'submitted' in request.GET:
submitted = True
return render(request, 'quotes/quote.html', {'form': form, 'page_list': Page.objects.all(), 'submitted': submitted})
The website successfully sends the email; however, at the moment I am limited to sending only one input from the contact form (in this case, 'company') for the email description (which is utilized in the send_mail command).
Does anyone know if I can modify the request.POST command or use another type of method to send more than one contact form input for the email description (i.e., 'company', 'phone', 'address', etc.)?
You can assign all the variables company, phone, address separately then concatenate them as description.
then email description.
See example below:
if request.method == 'POST':
form = QuoteForm(request.POST, request.FILES)
company = request.POST['company']
phone = request.POST['phone']
address = request.POST['company']
description = str(company) + ' '+ str(phone) + ' '+ str(address)
if form.is_valid():
form.save()
# assert false
send_mail('Contact Form', description, settings.EMAIL_HOST_USER, ['sample#gmail.com'], fail_silently=False)
return HttpResponseRedirect('/quote/?submitted=True')
you can also add some text in between like this:
description = 'The company is ' + str(company) + '. Phone number is '+ str(phone) + '. address is '+ str(address)
Hope that helps.
You can follow me on youtube am sharing all me experience on my channel:
Channel Address is: https://www.youtube.com/channel/UCEXgQzMw_DXxk1M4Rlsciag?sub_confirmation=1

django email fails to send in production, works for errors, fails for a particular view

I'm trying to automatically send an email with a django contact us form.
The contact form view works in development properly via django.core.mail.backends.console.EmailBackend
Sending of emails to admins for errors in procution works properly.
However sending emails for the contact view/form doesn't work in production.
No errors are produced in production when submitting the contact form.
the post request appears in the logs, but there isn't any other useful information (that I can see) apart from that.
I'm not sure how best to pinpoint the error?
view:
#require_http_methods(['GET', 'HEAD', 'POST'])
def contact_view(request):
form = ContactForm()
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
contact_name = form.cleaned_data.get('contact_name', '')
contact_email = form.cleaned_data.get('contact_email', '')
email_content = form.cleaned_data.get('message', '')
email = EmailMessage(
subject="New contact form submission",
body=email_content,
to=('support#somedomain.com',),
from_email=f'{contact_name} <{contact_email}>',
reply_to=(contact_email,),
)
email.send()
messages.success(request,
"Your email has been sent. Thanks for contacting us, we'll get back to you shortly")
return redirect('contact')
context = {'form': form}
return render(request, 'pages/contact.html', context)
production email settings:
DEFAULT_FROM_EMAIL = env('DJANGO_DEFAULT_FROM_EMAIL',
default=' <noreply#some_domain.com>')
EMAIL_SUBJECT_PREFIX = env('DJANGO_EMAIL_SUBJECT_PREFIX', default='[some_domain]')
SERVER_EMAIL = env('DJANGO_SERVER_EMAIL', default=DEFAULT_FROM_EMAIL)
# Anymail with Mailgun
INSTALLED_APPS += ("anymail", )
ANYMAIL = {
"MAILGUN_API_KEY": env('DJANGO_MAILGUN_API_KEY'),
"MAILGUN_SENDER_DOMAIN": env('MAILGUN_SENDER_DOMAIN')
}
EMAIL_BACKEND = "anymail.backends.mailgun.EmailBackend"
Your admin emails work because they are using DEFAULT_FROM_EMAIL which is allowed.
Your email provider may not allow you to send emails from the address entered on the contact form.
You should use your email address for the from_email, and use the email address from the form as the reply_to email address.

Retrieving info from contact form django

I keep working with django and I was building a contact form.
I want to retrieve the information in the contact form, which I was able to do so far, but I am facing the problem that the user that fills in the form is also receiving an email with the information and MY email ( which I don't want ).
I am using the function EmailMultiAlternatives in my view, and have configured propertly my settings.py with the email account, and extra data needed for emails.
Can the information from a form be only received by me (administrator)?
Here is my view:
form = ContactForm(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
name = form.cleaned_data['name']
message = form.cleaned_data['message']
to = #my email
html_content = "received from [%s] ***message*** %s"%(email,message)
msg = EmailMultiAlternatives('Subject', html_content, 'from#server.com', [to])
msg.attach_alternative(html_content, 'text/html')
msg.send()