Java : Using Javamail to read email - java

I've been working on a program, that's suppose to use javamail, to read through an inbox, and if an email contains a specific String, it should be opened.
First off, this is my first time trying to use this javamail api - I'm pretty sure that my properties are all messed up - Can anyone give me at tip on correctly setting up properties for javamail?
Secondly, it seems like i can connect via the API, but if I try to search for subjects AND the subject is null, I get a null pointer exception - If I however don't try to match the subject with "Ordretest", I get no nullpointer - Any tips would be a great help :)
package vildereMail;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.InternetAddress;
import javax.mail.search.FromTerm;
import javax.mail.search.SearchTerm;
import javax.mail.search.SubjectTerm;
public class vildereMail {
public boolean match(Message message) {
try {
if (message.getSubject().contains("Ordretest")) {
System.out.println("match found");
return true;
}
} catch (MessagingException ex) {
ex.printStackTrace();
}
return false;
};
public static void main(String[] args) {
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imaps");
props.put("mail.imap-mail.outlook.com.ssl.enable", "true");
props.put("mail.pop3.host", "outlook.com");
props.put("mail.pop3.port", "995");
props.put("mail.pop3.starttls.enable", "true");
try {
Session session = Session.getInstance(props, null);
Store store = session.getStore();
store.connect("imap-mail.outlook.com", "myEmail#live.dk", "MyPassword");
session.setDebug(true);
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_ONLY);
SearchTerm sender = new FromTerm(new InternetAddress("myMail#live.dk"));
Message[] messages = inbox.search(sender);
System.out.println(messages);
for (int i = 0 ; i < messages.length ; i++) {
System.out.println(messages[i].getSubject());
if (messages[i].getSubject().equals(null)) {
System.out.println("null in subject");
break;
}
else if (messages[i].getSubject().contains("Ordretest")){
System.out.println("1 match found");
}
else {
System.out.println("no match");
}
}
System.out.println("no more messages");
store.close();
} catch (Exception mex) {
mex.printStackTrace();
}
}
}

Without knowing on which line you get the NPE (Null Pointer Exception) I guess it occurs here:
if (messages[i].getSubject().equals(null))
If getSubject() returns null and you try to do .equals() it will throw a NPE (because you try to invoke a method).
So try to rewrite it to (assuming your message object can't be null):
if (messages[i].getSubject() == null)

Where to start...
Have you found the JavaMail FAQ?
You can get rid of all the property settings because they're doing nothing since you're using the "imaps" protocol, not the "pop3" protocol.
As others have explained, the getSubject method might return null, so you need to check for that.

Related

How to fix Java Mail not displaying new emails in while loop

I'm making a script to turn on and off my lights using email and EVERYTHING works besides the fact that it won't update to the newest email and I don't know why. I couldn't find anything online, and I didn't try anything because I'm completely lost. BTW for more info the first time the script runs it runs the newest email but it doesn't do it again after that
This is my code please help
to my understanding the way the while loop should work is get a subject, then check to see if it matches what im asking it to look for then weather it is or isnt it goes about to the top and checks the most recent subject again then checing if its what im looking for then doing it again and again and again
import java.util.Properties;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
public class GetEmails {
public static void on(){
SSH on = new SSH();
on.command = "python3 on.py";
on.run();
}
public static void off(){
SSH off = new SSH();
off.command = "python3 off.py";
off.run();
}
public static void check(String host, String storeType, String user,
String password)
{
try {
//create properties field
Properties properties = new Properties();
properties.put("mail.pop3.host", host);
properties.put("mail.pop3.port", "995");
properties.put("mail.pop3.starttls.enable", "true");
Session emailSession = Session.getDefaultInstance(properties);
//create the POP3 store object and connect with the pop server
Store store = emailSession.getStore("pop3s");
store.connect(host, user, password);
//create the folder object and open it
Folder emailFolder = store.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
// retrieve the messages from the folder in an array
Message[] messages = emailFolder.getMessages();
boolean power = true;
while(true){
int i = messages.length - 1;
Message message = messages[i];
String subject = message.getSubject();
// System.out.println(subject);
if(subject.equals("+myRoom") & power == false){
on();
power = true;
System.out.println("Light on");
}
else if (subject.equals("-myRoom") & power == true){
off();
power = false;
System.out.println("Light Off");
}
else{
continue;
}
}
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String host = "pop.gmail.com";// change accordingly
String mailStoreType = "pop3";
String username = "EMAIL#gmail.com";// change accordingly
String password = "PASSWORD";// change accordingly
check(host, mailStoreType, username, password);
}
}
The problem is that you only call getMessages() before the while loop and then continuously check the same set of downloaded messages over and over again in the while-loop.
You need to change the while-loop to download the latest (set of) messages.
I would also point out that your code does not account for the possibility of receiving non-command messages that might push the latest command message into the "not the latest" slot (e.g. latest command message might have index messages.length - 2 while the non-command message has the messages.length - 1 index) nor does it account for the possibility of getting disconnected due to network outages or the server dropping your connection (which happens all the time for any number of reasons).

javax.mail.AuthenticationFailedException: [AUTH] Web login required

I build an application using Java to read emails. And It worked without any errors past days. But suddenly today came up an error like this.
javax.mail.AuthenticationFailedException: [AUTH] Web login required: https://support.google.com/mail/answer/78754
at com.sun.mail.pop3.POP3Store.protocolConnect(POP3Store.java:207)
at javax.mail.Service.connect(Service.java:295)
at javax.mail.Service.connect(Service.java:176)
at MailReader.readMail(MailReader.java:44)
at MailReader.run(MailReader.java:32)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
I can't figure out how to fix this. I didn't put 2-way authentication. And also I put less secure app allowed. So I can't figure out what is wrong. Anybody can help me? I greatly appreciate that.
Here is the code I am using,
String host = "pop.gmail.com";
String username = "somename#gmail.com";
String password = "password";
Properties prop = new Properties();
Session session = Session.getInstance(prop, null);
Store store = session.getStore("pop3s");
store.connect(host, username, password);
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_WRITE);
The error was due to an error at Google, which caused POP3 services to work incorrectly. It was fixed after 2 days.
Could not find official statement, only forum posts. Related sources:
1, 2, 3
My working snippet looks like below:
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;
public class CheckingMails {
public static void check(String host, String user, String password)
{
try {
// create properties field
Properties properties = new Properties();
properties.put("mail.pop3s.host", host);
properties.put("mail.pop3s.port", "995");
properties.put("mail.pop3s.starttls.enable", "true");
// Setup authentication, get session
Session session = Session.getInstance(properties,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, password);
}
});
// session.setDebug(true);
// create the POP3 store object and connect with the pop server
Store store = session.getStore("pop3s");
store.connect();
// create the folder object and open it
Folder emailFolder = store.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
// retrieve the messages from the folder in an array and print it
Message[] messages = emailFolder.getMessages();
System.out.println("messages.length---" + messages.length);
for (int i = 0, n = messages.length; i < n; i++) {
Message message = messages[i];
System.out.println("---------------------------------");
System.out.println("Email Number " + (i + 1));
System.out.println("Subject: " + message.getSubject());
System.out.println("From: " + message.getFrom()[0]);
System.out.println("Text: " + message.getContent().toString());
}
// close the store and folder objects
emailFolder.close(false);
store.close();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String host = "pop.gmail.com";
String username = "abc#gmail.com";// change accordingly
String password = "*****";// change accordingly
check(host, username, password);
}
}
My problem was that the same code was working on local but not on the remote cloud (Bitbucket pipeline) although I set the less secure enable. I solved it by enabled 2 step verification and create an app password. Then used this app password instead of the normal password in the code.
You can check the following link as well: https://docs.maildev.com/article/121-gmail-web-login-required-error---answer78754-failure

