MailCore2 - Fetch message content without downloading images or attachments? - ios

I want to provide a preview of a user's messages, but I don't wish to download attachments just in order to do that.
The information I need is:
Subject
Date
Sender information (display name if available, email address)
Plain-text message
By calling the method fetchMessagesByNumberOperationWithFolder: with request kind MCOIMAPMessagesRequestKindHeaders, I get the date and subject, but it's very slow to return if any of the messages have attachments. By calling it with request kind MCOIMAPMessagesRequestKindUid, it returns very quickly, with just the Uid (and the current date, as a placeholder). From there, I still need to get the subject, the date and the sender.
Now I'm still trying to get this information, while avoiding downloading message attachments.
Calling fetchParsedMessageOperationWithFolder: or fetchMessageOperationWithFolder: both download the message with attachments, and are thus very slow to return.
Because fetchMessageOperationWithFolder: completes with a NSData object, checking the size of the given object reveals it to be the size of a regular message, plus its' attachment.
What can I do to get the information I need, without downloading any attachments?
EDIT: Calling requiredPartsForRendering could give me the content of the email, but in order to retrieve the Date and sender information, I'd still have to have a request kind of MCOIMAPMessagesRequestKindHeaders, which would download the attachment.
So to clarify:
I want to get the following information from an IMAP email, without downloading the email attachments:
Subject
Date
Sender information (display name if available, email address)
Plain-text message

The following methods should be helpful to you:
-[MCOAbstractMessage requiredPartsForRendering] will return the message parts that you needs to fetch to be able to show the text content of the message.
-[MCOIMAPSession fetchMessageAttachmentOperationWithFolder:uid:partID:encoding:] will help you fetch each of those parts.
-[MCOIMAPMessage htmlRenderingWithFolder:delegate:] will return the rendered content as HTML (or nil if you don't provide all the content of the parts through the delegate.
-[NSString mco_flattenHTML] is also useful if you'd like to convert the HTML to a unformatted string.

Related

Get Last Email Content From Graph Message

I am wanting to get just the most recent message from an email using Graph. So I don't want the whole email chain, just the body or text content of the most recent email. Is this possible without HTML parsing?
thanks
If you use the UniqueBody property https://learn.microsoft.com/en-au/graph/api/resources/message?view=graph-rest-1.0 that should contain what your after eg
https://graph.microsoft.com/v1.0/me/messages?select=subject,receivedDateTime,conversationid,uniquebody

How to send nested attachments?

Stuck here writing JS code to send out an email via REST within a custom Outlook add-in.
Scenario is following
report
\
\---- another message (item attachment)
\
\------- attachment (file attachment)
In words, I am sending a new report message which includes another message as an Item Attachment (that works fine).
But now, the problem is that, when sending with another message that has attachments, then this fails. Opening the report which has the other message attached doesn't show the attachments.
Query is POST https://outlook.office365.com/api/v2.0/me/sendmail
Returns 202 Accepted
Body is quite long and on this Gist
https://gist.github.com/binarykitchen/2b95331c5c85e7cb4ca6f6917dc67a67
You can see Message has Attachments which has an Item Attachment (attaching another message) which has one file attachment called "bat_kitten.jpeg"
How come this sent message doesn't have this file attachment but server still responds with accepted 202?
Maybe some parameters are wrong? Not sure what to set for ContentId and ContentLocation for that file attachment?
Or are nested attachments not supported yet?
Any clues would be very much appreciated.

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");
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.

IMAP FETCH Subject

Using IMAP via telnet, I want to be able to extract the subject from the specific given email. Now I know that the fetch command is responsible for getting data from an email.
My question is, how do I get the subject header specifically, without using a call to BODY[HEADER.FIELDS (SUBJECT)] (which will, in the eyes of the server, 'open the email' and thus set the /seen flag, which is what I don't want to occur)?
I understand FETCH FULL returns the full header, which contains the subject but it's a nightmare to parse through and could be riddled with unseen pitfalls if I manually parse it. How would I get the server to give me just the subject from the header?
I discovered the answer:
BODY.PEEK[HEADER.FIELDS (SUBJECT)]
.PEEK tells it not open it (so /seen isn't set).
Besides BODY.PEEK, you could fetch ENVELOPE, which gives you a parsed summary of much of the message metadata.
"a1 FETCH 1:* (FLAGS BODY[HEADER.FIELDS (SUBJECT DATE FROM)])\r\n"

Is this a proper implementation of PUT idempotency and what should the response be?

The way I have understood idempotency thus far is basically: If I send 10 identical PUTs to a server the resulting additional resources created will be identical to if I had sent a single PUT statement.
What I take this to mean is that the following implementation would adhere to this:
[AcceptVerbs(HttpVerbs.Put)]
ContentResult User(){
//parse XML that was sent to get User info
//User has an e-mail address which is unique to the system
//create a new user in the system only if one for this e-mail address does not exist
return Content(something, "text/xml");
}
There now if I sent 10 PUTs with XML for User data and they all contain the same e-mail address, only one user will be created.
However, what if they send 10 requests (for whatever reason) and they are all different, but the e-mail is the same. If the first request doesn't make it through then the data of the 2nd request will be used to create the user, and the following 8 requests will be ignored. Is there a flaw here? Or should I literally only ignore requests that are explicitly identical in every way and instead send back an error saying the user already exists if they use the same e-mail address?
Also, what kind of response should be sent from a such PUT statement? Info about the user? Maybe an ID to manipulate them with other API calls? Or perhaps it should just say "success" or "fail: [error details]"?
Your question doesn't reveal the URL where the PUT request is sent to. This is actually very important as it is not the email address within the XML data that dictates whether a new resource is created or an old one updated but the URL that you are sending the request to.
So, if you send PUT to /users/jonh.doe#foo.com/ it either creates the user john.doe#foo.com or updates it if it was already in the system.
Similaraly, if you send PUT to /users/123/ (using id instead of email) it will create or update user 123. However, in this case if the email has to be unique and somebody sends PUT /users/456/ and within that XML is the same email as what the user 123 already has, you have to respond with 409 Conflict.
If the user already exists with the same email address, then the 2nd and subsequent PUT operations should update the data for that resource. The success or failure should be communicated in the status code. If the update succeeds, respond with "200 OK", or "204 No Content"; you can return some information, but don't expect caches to store it as if it were the new representation you would obtain from a GET. If you do not intend for that resource to ever accept a PUT operation other than the first one, then respond instead with "405 Method Not Allowed", with an explanation in the response body. Use "409 Conflict" (again, with an explanation in the response body) if the submitted representation might replace the resource, but can't because it's particular fields cannot be reconciled with the existing state.

Resources