Reading mails sent from GMail - java

I am using JavaMail to read mail in my Android app. I have tried to cover all combinations i.e Mail sent/received on/from Custom Server/Gmail ID/Live ID.
The problem occurs with SOME of the mails sent from GMail WITH Attachment. I am able to receive the attachment, but the content returns javax.mail.internet.MimeMultipart#44f2e698
Here's the code used to receive and read messages:
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imap");
try {
/* Create the session and get the store for read the mail. */
Session session = Session.getInstance(props, null);
Store store = session.getStore("imaps");
store.connect("imap.gmail.com", Username, Password);
/* Mention the folder name which you want to read. */
Folder inbox = store.getFolder("INBOX");
System.out.println("No of Unread Messages : " + inbox.getUnreadMessageCount());
/* Open the inbox using store. */
inbox.open(Folder.READ_ONLY);
Message messages[] = inbox.getMessages();
Log.d("Inbox", "Message Count: "+inbox.getMessageCount());
for (int i = messages.length - 1 ; i > 0; --i) {
Log.i("ContentType", "ContentType: "+messages[i].getContentType());
Object msgContent = messages[i].getContent();
String content = "";
/* Check if content is pure text/html or in parts */
if (msgContent instanceof Multipart) {
Multipart multipart = (Multipart) msgContent;
Log.e("BodyPart", "MultiPartCount: "+multipart.getCount());
for (int j = 0; j < multipart.getCount(); j++) {
BodyPart bodyPart = multipart.getBodyPart(j);
String disposition = bodyPart.getDisposition();
if (disposition != null && (disposition.equalsIgnoreCase("ATTACHMENT"))) { // BodyPart.ATTACHMENT doesn't work for gmail
System.out.println("Mail have some attachment");
DataHandler handler = bodyPart.getDataHandler();
System.out.println("file name : " + handler.getName());
}
else {
System.out.println("Content: "+bodyPart.getContent());
content= bodyPart.getContent().toString();
}
}
}
else
content= messages[i].getContent().toString();
What I know about the problematic mails:
getFrom also return the name i.e it comes in this format FirstName LastName &ltemailID#gmail.com&gt
MultiPart contains 2 BodyParts:
BodyPart 1 returns the content as javax.mail.internet.MimeMultipart#44f2e698
BodyPart 2 returns the correct name for attachment

BodyPart 1 returns the content as
javax.mail.internet.MimeMultipart#44f2e698
Try calling getBodyPart on the MimeMultiPart
That probably returns a MimeBodyPart you can call getContent() on
http://docs.oracle.com/javaee/5/api/javax/mail/internet/MimeBodyPart.html#content

You're probably only handling the simplest case of a text message with attachments. MIME allows much more. You need to learn about the difference between multipart/mixed, multipart/alternative, multipart/related, and multipart/signed. The JavaMail FAQ has more information on handling attachments and the msgshow.java demo program included with the JavaMail download bundle shows how to process messages with nested multiparts.

Related

why the reply mail is sent as attachment when I send it to outlook account using javamail?

I tried in many ways to get the reply in same thread using outlook account and javamail api but iam not able to get reply in same thread instead iam getting as attachment.
I tried to copy whole content and save in current message even then iam getting as attachment, also tried to change the content disposition as inline still it didn't work
you can find the code below which i had tried.
Properties properties = new Properties();
Session emailSession = Session.getDefaultInstance(properties,null);
store = emailSession.getStore("imaps");
store.connect(host,mailbox_username, mailbox_password);
folder = store.getFolder("Inbox");
folder.open(Folder.READ_WRITE);
Message[] unreadMessages = folder.search(new FlagTerm(new Flags(Flags.Flag.SEEN),false));
if(unreadMessages.size()>0)
{
for (int i = 0; i < unreadMessages.length; i++)
{
log.info("retriving message "+(i+1))
Message message = unreadMessages[i]
Address[] froms = message.getFrom();
String senderEmailAddress =(froms[0]).getAddress();
if(senderEmailAddress.endsWith("#gmail.com"))
{
subject = message.getSubject()
log.info(message.getSubject())
}
else
{ //reply to same mail here we need to reply to the message
Message message2 = new MimeMessage(emailSession);
message2= (MimeMessage) message.reply(false);
message2.setSubject("RE: " + message.getSubject());
//message2.setFrom(new InternetAddress(from));
message2.setReplyTo(message.getReplyTo());
message2.addRecipient(Message.RecipientType.TO, new InternetAddress(senderEmailAddress));
BodyPart messageBodyPart = new MimeBodyPart();
content = "some reply message"
//multipart.addBodyPart(content);
messageBodyPart.setText(content);
Multipart multipart = new MimeMultipart("related");
multipart.addBodyPart(messageBodyPart);
messageBodyPart = new MimeBodyPart();
//messageBodyPart.setDataHandler(message.getDataHandler());
//bodyPart.setDataHandler(new DataHandler(ds));
//messageBodyPart.setHeader("Content-Type", "image/jpeg; name=image.jpg");
//messageBodyPart.setHeader("Content-ID", "<image>");
//messageBodyPart.setHeader("Content-Disposition", "inline");
//messageBodyPart.addBodyPart(bodyPart);
//msg.setContent(content);
messageBodyPart.setDisposition(MimeBodyPart.INLINE);
messageBodyPart.setContent(message, "message/rfc822");
messageBodyPart.setDataHandler(message.getDataHandler());
// Add part to multi part
multipart.addBodyPart(messageBodyPart);
// Associate multi-part with message
message2.setContent(multipart);
Transport t = emailSession.getTransport("smtp");
try {
t.connect(mailbox_username, mailbox_password);
t.sendMessage(message2, message2.getAllRecipients());
} finally {
t.close();
}
}
}
}
"inline" vs. "attachment" is just advice for the mail reader. Many ignore the device, or aren't capable of displaying all content types inline.
If you want the text of the original message to appear in the body of the reply message (e.g., indented with ">"), you need to extract the original text and reformat it appropriately, adding it to the text of the reply, then set that new String as the content of the reply message.

JavaMail MimeBodyPart is not being added to MimeMultipart "properly"

Let it be clear that Java is working correctly. The problem is with the programmer!
I need to add 3 attachments to an email (1 zip, 1 png, 1 jpeg). Initially I wrote code that can add each item on it's own - and it works. Then to add all 3 items at the same time I took the same code (with very minor modifications) and put it in a for loop. This is where I am having an issue. The loop adds 3 attachments to the email, but the problem is that all the attachments are same identical attachment. Specifically, the first two attachments that should be attached in the first 2 iterations of the for loop are not attached, and the third attachment (the attachment that is up to bat at the third iteration) is attached 3 times.
I read the Java docs, I tried all kinds of changes and I am having a hard time understanding where I am going wrong. The reality is that I don't have enough programming ability to move forward. I'm stuck. Any advice would be greatly appreciated! I attached most of the class, but the real problem is in the for loop - why are all 3 unique objects not being attached?
Thanks in advance.
try
{
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(userLogin));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(primaryRecipient));
MimeBodyPart bodyPart = new MimeBodyPart(); //container to hold the email contents (body only - the text)
bodyPart.setText(emailBody);
MimeMultipart multipart = new MimeMultipart();
multipart.addBodyPart(bodyPart);
MimeBodyPart mimePart = new MimeBodyPart();
String filename; //hold the current path
FileDataSource resource;//object to grab the physical resource
for(int i = 0; i < itemsToAttach.length; i++)
{
filename = itemsToAttach[i];
System.out.println("Test: " + itemsToAttach[i]);//#############################test only
resource = new FileDataSource(filename);
mimePart.setDataHandler(new DataHandler(resource));
mimePart.setFileName(filename);//###########fix the long ugly name
multipart.addBodyPart(mimePart);
System.out.println("multipart contents: " + multipart.toString());
}
message.setContent(multipart);
message.setSubject(emailSubject);
Transport.send(message);
System.out.println("Sent message successfully....");
}
catch (MessagingException e)
{
throw new RuntimeException(e);
}
The output looks like this:
The file is present!
Sending cc to: mikexxxxxxx#hotmail.com
Sending bcc to: mikexxxxxx#gmail
Test: C:\Users\Mike\workspace\Z_ToTransfer\Assig4_SendEmails\part2_send_email_with_attachment\attachments\test attachments.zip
multipart contents: javax.mail.internet.MimeMultipart#164da25
Test: C:\Users\Mike\workspace\Z_ToTransfer\Assig4_SendEmails\part2_send_email_with_attachment\attachments\axiom.jpeg
multipart contents: javax.mail.internet.MimeMultipart#164da25
Test: C:\Users\Mike\workspace\Z_ToTransfer\Assig4_SendEmails\part2_send_email_with_attachment\attachments\another attachment.png
multipart contents: javax.mail.internet.MimeMultipart#164da25
Sent message successfully....
Looks like you are reusing the same object and it is getting overwritten on every iteration of the loop. Thant's why the only entry persists is the last mimepart when you send the message:
You can do following:
Create a different object of MimebodyPart for every new file:
MimeBodyPart[] mimePart = new MimeBodyPart[itemsToAttach.length];
String filename; //hold the current path
FileDataSource resource;//object to grab the physical resource
for(int i = 0; i < itemsToAttach.length; i++)
{
mimePart[i] = new MimeBodyPart();
filename = itemsToAttach[i];
System.out.println("Test: " + itemsToAttach[i]);//#############################test only
resource = new FileDataSource(filename);
mimePart[i].setDataHandler(new DataHandler(resource));
mimePart[i].setFileName(filename);//###########fix the long ugly name
multipart.addBodyPart(mimePart[i]);
System.out.println("multipart contents: " + multipart.toString());
}

