imapc++builderindyc++builder-xe8

Download email attachment files using Indy IMAP4 in C++ Builder


I am looking for a step by step solution on how to download mail attachments using Indy Imap in C++ Builder (I use C++ Builder XE8). I have read some tutorial in Delphi, but really getting Confused.

For example, what should I do after selecting the mailbox?

ImapClient->UIDRetrieve()

or

ImapClient->RetrieveStructure()

or

ImapClient->RetrievePart()

or

ImapClient->RetrieveEnvelop().

Then, what should I do next to identify the MessagePart no, haveing the attachment file?

The Last One, how to save that file to local drive?

Should I translate the following in C++?

TIdAttachmentFile(mbMsgP.MessageParts.Items[liCount]).SaveToFile(fName);

But I cant create a statement like this

 TIdAttachmentFile(IdMessage1->MessageParts->items[no])->SaveToFile("filename");

Solution

  • I have read some tutorial in Delphi, but really getting Confused.

    Not surprising, since IMAP is a complex and confusing protocol in general. That is why TIdIMAP4 has so many more methods compared to other mailbox protocols like TIdPOP3 and TIdSMTP (and it doesn't even implement everything IMAP is capable of).

    For example, what should I do after selecting the mailbox?

    ImapClient->UIDRetrieve() or ImapClient->RetrieveStructure() or ImapClient->RetrievePart() od ImapClient->RetrieveEnvelop().

    That really depends on what you intend to do with the emails and their attachments.

    (UID)Retrieve() downloads an entire email, parsing it into a TIdMessage and marking it as "read" on the server.

    (UID)RetrieveStructure() retrieves the parent/child hierarchy of the various MiME parts within an email, creating an entry for each part in a TIdMessage.MessageParts or TIdImapMessageParts collection, providing some basic descriptive information about each part such as content type and part number. The actual content of each part is not retrieved.

    (UID)RetrievePart() retrieves the actual content of a specific MIME part of an email. You do not need to download the entire email. But you do have to download the email's structure first so that you know the part number that you want to retrieve.

    (UID)RetrieveEnvelope() retrieves some basic top-level headers for an email: date, subject, from, sender, reply-to, to, cc, bcc, in-reply-to, and message-id.

    Then, what should I do next to identify the MessagePart no, haveing the attachment file?

    If you download an entire email, you would have to loop through its MessageParts collection looking for a TIdAttachment object containing the desired filename/contenttype that you are interested in.

    If you download just a part of an email, you would have to retrieve the email's structure and loop through the resulting collection looking for an entry containing the desired filename/contenttype that you are interested in, then you can request that specific part's content.

    The Last One, how to save that file to local drive?

    If you download an entire email, then you would call SaveToFile() on the desired TIdAttachment object:

    static_cast<TIdAttachment*>(IdMessage1->MessageParts->Items[no])->SaveToFile("filename");
    

    If you download an email's structure, you can use (UID)RetrievePart() to retrieve the attachment's data into a TStream object, such as a TFileStream.