Skip to Content
Technical Articles
Author's profile photo Morten Wittrock

Replacing the message body with an attachment

A few days ago I answered this interesting question by Florian Kube in the Questions & Answers area. It struck me that the solution might be of more general interest, so in this blog post I’m going to expand a bit on my answer.

Florian’s scenario is this: He picks up an email with a sender Mail channel. The email has an XML attachment, and it is the contents of this attachment, he wants to process. He therefore needs to replace the message body with the attached XML document, and then proceed with mapping and so forth.

I’m going to show you how to solve this problem using scripting. The code is written in Groovy, but if your prefer JavaScript, translating it is straightforward.

Methods of the Message class

Access to the body and attachments of a message is provided by the com.sap.gateway.ip.core.customdev.util.Message object, which the runtime passes to your Groovy function. The API documentation available for this interface is available here.

The two methods, we are going to use, are getAttachments and setBody. The former returns a java.util.Map object containing the message’s attachments, and the latter sets a new message body.

Extracting the attachment contents

Let us deal with the attachment first, since that is the more complicated part. The keys of the Map returned by getAttachments are attachment names, and the values are javax.activation.DataHandler objects. The DataHandler objects contain the actual attachment data. Given the scenario, we assume that the Map contains exactly one attachment, but we do not know its key ahead of time.

In order to get the Map’s only value without knowing its associated key, I retrieve the Collection of all the Map’s values and iterate it once. The code looks like this (required import statements not shown):

Map<String, DataHandler> attachments = message.getAttachments()
Iterator<DataHandler> it = attachments.values().iterator()
DataHandler attachment = it.next()

(You could combine the three lines into a single line, if you are so inclined, but that would make the intention of the code less clear, IMHO.)

Setting the message body

The DataHandler class offers a couple of different ways to get at the wrapped data. We are going to use the getContent method, which returns a java.lang.Object object. Why? Because an Object instance is what the setBody method of the Message class expects. Here is the code that replaces the message body:

message.setBody(attachment.getContent())

Putting the pieces together

We are now ready to put it all together. Here is the complete script:

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()
   Iterator<DataHandler> it = attachments.values().iterator()
   DataHandler attachment = it.next()
   message.setBody(attachment.getContent())
   return message
}

In order to use it, put the code in a Script step at the very beginning of your integration flow. After this step, proceed with whatever processing your scenario requires.

How to handle messages with no attachments

Keep in mind that the script assumes that the message has exactly one attachment. If it does not have any attachments, the code will fail. Determining why it fails, is left as an exercise for the reader 🙂

If this assumption is not always met in your particular scenario, you can test for the presence of attachments, by checking whether the Map returned by getAttachments is empty. You do this by calling its isEmpty method as follows:

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 {
      Iterator<DataHandler> it = attachments.values().iterator()
      DataHandler attachment = it.next()
      message.setBody(attachment.getContent())
   }
   return message
}

