5
votes

I am building a system where intranet users are allowed to drag and drop files into a div on our ColdFusion site, which after some validation will then automatically upload them to a file server. One of my requirements is: when the file which was uploaded is a .msg file (Outlook Email), extract any files which are attachments to that email and upload them individually. This is possible using the org.apache.poi.hsmf.MAPIMessage Java object. With the following code I am able to see each attachment object listed out. I can then get their filenames and extensions and save each one to the local file system.

However, this does not work if the attachment is another .msg file. When I call getEmbeddedAttachmentObject() on an attached .msg file, it returns an object which contains only "undefined". Non .msg files return a binary object which I can then pass into the FileWrite() ColdFusion function. Further examination of the MAPIMessage object shows that it has a write() method, but upon calling it I get an error stating:

Note - writing is not yet supported for this file format, sorry.

This is backed up by the documentation on http://poi.apache.org as well.

To summarize, I can write each email message attachment to the file system without a problem, unless the attachment is another email message. Am I out of luck or is there another way to accomplish this?

<cfscript>
  // Load test .msg into MAPIMessage object
  MAPIMessage = createObject("java", "org.apache.poi.hsmf.MAPIMessage");
  message = MAPIMessage.init('C:\Test\Test Email 1 Attachment.msg');

  // Get array of attached files
  attachments = message.getAttachmentFiles();

  // If attachments were found
  if(arrayLen(attachments) > 0) {

    // Loop over each attachment
    for (i=1; i LTE arrayLen(attachments); i++) {

      // Dump the current attachment object
      writeDump( attachments[i] );

      // Get current attachment's binary data
      local.data=attachments[i].getEmbeddedAttachmentObject();

      // Dump binary data
      writeDump( local.data );

      // Get attachment's filename and extension
      attachmentFileName = attachments[i].attachLongFileName.toString();
      attachmentExtension = attachments[i].attachExtension.toString();

      // Dump filename and extension
      writeDump( attachmentFileName );
      writeDump( attachmentExtension );

      // Write attachment to local file system     
FileWrite("#expandPath('/')##attachments[i].attachLongFileName.toString()#", local.data);

   }
  }
</cfscript>
1

1 Answers

0
votes

After much research I found a solution to my problem. I was not able to save an embedded msg file using org.apache.poi.hsmf.MAPIMessage java object which ships with ColdFusion due to the not yet implemented write() method. Instead, I used a 3rd party tool called Aspose.Email for Java Aspose is a paid product, and is the only way that I was able to accomplish what I needed to do.

Here is my implementation. This does everything I need it to.

        local.msgStruct.attachments = [];

        // Create MapiMessage from the passed in .msg file
        MapiMessage = createObject("java", "com.aspose.email.MapiMessage");
        message = MapiMessage.fromFile(ARGUMENTS.msgFile);

        // Get attachments
        attachments = message.getAttachments();
        numberOfAttachments = attachments.size();

        // If attachments exist
        if(numberOfAttachments > 0) {

            // Loop over attachments
            for ( i = 0; i LT numberOfAttachments; i++) {

                // Get current Attachment
                currentAttachment = attachments.get_Item(i);

                // Create struct of attachment info
                local.attachmentInfo = {};
                local.attachmentInfo.fileName = currentAttachment.getLongFileName();
                local.attachmentInfo.fileExtension = currentAttachment.getExtension();

                // If an attachmentDestination was specified
                if(ARGUMENTS.attachmentDestination NEQ ''){

                // Ignore inline image attchments (mostly email signature images)
                if( NOT (left(local.attachmentInfo.fileName, 6) EQ 'image0' AND local.attachmentInfo.fileExtension EQ '.jpg') ){

                    // Get attachment object data (only defined for Outlook Messages, will return undefined object for other attachment types)
                    attachmentObjectData = currentAttachment.getObjectData();

                    // Check if attachment is an outlook message
                    if( isDefined('attachmentObjectData') AND attachmentObjectData.isOutlookMessage()){
                        isAttachmentOutlookMessage = 'YES';
                    } else {
                        isAttachmentOutlookMessage = 'NO';
                    }

                    ////////////////////////////
                    // ATTACHMENT IS AN EMAIL //
                    ////////////////////////////
                    if( isAttachmentOutlookMessage ){

                        // Get attachment as a MapiMessage
                        messageAttachment = currentAttachment.getObjectData().toMapiMessage();

                        // If an attachmentDestination was specified
                        if(ARGUMENTS.attachmentDestination NEQ ''){

                            // Set file path
                            local.attachmentInfo.filePath = ARGUMENTS.attachmentDestination;

                            // Set file path and file name
                            local.attachmentInfo.filePathAndFileName = ARGUMENTS.attachmentDestination & local.attachmentInfo.fileName;

                            // Save attachment to filesystem
                            messageAttachment.save(local.attachmentInfo.filePathAndFileName);
                        }

                    ////////////////////////////////
                    // ATTACHMENT IS NOT AN EMAIL //
                    ////////////////////////////////
                    } else {

                        // If an attachment destination was specified
                        if(ARGUMENTS.attachmentDestination NEQ ''){

                            // Set file path
                            local.attachmentInfo.filePath = ARGUMENTS.attachmentDestination;

                            // Set file path and file name
                            local.attachmentInfo.filePathAndFileName = ARGUMENTS.attachmentDestination & local.attachmentInfo.fileName;

                            // Save attachment to filesystem
                            currentAttachment.save(local.attachmentInfo.filePathAndFileName);
                        }
                    }

                    // Verify that the file was saved to the file system
                    local.attachmentInfo.savedToFileSystem = fileExists(ARGUMENTS.attachmentDestination & local.attachmentInfo.fileName);

                    // Add attachment info struct to array
                    arrayAppend(local.msgStruct.attachments,local.attachmentInfo);

                } // End ignore inline image attachments

            } // End loop over attachments

        } // End if attachments exist