Select mails from inbox alone via poplib - python

I need to download emails from the gmail inbox only using poplib.Unfortunately I do not see any option to select Inbox alone, and poplib gives me emails from sent items too.
How do I select emails only from inbox?
I dont want to use any gmail specific libraries.

POP3 has no concept of 'folders'. If gmail is showing you both 'sent' as well as 'received' mail, then you really don't have any option but to receive all that email.
Perhaps you would be better off using IMAP4 instead of POP3. Python has libraries that will work with gmail's IMAP4 server.

I assume you have enabled POP3/IMAP access to your GMail account.
This is sample code:
import imaplib
conn= imaplib.IMAP4_SSL('imap.googlemail.com')
conn.login('yourusername', 'yourpassword')
code, dummy= conn.select('INBOX')
if code != 'OK':
raise RuntimeError, "Failed to select inbox"
code, data= self.conn.search(None, ALL)
if code == 'OK':
msgid_list= data[0].split()
else:
raise RuntimeError, "Failed to get message IDs"
for msgid in msgid_list:
code, data= conn.fetch(msgid, '(RFC822)')
# you can also use '(RFC822.HEADER)' only for headers
if code == 'OK':
pass # your code here
else:
raise RuntimeError, "could not retrieve msgid %r" % msgid
conn.close()
conn.logout()
or something like this.

This Java code would suggest that you can select a particular "folder" to download, even when using POP3. Again, this is using Java, not Python so YMMV.
How to download message from GMail using Java (blog post discusses pushing content into a Lucene search engine locally)

Related

