I am trying to fetch unread mail from the INBOX from a gmail account. I wrote a small demo program and found that Gmail's pop3 behaves unexpectedly in a number of situations
When you try to get a list of available folders, Pop3 returns just the INBOX and not all the labels while IMAP does it correct. I am in-lining the code here.
POP3
public static Result getPop3FolderList()
{
Properties props = System.getProperties();
props.put("mail.store.protocol", "pop3s");
props.put("mail.pop3.host", "pop.gmail.com");
props.put("mail.pop3.user", Application.email);
props.put("mail.pop3.socketFactory", 995);
props.put("mail.pop3.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.pop3.port", 995);
Session session = Session.getInstance(props,new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(Application.email, Application.pwd);
}
});
try{
Store store=session.getStore("pop3");
store.connect(Application.email,Application.pwd);
javax.mail.Folder[] folders = store.getDefaultFolder().list("*");
String opHtml = "<ul>";
for (javax.mail.Folder folder : folders) {
if ((folder.getType() & javax.mail.Folder.HOLDS_MESSAGES) != 0) {
opHtml += "<li>" + folder.getFullName()+ "+" + folder.getMessageCount() + "</li>";
}
}
opHtml += "</ul>";
return ok(opHtml).as("text/html");
} catch(MessagingException e) {
return ok("Error in getting list.<br />" + e.getMessage()).as("text/html");
}
}
IMAP
public static Result getImapFolderList()
{
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imaps");
try {
Session session = Session.getInstance(props,new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(Application.email, Application.pwd);
}
});
javax.mail.Store store = session.getStore("imaps");
store.connect("imap.gmail.com", Application.email, Application.pwd);
javax.mail.Folder[] folders = store.getDefaultFolder().list("*");
String opHtml = "<ul>";
for (javax.mail.Folder folder : folders) {
if ((folder.getType() & javax.mail.Folder.HOLDS_MESSAGES) != 0) {
opHtml += "<li>" + folder.getFullName()+ ":" + folder.getMessageCount() + "</li>";
}
}
opHtml += "</ul>";
return ok(opHtml).as("text/html");
} catch (MessagingException e) {
return ok("Error in getting list.<br />").as("text/html");
}
}
Even When retrieving the mail, when I put the unread mails filter, gmail returns a number of read mail that are not even part of inbox but long archived ones. IMAP, on the other hand behaves expectedly.
Additional Info : I have enabled pop3 only for the new mail and not from the beginning
Am I using the pop3 wrong or is it broken in gmail?
Apparently, POP3 doesn't handle folders. I had the same problem when accessing Exchange mailboxes - IMAP gets folders, POP3 only gets the Inbox.
I found more info here: How to retrieve gmail sub-folders/labels using POP3?
Related
I am trying to use delegate mail access through javamail. I have configured the delegate access correctly on my system. But when I try to run the following code
import java.util.Properties;
import javax.mail.*;
public class Test {
public static void main(String[] args) {
Properties props = System.getProperties();
props.put("mail.imaps.auth.plain.disable", "true");
props.put("mail.smtp.ssl.enable", "true");
try {
Session session = Session.getInstance(props, null);
session.setDebug(true);
Store store = session.getStore("imaps");
store.connect(mailServerIP, 993, "myAlias/DelegateAlias", "mypassword");
System.out.println(store);
Folder inbox = store.getFolder("Inbox");
inbox.open(Folder.READ_ONLY);
Message messages[] = inbox.getMessages();
for (Message message : messages) {
System.out.println(message);
}
} catch (Exception e) {
e.printStackTrace();
System.exit(2);
}
}
}
it shows me the following error
javax.mail.AuthenticationFailedException: LOGIN failed.
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:715)
at javax.mail.Service.connect(Service.java:364)
at com.adecco.smpt.TestSSL.main(TestSSL.java:26)
If I try to access my mail box instead of shared mailbox everything works well. Is there a different syntax to access the SHARED MAILBOX in JAVA?
I am using the private mail server.
I have some confusion about message deleting. I have well
connection to email, but code didn't work.
public class GetMyInbox {
public static void main(String[] args) {
Properties prop = System.getProperties();
prop.setProperty("mail.store.protocol", "imaps");
System.out.println("Start connection...");
Session session = Session.getDefaultInstance(prop,null);
try {
Store store = session.getStore("imaps");
store.connect("host", "email","password");
System.out.println("Connected!");
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_WRITE);
Message msg = folder.getMessage(1779);
Address from = msg.getFrom()[0];
List<Message> messages = Arrays.asList(folder.getMessages());
for (Message m : messages) {
if (m.getFrom()[0].equals(from)) {
m.setFlag(Flags.Flag.DELETED, true);
}
}
} catch ...
method equals don't work.
I tried do the same with string
if (m.getFrom()[0].toString().contains("string")){
...
}
Actually, the flag has changed to deleted (it doesn't delete physically). While fetching emails you have to exclude /delete flags.
I want to test my Emil Com server and SMTP capacity. So i need to send mail to different Email account from my Application. But i cant not create 10000 mail iD's each time. IS there any simulation tool available to send a Email from my application without creating the Mail id's (Gmail, yahoo etc)
Use this method emailNotification() and implement as per your need. Concatinate all the email_id with a comma seprator abc#abc.com,abc1#abc.com,abc2#abc.com and pass the string to the v_sBCC.
This function might help you out. Thanks..
private void emailNotification(){
String v_sTo;
String v_sFrom;
String v_sBCC = "abc#gmail.com,abc1#gmail.com" //add a number of emails with a Comma separator.
DataSource v_objSource;
Properties v_objProperties;
Session v_objSession;
MimeMessage v_sMessage;
BodyPart v_objMessageBodyPart;
Multipart v_objMultipart;
try {
v_sFrom = "Set From Name To Show User that From which Email you received Mail";
v_objProperties = new Properties();
v_objProperties.put("mail.smtp.host", smtp.google.com);
v_objProperties.put("mail.smtp.auth", "true");
v_objProperties.put("mail.debug", "false");
v_objProperties.put("mail.smtp.port", 25);
v_objProperties.put("mail.smtp.socketFactory.port", 25);
v_objProperties.put("mail.smtp.starttls.enable", "true");
v_objProperties.put("mail.transport.protocol", "smtp");
v_objSession = Session.getInstance(v_objProperties, new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("gmail.id", "password");
}
});
v_sMessage = new MimeMessage(v_objSession);
v_sMessage.setFrom(new InternetAddress(v_sFrom, "Your Company Name"));
v_sMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(v_sTo));
v_sMessage.addRecipient(Message.RecipientType.BCC, new InternetAddress(v_sBCC));
v_sMessage.setSubject("Set Your Own Subject");
v_sMessage.setText("Set Your Own Body");
Transport.send(v_sMessage);
} catch (MessagingException v_exException) {
v_exException.printStackTrace();
} catch (UnsupportedEncodingException v_exException) {
v_exException.printStackTrace();
}
}
I am trying to connect to locally hosted email POP3 inbox and display emails in the mailbox, but I keep getting error:
Exception in thread "main" javax.mail.MessagingException: Connect failed;
nested exception is:
java.net.ConnectException: Connection refused
at com.sun.mail.pop3.POP3Store.protocolConnect(POP3Store.java:209)
at javax.mail.Service.connect(Service.java:295)
at javax.mail.Service.connect(Service.java:176)
at com.kami.utils.MailClient.checkInbox(MailClient.java:33)
at com.kami.Main.main(Main.java:38)
My class looks like this:
public class MailClient {
private String host;
private String username;
private String password;
private String provider;
protected Session session;
public MailClient() {
Properties props = new Properties();
this.host = "localhost";
this.username = "unix-user";
this.password = "unix-password";
this.provider = "pop3";
this.session = Session.getDefaultInstance(props, null);
}
public void checkInbox() throws MessagingException, IOException {
Store store = session.getStore(provider);
store.connect(host, username, password); //This is line 33
Folder inbox = store.getFolder("inbox");
inbox.open(Folder.READ_ONLY);
Message[] messages = inbox.getMessages();
for(Message message : messages){
System.out.println(message.getReceivedDate());
System.out.println(message.getSubject());
}
inbox.close(true);
store.close();
}
}
It is locally hosted email server using Dovecot IMAP/POP3 Server Version 2.2.9 and Postfix Mail Server Postfix version 2.11.0
First telnet 110 port in your machine to check if the service is running there. In my laptop i don't have a pop3 server running, and this is the result:
hans#andes:~$ telnet localhost 110
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
If the connection succeed, follow the protocol authentication of pop3 with your own data:
hans#andes:~$ telnet mail.foo.com 110
Trying X.X.X.X...
Connected to mail.foo.com.
Escape character is '^]'.
+OK mail.foo.com POP3 server ready
user fooUser
+OK hello fooUser, please enter your password
pass fooPassword
+OK server ready
In your case telnet localhost; note too that you only should issue the commands: telnet, user and pass. The rest is the response from the server.
If all this works, the problem is on something with your java configuration, check the documentation and samples from the library.
The below method will fetch messages from a pop mailbox (given _Host=localhost, _User=unix-user, _Password=unix-password, _Protocol="pop3"). However you must be sure of a few things:
1) "localhost" is running a "pop3" server and not a "pop3s" (secure protocol) server;
2) the "pop3" server on "localhost" is listening on the default port
3) "unix-user" has a pop3 mailbox
Based on your follow-up, it seems like you are expecting to be able to send mail from the pop3 account. This is not how it works as pop3 is only a way to retrieve messages, not send them. To send mail, you need to establish a separate connection to an SMTP server.
public Message[] getMessages(int maxCount)
throws MessagingException
{
// Get a Session object
Properties props = new Properties();
Session session = Session.getInstance(props);
// Get a Store object
Store store = session.getStore(_protocol);
// Connect
store.connect(_host,_user,_password);
// Open a Folder
Folder folder = store.getFolder(_mailbox);
if (folder == null || !folder.exists())
throw new ApplicationException("Invalid mailbox");
//Gets up to maxCount messages from the pop box
folder.open(Folder.READ_WRITE);
Message[] messages = Monitor.EMPTY_MESSAGE_ARRAY;
int toMessageIndex=folder.getMessageCount();
if (toMessageIndex > 0) {
if (toMessageIndex > maxCount)
toMessageIndex = maxCount;
messages = folder.getMessages(1,toMessageIndex);
}
// Go through all the new messages and make sure they are loaded. Use the outputStream
//to force all information to be downloaded.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (int i = 0; i < messages.length && shouldRun(); i++) {
try {
//Force the download of all message information
bos.reset();
messages[i].writeTo(bos);
getLog().enter(
this,
"[readAndClearInBox] Read message to " + messages[i].getAllRecipients()[0].toString());
} catch (Exception mex) {
getLog().error(this, mex, "[readAndClearInBox] Message exception");
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
try {
Monitor.dumpEnvelope(getLog(), pw, messages[i]);
} catch (Exception ex) {
getLog().error(this, mex, "[readAndClearInBox] Could only display faulty message.");
} finally {
pw.flush();
getLog().enter(this, "[readAndClearInBox]" + sw.toString());
}
} finally {
//Mark the message for deletion
messages[i].setFlag(Flags.Flag.DELETED, true);
}
}
//Close folder and expunge all deleted messages, unless the read was aborted
if (shouldRun()) {
getLog().enter(this,"Found " + messages.length + " messages; closing inbox.");
folder.close(true);
store.close();
return messages;
} else {
getLog().enter(this,"Found " + messages.length + " messages; closing inbox without expunging.");
folder.close(false);
store.close();
_bShouldRun = true;
return Monitor.EMPTY_MESSAGE_ARRAY;
}
}
I am developing an application that needs to pull specific filtered messages. I also need to be able to exclude certain messages. for instance, a user may want to exclude all message with the subject, which in this case I would create a SubjectTerm, and put it inside a NotTerm. This is returning 0 messages for some reason. while when i ask just for the subject term, it returns the correct message.The specific service i am trying to use this code with are yahoo and hotmail.
package javaapplication2;
import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.search.*;
public class imapyahoo {
public static void main(String[] args) {
//set the properties for an ssl connection to the imap server.
java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
Properties props = new Properties();
props.setProperty("mail.store.protocol", "imaps");
props.setProperty("mail.imap.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.imap.socketFactory.fallback", "false");
props.setProperty("mail.imap.socketFactory.port", "993");
try {
Session session = Session.getInstance(props, null);
Store store = session.getStore();
System.out.println("connecting....");
store.connect("imap.mail.yahoo.com", "account", "password");
System.out.println("connected");
System.out.println("searching inbox");
Folder inbox = store.getFolder("inbox");
inbox.open(Folder.READ_ONLY);
//apply the search term.
SearchTerm st = new NotTerm(new SubjectTerm("dogs"));
Message[] msgs =inbox.search(st);
System.out.println(msgs.length);
System.out.println("done searching");
//print out the messages
int i =1;
for (Message msg : msgs){
System.out.println(i);
System.out.println(msg.getSubject());
i++;
}
inbox.close(true);
store.close();
} catch (Exception mex) {
mex.printStackTrace();
}
}
}