Java send email bot Custom message with JOptionPane

I'm not a very experienced coder, but I have been learning. Right now I am in the process of writing a test email bot to, well, send emails. I ran across a problem when I tried to make it so you could type out the message and subject of the email in a JOptionPane Dialog box.
Here is the code, look at the Strings at the top and the messageobjs at the bottom..
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.swing.JOptionPane;
public class Ebot2
{
public static void main(String[] args)
{
String Dest;
Dest = JOptionPane.showInputDialog("Who would you like to message?");
String Subject;
Subject = JOptionPane.showInputDialog("What is the message subject?");
String Message;
Message = JOptionPane.showInputDialog("What is the message?");
String sendrmailid = "email#gmail.com";
final String uname = "email";
final String pwd = "pass";
Properties propvls = new Properties();
propvls.put("mail.smtp.auth", "true");
propvls.put("mail.smtp.starttls.enable", "true");
propvls.put("mail.smtp.host", "smtp.gmail.com");
propvls.put("mail.smpt.port", "25");
Session sessionobj = Session.getInstance(propvls,
new javax.mail.Authenticator()
{
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(uname, pwd);
}
});
try
{
Message messageobj = new MimeMessage(sessionobj);
messageobj.setFrom(new InternetAddress(sendrmailid));
messageobj.setRecipients(Message.RecipientType.TO,InternetAddress.parse(Dest));
messageobj.setSubject(Subject);
messageobj.setText(Message);
Transport.send(messageobj);
System.out.println("Your email sent successfully....");
}
catch (MessagingException exp)
{
throw new RuntimeException(exp);
}
}
}
sorry for the shit formatting, the code block thing was difficult. Anyways the error Im getting started, after I changed the setSubject and setText to Strings that are entered through a JOptionPane. And the error is..
Ebot2.java:53: error: cannot find symbol
messageobj.setRecipients(Message.RecipientType.TO,InternetAddress.parse(Dest));
^
symbol: variable RecipientType
location: variable Message of type String
1 error
Thanks to anyone who answers, I really need help on this!
I fixed it guys. The problem was I had the String for the message set as Message (same problem with subject) which was also a variable. So I just renamed the string and it all worked. Thanks for the help anyways, glad to know I can go to this site for questions.
Next I'm going to try to figure out how to send the email multiple times, but I should be able to figure that out on my own.