Python client.Dispatch("outlook.application") fails in specific case (#company emails)

Hi there,
Everything is working fine, except one thing I can't send email to clients that have non-standard email (if their email are #gmail, #outlook, etc, it sends the email normally)
I have a client with the following email client#company.com (not the real email obviously), I can't send that email to him. There goes my method. I'd love some help.
mail.Send()
File "", line 2, in Send pywintypes.com_error:
(-2147024809, 'The parameter is incorrect.', None, None)
def main_send_email(self, to, header, attached_msg, pdf_files=None):
import pythoncom
# return super().main_send_email(to, header, attached_msg, pdf_files)
self.outlook_app = client.Dispatch(
'outlook.application', pythoncom.CoInitialize())
s = client.Dispatch("Mapi.Session")
mail = self.outlook_app.CreateItem(0)
# set the account
account = None
for acc in mail.Session.Accounts:
if "39" in acc.DisplayName:
account = acc
mail._oleobj_.Invoke(*(64209, 0, 8, 0, account))
# mail.SendUsingAccount = self.outlook_app.Session.Accounts.Item(1)
# set email sender
# mail.To = 'silsilinhas#gmail.com'
mail.To = to
mail.Subject = header
mail.HTMLBody = attached_msg
if pdf_files is not None:
for pdf in pdf_files:
mail.Attachments.Add(pdf)
mail.Send()
First of all, I've noticed the following line of code which is useless and never used:
s = client.Dispatch("Mapi.Session")
It seems there is no need to create a new MAPI session in the code if you automate Outlook.
Second, the Send method may trigger a security issue when automating Outlook from external applications. It can be a security prompt or just an exception thrown at runtime. There are several ways for suppressing such prompts/issues:
Use a third-party components for suppressing Outlook security warnings. See Security Manager for Microsoft Outlook for more information.
Use a low-level API which doesn't trigger such issues/prompts instead of OOM. Or any other third-party wrappers around that API, for example, Redemption.
Develop a COM add-in which has access to the trusted Application object. And then communicate from a standalone application with an add-in using standard .Net tools (Remoting).
Use group policy objects for setting up machines to not throw such issues.
Install the latest AV software.
Third, you may try to set recipients for the mail item using the Recipients collection which provides the Resolve method which attempts to resolve a Recipient object against the Address Book. Read more about that in the How To: Fill TO,CC and BCC fields in Outlook programmatically article.
In a program i wrote I have found the error "(-2147024809, 'The parameter is incorrect.', None, None)" whenever I try using mail.Send() before calling mail.Display().
Seems fairly consistent but can't explain why!
Hope this helps (sorry if it doesn't!)
...
if pdf_files is not None:
for pdf in pdf_files:
mail.Attachments.Add(pdf)
mail.Display() ##this line here
mail.Send()

How do I identify Outlook "message id" over imap/pop3 in Python?

Problem
I am using a "logic app" in Azure to create a queue of incoming mails. The way the emails are registered are using a "message id", which is described as "a unique identifier for a message". I would like to be able to fetch emails over imap using this id - is this possible?
Logic app "message id"
Example of "message id":
AQMkADAwATM3ZmYAZS0yNTYwLWNkZAAzLTAwAi0wMAoARgAAA-U4TGbG56lEtdoXy_23gW0HAKhWKDtf5AJErHyhh_b9NYQAAAIBDAAAAKhWKDtf5AJErHyhh_b9NYQAAAIFfgAAAA==
Example of logic app:
What I have tried
I have tried just to download all emails as eml, and then to read them into notepad++ to see if the "message id" even exists in the eml-files, but they don't.
# Library for downloading emails
import imaplib
# Logging in
mail = imaplib.IMAP4_SSL("outlook.office365.com",993)
mail.login(email_user, email_pass)
# Downloading emails to eml
mail.select('Inbox')
typ, data = mail.search(None, 'ALL')
for num in data[0].split():
typ, data = mail.fetch(num, '(RFC822)')
f = open('%s/%s.eml' %("/my/path/", num), 'wb')
f.write(data[0][1])
mail.close()
mail.logout()
May i know why are you trying to fetch email over IMAP . As you can fetch fetch email using message id from outlook api too. Here is the api which you can use:
GET https://outlook.office.com/api/v2.0/me/messages/{message_id}
You can find more details here:
https://learn.microsoft.com/en-us/previous-versions/office/office-365-api/api/version-2.0/mail-rest-operations#GetMessages
Also just to update , in outlook you wont' find the message id in .eml or in body, it's available in internet header. Most clients utilities download the headers (including the Message-ID) of all messages, store them, and then post-process them. For outlook you can find it in internet header like below:
Reference: https://www.codetwo.com/kb/messageid/
Still if you want to access email using IMAP, try below thread and see if it helps:
https://www.go4expert.com/articles/accessing-email-using-imap-python-t28838/
https://social.msdn.microsoft.com/Forums/en-US/29f44441-feda-4f81-a04c-40d53b3dfdc5/how-to-access-an-email-using-messageid-in-outlook?forum=outlookdev
Hope it helps.

Catching smtp exception in EmailMultiAlternatives django

I am writing a management command where I will be sending emails to multiple recipients. I would like to make a log where I can tell if the mail is sent to a recipient successfully or not. So far I am able to get this much code running
from django.core.mail import EmailMultiAlternatives
from smtplib import SMTPException
try:
msg = EmailMultiAlternatives(data['subject'], data['text_content'], data['from_mail'], data['recipient_list'], bcc=data['bcc_address'])
if data['html_content']:
msg.attach_alternative(data['html_content'], "text/html")
msg.send(fail_silently=False)
except SMTPException as e:
error_code,error_msg = e.smtp_code, e.smtp_error
print error_code, error_msg
'''except Exception as e:
print e
print "==========="
print traceback.print_exc()'''
I am kind of stuck now. I deliberately put the wrong recipient emails in data['recipient_list'], but still I am not able to catch the error. I am not sure what I am doing wrong. What is to correct way to catch smtp exception in django
It won't work this way. SMTP server will send email regardless of whether such email exists or not. You may receive bounce email to your inbox later, but this is different case.
I'd say that should validate email address syntax and that's all you can do. You can also take benefit of send() return value which is number of emails sent.

How to send myself an email notification when a suds job is done?

I'm learning to use suds in a python script to send SQL queries to a database. I'd like to able to send myself an email when the query job is finished (it has a job ID so I'm able to check its status). How do I do that?
This is how you send an email via python just fill in the blanks and input it to your code:
import smtplib
content = ("Content to send")
mail = smtplib.SMTP('smtp.gmail.com',587)
mail.ehlo()
mail.starttls()
mail.login('your_email#gmail.com','123your_password')
mail.sendmail('your_email#gmail.com','destination_email#gmail.com',content)
mail.close()
print("Sent")
(you dont have to use gmail as most addresses will still work through the gmail smtp)
If email is not required, you can also send chat messages to yourself.
Two projects achieving this :
Nimrod, for Facebook Messenger : https://www.nimrod-messenger.io/
Telegram Middleman, for Telegram : https://github.com/n1try/telegram-middleman-bot
I just wrote a Python decorator for this purpose. You can realize it in one line.
https://github.com/Wenzhi-Ding/py_reminder
from py_reminder import monitor
#monitor('SQL Query of xxx')
def query(sql):
...send your query...
query()
Once this function finishes / or is caught an error, you will get an email notification with some brief information.

How to send an email through gmail using python?

I'm trying to send emails with my gmail account using python. I've already read many questions here and around the Internet, but none of them solved my problem.
The code that I'm using is the following (thanks to rosettacode), which is very similar to many other code snippets that can be found about this topic:
def sendemail(from_addr, to_addr_list, cc_addr_list,
subject, message,
login, password,
smtpserver='smtp.gmail.com:587'):
header = 'From: %s\n' % from_addr
header += 'To: %s\n' % ','.join(to_addr_list)
header += 'Cc: %s\n' % ','.join(cc_addr_list)
header += 'Subject: %s\n\n' % subject
message = header + message
server = smtplib.SMTP(smtpserver)
server.ehlo()
server.starttls()
server.ehlo()
server.login(login,password)
problems = server.sendmail(from_addr, to_addr_list, message)
server.quit()
return problems
My problem is during the login phase. It returns the following error message:
SMTPAuthenticationError: (534, '5.7.14 <https://accounts.google.com/ContinueSignIn?sarp=1&scc=1&plt=AKgnsbsMX\n5.7.14 Z4_8qLgwTbhS2CwFvVApFvRfpIS1Vbbfun6gHcf0D6jgSQ-ixMn79mf3AivveTs9IhYsgq\n5.7.14 pmrp157H4Vmk6-ybAC9u2d2lNMYyy5pdmociqeSxBBwFGEPGJKHKdJpSocx86gzG-im6V-\n5.7.14 hsOeMKiJRAuGZjHUprEwj8oABwLzWQ8vEzovpXk79M-i8cnFseW-PNLxLlsK21WaLHLKmZ\n5.7.14 Ll3tEgQ> Please log in via your web browser and then try again.\n5.7.14 Learn more at\n5.7.14 https://support.google.com/mail/bin/answer.py?answer=78754 dc8sm25406976wib.7 - gsmtp')
I followed the suggested link and I found this answer, but I don't know if it could be the solution.
So, what's the problem? My account's settings? My code?
Google has recently tightened their security. Application that use username/password directly have been deactivated. All users are still able to reactivate these less secure application in their security settings as you have been reading in the link you gave in your question. This is the only solution at this point.
The alternative would be to use an other SMTP server for sending.
The error message you quote says
[..] Please log in via your web browser and then try again.
5.7.14 Learn more at
5.7.14 https://support.google.com/mail/bin/answer.py?answer=78754
This was already discussed in server send emails using gmail smtp gets alerts.
So I'd say that your code is fine and you're dealing with a Google-specific security mechanism.
You could enable Google's 2-step authentication and then generate an application-specific password for your script. I do the same (I also have similar code as you) and it works fine.

Categories

Resources