I want to modify or remove the "Message-ID" header when replying to an email with Javamail. After some research I found out I need to create a custom class that extends MimeMessage. Here is the class that I have created.
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
class MyMessage extends MimeMessage
{
public MyMessage(Session session)
{
super(session);
}
#Override
protected void updateMessageID() throws MessagingException {
removeHeader("Message-Id");
}
}
The code below is related to fetching the messages
public List<EmailSenderInfo> checkEmail() throws Exception
{
String host = "HOST";
String username = "MYUSERNAME";
String password = "MYPASS";
List<EmailSenderInfo> emailSenderList = new ArrayList<EmailSenderInfo>();
Properties properties = System.getProperties();
properties.setProperty("mail.store.protocol", "imaps");
Session session = Session.getDefaultInstance(properties);
Store store = session.getStore("imaps");
store.connect(host, username, password);
/*
* Folder[] f = store.getDefaultFolder().list(); for (Folder fd : f)
* System.out.println(">> " + fd.getName());
*/
Folder folder = store.getFolder("INBOX");
if (!folder.exists())
{
System.out.println("No INBOX...");
System.exit(0);
}
folder.open(Folder.READ_WRITE);
Message[] msg = folder.getMessages();
if (msg.length < 1)
{
System.out.println("No new messages!");
throw new Exception("No new messages!");
}
for (int i = 0; i < msg.length; i++)
{
if (!msg[i].isSet(Flag.SEEN))
{
EmailSenderInfo emailSenderInfo = new EmailSenderInfo();
emailSenderInfo.message = msg[i];
System.out.println("------------ Message " + (i + 1) + " ------------");
// String from = InternetAddress.toString(msg[i].getFrom());
Address[] fromArray = msg[i].getFrom();
InternetAddress fromInternetAddress = (InternetAddress) fromArray[0];
String from = fromInternetAddress.getAddress();
String fromName = fromInternetAddress.getPersonal();
if (fromName != null)
{
emailSenderInfo.fromName = fromName;
}
if (from != null)
{
// System.out.println("From: " + from);
emailSenderInfo.from = from;
}
// String replyTo = InternetAddress.toString(msg[i].getReplyTo());
Address[] replyToArray = msg[i].getFrom();
InternetAddress ReplyToInternetAddress = (InternetAddress) replyToArray[0];
String replyTo = ReplyToInternetAddress.getAddress();
String replyToName = ReplyToInternetAddress.getPersonal();
if (replyTo != null)
{
// System.out.println("Reply-to: " + replyTo);
emailSenderInfo.replyTo = replyTo;
}
if (replyToName != null)
{
// System.out.println("Reply-to: " + replyTo);
emailSenderInfo.replyToName = replyToName;
}
String to = InternetAddress.toString(msg[i].getRecipients(Message.RecipientType.TO));
if (to != null)
{
// System.out.println("To: " + to);
emailSenderInfo.to = to;
}
String subject = msg[i].getSubject();
if (subject != null)
{
// System.out.println("Subject: " + subject);
emailSenderInfo.subject = subject;
}
Date sentDate = msg[i].getSentDate();
if (sentDate != null)
{
System.out.println("Sent: " + sentDate);
emailSenderInfo.sentDate = sentDate;
}
String bodyHtml = "";
// get content
Multipart multipart = (Multipart) msg[i].getContent();
for (int x = 0; x < multipart.getCount(); x++)
{
BodyPart bodyPart = multipart.getBodyPart(x);
String disposition = bodyPart.getDisposition();
if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()))
{
// dealing with attachments only
System.out.println("Mail has some attachment : ");
DataHandler handler = bodyPart.getDataHandler();
System.out.println("file name : " + handler.getName());
System.out.println("ddddd: " + bodyPart.getContent().toString());
}
else
{
String classType = bodyPart.getContent().getClass().toString();
if (classType.contains("java.lang.String"))
{
bodyHtml = bodyPart.getContent().toString();
}
else if (classType.contains("javax.mail.internet.MimeMultipart"))
{
MimeMultipart bodyContent = (MimeMultipart) bodyPart.getContent();
for (int b = 0; b < bodyContent.getCount(); b++)
{
IMAPBodyPart imapBody = (IMAPBodyPart) bodyContent.getBodyPart(b);
System.out.println("1: " + imapBody.getContent());
bodyHtml = imapBody.getContent().toString();
// System.out.println("2: " + bodyContent.getBodyPart(b));
// System.out.println("3: " + bodyPart.getContent().toString());
}
}
}
emailSenderInfo.bodyHtml = bodyHtml;
}
MyMessage reply = (MyMessage) msg[i].reply(false);
emailSenderInfo.reply = reply;
// reply.setFrom(msg[i].getFrom()[0]);
MimeMessage orig = (MimeMessage) msg[i];
StringBuffer buffer = new StringBuffer("Thanks\n\n");
if (orig.isMimeType("text/plain"))
{
String content = (String) orig.getContent();
StringReader contentReader = new StringReader(content);
BufferedReader br = new BufferedReader(contentReader);
String contentLine;
while ((contentLine = br.readLine()) != null)
{
buffer.append("> ");
buffer.append(contentLine);
buffer.append("\r\n");
}
}
// Set the reply content
// reply.setText(buffer.toString());
// emailSenderInfo.reply = reply;
emailSenderList.add(emailSenderInfo);
// System.out.println();
}// end if unread
}
folder.close(true);
store.close();
return emailSenderList;
}
I have two methods in my program. One of them checks mail and another one which replies to emails.
Message reply = msg[i].reply(false);
"reply" gets passed to this method along with other parameters.
public void sendReply(String from, String replyTo, Message reply, String messageReply, Boolean attachment) throws Exception
{
String host = "MYHOST";
String username = "MYUSERNAME";
String pass = "MYPASSWORD";
Properties props = System.getProperties();
props.put("mail.smtp.starttls.enable", "true"); // added this line
props.put("mail.smtp.host", host);
props.put("mail.smtp.user", username);
props.put("mail.smtp.password", pass);
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(props);
MimeMessage mimeReply = (MimeMessage) reply;
mimeReply.setFrom((Address) InternetAddress.parse(from)[0]);
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(messageReply, "text/html");
Multipart multipart = new MimeMultipart();
// Set text message part
multipart.addBodyPart(messageBodyPart);
if (attachment)
{
messageBodyPart = new MimeBodyPart();
String filename = "test.jpg";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
}
mimeReply.setContent(multipart);
Transport transport = session.getTransport("smtp");
transport.connect(host, username, pass);
transport.sendMessage(mimeReply, InternetAddress.parse(replyTo));
transport.close();
System.out.println("Message Sent!");
}
I have to use the MyMessage class in order to remove the "Message-ID" header. I have tried the following
MyMessage mimeReply = (MyMessage) reply;
But I get the following error in runtime
java.lang.ClassCastException: javax.mail.internet.MimeMessage cannot be cast to javamailer.MyMessage
How can use "MyMessage" class so I can remove the "Message-ID" header with the reply message?
You can try the following:
When replying to an email:
When you create a message create, right now it should be like:
MimeMessage msg = new MimeMessage(session);
change it to,
MyMessage msg = new MyMessage(session);
When checking email you don't need to remove the header as that message is already in the mailbox, what I think you need to do is when replying to a mail at that instance for the name mail instantiate like :
MyMessage msg = new MyMessage(session);
msg.updateMessageID();
Since you are using reference to existing message:
You can do something like:
Create a new constructor:
public MyMessage (MimeMessage message) {
super(message);
}
When replying:
MyMessage mimeReply = new MyMessage(reply);
mimeReply.updateMessageID();
Then send the mimeReply NOT reply.
Related
I have this sendmail function that I want to Test in Junit 4 using MockMvc.
I have provided my test case and WiserAssertions.java file I am using to test the function.
When testing the Junit test case I am getting the AssertionError that
java.lang.AssertionError: No message from [demoprojintern#gmail.com] found!
at com.appointment.request.controller.WiserAssertions.lambda$7(WiserAssertions.java:67)
Can someone help me out what am I missing?
sendmail() function
public void sendmail(Request request) throws AddressException, MessagingException, IOException {
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
String email = request.getEmail();
int requestId1 = request.getRequestId();
String requestId = Integer.toString(requestId1);
String name = request.getLegalName();
String cause = request.getCause();
String doa = request.getDateOfAppointment();
String toa = request.getAppointmentTime();
int status = request.getRequestStatus();
String generic = "Hello, " + name + "<br><br>" + "Your request with Request ID: " + requestId + " for " + "the cause of "
+ cause + " on " + doa + " at " + toa + " has been ";
String regards = "<br><br><br>Thanks and Regards,<br>";
Session session = Session.getInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("<my-email-id>", "<my-email-id's password");
}
});
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("<my-email-id>", false));
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email));
msg.setSubject("Regarding your Appointment Request");
msg.setContent(" ", "text/html");
msg.setSentDate(new Date());
MimeBodyPart messageBodyPart = new MimeBodyPart();
if (status == 0) {
String messageForPendingRequest = generic + "<strong>RECEIVED</strong>." + regards;
messageBodyPart.setContent(messageForPendingRequest, "text/html");
}
if (status == 1) {
String messageForPendingRequest = generic + "<strong>APPROVED</strong>." + regards;
messageBodyPart.setContent(messageForPendingRequest, "text/html");
}
if (status == 2) {
String messageForPendingRequest = generic + "<strong>SUGGESTED</strong>." + regards;
messageBodyPart.setContent(messageForPendingRequest, "text/html");
}
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
msg.setContent(multipart);
Transport.send(msg);
}
These are the dependencies of my pom.xml for sending the email and testing the mail respectively
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.subethamail</groupId>
<artifactId>subethasmtp</artifactId>
<version>3.1.7</version>
<scope>test</scope>
</dependency>
This is my junit test case
private Wiser wiser;
#Test
public void send() throws Exception {
Request request = new Request(1234, "Richie Rich", "<patient's-email-id>", "Brain", 27, "2019-12-17", "13:00", 0, "", "", "");
String email = request.getEmail();
int requestId1 = request.getRequestId();
String requestId = Integer.toString(requestId1);
String name = request.getLegalName();
String cause = request.getCause();
String doa = request.getDateOfAppointment();
String toa = request.getAppointmentTime();
String generic = "Hello, " + name + "<br><br>" + "Your request with Request ID: "
+ requestId + " for " + "the cause of "
+ cause + " on " + doa + " at " + toa + " has been ";
String regards = "<br><br><br>Thanks and Regards,<br>";
String jsonRequest = objectMapper.writeValueAsString(request);
this.mockMvc.perform(post("/sendemail").content(jsonRequest).contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(status().isOk());
// assert
WiserAssertions.assertReceivedMessage(wiser)
.from("<sender-mail-id>")
.to(email)
.withSubject("Regarding your Appointment Request")
.withContent(generic + "<strong>RECEIVED</strong>." + regards);
}
This is my WiserAssertions.java that I got from a blog
public class WiserAssertions {
private final List<WiserMessage> messages;
private WiserAssertions(List<WiserMessage> messages) {
this.messages = messages;
}
public static WiserAssertions assertReceivedMessage(Wiser wiser) {
return new WiserAssertions(wiser.getMessages());
}
private static Supplier<AssertionError> assertionError(String errorMessage, String... args) {
return () -> new AssertionError(MessageFormat.format(errorMessage, args));
}
public static <T> T unchecked(ThrowingSupplier<T> supplier) {
try {
return supplier.get();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public WiserAssertions from(String from) {
findFirstOrElseThrow(m -> m.getEnvelopeSender().equals(from),
assertionError("No message from [{0}] found!", from));
return this;
}
public WiserAssertions to(String to) {
findFirstOrElseThrow(m -> m.getEnvelopeReceiver().equals(to),
assertionError("No message to [{0}] found!", to));
return this;
}
public WiserAssertions withSubject(String subject) {
Predicate<WiserMessage> predicate = m -> subject.equals(unchecked(getMimeMessage(m)::getSubject));
findFirstOrElseThrow(predicate,
assertionError("No message with subject [{0}] found!", subject));
return this;
}
public WiserAssertions withContent(String content) {
findFirstOrElseThrow(m -> {
ThrowingSupplier<String> contentAsString =
() -> ((String) getMimeMessage(m).getContent()).trim();
return content.equals(unchecked(contentAsString));
}, assertionError("No message with content [{0}] found!", content));
return this;
}
private void findFirstOrElseThrow(Predicate<WiserMessage> predicate, Supplier<AssertionError> exceptionSupplier) {
messages.stream().filter(predicate)
.findFirst().orElseThrow(exceptionSupplier);
}
private MimeMessage getMimeMessage(WiserMessage wiserMessage) {
return unchecked(wiserMessage::getMimeMessage);
}
interface ThrowingSupplier<T> {
T get() throws Throwable;
}
}
I try to send a mail with following code snippet:
message = new MimeMessage(mailSession);
message.setFrom(from);
message.setRecipients(Message.RecipientType.TO, to);
if(cc != null && cc.length > 0){
message.setRecipients(Message.RecipientType.CC, cc);
}
if(bcc != null && bcc.length > 0){
message.setRecipients(Message.RecipientType.BCC, bcc);
}
if(replyTo != null && replyTo.length > 0){
message.setReplyTo(replyTo);
}
message.setSubject(subject, "utf-8");
message.setSentDate(new java.util.Date());
if (headers != null && !headers.isEmpty()) {
for (String headName : headers.keySet()) {
message.addHeader(headName, headers.get(headName));
}
}
if (Utils.isEmpty(bodyText)) {
bodyText = HTMLHelper.html2text(body);
}
message.setContent(this.buildMessageBody(body, bodyText));
transporter = mailSession.getTransport();
transporter.connect();
transporter.sendMessage(message, message.getAllRecipients());
Bellow following additional methods:
private Multipart buildMessageBody(String body, String bodyText) throws MessagingException {
if(attachments == null || attachments.isEmpty()){
return getAlternativeBodyMimeMultipart(body, bodyText);
}
MimeMultipart multipartRoot = new MimeMultipart("mixed");
BodyPart contentBodyPart = buildContentBodyPart(body, bodyText);
multipartRoot.addBodyPart(contentBodyPart);
List<BodyPart> attachmentParts = buildAttachmentParts();
for(BodyPart singleAttachmentPart : attachmentParts){
multipartRoot.addBodyPart(singleAttachmentPart);
}
return multipartRoot;
}
private List<BodyPart> buildAttachmentParts() {
List<BodyPart> attachmentsParts = new ArrayList<BodyPart>();
for (int i = 0; i < attachments.size(); i++) {
BinaryAttachment attach = attachments.get(i);
MimeBodyPart mbp = new MimeBodyPart();
System.setProperty("mail.mime.encodefilename", "true");
try {
mbp.setDataHandler(new DataHandler(attach));
mbp.setFileName(MimeUtility.encodeText(attach.getName()));
attachmentsParts.add(mbp);
} catch (Exception e) {
logger.error("buildBodyWithAttachment",e);
}
}
return attachmentsParts;
}
private BodyPart buildContentBodyPart(String body, String bodyText) throws MessagingException {
MimeMultipart alternativePart = getAlternativeBodyMimeMultipart(body, bodyText);
BodyPart content = new MimeBodyPart();
content.setContent(alternativePart);
return content;
}
For exemple my sender in "from" variable when I call messages.setFrom(from) have following value:
"M. Test ADMINISTRATEURÈÁÍ admin#demo.onmicrosoft.com"
But when I receive my mail in my mailbox, the send have the following name ...
M. Test ADMINISTRATEURÃÃÃ
From: "M. Test ADMINISTRATEUR???" admin#demo.onmicrosoft.com
I think the problem come from the encoding of "from" which create by:
from = new InternetAddress(sender) and sender is "M. Test ADMINISTRATEURÈÁÍ admin#demo.onmicrosoft.com".
How can I solve this?
You will have to specify the charset - UTF-8 in the InternetAddress constructor.
from = new InternetAddress(email, sender, "UTF-8")
The constructor from JavaMail for the above code is as below.
/**
* Construct an InternetAddress given the address and personal name.
* The address is assumed to be a syntactically valid RFC822 address.
*
* #param address the address in RFC822 format
* #param personal the personal name
* #param charset the MIME charset for the name
* #exception UnsupportedEncodingException if the personal name
* can't be encoded in the given charset
*/
public InternetAddress(String address, String personal, String charset)
throws UnsupportedEncodingException {
this.address = address;
setPersonal(personal, charset);
}
I am developing an application that needs to send an email via JavaMail with a specific Message ID.
I have extended the Java MimeMessage class to override the updateMessageID method so that I can set the message ID myself. The problem is that when I call the Transport.send(msg) method it is not calling the updateMessageID method. I thought perhaps I needed to call the saveChanges() method prior to calling Transport.send(msg). Even when I explicitly call msg.saveChanges() this does not trigger the updateMessageID method to be called.
What makes this all the more wacky is the fact that when I convert my test application to a JSP and run it, the Transport.send(msg) method DOES call the updateMessageID method.
Both my server and my webserver that I tested on are running jdk1.7.0_71.
Extended MimeMessage Class
package com.my.framework;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class MYMimeMessage extends MimeMessage {
Session session;
private static int id = 0;
private static String messageID = null;
public MyMimeMessage(Session session) {
super(session);
this.session=session;
}
protected void updateMessageID() throws MessagingException {
System.out.println("Calling updateMessageID()");
setHeader("Message-ID", "<" + getUniqueMessageIDValue(session) + ">");
}
/* Added to pass message id in */
public static void setMessageID(String cid)
{
messageID = cid;
}
public static String getUniqueMessageIDValue(Session ssn) {
String suffix = null;
InternetAddress addr = InternetAddress.getLocalAddress(ssn);
if (addr != null)
suffix = addr.getAddress();
else {
suffix = "javamailuser#localhost"; // worst-case default
}
if(messageID == null)
{
messageID = "987654321";
}
StringBuffer s = new StringBuffer();
// Unique string is <messageID>.<id>.<currentTime>.FDDMail.<suffix>
s.append(messageID).append('.').append(getUniqueId()).append('.').
append(System.currentTimeMillis()).append('.').
append("FDDMail.").
append(suffix);
System.out.println("RETURNING THE new ID: " + s.toString()");
return s.toString();
}
private static synchronized int getUniqueId() {
return id++;
}
}
I call this MimeMessageClass from a mail wrapper called SimpleEmail. It is mostly a bunch of get/set functions. All of the meat is in the sendEmail method...
public String sendEmail()
{
String msgText1 = this.getBody();
// Create some properties and get the default Session
Properties props = System.getProperties();
props.put("mail.smtp.host", this.getSmtpClient());
props.put("mail.from", "");
Session session = Session.getDefaultInstance(props, null);
try
{
// Create a message
MyMimeMessage msg = new MyMimeMessage(session);
if (null != sender && sender.length() > 0)
{
msg.setSender(new InternetAddress(sender));
}
if((this.getReply_to() != null) && (this.getReply_to().length() > 0))
{
Address emailReplyTo[] = new Address[1];
emailReplyTo[0] = new InternetAddress(this.getReply_to());
msg.setReplyTo(emailReplyTo);
}
msg.setFrom(new InternetAddress(this.getFrom()));
if(this.to == null || this.to.size() <= 0)
{
return "Error: No To to send";
}
int toIndex = 0;
InternetAddress [] address = new InternetAddress [this.to.size()];
while(this.HasNextTo())
{
address[toIndex] = new InternetAddress(this.nextTo());
toIndex++;
}
msg.setRecipients(Message.RecipientType.TO, address);
if(this.subject == null)
{
this.subject = "<no subject>";
}
msg.setSubject(this.subject);
if(!useTextHeader)
{
//Create and fill the first message part
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setDataHandler(new DataHandler(new HTMLDataSource(msgText1)));
Multipart mp = new MimeMultipart();
mp.addBodyPart(mbp1);
// Create the second message part
MimeBodyPart mbp2;
FileDataSource fds;
String filename;
if(this.attachments != null) {
Set attachmentPathAndNames = this.attachments.keySet();
Iterator attachmentIterator = attachmentPathAndNames.iterator();
while(attachmentIterator.hasNext()) {
String attachmentPathAndName = (String)attachmentIterator.next();
filename = (String)this.attachments.get(attachmentPathAndName);
if(filename == null) {
String[] dirs = attachmentPathAndName.split("\\/");
filename = dirs[dirs.length - 1];
}
mbp2 = new MimeBodyPart();
fds = new FileDataSource(attachmentPathAndName);
mbp2.setDataHandler(new DataHandler(fds));
mbp2.setFileName(filename);
//Create the Multipart and its parts to it
mp.addBodyPart(mbp2);
}
}
//add the Multipart to the message
msg.setContent(mp);
}
else
{
msg.setText(msgText1);
}
//set the Date: header
msg.setSentDate(new Date());
//set the MessageID Header
msg.setMessageID(this.messageID);
//send the message
try
{
Transport.send(msg);
}
catch(Exception e)
{
System.out.println("STOP WE THREW AN ERROR!!!!!!!!!!!!!!!");
}
}
catch (MessagingException mex)
{
mex.printStackTrace();
System.out.println("Error: SimpleEmail.SendEmail() = Caught MessagingException: " + mex.toString());
return "Error: SimpleEmail.SendEmail() = Caught MessagingException: " + mex.toString();
}
return this.SUCESS_MESSAGE;
}
So, when I call from a JSP I can see the two print statements from MyMimeMessage class
<%# page import="com.ifx.framework.SimpleEmail" %>
<%
String toAddr = request.getParameter("emailAddr");
String mid = request.getParameter("customID");
String SMTP_CLIENT = "myserver.mydomain.com";
String body = "Hi " + toAddr + "!<br>Today we are testing to see if the setting messageID to " + mid + " works!";
String sendResult = "No Email Sent";
if(toAddr != null)
{
SimpleEmail se = new SimpleEmail();
se.addTo(toAddr);
se.setSubject("Testing Headers");
se.setSmtpClient(SMTP_CLIENT);
se.setFrom("cms_zippylube#gointranet.com");
se.setBody(body);
se.setMessageID(mid);
sendResult = se.sendEmail();
}
%>
<!DOCTYPE html>
<html>
<head>
<title>
Test Page
</title>
<style>
label {
width: 200px;
display: inline-block;
margin-bottom: 5px;
}
</style>
</head>
<body>
<p style="background-color: #ADD8E6; border: solid 2px #000080;">
<%=sendResult%>
</p>
<form action="#" method="post">
<label for=emailAddr>Email Address:</label><input id="emailAddr" name="emailAddr" type="email"/> <br>
<label for=customValue>Custom Message ID:</label><input id="customID" name="customID" type="text"/> <br>
<input type="submit" value="Submit"/>
</form>
</body>
</html>
In my logs I see:
Calling updateMessage()
RETURNING THE new ID: 8675309.0.1430500125923.FDDMail.javamailuser#localhost
When I check the resulting email, the Message-ID in the header matches what was set.
Here is where my problem is, when I run a standalone version it still sends out the email but doesn't call the updateMessageID method and does not print out the debugging statements.
import com.ifx.framework.SimpleEmail;
public class headerTest
{
public static void main(String args[])
{
String toAddr = args[0];
String mid = args[1];
String SMTP_CLIENT = "myserver.mydomain.com";
String body = "Hi " + toAddr + "!<br>Today we are testing to see if the header message id is retained";
String sendResult = "No Email Sent";
if(toAddr != null)
{
SimpleEmail se = new SimpleEmail();
se.addTo(toAddr);
se.setSubject("Testing Headers");
se.setSmtpClient(SMTP_CLIENT);
se.setFrom("dummy#test.com");
se.setBody(body);
se.setMessageID(mid);
sendResult = se.sendEmail();
}
System.out.println("Done!");
}
}
The only output that I get when I run this is:
Done!
whereas I am expecting
Calling updateMessage()
RETURNING THE new ID: 8675309.0.1430500125923.FDDMail.javamailuser#localhost
Done!
I've got my entire team (including sysadmin) stumped on this issue. Any and All suggestions would be greatly appreciated!
It sounds like you're testing with two different servers so I'm guessing that they're using different versions of JavaMail. What versions are they using? What does the JavaMail debug output show?
I am trying to read Unread mail from my gmail Inbox using Javamail API.
Here is my code ...
final Properties props = new Properties();
props.setProperty("mail.store.protocol", "imaps");
String attachFiles = "";
try
{
final Session session = Session.getInstance(props, null);
final Store store = session.getStore();
store.connect("imap.gmail.com", "*********", "*********");
final Folder inbox = store.getFolder("INBOX");
final MailCountEventListener listener = new MailCountEventListener();
inbox.addMessageCountListener(listener);
inbox.open(Folder.READ_ONLY);
final Message msg = inbox.getMessage(inbox.getMessageCount());
final Address[] in = msg.getFrom();
for (final Address address : in)
{
System.out.println("FROM:" + address.toString());
}
final Multipart mp = (Multipart) msg.getContent();
final BodyPart bp = mp.getBodyPart(0);
if (msg.getContentType().contains("multipart"))
{
final int numberOfParts = mp.getCount();
for (int partCount = 0; partCount < numberOfParts; partCount++)
{
final MimeBodyPart part = (MimeBodyPart) mp.getBodyPart(partCount);
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()))
{
// this part is attachment
final String fileName = part.getFileName();
attachFiles += fileName + ", ";
part.saveFile("E:/" + File.separator + fileName);
}
else
{
System.out.println("MultiPart Message Content :" + part.getContent().toString());
}
}
if (attachFiles.length() > 1)
{
attachFiles = attachFiles.substring(0, attachFiles.length() - 2);
}
System.out.println("Attachments: " + attachFiles);
}
System.out.println("SENT DATE:" + msg.getSentDate());
System.out.println("SUBJECT:" + msg.getSubject());
System.out.println("CONTENT:" + bp.getContent());
}
catch (final Exception mex)
{
mex.printStackTrace();
}
My code is working fine. It is reading mail body with attached templates. Now I want to call MessageCountListener so that if any new Mail will come into my Inbox, Listener should be called automatically and read new mail body.
But Here the problem is My listener is not calling.
public class MailCountEventListener implements MessageCountListener
{
/*
* (non-Javadoc)
*
* #see javax.mail.event.MessageCountListener#messagesAdded(javax.mail.event.MessageCountEvent)
*/
#Override
public void messagesAdded(final MessageCountEvent messagecountevent)
{
String attachFiles = "";
System.out.println("message listner invoked.");
final Message[] msgs = messagecountevent.getMessages();
System.out.println("Got " + msgs.length + " new messages");
try
{
final Message msg = msgs[0];
final Address[] in = msg.getFrom();
for (final Address address : in)
{
System.out.println("FROM:" + address.toString());
}
final Multipart mp = (Multipart) msg.getContent();
final BodyPart bp = mp.getBodyPart(0);
if (msg.getContentType().contains("multipart"))
{
final int numberOfParts = mp.getCount();
for (int partCount = 0; partCount < numberOfParts; partCount++)
{
final MimeBodyPart part = (MimeBodyPart) mp.getBodyPart(partCount);
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()))
{
// this part is attachment
final String fileName = part.getFileName();
attachFiles += fileName + ", ";
part.saveFile("E:/" + File.separator + fileName);
}
else
{
System.out.println("MultiPart Message Content :" + part.getContent().toString());
}
}
if (attachFiles.length() > 1)
{
attachFiles = attachFiles.substring(0, attachFiles.length() - 2);
}
System.out.println("Attachments: " + attachFiles);
}
System.out.println("SENT DATE:" + msg.getSentDate());
System.out.println("SUBJECT:" + msg.getSubject());
System.out.println("CONTENT:" + bp.getContent());
}
catch (final Exception mex)
{
mex.printStackTrace();
}
}
/*
* (non-Javadoc)
*
* #see javax.mail.event.MessageCountListener#messagesRemoved(javax.mail.event.MessageCountEvent)
*/
#Override
public void messagesRemoved(final MessageCountEvent messagecountevent)
{
// YTODO Auto-generated method stub
}
}
adding Listener ..
final MailCountEventListener listener = new MailCountEventListener();
inbox.addMessageCountListener(listener);
I am not able to figure out where I am doing wrong. My event is not calling. Please help
The server only notifies the client of new messages as part of executing a command. You either need to execute a command periodically, e.g., by calling getMessageCount, or you need to use the IMAP IDLE support to wait for notifications. See also the IdleManager that's new in JavaMail 1.5.2.
I work with log4j.properties through WSO2 products. I needed implement a appender to work with SMTPAppender and send emails notifications using gmail smtp server. So, when I config log4j and start ESB WSO2 Server, the manage console print: log4j:ERROR Could not instantiate class [com.notification.GmailSMTPAppender].
My implementation was:
package com.notification;
public class GmailSMTPAppender extends SMTPAppender {
protected Session session;
public GmailSMTPAppender() {
super();
}
/**
* Create mail session.
*
* #return mail session, may not be null.
*/
protected Session createSession() {
Properties props = new Properties();
props.put("mail.smtps.host", getSMTPHost());
props.put("mail.smtps.auth", "true");
Authenticator auth = null;
if (getSMTPPassword() != null && getSMTPUsername() != null) {
auth = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(getSMTPUsername(),
getSMTPPassword());
}
};
}
session = Session.getInstance(props, auth);
if (getSMTPProtocol() != null) {
session.setProtocolForAddress("rfc822", getSMTPProtocol());
}
if (getSMTPDebug()) {
session.setDebug(getSMTPDebug());
}
return session;
}
/**
* Send the contents of the cyclic buffer as an e-mail message.
*/
protected void sendBuffer() {
try {
MimeBodyPart part = new MimeBodyPart();
StringBuffer sbuf = new StringBuffer();
String t = layout.getHeader();
if (t != null)
sbuf.append(t);
int len = cb.length();
for (int i = 0; i < len; i++) {
LoggingEvent event = cb.get();
sbuf.append(layout.format(event));
if (layout.ignoresThrowable()) {
String[] s = event.getThrowableStrRep();
if (s != null) {
for (int j = 0; j < s.length; j++) {
sbuf.append(s[j]);
sbuf.append(Layout.LINE_SEP);
}
}
}
}
t = layout.getFooter();
if (t != null)
sbuf.append(t);
part.setContent(sbuf.toString(), layout.getContentType());
Multipart mp = new MimeMultipart();
mp.addBodyPart(part);
msg.setContent(mp);
msg.setSentDate(new Date());
send(msg);
} catch (Exception e) {
LogLog.error("Error occured while sending e-mail notification.", e);
}
}
/**
* Pulled email send stuff i.e. Transport.send()/Transport.sendMessage(). So
* that on required this logic can be enhanced.
*
* #param msg
* Email Message
* #throws MessagingException
*/
protected void send(Message msg) throws MessagingException {
SMTPTransport t = (SMTPTransport) session.getTransport("smtps");
try {
t.connect(getSMTPHost(), getSMTPUsername(), getSMTPPassword());
t.sendMessage(msg, msg.getAllRecipients());
} finally {
System.out.println("Response: " + t.getLastServerResponse());
t.close();
}
}
}
How I can instantiate of this appender on my log4j.properties configuration ??
Do you need to programatically add the Appender?
Check the following post