I have a program where I have a number of users which each could be sending emails from different email accounts.
When I try to use JavaMail to send emails. They always get sent out by the account of the user who sent an email first.
user1 = new User("dummy-email#gmail.com", "dumpass12");
user2 = new User("second-dummy#gmail.com", "secondpass12");
user1.sendMail(toAddress, subject, body);
user2.sendMail(toAddress, subject, body);
Now when I do something like this, the second user will send a message but it will come from the SAME mailbox as user1 (i.e. both messages will come from dummy-email#gmail.com).
Can somebody explain to me why this is happening? Do I have to close the connection somehow? How can I send the two emails and have them come from the different accounts? Please help me.
Here is my code which actually sends the email connecting to the user's gmail account.
public void sendMail(String toAddress, String subject, String body){
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
Session session = Session.getDefaultInstance(props,
new javax.mail.Authenticator()
{
protected PasswordAuthentication getPasswordAuthentication()
{ return new PasswordAuthentication(getUsername(),getPassword()); }
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(getUsername()));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(toAddress));
message.setSubject(subject);
message.setContent(body, "text/html");
Transport.send(message);
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
Replace Session.getDefaultInstance() with Session.getInstance(). To understand why, read the javadocs for those methods carefully.
Related
public static void sendEmail(String msgHeader, String msg, String emailId, String emailFrom) {
Properties props = new Properties();
props.put("mail.smtp.auth", "false");
props.put("mail.debug", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", mailServer);
props.put("mail.smtp.port", port#);
props.put("mail.smtp.auth.mechanisms", "NTLM");
props.put("mail.smtp.auth.ntlm.domain", domainName);
Session session = Session.getDefaultInstance(props, null);
try {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(emailFrom));
to = emailId;
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
message.setSubject(msgHeader);
message.setText(msg, "utf-8", "html");
message.saveChanges();
session.getDebug();
Transport.send(message);
// Copy message to "Sent Items" folder as read
Store store = session.getStore("ntlm");
store.connect(mailServer, emailFrom, pwd);
Folder folder = store.getFolder("Sent Items");
folder.open(Folder.READ_WRITE);
message.setFlag(Flag.SEEN, true);
folder.appendMessages(new Message[] {message});
store.close();
} catch (Exception ex) {
logger.error("Error occured while sending Email !", ex);
}
}
When I try to execute the code above, i am able to send out the emails. the issue is with saving the email. I get an error (NoSuchProviderException) at the line
Store store = session.getStore("ntlm");
I have a few questions on this:-
The email sending part works without password verification with ntlm. Is it possible to save the sent email into the sent items folder without password verification. If yes then how?
session.getStore doesnt work when i use
a. smtp - exception (Invalid provider)
b. ntlm - exception (NoSuchProviderException)
what should i use here.
Thanks in advance for your help.
"ntlm" is not a type of Store, it's an authentication mechanism. The store types supported by JavaMail are "imap" and "pop3". You almost certainly want "imap". Just like sending, you're going to need to supply your username and password when connecting to your imap server.
Also, upgrade to the current version of JavaMail if possible.
I try to send email with Intent. I wrote code witch can send email
send.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent email = new Intent(Intent.ACTION_SEND);
email.putExtra(Intent.EXTRA_EMAIL, new String[] { Email });
email.putExtra(Intent.EXTRA_SUBJECT,"subject");
email.putExtra(Intent.EXTRA_TEXT, "text1");
email.setType("message/rfc822");
startActivity(Intent.createChooser(email, "Choose an Email client :"));
}
});
I can send email, but when I choose email client then I can change subject text and extra text. How I can write code to use would not can change subject and extra texts when user would choose email client?
The only way to avoid the user from changing email text is to issue the mail
programmatically, i.e. with no UI. It is usually done in Android by using the JavaMail API.
Send Email via JavaMail
First add lines below to your sender class:
static {
Security.addProvider(new JSSEProvider());
}
JSSEP stands for Java Secure Socket Extension, which is the protocol used for
Gmail authentication that we will later on use.
You can grab a working sample of JSSEProvider at:
https://android.googlesource.com/platform/libcore/+/jb-mr2-release/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java
Create a sender class :
public class EmailSender extends javax.mail.Authenticator {
void sendMail(username, password, ) {
...
}
}
We now move to sendMail() method implementation:
Start by setting properties for transmission via Gmail:
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.host", "smtp.gmail.com"); // <--------- via Gmail
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.quitwait", "false");
session = Session.getDefaultInstance(props, this);
And follow by sending the mail:
MimeMessage message = new MimeMessage(session);
DataHandler handler = new DataHandler(new ByteArrayDataSource(body.getBytes(), "text/plain"));
message.setSender(new InternetAddress(sender));
message.setSubject(subject);
message.setDataHandler(handler);
message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipients));
Transport.send(message);
ByteArrayDataSource is a standard implementation. You can grab it from
http://commons.apache.org/proper/commons-email/apidocs/src-html/org/apache/commons/mail/ByteArrayDataSource.html
You wil also need to add the method below, returning the PasswordAuthentication, to your class:
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, password);
}
Good luck.
If you really need to lock in the subject and message body, but let the user choose the email recipients (the To list), you'll have to provide them a dialog to enter in email recipient, and then send the email in an automated fashion by using something like Apache Commons EMail
As a user, I'd be pretty wary of having an email sent from my phone where I can't see the subject line and body text. You may want to just use the method you have now wehre they can edit the text, or at least show them what you're sending.
For a web application I'm working on I made a method to send email notifications. The message has to come from a specific account, but I would like the "from" header field to read as an entirely different email address. Here is my code (I've changed the actual email addresses to fake ones):
public static boolean sendEmail(List<String> recipients, String subject, String content){
String header = "This is an automated message:<br />"+"<br />";
String footer = "<br /><br />unsubscribe link here";
content = header + content + footer;
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");
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
//This is where the email account name and password are set and can be changed
return new PasswordAuthentication("ACTUAL.ADRESS#gmail.com", "PASSWORD");
}
});
try{
MimeMessage message = new MimeMessage(session);
try {
message.setFrom(new InternetAddress("FAKE.ADDRESS#gmail.com", "FAKE NAME"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
message.setReplyTo(new Address[]{new InternetAddress("no-reply#gmail.com")});
for(String recipient: recipients){
message.addRecipient(Message.RecipientType.BCC,new InternetAddress(recipient));
}
message.setSubject(subject);
message.setContent(content,"text/html");
Transport.send(message);
return true;
}catch (MessagingException mex) {
mex.printStackTrace();
return false;
}
}
For the above method sending an email with it will have the following email header:
from: FAKE NAME <ACTUAL.ADRESS#gmail.com>
I want it to read:
from: FAKE NAME <FAKE.ADRESS#gmail.com>
What am I doing wrong? Any help is appreciated!
What you are looking to do is called "spoofing." It appears as though you are using Google's SMTP servers, if this is the case, you will not be able to do this successfully. For security purposes, Google will only allow the "from" address to be the authenticated email address.
See this related question
I need to send at least 200 messages from a stretch. When the program starts, send mail successfully to 15 or 17, then I get this error:
MESSAGE ERROR:
com.sun.mail.smtp.SMTPSendFailedException: 421 4.4.2 Message submission rate for this client has exceeded the configured limit
What I can do?
CODE JAVA
public void mandarEmail(String correos, String mensaje, String asunto) {
Message message;
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.transport.protocol", "smtp");
props.setProperty("mail.smtp.port", "587");
props.put("mail.smtp.host", "pod51004.outlook.com");
props.put("mail.smtp.debug", "true");
Session session = Session.getInstance(props, new javax.mail.Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("docemail#usmp.pe", "docpass");
}
});
try {
message = new MimeMessage(session);
message.setFrom(new InternetAddress("USMP - FN <documentos-fn#usmp.pe>"));
message.setSubject(asunto);
message.addRecipients(Message.RecipientType.TO, InternetAddress.parse(correos));
message.addRecipients(Message.RecipientType.BCC, new InternetAddress[]{new InternetAddress("ivan_pro_nice#hotmail.com")});
message.setContent(mensaje, "text/html; charset=utf-8");
Transport transport = session.getTransport("smtp");
transport.connect("docemail#usmp.pe", "docpass");
transport.sendMessage(message, message.getAllRecipients());
transport.close();
} catch (MessagingException e) {
throw new RuntimeException(e);
} finally {
props = null;
message = null;
}
}
That's the server you're connecting to, and not a client issue. Here's a doc on how to parse SMTP codes from the server.
A mail server will reply to every request a client (such as your email
program) makes with a return code. This code consists of three
numbers.
In your case, you're getting 421.
You probably need to pay for a "business" account from your mail server vendor so they'll let you send more email.
if you want to send single email to 200 clients. Than u can add an array of reciever's email addresses of size upto 50.
but i you want to send different msg for each email. Then you can create a new connection to email server with a counter that counts send emails as well as it counts 15 it should create a new connection.
to test your code use mailtrap.io
Hi I have to send email in java.
The below has successfully worked for me.
public class SendMail {
public static void main(String[] args) {
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
Session session = Session.getDefaultInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("xxxx#gmail.com","xxxxx!1");
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("krishnaveni.veeman#gmail.com"));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("mercy.krishnaveni#gmail.com"));
message.setSubject("Testing Subject");
message.setText("Dear Mail Crawler," +
"\n\n No spam to my email, please!");
Transport.send(message);
System.out.println("Done");
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
}
Here I have mentioned gmail username and password. But I have to send email without using username and password in my code. How can I develop this. Please help me.
create a mail.properties file and put username and password into in that file. Use Properties to retrieve data from this file in your code.
This link could be useful to load Properties object
http://www.dzone.com/snippets/loading-property-file