I was wondering if anyone was able to figure out this one yet.
steps:
1. Grab email from IMAP/POP3 box
2. Transform to a set of attachments
3. Save attachments in a specific folder based on email subject or attachment name
here what I have come up with, however it's not working yet. I was able to save the text of the email as text (set transformer-refs of imap to "EmailToByteMessage"), but saving the attachments did not work. Am I on the right path?
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:imap="http://www.mulesoft.org/schema/mule/imap"
xmlns:file="http://www.mulesoft.org/schema/mule/file"
xmlns:email="http://www.mulesoft.org/schema/mule/email"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.0/mule.xsd
http://www.mulesoft.org/schema/mule/email http://www.mulesoft.org/schema/mule/email/3.0/mule-email.xsd
http://www.mulesoft.org/schema/mule/imap http://www.mulesoft.org/schema/mule/imap/3.0/mule-imap.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/3.0/mule-file.xsd">
<imap:connector name="imapConnector" backupEnabled="true" backupFolder="newBackup" checkFrequency="5000" mailboxFolder="INBOX" deleteReadMessages="true"/>
<file:connector name="receiveConnector" fileAge="500" autoDelete="true" pollingFrequency="100"/>
<email:mime-to-bytes-transformer name="EmailToByteMessage"/>
<expression-transformer name="getAttachment0">
<return-argument evaluator="attachment" expression="0"/>
</expression-transformer>
<model>
<service name="ServiceSaveEmailToFile">
<description>Save email to File</description>
<inbound>
<imap:inbound-endpoint user="$USER" port="$PORT" password="$PASSWORD" host="$HOST" disableTransportTransformer="true" transformer-refs="EmailToByteMessage getAttachment0"/>
</inbound>
<outbound>
<pass-through-router>
<file:outbound-endpoint path="./test" outputPattern="last_${DATE}_email.txt" />
</pass-through-router>
</outbound>
</service>
</model>
</mule>
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email
I have attached 20091127.htm to plain text email.
Expression Evaluator "attachment" with expression "#[attachment:20091127]" returned null
Expression Evaluator "attachment" with expression "#[attachment:20091127.htm]" returned null
The attachment-list expression have also returned null.
That did not solve the problem. It is I am sure the right way to go, although I can't figure out the right configuration.
Does anyone have a working example of save attachments from the pop3/imap emails?
Edited by: Vladimir Baranov on Sep 24, 2010 2:39 PM
The attachment-list expression have also returned null.
Do you happen to have any sample source code that uses attachments-list:{all} expression-transformer?
Vladimir
Thank you!
1. Could not find a transformer to transform "javax.mail.internet.MimeBodyPart" to "java.io.InputStream".
My configuration looks as:
<email:email-to-string-transformer name="EmailToByteMessage"/>
<expression-transformer name="getAttachment0">
<return-argument evaluator="attachment" expression="#attachment-list:{all}"/>
</expression-transformer>
...
<inbound>
<imap:inbound-endpoint connector-ref="mailIn"
host="mailserver"
port="245"
user="username"
password="password"
transformer-refs="EmailToByteMessage getAttachment0">
</imap:inbound-endpoint>
</inbound>
<echo-component/>
<outbound>
<multicasting-router>
<file:outbound-endpoint
path="email/inbox/msg"
outputPattern="${DATE:HH-mm-ss.SSS}-${COUNT}.dat"/>
</multicasting-router>
</outbound>
1. Could not find a transformer to transform "javax.mail.internet.MimeBodyPart" to "java.io.InputStream".
<echo-component/>
<outbound>
<multicasting-router>
<file:outbound-endpoint
path="email/inbox/msg"
outputPattern="${DATE:HH-mm-ss.SSS}-${COUNT}.dat"/>
</multicasting-router>
</outbound>
Thanks. I tried that configuration you suggested as below:
<email:email-to-string-transformer name="EmailToByteMessage"/>
<expression-transformer name="getAttachment0">
<return-argument evaluator="attachment" expression="#attachments-list:*"/>
</expression-transformer>
<service name="sample-service">
<inbound>
<imap:inbound-endpoint connector-ref="mailIn"
host="mailserver"
port="143"
user="username"
password="secret" transformer-refs="EmailToByteMessage getAttachment0">
</imap:inbound-endpoint>
</inbound>
<outbound>
<list-message-splitter-router>
<file:outbound-endpoint path="email/inbox/msg" outputPattern="last_${DATE}_email.txt">
<expression-transformer>
<return-argument expression="payload.inputStream"
evaluator="groovy" />
</expression-transformer>
</file:outbound-endpoint>
</list-message-splitter-router>
</outbound>
</service>
And it generated the following error:
********************************************************************************
Message : Failed to route event via endpoint: null. Message payload is of type: MimeBodyPart
Type : org.mule.api.routing.RoutingException
Code : MULE_ERROR-39999
JavaDoc : http://www.mulesource.org/docs/site/current2/apidocs/org/mule/api/routing/RoutingException.html
Payload : javax.mail.internet.MimeBodyPart@5f845f84
********************************************************************************
Exception stack is:
1. Object "javax.mail.internet.MimeBodyPart" not of correct type. It must be of type "java.util.List" (java.lang.IllegalArgumentException)
org.mule.routing.outbound.ListMessageSplitter:40 (http://java.sun.com/j2se/1.5.0/docs/api/java/lang/IllegalArgumentException.html)
2. Failed to route event via endpoint: null. Message payload is of type: MimeBodyPart (org.mule.api.routing.RoutingException)
org.mule.routing.outbound.DefaultOutboundRouterCollection:97 (http://www.mulesource.org/docs/site/current2/apidocs/org/mule/api/routing/RoutingException.html)
********************************************************************************
Root Exception stack trace:
java.lang.IllegalArgumentException: Object "javax.mail.internet.MimeBodyPart" not of correct type. It must be of type "java.util.List"
at org.mule.routing.outbound.ListMessageSplitter.splitMessage(ListMessageSplitter.java:40)
at org.mule.routing.outbound.AbstractRoundRobinMessageSplitter.getMessageParts(AbstractRoundRobinMessageSplitter.java:92)
at org.mule.routing.outbound.AbstractMessageSplitter.route(AbstractMessageSplitter.java:37)
at org.mule.routing.outbound.DefaultOutboundRouterCollection$1.doInTransaction(DefaultOutboundRouterCollection.java:88)
at org.mule.transaction.TransactionTemplate.execute(TransactionTemplate.java:45)
at org.mule.routing.outbound.DefaultOutboundRouterCollection.route(DefaultOutboundRouterCollection.java:93)
at org.mule.service.AbstractService.dispatchToOutboundRouter(AbstractService.java:867)
at org.mule.model.seda.SedaService.dispatchToOutboundRouter(SedaService.java:552)
at org.mule.model.seda.SedaService$ComponentStageWorker.run(SedaService.java:575)
at org.mule.work.WorkerContext.run(WorkerContext.java:310)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1061)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:575)
at java.lang.Thread.run(Thread.java:811)
********************************************************************************
I really appreciate any further help.
Thanks for keeping me straight here. I did change the syntax to what you specified. But my problem really is that with an email-to-string-converter on the inbound endpoint along with the attachment expression, it was complaining about the list-message-splitter not expecting a MimeBodyPart - but requires a java.util.List.
So, I used the other expression-transformer that you specified for payload.stream, and now I get the following error.
[10/11/10 10:00:27:289 EDT] 00000023 DefaultServic E org.mule.AbstractExceptionListener logException
********************************************************************************
Message : Expression Evaluator "attachments-list" with expression "*" returned null but a value was required.
Type : org.mule.api.transformer.TransformerException
Code : MULE_ERROR-65263
Transformer : ExpressionTransformer{this=2adc2adc, name='getAttachment0', ignoreBadInput=false, returnClass=class java.lang.Object, sourceTypes=[class java.lang.Object]}
JavaDoc : http://www.mulesource.org/docs/site/current2/apidocs/org/mule/api/transformer/TransformerException.html
********************************************************************************
Exception stack is:
1. Expression Evaluator "attachments-list" with expression "*" returned null but a value was required. (org.mule.api.transformer.TransformerException)
org.mule.expression.transformers.ExpressionTransformer:65 (http://www.mulesource.org/docs/site/current2/apidocs/org/mule/api/transformer/TransformerException.html)
********************************************************************************
Root Exception stack trace:
org.mule.api.transformer.TransformerException: Expression Evaluator "attachments-list" with expression "*" returned null but a value was required.
at org.mule.expression.transformers.ExpressionTransformer.transform(ExpressionTransformer.java:65)
at org.mule.transformer.AbstractMessageAwareTransformer.doTransform(AbstractMessageAwareTransformer.java:68)
at org.mule.transformer.AbstractTransformer.transform(AbstractTransformer.java:254)
at org.mule.DefaultMuleMessage.applyAllTransformers(DefaultMuleMessage.java:621)
at org.mule.DefaultMuleMessage.applyTransformers(DefaultMuleMessage.java:582)
at org.mule.DefaultMuleMessage.applyTransformers(DefaultMuleMessage.java:575)
at org.mule.DefaultMuleEvent.transformMessage(DefaultMuleEvent.java:326)
at org.mule.DefaultMuleEvent.transformMessage(DefaultMuleEvent.java:321)
at org.mule.component.simple.PassThroughComponent.doInvoke(PassThroughComponent.java:27)
at org.mule.component.AbstractComponent.invokeInternal(AbstractComponent.java:133)
at org.mule.component.AbstractComponent.invoke(AbstractComponent.java:161)
at org.mule.service.AbstractService.invokeComponent(AbstractService.java:929)
at org.mule.model.seda.SedaService.access$100(SedaService.java:56)
at org.mule.model.seda.SedaService$ComponentStageWorker.run(SedaService.java:574)
at org.mule.work.WorkerContext.run(WorkerContext.java:310)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1061)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:575)
at java.lang.Thread.run(Thread.java:811)
********************************************************************************
But all that I am trying to do is simple - listen to an IMAP endpoint and copy the message and the attachment to a file location (my ultimate goal is to put those documents in an ECM solution).
Thanks
Anand
Would you mind sharing with the group what configuration is working for you. As you can see in the thread, I am trying to do the same thing and save an attachment but not having any luck.
Thanks
Anand
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:imap="http://www.mulesoft.org/schema/mule/imap"
xmlns:file="http://www.mulesoft.org/schema/mule/file"
xmlns:email="http://www.mulesoft.org/schema/mule/email"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.0/mule.xsd
http://www.mulesoft.org/schema/mule/email http://www.mulesoft.org/schema/mule/email/3.0/mule-email.xsd
http://www.mulesoft.org/schema/mule/imap http://www.mulesoft.org/schema/mule/imap/3.0/mule-imap.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/3.0/mule-file.xsd">
<imap:connector name="imapConnector" backupEnabled="true" backupFolder="newBackup" checkFrequency="5000" mailboxFolder="INBOX" deleteReadMessages="false"/>
<file:connector name="receiveConnector">
<file:expression-filename-parser/>
</file:connector>
<email:mime-to-bytes-transformer name="EmailToByteMessage"/>
<email:email-to-string-transformer name="emailToString" />
<expression-transformer name="getAttachment0">
<return-argument evaluator="attachments-list" expression="#[attachments-list:*]"/>
</expression-transformer>
<model>
<service name="ServiceSaveEmailToFile">
<description>Save email to File</description>
<inbound>
<imap:inbound-endpoint user="USER" port="143" password="PASSWORD" host="HOST" disableTransportTransformer="true"/>
</inbound>
<outbound>
<list-message-splitter-router>
<file:outbound-endpoint path="./test" connector-ref="receiveConnector" transformer-refs="getAttachment0" outputPattern="mail-#[function:datestamp].pdf"/>
<payload-type-filter expectedType="java.util.List"/>
</list-message-splitter-router>
</outbound>
</service>
</model>
</mule>
When I have the Payload Filter, nothing happens - other than the message that nothing matches the type of payload. When I don't have the Payload filter, it complains that a Mime Type Body Part is not compatible with java.util.List - which is what a List message splitter expects. Of course, one caveat is that I am still using 2.2 where as you appear to be using 3.0.
Any suggestions any one?
Thanks
Anand
I can only offer suggestions if you will be using 3.0.
-Vladimir
I tried something similar with POP3 but failed. Although not with
Mule, http://www.esbcompare.org/2010/10/download-email-and-save-attachments.html
seemed quite handy. Meanwhile I got tied up with other work, and I
will revisit this issue again later, and hopefully someone will share
a configuration with Mule by then
Thanks, Prince J
So, I switched to Mule 3. I tried the configuration you have provided and I get 2 different errors.
First, with the payload filter in place, I get the following:
**********************************************************************
WARN 2010-11-01 14:17:10,071 [s1.2] org.mule.routing.outbound.DefaultOutboundRouterCollection: Message did not match an
y routers on: s1 and there is no catch all strategy configured on this router. Disposing message
Without the payload filter, I get the following:
**********************************************************************
* Application: mailqueue *
* OS encoding: Cp1252, Mule encoding: UTF-8 *
* *
* Agents Running: *
* JMX Agent *
* Wrapper Manager: Mule PID #5368, Wrapper PID #3832 *
**********************************************************************
ERROR 2010-11-01 14:10:24,304 [s1.2] org.mule.exception.DefaultServiceExceptionStrategy:
********************************************************************************
Message : Failed to route event via endpoint: org.mule.routing.outbound.ListMessageSplitter@788315. Messag
e payload is of type: String
Code : MULE_ERROR-39999
--------------------------------------------------------------------------------
Exception stack is:
1. Object "java.lang.String" not of correct type. It must be of type "java.util.List" (java.lang.IllegalArgumentExceptio
n)
org.mule.routing.outbound.ListMessageSplitter:40 (null)
2. Failed to route event via endpoint: org.mule.routing.outbound.ListMessageSplitter@788315. Message payload is of type:
String (org.mule.api.routing.RoutingException)
org.mule.routing.outbound.AbstractOutboundRouter:118 (http://www.mulesoft.org/docs/site/current2/apidocs/org/mule/api/
routing/RoutingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.lang.IllegalArgumentException: Object "java.lang.String" not of correct type. It must be of type "java.util.List"
at org.mule.routing.outbound.ListMessageSplitter.splitMessage(ListMessageSplitter.java:40)
at org.mule.routing.outbound.AbstractRoundRobinMessageSplitter.getMessageParts(AbstractRoundRobinMessageSplitter
.java:95)
at org.mule.routing.outbound.AbstractMessageSplitter.route(AbstractMessageSplitter.java:45)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
This clearly indicates that I should have payload filter. However, there appears to be some other transformationn that needs to happen. I am trying to connect to Microsoft Exchange - not sure that is causing some other issues.
Thanks
Anand
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:imap="http://www.mulesource.org/schema/mule/imap/2.2"
xmlns:vm="http://www.mulesource.org/schema/mule/vm/2.2"
xmlns:file="http://www.mulesource.org/schema/mule/file/2.2"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.mulesource.org/schema/mule/core/2.2 http://www.mulesource.org/schema/mule/core/2.2/mule.xsd
http://www.mulesource.org/schema/mule/imap/2.2 http://www.mulesource.org/schema/mule/imap/2.2/mule-imap.xsd
http://www.mulesource.org/schema/mule/vm/2.2 http://www.mulesource.org/schema/mule/vm/2.2/mule-vm.xsd
http://www.mulesource.org/schema/mule/file/2.2 http://www.mulesource.org/schema/mule/file/2.2/mule-file.xsd">
<imap:connector name="imapConnector"/>
<vm:connector name="vmConnector" queueEvents="true"/>
<custom-transformer name="attachmentToInputStream"
class="DataHandlerToInputStream"/>
<expression-transformer name="returnAttachments">
<return-argument evaluator="attachments-list" expression="{all}" optional="false"/>
</expression-transformer>
<model name="testImap">
<service name="attachmentWriter">
<inbound>
<imap:inbound-endpoint user="user" password="password" host="imap.gmail.com" port="993"
transformer-refs="returnAttachments"/>
</inbound>
<outbound>
<list-message-splitter-router>
<file:outbound-endpoint path="./.mule/out" outputPattern="last_${DATE}_email.txt">
<transformer ref="attachmentToInputStream"/>
</file:outbound-endpoint>
</list-message-splitter-router>
</outbound>
</service>
</model>
</mule>
---------------------------------------------------------------------
Here is the config:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:smtp="http://www.mulesource.org/schema/mule/smtp/2.2"
xmlns:imap="http://www.mulesource.org/schema/mule/imap/2.2"
xmlns:email="http://www.mulesource.org/schema/mule/email/2.2"
xmlns:file="http://www.mulesource.org/schema/mule/file/2.2"
xmlns:jms="http://www.mulesource.org/schema/mule/jms/2.2"
xmlns:vm="http://www.mulesource.org/schema/mule/vm/2.2"
xsi:schemaLocation="
http://www.mulesource.org/schema/mule/core/2.2 http://www.mulesource.org/schema/mule/core/2.2/mule.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.mulesource.org/schema/mule/smtp/2.2 http://www.mulesource.org/schema/mule/smtp/2.2/mule-smtp.xsd
http://www.mulesource.org/schema/mule/imap/2.2 http://www.mulesource.org/schema/mule/imap/2.2/mule-imap.xsd
http://www.mulesource.org/schema/mule/email/2.2 http://www.mulesource.org/schema/mule/email/2.2/mule-email.xsd
http://www.mulesource.org/schema/mule/file/2.2 http://www.mulesource.org/schema/mule/file/2.2/mule-file.xsd
http://www.mulesource.org/schema/mule/jms/2.2 http://www.mulesource.org/schema/mule/jms/2.2/mule-jms.xsd
http://www.mulesource.org/schema/mule/vm/2.2 http://www.mulesource.org/schema/mule/vm/2.2/mule-vm.xsd">
<imap:connector name="mailIn"
mailboxFolder="INBOX"
checkFrequency="60000"
deleteReadMessages="true"/>
<smtp:connector name="mailOut"
contentType="text/plain"
fromAddress="donot...@company.com"
replyToAddresses="in...@company.com"/>
<vm:connector name="vmConnector" queueEvents="true"/>
<expression-transformer name="returnAttachments">
<return-argument evaluator="attachments-list" expression="{all}" optional="false"/>
</expression-transformer>
<file:connector name="fileName">
<file:expression-filename-parser/>
</file:connector>
<custom-transformer name="ImapTrans" class="org.mule.transport.email.transformers.TransformerImapToObject"/>
<custom-transformer name="ExtractMapfileName" class="org.mule.transport.email.transformers.ExtractMapfileName" />
<custom-transformer name="attachmentToInputStream"
class="org.mule.transport.email.transformers.DataHandlerToInputStream"/>
<model name="M2">
<service name="S2">
<inbound>
<imap:inbound-endpoint connector-ref="mailIn"
host="server"
port="143"
user="username"
password="password" transformer-refs="ImapTrans"/>
</inbound>
<outbound>
<list-message-splitter-router>
<vm:outbound-endpoint path="ListElement"/>
</list-message-splitter-router>
</outbound>
</service>
<service name="S3">
<inbound>
<vm:inbound-endpoint path="ListElement" transformer-refs="ExtractMapfileName"/>
</inbound>
<outbound>
<multicasting-router>
<file:outbound-endpoint path="./.mule/out" connector-ref="fileName" outputPattern="#[header:FileName]"/>
</multicasting-router>
</outbound>
</service>
</model>
</mule>
And the attached Java files. This worked for me in an embedded mule deployment (Websphere 6.1) going after an Exchange 2003 mail box. The file names are preserved and had to come up with a kludge to name the core message also as a .msg file.
Thanks
Anand