Fred (The Silva) 0 Posted June 10 Hi. How can I retrieve INBOX email messages in Indy 10.6.2, using "TIdIMAP4SearchRec" for *only* (filtering): > "UnSeen" messages > "Recent" messages > Messages that have the word 'Sales' on Subject Thanks, Share this post Link to post
Remy Lebeau 1330 Posted June 10 Call the TIdIMAP4.(UID)SearchMailBox() method, providing it with an array of desired filter criteria. It will populate the TIdIMAP4.MailBox.SearchResult list with numbers/UIDs of matching emails, which you can then download with any of the various TIdIMAP4.(UID)Retrieve...() methods. Share this post Link to post
Fred (The Silva) 0 Posted June 10 the issue is: having var LEMailSearchInfo : array of TIdIMAP4SearchRec; if I do: SetLength(LEMailSearchInfo, 1); LEMailSearchInfo[0].SearchKey := skUnseen; it find a new (unseen) messages If I do: SetLength(LEMailSearchInfo, 2); LEMailSearchInfo[0].SearchKey := skUnseen; LEMailSearchInfo[1].SearchKey := skRecent; it didn't find the messages Where can I get a tutorial on how to use and combine all TIdIMAP4SearchKey enum options? Share this post Link to post
Remy Lebeau 1330 Posted June 10 (edited) 2 hours ago, Fred (The Silva) said: If I do: SetLength(LEMailSearchInfo, 2); LEMailSearchInfo[0].SearchKey := skUnseen; LEMailSearchInfo[1].SearchKey := skRecent; it didn't find the messages That will search for messages that are flagged as both UNSEEN AND RECENT. If you want to search for UNSEEN OR RECENT instead, you will have to add a 3rd array entry for the skOr search key: OR <search-key1> <search-key2> For example: SetLength(LEMailSearchInfo, 3); LEMailSearchInfo[0].SearchKey := skOr; LEMailSearchInfo[1].SearchKey := skUnseen; LEMailSearchInfo[2].SearchKey := skRecent; If you want to add a 3rd OR filter, you will need a 2nd skOk entry, eg: SetLength(LEMailSearchInfo, 5); LEMailSearchInfo[0].SearchKey := skOr; LEMailSearchInfo[1].SearchKey := skOr; LEMailSearchInfo[2].SearchKey := skUnseen; LEMailSearchInfo[3].SearchKey := skRecent; LEMailSearchInfo[4].SearchKey := skSubject; LEMailSearchInfo[4].Text := 'Sales'; // or: LEMailSearchInfo[4].SearchKey := skHeader; LEMailSearchInfo[4].FieldName := 'Subject'; LEMailSearchInfo[4].Text := 'Sales'; Quote Where can I get a tutorial on how to use and combine all TIdIMAP4SearchKey enum options? There isn't one, unfortunately. The (UID)SearchMailBox() methods are just a thin wrapper for the IMAP SEARCH command, so you'll have to read RFC 3501 Section 6.4.4 for how search semantics work. Also, https://stackoverflow.com/questions/12809709/ has some good information about using multiple ORs with IMAP search. Edited June 10 by Remy Lebeau Share this post Link to post
softtouch 5 Posted June 19 @Remy Lebeau, to not to open a new thread, because my question is related: When I want to get emails when a specific text exist in the body, and another text does not exist, can I do it like this? SetLength(sr,3); sr[0].key:=skNot; sr[1].key:=skBody; sr[1].text:='This should not be in the body'; sr[2].key:=skBody; sr[2].text:='This must be in th ebody'; Share this post Link to post
Remy Lebeau 1330 Posted June 20 4 hours ago, softtouch said: When I want to get emails when a specific text exist in the body, and another text does not exist, can I do it like this? Did you try it and see what happens? (BTW, you have a typo in your search text, maybe that is contributing to you not being able to find emails?) Offhand, what you show looks OK to me, as it would create this SEARCH command: SEARCH NOT BODY "This should not be in the body" BODY "This must be in th ebody" Which is logically treated like this: SEARCH (NOT BODY "This should not be in the body") AND (BODY "This must be in th ebody") But, if that doesn't work for you, then try reversing the order of the search keys: SetLength(sr,3); sr[0].key:=skBody; sr[0].text:='This must be in th ebody'; sr[1].key:=skNot; sr[2].key:=skBody; sr[2].text:='This should not be in the body'; Which creates the command: SEARCH BODY "This must be in th ebody" NOT BODY "This should not be in the body" Which is treated as: SEARCH (BODY "This must be in th ebody") AND (NOT BODY "This should not be in the body") If it still doesn't work, then which email provider are you connected to, exactly? Outlook 365, for instance, seems to be troublesome in regards to BODY searches (or at least, it was a couple of years ago): https://answers.microsoft.com/en-us/outlook_com/forum/all/office365-imap-does-not-return-the-email-when-body/0a98b753-bb0d-4fa3-9488-773b98d8acc4 https://stackoverflow.com/questions/66034478/outlook-imap-search-not-returning-correct-value-with-body-search-criteria Share this post Link to post
softtouch 5 Posted June 20 17 hours ago, Remy Lebeau said: Did you try it and see what happens? (BTW, you have a typo in your search text, maybe that is contributing to you not being able to find emails?) Offhand, what you show looks OK to me, as it would create this SEARCH command: SEARCH NOT BODY "This should not be in the body" BODY "This must be in th ebody" Which is logically treated like this: SEARCH (NOT BODY "This should not be in the body") AND (BODY "This must be in th ebody") But, if that doesn't work for you, then try reversing the order of the search keys: SetLength(sr,3); sr[0].key:=skBody; sr[0].text:='This must be in th ebody'; sr[1].key:=skNot; sr[2].key:=skBody; sr[2].text:='This should not be in the body'; Which creates the command: SEARCH BODY "This must be in th ebody" NOT BODY "This should not be in the body" Which is treated as: SEARCH (BODY "This must be in th ebody") AND (NOT BODY "This should not be in the body") If it still doesn't work, then which email provider are you connected to, exactly? Outlook 365, for instance, seems to be troublesome in regards to BODY searches (or at least, it was a couple of years ago): https://answers.microsoft.com/en-us/outlook_com/forum/all/office365-imap-does-not-return-the-email-when-body/0a98b753-bb0d-4fa3-9488-773b98d8acc4 https://stackoverflow.com/questions/66034478/outlook-imap-search-not-returning-correct-value-with-body-search-criteria I tried it and it seems to work. I assume if I have multiple "NOT" criteria, I need to do it like this? sr[0].key:=skNot; sr[1].key:='skBody; sr[1].text:='This should not be in the body'; sr[2].key:='skBody; sr[2].text:='This should also not be in the body'; So when it see the skNot, it will use only the next criteria for the skNot or until it get another sk??? criteria? Share this post Link to post
Remy Lebeau 1330 Posted June 20 (edited) 18 minutes ago, softtouch said: I tried it and it seems to work. I covered that in my earlier reply. That example is performing: "SEARCH NOT BODY <body1> BODY <body2>" which AFAIK is treated as: "(NOT BODY <body1>) AND (BODY <body2>)" 18 minutes ago, softtouch said: I assume if I have multiple "NOT" criteria, I need to do it like this? NOT takes only 1 condition as input. If you want multiple NOT conditions, you need multiple NOTs in the array, 1 for each condition, ie: "SEARCH NOT <criteria1> NOT <criteria2>" which is treated as: "(NOT <criteria1>) AND (NOT <criteria2>)" or: "SEARCH NOT OR <critera1> <criteria2>" which is treated as: "NOT (<criteria1> OR <criteria2>)" Quote So when it see the skNot, it will use only the next criteria for the skNot or until it get another sk??? criteria? Only 1 criteria per NOT. Please read RFC 3501 Section 6.4.4 Edited June 20 by Remy Lebeau Share this post Link to post