How to get filename of all attachements of email?

I am trying to get the filename of all the attachements of emails using java and imap.My code is:
MimeMessage msg = (MimeMessage) messages[i];
String fileName = msg.getFileName();
System.out.println("The file name of this attachment is " + fileName);
but it prints null always even if email contain attachment..I have seen different codes on SO but none worked...and I don't know what to do if attachment is more than one .
PS:I only want to get the filename and don't want to download attachments.
First, to determine if a message may contain attachments using the following code:
// suppose 'message' is an object of type Message
String contentType = message.getContentType();
if (contentType.contains("multipart")) {
// this message may contain attachment
}
Then we must iterate through each part in the multipart to identify which part contains the attachment, as follows:
Multipart multiPart = (Multipart) message.getContent();
for (int i = 0; i < multiPart.getCount(); i++) {
MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(i);
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {
// this part is attachment
// code to save attachment...
}
}
And to save the file, you could do:
part.saveFile("D:/Attachment/" + part.getFileName());
Source
there is an easier way with apache commons mail:
final MimeMessageParser mimeParser = new MimeMessageParser(mimeMessage).parse();
final List<DataSource> attachmentList = mimeParser.getAttachmentList();
for (DataSource dataSource: attachmentList) {
final String fileName = dataSource.getName();
System.out.println("filename: " + fileName);
}
I was facing the same issue when the email contained another email as an attachment. The content-disposition of such an attachment does not contain fileName.
String contentType = message.getContentType();
List<String> attachmentFiles = new ArrayList<String>();
if(contentType.contains("multipart"))
{
Multipart multiPart = (Multipart)message.getContent();
int numberOfParts = multiPart.getCount();
for(int partCount = 0; partCount < numberOfParts; partCount++)
{
MimeBodyPart part = (MimeBodyPart)multiPart.getBodyPart(partCount);
if(Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {
String fileName = part.getFileName();
String extension = FilenameUtils.getExtension(fileName);
//If the attachment is an email, fileName will be null.
if ("message/rfc822".equalsIgnoreCase(part.getContentType())) {
MimeMessage tempMessage = new MimeMessage(null, part.getInputStream());
fileName = tempMessage.getSubject()+".eml"; //all the email attachments will be converted to .eml format.
extension = "eml";
}
File tempEmailFile = File.createTempFile(messageId + "_" + partCount , "." + extension);
part.saveFile(tempEmailFile);
attachmentFiles.add(fileName);
attachmentFiles.add(tempEmailFile.getAbsolutePath());
}
}
}
Reference: javamail also extract attachments of encapsulated message Content-Type: message/rfc822

Javamail Parsing Email Body with 7BIT Content-Transfer-Encoding

I've been implementing an feature to read email file. If the file have attachment, return attachment name.
Now I'm using Javamail library to parse email file. Here is my code.
public static void parse(File file) throws Exception {
InputStream source = new FileInputStream(file);
MimeMessage message = new MimeMessage(null, source);
Multipart multipart = (Multipart) message.getContent();
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
String disposition = bodyPart.getDisposition();
if (disposition != null
&& disposition.equalsIgnoreCase(Part.ATTACHMENT)) {
System.out.println("FileName:"
+ MimeUtility.decodeText(bodyPart.getFileName()));
}
}
}
It works fine but when email file have 7bit Content-Transfer-Encoding, bodyPart.getFileName() make NullPointerException.
Is there any way to get attachement name when email is 7bit Content-Transfer-Encoding?
Sorry for my poor English.
Edited: Here is some info about my test file.
(X-Mailer: Mew version 2.2 on Emacs 21.3 / Mule 5.0 (SAKAKI)); (Mime-Version:1.0):(Content-Type: Multipart/Mixed); (Content-Transfer-Encoding: 7bit)
If my answer does not work, show the stack trace.
Use a Session, as that probably is the only thing being null.
Properties properties = new Properties();
Session session = Session.getDefaultInstance(properties);
MimeMessage message = new MimeMessage(session, source);
Not all attachments have a filename. You need to handle that case.
And you don't need to decode the filename.
You can handle the case of "attachments not having a name" in this way:
String fileName = (bodyPart.getFileName() == null) ? "your_filename"
: bodyPart.getFileName();

