I am currently trying to set up a view so when the user visits the path /clip it will send an email to the user's inbox.
Eg. I visit path, email turns up in my inbox.
I am using this:
from django.core.mail import send_mail
def clippy(request):
current_user = request.user
subject = "test"
message = "testing"
recipient_list = [current_user.email]
send_mail(subject, message, recipient_list)
I'm using 3.0.4 and get this error when I visit the path:
send_mail() missing 1 required positional argument: 'recipient_list'
Can anyone help? Thanks
EDIT: I have used the answer by reza heydari and it fixes this issue, now I get the following:
TypeError at /clip/
send_mail() missing 1 required positional argument: 'from_email'
#login_required()
def clippyemail(request):
current_user = request.user
subject = 'Clippy here',
message = 'Hi! I am clippy! You resserected me somehow so thanks!',
recipient_list = [current_user.email, ]
send_mail(subject, message, recipient_list=recipient_list)
is there any way I can set it up so it just sends the email using the SMTP settings in settings.py?
The 3rd arg of send_mail is from_email based on docs
Change your code like that:
send_mail(subject, message, from_email="example#email.com", recipient_list=recipient_list)
And also add
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
For your local to recieve email in terminal
Related
I am writing a web application and am trying to use sendgrid to handle email delivery services.
I am writing the application in Flask.
Right now I have a contact form, and my problem is that the email only gets delivered if I send the e-mail from my pre-approved e-mail address with sendgrid. Obviously this is not good since everyone else who fills out the e-mail form will not have it go through.
Here's the code that I have:
ROUTE
app.config['MAIL_SERVER'] = 'smtp.sendgrid.net'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = 'apikey'
app.config['MAIL_PASSWORD'] = os.environ.get('SENDGRID_API_KEY')
app.config['MAIL_DEFAULT_SENDER'] = os.environ.get('MAIL_DEFAULT_SENDER')
#app.route('/contact', methods=['GET', 'POST'])
def contactpage():
if request.method == 'POST':
print("Message sent")
print(request.form.to_dict())
m = message(request.form.to_dict())
m.send()
title = "Jonathan Bechtel contact form"
description = "Contact Jonathan Bechtel with questions about teaching or working with him"
return render_template("contact.html",
title=title,
description=description)
Here's my code for actually sending the e-mail:
import os
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
class message():
def __init__(self, message_data):
for key in message_data:
print(key, message_data[key])
setattr(self, key, message_data[key])
def send(self):
message = Mail(
from_email = self.email,
to_emails = 'jonathanbechtel#gmail.com',
subject = 'Sample Email Message',
html_content = f'<strong>From: {self.email}</strong><br><strong>Reason: {self.reason}</strong><br><strong>Message:</strong>{self.message}')
try:
sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
response = sg.send(message)
except Exception as e:
print(e)
If I set the from address in my contact form to my own the e-mail works fine. However, if I use any other one the message does not go through and generates a 403 status code.
I think this means that I'm just not using the correct part of the API but am not sure where to start.
Thank you.
Twilio SendGrid developer evangelist here.
SendGrid does not allow you to send emails from just any email address. I can see that in this case you are just trying to create a contact form that only sends emails to your email address so being able to send from any email address might be useful. But consider a form that allowed users to set the to and the from address and you can see how that might get abused.
You can read more about sender identity and SendGrid here.
In the meantime, for your use-case here is what I would suggest.
Set the from email to your pre-approved email address, include the user's email address in the body of the email, as you are doing already. Then add the user's email as a reply-to email as well, that way you can respond to the email and it will be sent straight to the user.
I believe you can set the reply-to with the mail object's reply_to method:
def send(self):
message = Mail(
from_email = APPROVED_SENDGRID_EMAIL,
to_emails = 'jonathanbechtel#gmail.com',
subject = 'Sample Email Message',
html_content = f'<strong>From: {self.email}</strong><br><strong>Reason: {self.reason}</strong><br><strong>Message:</strong>{self.message}')
# Set the reply-to email
message.reply_to(self.email)
try:
sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
response = sg.send(message)
except Exception as e:
print(e)
See the examples in the helper library for more detail.
I am working on a django web application. I have a contact us form. when a user submits the form, the message in the form is sent as a mail to a predefined email id.
For sending the email, I am using sendgrid. I created an account and generated an api for this purpose. I stored the api key in a dotenv file and access the api in the settings.py file
.env file
SENDGRID_API_KEY=XXXXXXXXXXXXXXXXXXXX
settings.py
import os
from dotenv import load_dotenv
load_dotenv()
...
EMAIL_BACKEND = "sendgrid_backend.SendgridBackend"
SENDGRID_API_KEY = os.environ.get("SENDGRID_API_KEY")
SENDGRID_SANDBOX_MODE_IN_DEBUG=False
views.py
def index(request):
if request.method == "POST":
ContactUsForm = ContactUs(request.POST)
if ContactUsForm.is_valid():
firstName = ContactUsForm['firstName']
fromEmail = ContactUsForm['email']
message = ContactUsForm['message']
send_mail(subject=f"{firstName} sent you a message", message=message, from_email=fromEmail, recipient_list=['toaddress#email.com'])
return redirect('home')
else:
ContactUsForm = ContactUs()
context = {'contactUs': ContactUsForm}
return render(request, 'index.html', context)
But when I submit the form, I get this error message
TypeError: 'in <string>' requires string as left operand, not BoundWidget
I dont know where I went wrong.
This is the link I followed to send emails with sendgrid
You're accessing the fields themselves, instead of the validated data. You need:
firstName = ContactUsForm.cleaned_data['firstName']
fromEmail = ContactUsForm.cleaned_data['email']
message = ContactUsForm.cleaned_data['message']
I've been trying to let users send email to my personal account via form. At first it was showing me
socket.gaierror: [Errno 11004] getaddrinfo failed
error which I solved by installing and configuring hMailServer in my device. Now when I try to send mail by my friend's email it send email by my own account instead. When I removed MAIL_HOST_USER = 'my_email' from settings file, it shows
smtplib.SMTPSenderRefused
error as mentioned in title. Any suggestions or related links will be appreciated.
My code is:
settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_PORT = 25
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'my_email'
EMAIL_HOST_PASSWORD = 'my_password'
EMAIL_USE_TLS = True
views.py
class contact(View):
def post(self, request):
form = ContactForm(request.POST)
if form.is_valid():
if send_mail(subject = form.cleaned_data['title'], message = form.cleaned_data['content'], from_email = form.cleaned_data['contact_email'], recipient_list = ['my_email'], fail_silently=False):
return render(request, 'index.html', {'form': form, 'message': 'Message delivered successfully', 'error':'', 'email_sent': 1 })
else:
return render(request, 'index.html', {'form': ContactForm(), 'error': form.errors})
Gmail, like more or less any other email provider or correctly configured mail server, does not allow you to set an arbitrary From address. An email server that allows this would be abused by spammers and quickly find itself on a spam blacklist.
What you can do is set my_email as sender and add a Reply-To header with the email address provided through the form.
You have to create an EmailMessage instance and call send():
from django.core.mail import EmailMessage
...
email = EmailMessage(
subject=form.cleaned_data['title'],
message=form.cleaned_data['content'],
from_email='my_email',
recipient_list=['my_email'],
reply_to=form.cleaned_data['contact_email']
)
sent = email.send(fail_silently=False)
if sent:
return render(request, 'index.html', {'form': form, 'message': 'Message delivered successfully', 'error':'', 'email_sent': 1 })
Note that Gmail has some limits on the number of emails you can send this way. Make sure you don't accidentally block your account.
N.B., you can configure gmail to relay messages on behalf of any sending address in a google apps organization (powered by gmail), but as Daniel Hepper noted, this is not the default for a personal gmail address. That said, I would wager that the OP's problem is likely that the port setting is incorrect. In gmail, the port setting should be 465 or 587 for TLS-using SMTP.
I would like to send email in Django 1.10.
This is the snippet code in settings.py file.
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'my email address'
EMAIL_HOST_PASSWORD = 'password'
EMAIL_PORT = '587'
EMAIL_USE_TLS = True
This is the snippet code in views.py file which is responsible for sending email.
from django.shortcuts import render
from django.core.mail import send_mail
from django.conf import settings
from .forms import contactForm
def contact(request):
form = contactForm(request.POST or None)
if form.is_valid():
name = form.cleaned_data['name']
comment = form.cleaned_data['comment']
subject = 'Message form MYSITE.com'
message = '%s %s' %(comment, name)
emailFrom = form.cleaned_data['email']
emailTo = [settings.EMAIL_HOST_USER]
send_mail(subject, message, emailFrom, emailTo, fail_silently=True)
context = locals()
template = "contact.html"
return render(request,template,context)
When I clicked submit button, I only received Review blocked sign-in attempt - google email.
So I have set my email account as Allow less secure apps: OFF.
Then hit the submit button again, I haven't received any email without any exception. As if sending email functionality working - browser loading for a little while.
I'm not sure why I couldn't receive email.
When I change fail_silently = False, I get a error like this.
SMTPAuthenticationError at /contact/
(534, '5.7.14 https://accounts.google.com/signin/continue?sarp=1&scc=1&plt=AKgnsbtS\n5.7.14 Mr_jh-DUic292PQTLx5X6kZmxxN8WFLelRksUwF0nHxSUPVpU_fX3m7ds3VOoUuTxL9Gya\n5.7.14 bqnAiUAIf2Er2n31EXEHIOpy2Kqn9cFH-PsIJSx1GBn_SxygkjHWgZ9KWc9cxIAKTGQtru\n5.7.14 O3QBqKb6vCyVHCiN8wUY6jAVRdoRg9aK9BL5GTo6QKUomIilah549hrwMgvMcYrrKCLMGI\n5.7.14 YuEWvMHHPdW6TXkBB75UP2wxRZ9fI> Please log in via your web browser and\n5.7.14 then try again.\n5.7.14 Learn more at\n5.7.14 https://support.google.com/mail/answer/78754 u2sm3991912edl.71 - gsmtp')
How can I handle it.
im trying to make a contact form in django 1.3, python 2.6.
Whats the reason of following error?
error:
SMTPRecipientsRefused at /contact/
{'test#test.megiteam.pl': (553, '5.7.1 <randomacc#hotmail.com>: Sender address
rejected: not owned by user test#test.megiteam.pl')}
my settings.py:
EMAIL_HOST = 'test.megiteam.pl'
EMAIL_HOST_USER = 'test#test.megiteam.pl'
EMAIL_HOST_PASSWORD = '###'
DEFAULT_FROM_EMAIL = 'test#test.megiteam.pl'
SERVER_EMAIL = 'test#test.megiteam.pl'
EMAIL_USE_TLS = True
edit: If any1 else was following djangobook, this is the part causing it:
send_mail(
request.POST['subject'],
request.POST['message'],
request.POST.get('email', 'noreply#example.com'), #get rid of 'email'
['siteowner#example.com'],
The explanation is in the error message. Your email host is rejecting the email because of the sender address randomacc#hotmail.com that you have taken from the contact form.
Instead, you should use your own email address as the sender address. You can use the reply_to option so that replies go to your user.
email = EmailMessage(
'Subject',
'Body goes here',
'test#test.megiteam.pl',
['to#example.com',],
reply_to='randomacc#hotmail.com',
)
email.send()
On Django 1.7 and earlier, there isn't a reply_to argument, but you can manually set a Reply-To header:
email = EmailMessage(
'Subject',
'Body goes here',
'test#test.megiteam.pl',
['to#example.com',],
headers = {'Reply-To': 'randomacc#hotmail.com'},
)
email.send()
Edit:
In the comments you asked how to include the sender's address in the message body. The message and from_email are just strings, so you can combine them however you want before you send the email.
Note that you shouldn't get the from_email argument from your cleaned_data. You know that the from_address should be test#test.megiteam.pl, so use that, or maybe import DEFAULT_FROM_EMAIL from your settings.
Note that if you create a message using EmailMessage as in my example above, and set the reply to header, then your email client should do the right thing when you hit the reply button. The example below uses send_mail to keep it similar to the code you linked to.
from django.conf import settings
...
if form.is_valid():
cd = form.cleaned_data
message = cd['message']
# construct the message body from the form's cleaned data
body = """\
from: %s
message: %s""" % (cd['email'], cd['message'])
send_mail(
cd['subject'],
body,
settings.DEFAULT_FROM_EMAIL, # use your email address, not the one from the form
['test#test.megiteam.pl'],
)