I am using email.message_from_string to parse an email message into Python. The documentation doesn't seem to say what standard fields there are.
How do I know what fields are available to read from, such as msg['to'], msg['from'], etc.? Can I still find this if I don't have an email message to experiment with on the command line?
email.message_from_string() just parses the headers from the email. Using keys() you get all present headers from the email.
import email
e = """Sender: test#test.dk
From: test#test.dk
HelloWorld: test
test email
"""
a = email.message_from_string(e)
print a.keys()
Outputs: ['Sender', 'From', 'HelloWorld']
Therefore, you will never find a manual that includes from, to, sender etc. as they are not part of the API, but just parsed from the headers.
Related
For my use case, I would like to manually set the displayed email addresses in the "to" and "from" field headers of the email, separate from the actual email recipient and sender. I am currently using the smtplib library in python and have managed to accomplish the desired effect with the "to" field and was looking to replicate it for the "from" field as well.
What I have so far:
EMAIL_ADDRESS_G = 'ayush.warikoo77#gmail.com'
from email.message import EmailMessage
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
smtp.login(EMAIL_ADDRESS_G, EMAIL_PASSWORD_G)
# What I would like to be displayed in the email
msg = EmailMessage()
msg["Subject"] = "Test"
msg["To"] = 'test#gmail.com' # shows up
msg['From'] = 'test#gmail.com' # does not show up
msg.set_content("Test body")
# Where I would like to be setting the actual email sender and recipient
smtp.send_message(msg, from_addr=EMAIL_ADDRESS_G, to_addrs=EMAIL_ADDRESS_G)
The above code produces the following:
As shown, the "to" field displays the desired set address, while the "from" field displays my actual email instead of "test#gmail.com". I believe it is being set when I call login with the account, but I am unsure if I can override it. Also happy to use another python email library, if it is not possible with smtplib.
Current --> Desired
To: test#gmail.com
From: ayush.warikoo77#gmail.com --> test#gmail.com
Actual Sender: ayush.warikoo77#gmail.com
Actual Reciever: ayush.warikoo77#gmail.com
Note that this would be used for archiving purposes, where a designated email client might actually be sending the emails, however, I would like the email to use the to and from fields of the message it is trying to document. So the desired displayed "from" field is separate from the actual sender.
Authenticated Gmail SMTP prevents you from spoofing the From header, presumably to prevent abuse.
For archiving purposes, using IMAP’s APPEND command will allow you to place whatever you like in your own mailbox (as it doesn’t count as sending email) and may be a better solution. (You will need to use an App Specific Password or OAUTH to login though).
I am having trouble sending an email to a list of recipients using an smtp.
I can send the email to the first recipient but not the rest. My recipients are in a list. I have tried turning the list into a string. As well as adding a comma or a semicolon to each email in the list but each to no avail.
My email list is formatted like this:
['name#email.com', 'name#email.com']
And I am using this to send it:
from Dmail import Email
sender_email = 'sender#email.com'
with Email(mail_server="smtp.myserver.org", sender_email=sender_email, mail_port=25, mail_use_ssl=False,
mail_use_tls=False) as email:
email.send("Test Body", email_list, subject="test")
Any help on this appreciated.
Currently, I have the email sending to myself and I can see that there are multiple recipients in the "to" column, but none of them are actually receiving the email.
Using Python 3.9+
Thank you.
I was able to fix this by doing:
email_list= '; '.join(email_list)
and
email.send("Test Body", email_list.split(';'), subject="test")
Need your assistance in saving the email as .png. The code below will get the body of the email, but it is unable to get a screenshot in the body of the email.
with open(r"output.txt", "w") as output:
for item in fromfolder.filter(is_read=False):
output.write('{}\n'.format(item.body))
item.is_read = True
item.save()
item.move(archieve)
Have tried saving email as eml and msg, but nothing is working out.
item.body contains the entire body of the email message, not just the image contained in the body.
exchangelib does not offer methods to parse the body of the email. You'll need to use other packages for that.
I think your best bet would be to parse the item.mime_content field which contains the raw email content. You can use e.g. email.parser.BytesParser.parse_bytes(mime_content) from https://docs.python.org/3/library/email.parser.html. This will return an EmailMessage with your PNG image.
I am currently working on a project in Python that would be connecting to an email server and looking at the latest email to tell the user if there is an attachment or a link embedded in the email. I have the former working but not the latter.
I may be having troubles with the if any() part of my script. As it seems to half work when I test. Although it may be due to how the email string is printed out?
Here is my code for connecting to gmail and then looking for the link.
import imaplib
import email
word = ["http://", "https://", "www.", ".com", ".co.uk"] #list of strings to search for in email body
#connection to the email server
mail = imaplib.IMAP4_SSL('imap.gmail.com')
mail.login('email#gmail.com', 'password')
mail.list()
# Out: list of "folders" aka labels in gmail.
mail.select("Inbox", readonly=True) # connect to inbox.
result, data = mail.uid('search', None, "ALL") # search and return uids instead
ids = data[0] # data is a list.
id_list = ids.split() # ids is a space separated string
latest_email_uid = data[0].split()[-1]
result, data = mail.uid('fetch', latest_email_uid, '(RFC822)') # fetch the email headers and body (RFC822) for the given ID
raw_email = data[0][1] # here's the body, which is raw headers and html and body of the whole email
# including headers and alternate payloads
print "---------------------------------------------------------"
print "Are there links in the email?"
print "---------------------------------------------------------"
msg = email.message_from_string(raw_email)
for part in msg.walk():
# each part is a either non-multipart, or another multipart message
# that contains further parts... Message is organized like a tree
if part.get_content_type() == 'text/plain':
plain_text = part.get_payload()
print plain_text # prints the raw text
if any(word in plain_text for word in word):
print '****'
print 'found link in email body'
print '****'
else:
print '****'
print 'no link in email body'
print '****'
So basically as you can see I have a variable called 'Word' which contains an array of keywords to search for in the plain text email.
When I send a test email with an embedded link that is in the format of 'http://' or 'https://' - the email prints out the email body with the link in the text like this -
---------------------------------------------------------
Are there links in the email?
---------------------------------------------------------
Test Link <http://www.google.com/>
****
found link in email body
****
And I get my print message saying 'found link in email body' - which is the result I am looking for in my test phase, yet this will lead onto something else to happen within the final program.
Yet, if I add an embedded link in the email with no http:// such as google.com then the link doesn't print out and I don't get the result, even though I have an embedded link.
Is there a reason for this? I'm also suspecting maybe my if any() loops is not really the best. I didn't really understand it when I originally added it but it worked for http:// links. Then I tried just a .com and got my problem which I am having trouble finding a solution for.
To check if there are attachments to an e-mail you can search the headers for Content-Type and see if it says "multipart/*". E-mails with multipart content types may contain attachments.
To inspect the text for links, images, etc, you can try using Regular Expressions. As a matter of fact, this is probably your best option in my opinion. With regex (or Regular Expressions) you can find strings that match a given pattern. The pattern "<a[^>]+href=\"(.*?)\"[^>]*>(.*)?</a>", for example, should match all links in your email message regardless of whether they are a single word or a full URL. I hope that helps!
Here's an example of how you can implement this in Python:
import re
text = "This is your e-mail body. It contains a link to <a
href='http//www.google.com'>Google</a>."
link_pattern = re.compile('<a[^>]+href=\'(.*?)\'[^>]*>(.*)?</a>')
search = link_pattern.search(text)
if search is not None:
print("Link found! -> " + search.group(0))
else:
print("No links were found.")
For the "end-user" the link will just appear as "Google", without www and much less http(s)... However, the source code will have the html wrapping it, so by inspecting the raw body of the message you can find all links.
My code is not perfect but I hope it gives you a general direction... You can have multiple patterns looked up in your e-mail body text, for image occurences, videos, etc. To learn Regular Expressions you'll need to research a little, here's another link, to Wikipedia
I'm making an API using Python requests, and HTTP GET is working fine, but I'm having a little bit of trouble with HTTP POST. So, as with a lot of websites, you can read information, but in order to make a post request (such as following a user, or writing a post), you need to have an authenticated session. THIS website, uses google to log in. Normally, I would just pass the username:password into the POST request formdata to log in, but this google thing is pretty wonky (and quite frankly I'm not that experienced). Does anyone have a reference or an example to help me out? ;/
I do not know about python requests but to send an email its as easy as this
import yagmail
yagmail.SMTP(emailh).send(email, subject, body)
#emailh = your email (just username no #gmail.com)
#email = send to (full email including domain ***#gmail.com or ***#outlook.com)
#subject = subject of the message
#body = body of the message
Even better
emailh = raw_input('Your email: ')
email = raw_input('Send to: ')
subject = raw_input('Subject: ')
body = raw_input('Body: ')
yagmail.SMTP(emailh).send(email, subject, body)
print('Email Sent.')
If this is what you are talking about anyway.
This page might be useful link