Avanti
Avanti

Reputation: 333

Find the subject of a specific email - imap -python

I need to find an email whose subject is 'Reset Password' from a particular sender named - xteam and then do some further actions with that mail

If I do this:

 imap_host = 'imap.gmail.com'
 imap_user = '[email protected]'
 imap_pass = 'pass113'

 imap = imaplib.IMAP4_SSL(imap_host)

 imap.login(imap_user, imap_pass)   
 status, message = imap.search(None, '(SUBJECT "Reset Password")')

There are many other senders in addition to xteam who have sent emails with 'Reset Password' subject

then I tried:

 status, message = imap.search(None, '(FROM "[email protected]")')

but xteam has sent many other irrelevant emails

Lastly:

 status, message = imap.search(None, '(AND (FROM "[email protected]") (SUBJECT "Reset Password"))')

This gives error:

imaplib.IMAP4.error: SEARCH command error: BAD [b'Could not parse command']

Which is the best possible way to do it.

Upvotes: 0

Views: 4670

Answers (1)

BoarGules
BoarGules

Reputation: 16942

The search function doesn't decode bracketed strings: it is expecting multiple parameters:

status, message = imap.search(None, 'FROM', "[email protected]", 'SUBJECT', "Reset Password")

AND does not need to be specifed because it is the default so brackets are meaningless. The OR operator doesn't need brackets either, because it takes only two operands. You can't do OR tag1 value1 tag2 value2 tag3 value3 because that would mean OR tag1 value1 tag2 value2 [AND] tag3 value3. Instead you do OR OR tag1 value1 tag2 value2 tag3 value3. Because of the rule about only two operands, that is implicitly bracketed as if it were OR ( OR tag1 value1 tag2 value2 ) tag3 value3. This Polish notation makes the IMAP parser easier to write, at the cost of of making complex queries involving OR difficult to get right. Below is the complete syntax for what a search key can look like:

search      = "SEARCH" [SP "CHARSET" SP astring] 1*(SP search-key)

but using imaplib you can leave the encoding as None to get the default. You can have multiple search-keys of the form

search-key  = "ALL" / "ANSWERED" / "BCC" SP astring /
              "BEFORE" SP date / "BODY" SP astring /
              "CC" SP astring / "DELETED" / "FLAGGED" /
              "FROM" SP astring / "KEYWORD" SP flag-keyword /
              "NEW" / "OLD" / "ON" SP date / "RECENT" / "SEEN" /
              "SINCE" SP date / "SUBJECT" SP astring /
              "TEXT" SP astring / "TO" SP astring /
              "UNANSWERED" / "UNDELETED" / "UNFLAGGED" /
              "UNKEYWORD" SP flag-keyword / "UNSEEN" /
              "DRAFT" / "HEADER" SP header-fld-name SP astring /
              "LARGER" SP number / "NOT" SP search-key /
              "OR" SP search-key SP search-key /
              "SENTBEFORE" SP date / "SENTON" SP date /
              "SENTSINCE" SP date / "SMALLER" SP number /
              "UID" SP sequence-set / "UNDRAFT" / sequence-set /
              "(" search-key *(SP search-key) ")"

As the last line shows, you can include brackets but they must be separate parameters.

Upvotes: 3

Related Questions