Java Current Directory Returns `null`

I'm trying to use the printWorkingDirectory() from Apache Commons FTP but it's only returning null. I can't navigate directories, list files, etc.
Log in pass all is success but how ever I try I can not change current directory.
I use this following code:
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
public class FTPDownloadFileDemo {
public static void main(String[] args) {
String server = "FTP server Address";
int port = portNo;
String user = "User Name";
String pass = "Pasword";
FTPClient ftpClient = new FTPClient();
String dir = "stocks/";
try {
ftpClient.connect(server, port);
ftpClient.login(user, pass);
System.out.println( ftpClient.printWorkingDirectory());//Always null
//change current directory
ftpClient.changeWorkingDirectory(dir);
boolean success = ftpClient.changeWorkingDirectory(dir);
// showServerReply(ftpClient);
if (success)// never success
System.out.println("Successfully changed working directory.");
System.out.println(ftpClient.printWorkingDirectory());// Always null
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
ex.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
This is rather old question that deserves an answer. This issue is likely a result of using FTPClient when secure connection is required. You may have to switch to FTPSClient if that is, indeed, the case. Further, output the response from the server with the following code snippet to troubleshoot the issue if secure client doesn't solve the it:
ftpClient.addProtocolCommandListener(
new PrintCommandListener(
new PrintWriter(new OutputStreamWriter(System.out, "UTF-8")), true));
Also, a server can reject your login attempt if your IP address is not white listed. So, being able to see the logs is imperative. The reason you see null when printing current working directory is because you are not logged in. Login method will not throw an exception but rather return a boolean value indicating if the operation succeeded. You are checking for success when changing a directory but not doing so when logging in.
boolean success = ftpClient.login(user, pass);
I faced the same, but I came across with a simple step.
Just added this.
boolean success = ftpClient.changeWorkingDirectory(dir);
ftpClient.printWorkingDirectory(); //add this line after changing the working directory
System.out.println(ftpClient.printWorkingDirectory()); //wont be getting null
Here I have the code and the console output
FTPClient.changeWorkingDirectory - Unknown parser type: "/Path" is current directory
I know I replied too soon ;-P, but I saw this post recently. Hope this helps to future searchers ;-)

Need help about "Get Attachment File Name" Tutorial from Java2s.com

i try the tutorial Get Attachment File Name from Java2s.com.
What i'm doing is to read email from the Outlook Web Access Light.
If i put the url address of the Outlook Web Access Light, i have the error:
Exception in thread "main" javax.mail.NoSuchProviderException: No provider for http
at javax.mail.Session.getProvider(Session.java:455)
at javax.mail.Session.getStore(Session.java:530)
at javax.mail.Session.getFolder(Session.java:602)
at MainClass.main(MainClass.java:19)
Java Result: 1
I don't understand the line :
("protocol://username#host/foldername");
here is the code:
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Part;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.URLName;
import javax.mail.internet.InternetAddress;
public class MainClass {
public static void main(String[] args) throws Exception {
URLName server = new URLName("protocol://username#host/foldername");
Session session = Session.getDefaultInstance(new Properties(), new MailAuthenticator());
Folder folder = session.getFolder(server);
if (folder == null) {
System.out.println("Folder " + server.getFile() + " not found.");
System.exit(1);
}
folder.open(Folder.READ_ONLY);
Message[] messages = folder.getMessages();
for (int i = 0; i < messages.length; i++) {
System.out.println(messages[i].getSize() + " bytes long.");
System.out.println(messages[i].getLineCount() + " lines.");
String disposition = messages[i].getDisposition();
if (disposition == null){
; // do nothing
}else if (disposition.equals(Part.INLINE)) {
System.out.println("This part should be displayed inline");
} else if (disposition.equals(Part.ATTACHMENT)) {
System.out.println("This part is an attachment");
String fileName = messages[i].getFileName();
System.out.println("The file name of this attachment is " + fileName);
}
String description = messages[i].getDescription();
if (description != null) {
System.out.println("The description of this message is " + description);
}
}
folder.close(false);
}
}
class MailAuthenticator extends Authenticator {
public MailAuthenticator() {
}
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password");
}
}
Thank you for your support
have a nice day
Given the error message I really think javaMail is expecting for protocol one of "smtp:" or "imap:" or "pop3:", because it is the way it constructs its session.
I don't think it will ever work with a web access, you have to get the address of the pop3/imp/smtp server the web interface connects to.
I'm not sure but "protocol://username#host/foldername" seems to describe a format rather than a real url, i.e. it tells you to add a protocol, a user name, a host and a folder like "http://Thomas#stackoverflow.com/need-help-about-get-attachment-file-name-tutorial-from-java2s-com" (just an example of how it might look like, this particular url is not likely to work/exist/whatever :) ).

Categories

Resources