Email Attachment Info when Downloading from IMAP without Attachments

If the Imap.AutoDownloadAttachments property is set to false, or if headers-only are downloaded, then emails will be downloaded without attachments.  However, attachment information, such as the count, and the size and filename of each attachment is still available.

When an email is downloaded from an IMAP server without the attachment data, the attachment information is added as headers to the email:

  • ckx-imap-numattach: contains the number of attachments.
  • ckx-imap-attach-nm-{N}: contains the name of the Nth attachment, where N begins at 1 for the 1st attachment.  For example “ckx-imap-attach-nm-1”
  • ckx-imap-attach-sz-{N}: contains the size in bytes of the Nth attachment.

The IMAP API provides methods for getting this information:

  • GetMailNumAttach
  • GetMailAttachSize
  • GetMailAttachFilename

Each of these methods begins with the string “GetMail”, and the 1st argument is the email object from which the information is to be retrieved.  If the “ckx-imap-*” header is not found, then it returns the information provided by the email object itself:

  • GetMailNumAttach:  If the ckx-imap-numattach header is not present, it returns the value of the emailObject.NumAttachments property.   (where emailObject is the email object passed to GetMailNumAttach)
  • GetMailAttachSize: If the ckx-imap-attach-sz-* header is not present, it calls emailObject.GetAttachmentSize and returns its value.
  • GetMailAttachFilename: If the ckx-imap-attach-nm-* header is not present, it calls emailObject.GetAttachmentFilename and returns its value.

The Chilkat.Email object (CkEmail, CkoEmail, etc.) also has properties and methods for getting attachment information.  However, these apply to attachments that are already downloaded and present within the email object.  For example:

  • Email.NumAttachments:  This property returns the number of attachments that are fully present within the email object.
  • Email.GetAttachmentFilename:  This method returns the filename of the Nth attachment that is already fully present in the email object.
  • Email.GetAttachmentSize:  Again, it returns the size in bytes of the Nth attachment that is fully present in the email object.

IMAP: Download email without attachments and downloading attachments separately.

Chilkat version 9.3.0, being released this week, includes new IMAP functionality to fetch emails without downloading attachments, and then subsequently fetch attachments one at a time separately.

There is a new boolean property named “AutoDownloadAttachments”, which has  a default value of True (YES).  If set to False (NO), then all Fetch* methods will not download attachments.

Note:  “related” items are downloaded.  These are images, style sheets, etc. that are embedded within the
HTML body of an email, and are not considered attachments.

Also:  All signed and/or encrypted emails must be downloaded in full.

When an email is downloaded without attachments, the attachment information is included in header fields.  The header fields have names beginning with “ckx-imap-“.  The attachment information can be obtained via the following methods:

imap.GetMailNumAttach
imap.GetMailAttachFilename
imap.GetMailAttachSize

Individual attachments can be downloaded via the newly added FetchAttachment* methods:

  1. FetchAttachment:  Downloads an attachment and saves to a file.
  2. FetchAttachmentBytes:  Downloads an attachment to an in-memory byte array.
  3. FetchAttachmentString: Downloads an attachment to a string variable.

Here are the FetchAttachment* method signatures in Objective-C:

// method: FetchAttachment
– (BOOL)FetchAttachment: (CkoEmail *)email
attachIndex: (NSNumber *)attachIndex
saveToPath: (NSString *)saveToPath;

// method: FetchAttachmentBytes
– (NSData *)FetchAttachmentBytes: (CkoEmail *)email
attachIndex: (NSNumber *)attachIndex;

// method: FetchAttachmentString
– (NSString *)FetchAttachmentString: (CkoEmail *)email
attachIndex: (NSNumber *)attachIndex
charset: (NSString *)charset;

IMAP: Sequence numbers change when deleting (but not UID’s)

Question:

When using IMAP and fetching emails by sequence, does looping through the sequence get affected by deleting in mid-sequence or other changes to the mailbox’s content on the server?

Answer:

The answer is obtained by examining the IMAP specification (RFC 3501).  Here’s what it says:

2.3.1.2.        Message Sequence Number Message Attribute

   A relative position from 1 to the number of messages in the mailbox.
   This position MUST be ordered by ascending unique identifier.  As
   each new message is added, it is assigned a message sequence number
   that is 1 higher than the number of messages in the mailbox before
   that new message was added.

   Message sequence numbers can be reassigned during the session.  For
   example, when a message is permanently removed (expunged) from the
   mailbox, the message sequence number for all subsequent messages is
   decremented.  The number of messages in the mailbox is also
   decremented.  Similarly, a new message can be assigned a message
   sequence number that was once held by some other message prior to an
   expunge.

   In addition to accessing messages by relative position in the
   mailbox, message sequence numbers can be used in mathematical
   calculations.  For example, if an untagged "11 EXISTS" is received,
   and previously an untagged "8 EXISTS" was received, three new
   messages have arrived with message sequence numbers of 9, 10, and 11.
   Another example, if message 287 in a 523 message mailbox has UID
   12345, there are exactly 286 messages which have lesser UIDs and 236
   messages which have greater UIDs.

GMail Labels are just IMAP Mailboxes

Question:
I’m going to be using them in VB.Net to process a GMail inbox. In GMail they use Labels instead of folders. Are the labels that belong to an email visible via your tool?

Ideally the VB application would process the inbox, and perform actions based on the label.

Answer:
I investigated and it refreshed my memory. GMail “labels” are just IMAP mailboxes. You can refer to the samples at http://www.example-code.com for VB.NET –> IMAP. You’ll find examples that list the mailboxes on the server. If you run it, you’ll see the labels listed. For example:

INBOX
Trash
[Gmail]
[Gmail]/All Mail
[Gmail]/Drafts
[Gmail]/Sent Mail
[Gmail]/Spam
[Gmail]/Starred
[Gmail]/Trash

VB6 Error — “TYPE MISMATCH (ERROR CODE 13)” w/ IMAP Search method

This happens if the Chilkat ActiveX objects are dragged and dropped onto your formvia the “Project–>Components” menu. Instead, add a reference to the objects via the “Project–>References” menu.

Instances of the object should be created dynamically. For example:

Dim imap as ChilkatImap
Set imap = New ChilkatImap

IMAP Authentication using OAUTH

Using the Chilkat IMAP component/library, it is possible to authenticate using OAUTH via the SendRawCommand method. Instead of calling the imap.Login method, you would instead call imap.SendRawCommand as shown here:

string response = imap.SendRawCommand("AUTHENTICATE XOAUTH <base64_data>"); 

Your application will need to compute the OAUTH base64 string. Chilkat does not implement that computations required for generating the OAUTH data.

IMAP Login: BAD Command received in Invalid state.

This error can happen if you connect to an IMAP server without SSL/TLS (i.e. at port 143) but the server does not allow unsecure sessions.  Oddly enough, the Microsoft Exchange IMAP4 server will accept the connection, but will fail any login attempt with this error.  Here is a sample SessionLog:

Connecting to IMAP server at xxxx.com:143
> ----IMAP RESPONSE----
> * OK The Microsoft Exchange IMAP4 service is ready.
> ----IMAP REQUEST----
> aaab LOGIN "mylogin"
> ----IMAP RESPONSE----
> aaab BAD Command received in Invalid state.

The solution is to use port 993 w/ SSL/TLS. Do this by setting the Chilkat.Imap.Port property = 993, and the Chilkat.Imap.Ssl property = True prior to connecting.