Skip to Content
Technical Articles

Filtering email attachments on filename or Content-Type with Groovy script

Recently I faced a use case in which a integration flow needed to be built capable of filtering specific attachments from incoming emails which required separate processing.  The code required to use the attachment content as payload is already available in this excellent blog by Morten Wittrock. However, in order to be able to apply filtering specific on attachment name and/or content-type a better understanding of how to retrieve this information is required. Therefore, in this blog we will investigate the involved attachment objects further.

 

Recap: groovy script to check and iterate attachments

The code block below shows  a variant of the Groovy script of Morten’s blog, which is the base of our use case. First we want to check if there are any attachments. if this is the case we will iterate over the attachment objects.  To achieve this we make use of two Groovy functions:

  • isEmpty(): check if the attachment Map is empty
  • values(): creates a collection of all the values in the Map which can be iterated

I prefer the values() approach over working with a while loop and hasNext() check, it keeps the code clean.

import com.sap.gateway.ip.core.customdev.util.Message
import java.util.Map
import java.util.Iterator
import javax.activation.DataHandler

def Message processData(Message message) {
	Map<String, DataHandler> attachments = message.getAttachments();
	if (attachments.isEmpty()) {
		// Handling of missing attachment goes here
	} else {
                //Handling of available attachments
		attachments.values().each{ attachment ->
		     //Processing of attachment data
		}
	}
	return message;
}

Adding attachment filtering

In order to achieve filtering we now have to look into the attachment object into detail. The object is of type javax.activation.DataHandler and is described as The DataHandler class provides a consistent interface to data available in many different sources and formats. If we examine the available methods closeley we find the two methods we require for filtering:

  • getName: returns the name of the object, in this case the full filename of the attachment
    • Example value: <filename>.pdf
  • getContentType: returns the MIME type with full parameters
    • Example value: application/pdf; name=<filename>.pdf

Note that also character set can be part of the getContentType method for example.

Putting it all together

Now we have all the required filter data available we can complete the script. Below are two examples: one which filters the Content-Type of having a PDF document, the other filters on specific file. The easiest way is to use the contains method to search for the existence of the key words. Both result in putting the file content as payload in the integration flow, as was in the earlier referenced blog.

import com.sap.gateway.ip.core.customdev.util.Message
import java.util.Map
import java.util.Iterator
import javax.activation.DataHandler

def Message processData(Message message) {
	Map<String, DataHandler> attachments = message.getAttachments();
	if (attachments.isEmpty()) {
		// Handling of missing attachment goes here
	} else {
		//Handling of available attachments
		attachments.values().each{ attachment ->
			if(attachment.getContentType().contains("pdf")){
				message.setBody(attachment.getContent());
			}
		}
	}
	return message;
}

 

import com.sap.gateway.ip.core.customdev.util.Message
import java.util.Map
import java.util.Iterator
import javax.activation.DataHandler

def Message processData(Message message) {
	Map<String, DataHandler> attachments = message.getAttachments();
	if (attachments.isEmpty()) {
		// Handling of missing attachment goes here
	} else {
		//Handling of available attachments
		attachments.values().each{ attachment ->
			if(attachment.getName().contains("<full or partial filename>")){
				message.setBody(attachment.getContent());
			}
		}
	}
	return message;
}

 

Possible extensions

One of the things which can easily be done is to apply additional processing of the semicolon separated headers in the getContentType method in order to get it in a list structure. This can be achieved by using the split function on the content.

Additionally, in many cases the attachment files would go to particular SFTP locations to be stored. This can be achieved storing the name of the attachment in a header of property. Additionally, you can set the filename dynamically from the groovy script by using the variable CamelFileName, as shown in this excellent blog by Sriprasad Shivaram Bhat.

Concluding, there is a lot of flexibility in processing available thanks to combination of Java and Groovy objects. It opens the door to a lot of interesting uses cases and system connections!

Be the first to leave a comment
You must be Logged on to comment or reply to a post.