I want to attach multiple files in outlook calendar invite using java

I want to attach multiple files inside a calendar invite using java.
Currently i am able to create an invite with the html body text but i am not able to add attachments to that invite.
Does anyone knows how to attach files.
I am not sending the invite as attachment. It is going as normal accept/decline way.
Please post ASAP .
Thanks in advance
CODE AS FOLLOWS :
MimetypesFileTypeMap mimetypes = (MimetypesFileTypeMap) MimetypesFileTypeMap.getDefaultFileTypeMap();
mimetypes.addMimeTypes("text/calendar ics ICS");
MailcapCommandMap mailcap = (MailcapCommandMap) MailcapCommandMap.getDefaultCommandMap();
mailcap.addMailcap("text/calendar;; x-java-content-handler=com.sun.mail.handlers.text_plain");
Properties props = new Properties();
props.setProperty("mail.transport.protocol", " ");
props.setProperty("mail.host", mailServer);
//props.setProperty("mail.user", "emailuser");
//props.setProperty("mail.password", "");
Session mailSession = Session.getDefaultInstance(props, null);
MimeMessage message = new MimeMessage(mailSession);
//message.addHeaderLine("text/calendar;method=REQUEST;charset=UTF-8");
/* String emailAddress = invite_email;
String fullName = invite_name;*/
String emailAddress = "XYZ#aBC.com";
String fullName = "ABCD";
message.setFrom(new InternetAddress(replyEmail, replyEmailName));
javax.mail.Address address = new InternetAddress(emailAddress, fullName);
message.addRecipient(MimeMessage.RecipientType.TO, address);
message.setSubject("abc" + invite_sub);
// Create a Multipart
Multipart multipart = new MimeMultipart("alternative");
//part 1, html text
BodyPart messageBodyPart = buildHtmlTextPart(team_id);
multipart.addBodyPart(messageBodyPart);
// Add part two, the calendar
BodyPart calendarPart = buildCalendarPartNew(emailAddress , fullName , invite_sub , invite_uuid ,start_date , finish_date , invite_seq , invite_status , invite_timezone );
multipart.addBodyPart(calendarPart);
// Add attachments to the body
multipart = addAttachment(multipart,Req_List);
//update the requisition id list back to " " once the attachment process is over
Req_List = " ";
// Put parts in message
System.out.println("setting the content of message");
message.setContent(multipart);
// send message
try {
Transport transport = mailSession.getTransport();
transport.connect();
transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO));
transport.close();
}
catch (Exception ex) {
System.out.println(ex.toString());
throw ex;
}
THE FUNCTION FOR ATTACHMENT MAINLY CONTAINS :
FileDataSource fds1 = new FileDataSource(sharepath_name);
attachment.setDataHandler(new DataHandler(fds1));
attachment.setFileName(fds1.getName());
attachment.setHeader("MIME-Version", "1.0");
attachment.setHeader("Content-Type", " "+mime_type+ "; name=\"" + sharepath_name + "\"");
attachment.setHeader("Content-Disposition", "attachment; filename=\"" + sharepath_name + "\"");
attachment.setHeader("Content-Transfer-Encoding", "base64");
multipart.addBodyPart(attachment);
return multipart;
there is no error as such , the invite is getting generated with the text , but the main problem is i want attachments inside the invite, i am not able to attach files inside the invite, i don't know how to attach files inside invite ?
Also the attachments i need to provide multiple attachments inside the invite.
Thanks in advance
Have you tried without setting the attachment headers manually? They should be set by MimeMessage.

Categories