Assigned Tags

      17 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Rajanikanth Kristam
      Rajanikanth Kristam

      Nice blog. Tells power of Groovy scripting .

      Author's profile photo Former Member
      Former Member

      Nice blog.

       

      Best Regards,

      Harsh B.

      Author's profile photo T. van Rooijen
      T. van Rooijen

      Hi Morten,

       

      I am looking for a way to add an attachment generated in a groovy script (a pdf file) to the header of the message so I can use it in the receiver mailadapter.

      So at the start of the script there is no attachment, just a message body with text, which is written to a pdf file using itext.

      What I cannot figure out is how to pass this on to the headers. Most of the examples I see work with strings and I guess the pdf file is an object of some sort.

       

      Thanks & Regards

      Tom

       

      Author's profile photo Morten Wittrock
      Morten Wittrock
      Blog Post Author

      Hi Tom

      I'm sorry that I didn't get back to you sooner. Just in case you haven't already found a solution: You can add the PDF in Groovy with a few lines of code. I wrote a short blog post about how you do that. You can find it here.

      Regards,

      Morten

      Author's profile photo Former Member
      Former Member

      Hi  Morten,

       

      Is this possible to update attachment content using script ?  or remove attachment?

       

      Thanks and Regards

      Eric

      Author's profile photo Jacques Otto
      Jacques Otto

      Hi Morten,

       

      Thanks for the excellent blogs, I am having a strange issue.   As in your previous blogs, in the first step in my Iflow I am using the script to try to create an attachment, to save the payload in that attachment, and then later in my Iflow I want to read that attachment value again to use it as the resulting message body.

       

      But for some reason it does not seem like the attachment is being created successfully.  As when I try to read it later down the line, nothing is found.

      Any help would be greatly appreciated.

      Author's profile photo Morten Wittrock
      Morten Wittrock
      Blog Post Author

      Hi Jacques

      I suggest that your post your question in the Q&A section, using the tag "SAP Cloud Platform Integration for process services". Provide as much detail as is needed. Include, for instance, your script code. Then myself and others will have a closer look.

      Regards,

      Morten

      Author's profile photo Jacques Otto
      Jacques Otto

      Thanks Morten.

      I played around with it a bit more and I got it working using the details you shared in your Blogs.

      Thank you so much.  Thanks for the great blogs.  Keep up the good work.

       

      Kind Regards
      Jacques Otto

      Author's profile photo Morten Wittrock
      Morten Wittrock
      Blog Post Author

      Hi Jacques

      I'm very happy to hear that 🙂

      Have a nice weekend,

      Morten

      Author's profile photo GargiSugur MohanBabu
      GargiSugur MohanBabu

      Hello Morten,

      How to handle more than one attachments in the script.

       

      Thanks,

      Mohan

      Author's profile photo Morten Wittrock
      Morten Wittrock
      Blog Post Author

      Hi Mohan

      If you have multiple attachments, and you want to replace the payload with one of them, you need some way of identifying that particular attachment. You would need to take a look at the keys in the attachments map, and determine which one to select based on those keys.

      Regards,

      Morten

      Author's profile photo GargiSugur MohanBabu
      GargiSugur MohanBabu

      Hello Morten,

      Thanks for the reply.

      I am able to send one attachment from SOAP UI to the Iflow and i am able to receive to my email with attachment. Now i am trying to test with multiple attachments...but i am able to receive the only one. can you please tell me how to receive all the attachments?

      Thanks,

      Mohan

      Author's profile photo Morten Wittrock
      Morten Wittrock
      Blog Post Author

      Hello again

      Please post this as a question in the Q&A section, and provide all the details of your situation.

      Regards,

      Morten

      Author's profile photo VijeyAananth SR
      VijeyAananth SR

      Hi Experts,

       

      Can any one give me the script to read the attachment id 72488 from below response. I need to use this in another call. Thank you.

      <?xml version="1.0" encoding="utf-8"?>
      <feed xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
      <entry>
      <content type="application/xml">
      <m:properties>
      <d:key>Attachment/attachmentId=72488</d:key>
      <d:status>OK</d:status>
      <d:editStatus>UPSERTED</d:editStatus>
      <d:message>Upserted successfully</d:message>
      <d:index m:type="Edm.Int32">0</d:index>
      <d:httpCode m:type="Edm.Int32">200</d:httpCode>
      <d:inlineResults m:type="Bag(SFOData.UpsertResult)"/>
      </m:properties>
      </content>
      </entry>
      </feed>

       

      Thanks.

      Author's profile photo Sara Barzano Cruz
      Sara Barzano Cruz

      Hi,

      did you manage to solve this?

      Author's profile photo Avinash Malla-Shetty
      Avinash Malla-Shetty

      Hi Morten Wittrock 

      one step forward. could you help me with this question ?

      Mail to SFTP - how to read the attachment name | SAP Community

      Author's profile photo Sindhuja Jayapandiyan
      Sindhuja Jayapandiyan

      Hi Morten Wittrock

       

      We are having issue in reading attachment from mail sender as groovy provided is reading inline embedded images such as signature in the mail also as attachment along with original attachments. Can you please guide us in restricting reading attachment only to original attachment of mail.

      Regards,

      Sindhuja.