I'm sending out an email to users with a generated link, and I wanna write a test that verifies whether the link is correct, but I can't find a way to get the content of the email inside the test.
Is there a way to do that?
If it helps at all, this is how I'm sending the email:
content = template.render(Context({'my_link': my_link}))
subject = _('Email with link')
msg = EmailMultiAlternatives(subject=subject,
from_email='MyWebsite Team <mywebsite#mywebsite.com>',
to=[user.email, ])
msg.attach_alternative(content, 'text/html')
msg.send()
The docs have an entire section on testing emails.
self.assertEqual(mail.outbox[0].subject, 'Email with link')
Related
I am trying to create a function to open a new Outlook message, but I would like the message to appear already with the recipient, subject fields.
So far what I have found is how to open a new Outlook window with the recipient, but I still can't get the subject to be displayed.
import webbrowser
webbrowser.open('mailto:email#domain.com', new=1)
Hope u can help me, ty.
mailto would work fine as long as you don't want HTML body or attachments. You can specify to/cc/bbc, subject, and body.
Something along the lines:
mailto:user1#domain.demo?subject=Test%20Subject&body=Test%20body&cc=user2#domain.demo&bcc=user3#domain.demo
And it will work under any OS and any email client.
Here is a potential solution using win32.com.client:
import win32.com.client as win32
outlook = win32.Dispatch("Outlook.Application") # Starts Outlook application
new_email = outlook.CreateItem(0) # Creates new email item
new_email.To = "email#domain.com" # Add recipients separated by comma or semicolon
new_email.Subject = "How to create new Outlook email in Python" # Your email subject
new_email.Body = "This text will be the body of your new email" # Your email body
new_email.Display(True) # Displays the new email item
email = 'user#example.com'
link = auth.generate_password_reset_link(email, action_code_settings)
# Construct password reset email from a template embedding the link, and send
# using a custom SMTP server.
send_custom_email(email, link)
So I'm using this code from https://firebase.google.com/docs/auth/admin/email-action-links#python in django
and I'm getting this error:
NameError: name 'send_custom_email' is not defined
And nothing is mentioned in the documentation. So if anyone knows the solutions it would be great.
sg = SendGridAPIClient(os.environ["SENDGRID_API_KEY"])
html_content = f"""
<p>Hello,</p>
<p>Follow this link to reset password</p>
<p>{link}</p>
<p>If you didn't ask to reset the password, you can ignore this
email.</p>
"""
message = Mail(
to_emails=xyz#gmail.com,
from_email=Email('abc#gmail.com', "ABC System")
subject="Reset your password for ABC System",
html_content=html_content
)
try:
response = sg.send(message)
print(response.status_code)
except HTTPError as e:
print(e.message)
The above script is used for sending an email using Sendgrid.
I am learning to use the sendgrid api with django python. For now, I can successfully send emails but I would like to make the email more appealing and apply some css styles. I looked online for some help but couldn't find any. Can someone please suggest me how i should go about it ?
This is what i tried so far
def sendemail(sender,recipient,subject,content,url):
sg = sendgrid.SendGridAPIClient(apikey="*****")
from_email = Email(sender)
to_email = Email(recipient)
subject = subject
content = Content("text", content+url)
mail = Mail(from_email, subject, to_email, content)
response = sg.client.mail.send.post(request_body=mail.get())
print(response.status_code)
print(response.body)
print(response.headers)
I try to send email which contains text, html version of body and attached file.
I use standart python example with additional code:
img = MIMEImage(some_image_file)
img.add_header('Content-Disposition','attachment; filename="file.jpg"')
msg.attach(text_body)
msg.attach(html_body)
msg.attach(img)
Gmail show my email well, however yandex.com' email client shows only attached picture without html or text body of the letter.
If I change order like that:
msg.attach(img)
msg.attach(html_body)
Yandex shows only html body of my letter, and do not show attachment!
Is there any additional headers I need to add in order to show my email correctly (html/txt body AND attached file) in any email clients?
After some research of email headers sent from normal email client, I found solution:
body = MIMEMultipart('alternative')
msg = MIMEMultipart('mixed')
....
body.attach(text_body)
body.attach(html_body)
msg.attach(body)
msg.attach(img)
I would like to receive email using python. So far I have been able to get the subject but not the body. Here is the code I have been using:
import poplib
from email import parser
pop_conn = poplib.POP3_SSL('pop.gmail.com')
pop_conn.user('myusername')
pop_conn.pass_('mypassword')
#Get messages from server:
messages = [pop_conn.retr(i) for i in range(1, len(pop_conn.list()[1]) + 1)]
# Concat message pieces:
messages = ["\n".join(mssg[1]) for mssg in messages]
#Parse message intom an email object:
messages = [parser.Parser().parsestr(mssg) for mssg in messages]
for message in messages:
print message['subject']
print message['body']
pop_conn.quit()
My issue is that when I run this code it properly returns the Subject but not the body. So if I send an email with the subject "Tester" and the body "This is a test message" it looks like this in IDLE.
>>>>Tester >>>>None
So it appears to be accurately assessing the subject but not the body, I think it is in the parsing method right? The issue is that I don't know enough about these libraries to figure out how to change it so that it returns both a subject and a body.
The object message does not have a body, you will need to parse the multiple parts, like this:
for part in message.walk():
if part.get_content_type():
body = part.get_payload(decode=True)
The walk() function iterates depth-first through the parts of the email, and you are looking for the parts that have a content-type. The content types can be either text/plain or text/html, and sometimes one e-mail can contain both (if the message content_type is set to multipart/alternative).
The email parser returns an email.message.Message object, which does not contain a body key, as you'll see if you run
print message.keys()
What you want is the get_payload() method:
for message in messages:
print message['subject']
print message.get_payload()
pop_conn.quit()
But this gets complicated when it comes to multi-part messages; get_payload() returns a list of parts, each of which is a Message object. You can get a particular part of the multipart message by using get_payload(i), which returns the ith part, raises an IndexError if i is out of range, or raises a TypeError if the message is not multipart.
As Gustavo Costa De Oliveir points out, you can use the walk() method to get the parts in order -- it does a depth-first traversal of the parts and subparts of the message.
There's more about the email.parser module at http://docs.python.org/library/email.message.html#email.message.Message.
it also good return data in correct encoding in message contains some multilingual content
charset = part.get_content_charset()
content = part.get_payload(decode=True)
content = content.decode(charset).encode('utf-8')
Here is how I solved the problem using python 3 new capabilities:
import imaplib
import email
mail = imaplib.IMAP4_SSL('imap.gmail.com')
mail.login(username, password)
mail.select(readonly=True) # refresh inbox
status, message_ids = mail.search(None, 'ALL') # get all emails
for message_id in message_ids[0].split(): # returns all message ids
# for every id get the actual email
status, message_data = mail.fetch(message_id, '(RFC822)')
actual_message = email.message_from_bytes(message_data[0][1])
# extract the needed fields
email_date = actual_message["Date"]
subject = actual_message["Subject"]
message_body = get_message_body(actual_message)
Now get_message_body is actually pretty tricky due to MIME format. I used the function suggested in this answer.
This particular example works with Gmail, but IMAP is a standard protocol, so it should work for other email providers as well, possibly with minor changes.
if u want to use IMAP4. Use outlook python library, download here : https://github.com/awangga/outlook
to retrieve unread email from your inbox :
import outlook
mail = outlook.Outlook()
mail.login('emailaccount#live.com','yourpassword')
mail.inbox()
print mail.unread()
to retrive email element :
print mail.mailbody()
print mail.mailsubject()
print mail.mailfrom()
print mail.mailto()