Polling Email Attachments in Mule
Polling Email Attachments in Mule
How can you use Mule to poll emails, extract attachments, and save them to a directory so that they can be picked up and processed further by another flow or application?
Join the DZone community and get the full member experience.Join For Free
While coding in Mule, you may face a scenario in which you need to extract and process purchase orders, sales orders, or other business documents. This is a standard case of automating the order lifecycle implemented in middleware. It’s a classic use case of polling emails, extracting the attachments, and saving the attachments to a particular directory so that they can be picked up and processed further by another Mule flow or other application. We will utilize the APIs provided by Mule.
In this post, I will just demonstrate the skeleton of the application. If your requirement demands transformation on the attachment, feel free to modify the flow to suit your business needs. Let’s get started.
1. Create a Mule Flow
This is demonstrated below:
For the inbound reference, you need to drag and drop the IMAP adapter. This adapter is based on the javax.mail API. Again, no coding is involved. Just provide the below details for polling inbound emails:
- HOST (for example, Imap.gmail.com)
- PORT = 993
- USERNAME (your Gmail or any other mail ID)
- PASSWORD (your email password or application-specific password; use the secure property placeholder for saving passwords)
- POLL directory (your email folder from where you need to poll the attachments; default null is inbox)
- ARCHIVE directory (email folder where the emails would be moved after processing; it's best practice to provide this)
2. Drag and Drop an Expression Filter Component
We are using this component to process only those emails that contain Mulesoft as its subject. Otherwise, the message will be rejected.
<expression-filter expression="#[message.inboundProperties.subject contains 'Mulesoft']" doc:name="Expression_if_Subject_contains_Mulesoft"/>
3. Loop Through and Save the Email Attachments
Save all the attachments with their proper name to a directory specified. Drag and drop the for-each component and insert two components inside it. One is set-payload and another is the file adapter as demonstrated below:
<foreach collection="#[message.inboundAttachments]" doc:name="ForEach_Attachment_from_mail"> <set-payload value="#[payload]" encoding="utf-8" mimeType="application/zip" doc:name="setPayload_as_Attachement"/> <file:outbound-endpoint path="C:\Users\VIBHOR\PO" outputPattern="#[flowVars.key]" connector-ref="File1" responseTimeout="10000" doc:name="Store_to_File"/> </foreach>
4. Make a Sub-Flow and Send a Confirmation Email
The confirmation email will tell the sender that the PO# which they sent through email got processed successfully. You need to use the SMTP adapter to achieve this (for example, to send the outbound mails from Mulesoft). Here is the code to achieve this:
<sub-flow name="send_CE_SubFlw"> <set-payload value="'Hello Your message has been posted successfully'" doc:name="set_message"/> <smtp:outbound-endpoint host="smtp.gmail.com" port="587" user="firstname.lastname@example.org" password="yourpWd" connector-ref="Gmail" to="#[sessionVars.sender]" subject="NNTO:Your file has been read successfully" responseTimeout="10000" doc:name="SMTP"/> </sub-flow>
Note: If you are getting an authentication error while using the IMAP or the SMTP connection, you need to make sure to do the following:
Enable the property "Allow less secure apps to be able to read and write emails (Gmail)" in your mail provider console.
If you have two-step authentication enabled in your email provider, use the application specific password instead of a normal password.
Enable SSL (HTTPS) if your email provider requires that.
If you face any difficulty, please feel free to reach out to me.
Opinions expressed by DZone contributors are their own.