Send email through Yahoo mail or Gmail with Java

I have a java email program that can take a mail host name , port number and then send an email, but I don't want to use the mail host at work, I wonder if I can send email through my Yahoo Mail or Gmail account with Java, do they have any Java API that my program can log me in and send emails ? Any sample code available ? Thanks.

Frank

[352 byte] By [Ni_Mina] at [2007-11-27 4:00:20]
# 1
Have you read the JavaMail FAQ? Search for "Yahoo" and "Gmail".
DrClapa at 2007-7-12 9:04:56 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 2

Thanks for reminding me, I did some search on "Yahoo" and "Gmail". For Yahoo someone posted some code that didn't work, for gmail, there seems to be a solution for sending email from command line. I wonder if I can send full fledged email : with CC, BCC, Attachment, Html email with images inside ...

I've done it with a local mail host, but how to do it with Yahoo or Gmail ?

Frank

>Have you read the JavaMail FAQ? Search for "Yahoo" and "Gmail".

Ni_Mina at 2007-7-12 9:04:56 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 3

> I wonder if I can send full fledged email : with CC, BCC, Attachment, Html email with images inside

The answer to this is: Every SMTP server in the world supports this. Your code should not depend on what server you are connecting to, except the part that actually does the connection.

The JavaMail FAQ has specific entries related to problems you may encounter with Yahoo and Gmail.

DrClapa at 2007-7-12 9:04:56 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 4

Well, in the FAQ (as I looked at six months ago), it doesn't have an concrete sample code of how to connect to Yahoo or Gmail, it points to MrPostman, and I found that it's few years old, the latest update was (08/27/2005), I wonder if it can still connect to the latest versions of Yahoo or Gmail. I remember I downloaded it a few months ago, and couldn't figure out how to send emails with it from a java program.

Is there any sample code showing how to do it ?

Frank

Ni_Mina at 2007-7-12 9:04:56 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 5
Amazingly, I actually do update the FAQ from time to time. :-)It's not an issue of code, it's an issue of configuration. http://java.sun.com/products/javamail/FAQ.html#yahoomail
bshannona at 2007-7-12 9:04:56 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 6
Hi , thanks for replying, I have noticed that question in the FAQ, but I don't have the Yahoo! Mail Plus, only the free account, and I have no plans to pay for the Yahoo! Mail Plus, does that mean there is no way out ?Frank
Ni_Mina at 2007-7-12 9:04:56 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 7
Switch to gmail?
bshannona at 2007-7-12 9:04:56 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 8
I do have Gmail, but how to send email via my java program ? Any sample code ?Frank> Switch to gmail?
Ni_Mina at 2007-7-12 9:04:56 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 9
Gee, I wonder if that information would be in the FAQ?Why don't you check and let me know...
bshannona at 2007-7-12 9:04:56 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 10

Woo, like magic, how come I didn't see it before ?! Was it there ? But thank you for reminding me ! ^_^

I've downloaded them (both activation.jar & mail.jar, I had the older versions), and will look into it, thanks again !

Frank

> Gee, I wonder if that information would be in the FAQ?

Ni_Mina at 2007-7-12 9:04:56 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 11

Does the Gmail approach applies to other web based emails ? I have an account with IX Hosting and have email accounts there that I can access from the web, can I use JavaMail to communicate with it ? In other words, is the Gmail approach a standard way of doing things with JavaMail that can by carried over to others ?

Ni_Mina at 2007-7-12 9:04:56 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 12

There is a standard way in JavaMail to configure access to SMTP,

IMAP, and POP3 servers. Not all web mail providers provide direct

access to their servers using those protocols. For example,

Hotmail does not. You'll need to check with your service provider.

If they provide instructions on how to configure other email clients

such as Thunderbird, you can probably configure JavaMail to access

the server.

bshannona at 2007-7-12 9:04:56 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 13
Great news ! I did setup Thunderbird to get emails from my accounts there, and it sounds like I'll be able to talk to my web mail accounts there from JavaMal, thanks, I'll give it a try.Frank
Ni_Mina at 2007-7-12 9:04:56 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 14
There is some news about Yahoo Mail API below, I wonder if the new release will work with JavaMail ? http://www.profy.com/2007/03/30/yahoo-mail-api-released http://www.readwriteweb.com/archives/yahoo_mail_api.phpFrank
Ni_Mina at 2007-7-12 9:04:56 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 15

In the FAQ, it says "A bug in older versions of the smtpsend command causes it to set the incorrect properties when using the -S (SSL) option, so we work around that bug by ..."

Does that mean in this new version of smtpsend, the bug has been fixed and therefore we can simply do the following ?

java smtpsend -S -M smtp.gmail.com -U user -P passwd -A user@gmail.com

Frank

Ni_Mina at 2007-7-21 21:00:37 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 16
I have several options as to use which host, either local or from several different web accounts, I wonder if there is a simply way to check which ones are available without actually sending a email to see if it succeeded or failed to find out ?Frank
Ni_Mina at 2007-7-21 21:00:37 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 17

> There is some news about Yahoo Mail API below, I

> wonder if the new release will work with JavaMail ?

It doesn't appear that they've written a JavaMail provider

to access Yahoo Mail using their new web service, and I

can't tell from their terms of use whether doing that would

be allowed.

bshannona at 2007-7-21 21:00:37 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 18

> I have several options as to use which host, either

> local or from several different web accounts, I

> wonder if there is a simply way to check which ones

> are available without actually sending a email to see

> if it succeeded or failed to find out ?

You can connect to the server, possibly authenticating,

and see if that works. Success connecting doesn't

guarantee that you'll be able to send mail, but it's a good

indicator.

bshannona at 2007-7-21 21:00:37 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 19

> In the FAQ, it says "A bug in older versions

> of the smtpsend command causes it to set the

> incorrect properties when using the -S (SSL) option,

> so we work around that bug by ..."

>

> Does that mean in this new version of

> smtpsend, the bug has been fixed and therefore we can

> simply do the following ?

>

> java smtpsend -S -M smtp.gmail.com -U user -P passwd

> -A user@gmail.com

Yes, that should work. Did you try it?

bshannona at 2007-7-21 21:00:37 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 20
Yes, I tried and it worked. Thanks.Frank
Ni_Mina at 2007-7-21 21:00:37 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 21
Does anyone know why Gmail has the following error message :Technical details of permanent failure:PERM_FAILURE: Message rejected for Sector 5 policy reasonsFrank
Ni_Mina at 2007-7-21 21:00:37 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 22

> Does anyone know why Gmail has the following error

> message :

>

> Technical details of permanent failure:

> PERM_FAILURE: Message rejected for Sector 5 policy

> reasons

No, but a quick google search shows that you're not alone.

If you figure it out, please post the answer here.

bshannona at 2007-7-21 21:00:37 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 23
Missing the "To:" field value will probably cause this error.Frank
Ni_Mina at 2007-7-21 21:00:37 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 24

I am accessing my ISP's mail host at work with JavaMail and got the following error, my actual valid email address is replaced below by

[ my_email@address.com ] :

===========================================================

To: my_email@address.com

Subject: Hello Frank

DEBUG: setDebug: JavaMail version 1.4ea

DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]

DEBUG SMTP: useEhlo true, useAuth true

DEBUG SMTP: trying to connect to host "mail.nmjava.com", port 25, isSSL false

220 mail54.opentransfer.com ESMTP

DEBUG SMTP: connected to host "mail.nmjava.com", port: 25

EHLO IT-FC-D-FNI

250-mail54.opentransfer.com

250-PIPELINING

250-8BITMIME

250 SIZE 1048576000

DEBUG SMTP: Found extension "PIPELINING", arg ""

DEBUG SMTP: Found extension "8BITMIME", arg ""

DEBUG SMTP: Found extension "SIZE", arg "1048576000"

DEBUG SMTP: use8bit false

MAIL FROM:<fni@IT-FC-D-FNI>

250 ok

RCPT TO:<my_email@address.com>

553 sorry, that domain isn't allowed to be relayed thru this MTA (#5.7.1)

DEBUG SMTP: Invalid Addresses

DEBUG SMTP:my_email@address.com

DEBUG SMTP: Sending failed because of invalid destination addresses

RSET

DEBUG SMTP: EOF: [EOF]

QUIT

DEBUG SMTP: EOF: [EOF]

javax.mail.SendFailedException: Invalid Addresses;

nested exception is:

com.sun.mail.smtp.SMTPAddressFailedException: 553 sorry, that domain isn't allowed to be relayed thru this MTA (#5.7.1)

at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:1196)

at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:584)

at smtpsend.main(smtpsend.java:150)

Caused by: com.sun.mail.smtp.SMTPAddressFailedException: 553 sorry, that domain isn't allowed to be relayed thru this MTA (#5.7.1)

at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:1047)

... 2 more

ADDRESS FAILED:

Address: my_email@address.com

Command: RCPT TO:<my_email@address.com>

RetCode: 553

Response: 553 sorry, that domain isn't allowed to be relayed thru this MTA (#5.7.1)

===========================================================

Does anyone know why ?

Frank

Ni_Mina at 2007-7-21 21:00:37 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 25
Back to the FAQ again, where a search for the word "relay" will explain.
DrClapa at 2007-7-21 21:00:37 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 26

I found out why, I used the wrong port.

Now it can relay my email through my ISP, but the receiver can't see the correct "From" address.

When I send the email, I set the "From" address to something like : 123@xyz.com, but the receiver sees something like this : my_user_Id_at_work@my_PC_id_at_work

It's not the From address I set. And it's not even a valid email address.

How to correct this ?

Frank

Ni_Mina at 2007-7-21 21:00:37 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 27
Your mail server at work is probably forcing the From address to be correct,so you can't send email with a forged From address. Generally, that's aVery Good Thing.You probably need to talk to your mail server administrator.
bshannona at 2007-7-21 21:00:37 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 28

What's the relations among the following items :

smtp/smtps , ssl, protocol, auth, user_name/password ?

My understanding is :

ssl: protocol==smtps

non-ssl : protocol==smtp

auth : use user_name/password

non-auth : no need for user_name/password ( yet you can still supply them )

Can there be a combination of [ non-ssl + auth ] and [ ssl + non-auth ] ?

I just need a quick answer, thanks.

Frank

Ni_Mina at 2007-7-21 21:00:37 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 29

Yes, both combinations are allowed in general, although I don't think

Yahoo Mail or Gmail allow them.

You can authenticate using a non-secure connection, although it's

not a good idea since it exposes your authentication information to

anyone who can intercept your communication. You can also

connect using a non-secure connection, switch the connection into

secure mode (using the "STARTTLS" command), and then authenticate

safely. (I believe at least Gmail allows this.)

You can also connect using a secure connection but not authenticate

to the server, if the server allows it, of course. A server within a company

firewall might allow such connections, although in some cases it will only

allow you to send messages within the company. (Search for "relay" in

the FAQ.)

bshannona at 2007-7-21 21:00:37 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 30

I have the following method that sends email, but I doubt if the logic is correct, it works, but it's not 100% correct when it comes to the relations of : user_name, password, Protocol, Ssl, Auth ...

Now it assumes Auth if there is a user_name, password, and if not Ssl, it will do : Transport.send(message)

Am I doing it the right way ? Need expert advice :

boolean Verbose=false,Debug=false,

Ssl=true,

Auth=true;

// Ssl=false,

// Auth=false;

// Ssl=false,

// Auth=true;

public void Send(String from,String to,String cc,String bcc,String host,String smtpPort,String subject,String body,String fileAttachment,String username,String password) throws Exception

{

String Attachments[];

Properties props=new Properties();// Create some properties and get the default Session

props.put("mail.smtp.host",host);

props.put("mail.smtp.port",smtpPort);

// props.put("mail.debug","true");

Session session=null;

Protocol=Ssl?"smtps":"smtp";

if (username != null && username.length()>0 && password != null && password.length()>0)

{

// props.put("mail.smtp.auth","true");

props.put("mail."+Protocol+".auth","true");

//session=Session.getDefaultInstance(props,new SMTPAuthenticator(username,password));

session=Session.getInstance(props,new SMTPAuthenticator(username,password));

}

//else session=Session.getDefaultInstance(props,null);

else session=Session.getInstance(props,null);

if (Debug) session.setDebug(true);

MimeMessage message=new MimeMessage(session);// Create a message

message.setFrom(new InternetAddress(from));

InternetAddress[] To_Address=InternetAddress.parse(to.replace(";",","),false);

message.setRecipients(Message.RecipientType.TO,To_Address);

InternetAddress[] Cc_Address=InternetAddress.parse(cc.replace(";",","),false);

message.addRecipients(Message.RecipientType.CC,Cc_Address);

InternetAddress[] Bcc_Address=InternetAddress.parse(bcc.replace(";",","),false);

message.addRecipients(Message.RecipientType.BCC,Bcc_Address);

message.setSubject(subject);

// You may need to encode the subject with this special method !

// message.setSubject(javax.mail.internet.MimeUtility.encodeText("Testing javamail with french : "));

message.setSentDate(new Date());

MimeBodyPart messageBodyPart=new MimeBodyPart();// Create the message part

messageBodyPart.setText(body); // Fill message

Multipart multipart=new MimeMultipart();

multipart.addBodyPart(messageBodyPart);

if (fileAttachment != null)// Part two is attachment

{

if (fileAttachment.indexOf(",")!=-1) Attachments=fileAttachment.split(",");

else if (fileAttachment.indexOf(";")!=-1) Attachments=fileAttachment.split(";");

else Attachments=new String[]{fileAttachment};

for (int i=0;i<Attachments.length;i++)

{

if (new File(Attachments[i]).exists())

{

messageBodyPart=new MimeBodyPart();

FileDataSource fds=new FileDataSource(Attachments[i]);

messageBodyPart.setDataHandler(new DataHandler(fds));

messageBodyPart.setFileName(Attachments[i]);

multipart.addBodyPart(messageBodyPart);

}

}

}

message.setContent(multipart); // Put parts in message

// message.setText(text); // If there is no attachment

if (!Ssl) Transport.send(message);// Send the message

else

{

// The simple way to send a message is : Transport.send(message);

// But we're going to use some SMTP-specific features for demonstration purposes so we need to manage the Transport object explicitly.

SMTPTransport t=(SMTPTransport)session.getTransport(Protocol);

try

{

if (Auth) t.connect(host,username,password);

else t.connect();

t.sendMessage(message,message.getAllRecipients());

}

finally

{

if (Verbose) System.out.println("Response: "+t.getLastServerResponse());

t.close();

}

}

session=null;

}

>

Ni_Mina at 2007-7-21 21:00:42 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 31

Ok, I guess it's code review time! :-)

You never use smtpPort.

You don't need SMTPAuthenticator since you're using the

connect method that supplies the username and password

directly.

You can simplify the code by always using the t.connect/t.sendMessage path,

even for non-SSL.

It's not clear what you intend the relationship to be between the Auth variable

and a non-null username and password. You could probably derive the

former from the latter.

bshannona at 2007-7-21 21:00:42 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 32

The smtpPort is used in props, which in turn is used to get a session, so user can specify any port they want, am I right ?

Are you saying if I use : "if (Auth) t.connect(host,username,password)" down there, then I don't need to use : SMTPAuthenticator at the beginning ?

To simplify, I can change :

if (!Ssl) Transport.send(message);// Send the message

else

{

// The simple way to send a message is : Transport.send(message);

// But we're going to use some SMTP-specific features for demonstration purposes so we need to manage the Transport object explicitly.

SMTPTransport t=(SMTPTransport)session.getTransport(Protocol);

try

{

if (Auth) t.connect(host,username,password);

else t.connect();

t.sendMessage(message,message.getAllRecipients());

}

finally

{

if (Verbose) System.out.println("Response: "+t.getLastServerResponse());

t.close();

}

}

Into this ? :

// The simple way to send a message is : Transport.send(message);

// But we're going to use some SMTP-specific features for demonstration purposes so we need to manage the Transport object explicitly.

SMTPTransport t=(SMTPTransport)session.getTransport(Protocol);

try

{

if (Auth) t.connect(host,username,password);

else t.connect();

t.sendMessage(message,message.getAllRecipients());

}

finally

{

if (Verbose) System.out.println("Response: "+t.getLastServerResponse());

t.close();

}

Frank

Ni_Mina at 2007-7-21 21:00:42 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 33
Oops, I missed that smtpPort usage. But yes, your change looks correct.
bshannona at 2007-7-21 21:00:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 34
Is this statement true : if I use : "if (Auth) t.connect(host,username,password)" down there, then I don't need to use : SMTPAuthenticator at the beginning ?ThanksFrank
Ni_Mina at 2007-7-21 21:00:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 35

Again, I'm not clear on what you intend the relationship to be

between Auth and username/password. In one place you make

a decision based on whether username and password are non-null

and in another place you make a similar decision based on Auth.

As far as i can guess about what you're trying to achieve, you don't

need the SMTPAuthenticator.

bshannona at 2007-7-21 21:00:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 36

That's because I wasn't clear how the process works, how do you know weather a mail server requires auth ? Do you get the info from the server admin ? In case of Yahoo, Gmail who do I ask ? Is there a way to automatically detect the requirement ?

So, I think I need to tell the program weather to auth or not, if it needs to, I then supply it with password, if it doesn't need to, just ignore the user_name and password, is this logical ?

Frank

Ni_Mina at 2007-7-21 21:00:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 37
You have to find out from the server admin what the requirements are forany particular server. Google and Yahoo publish the information you needon their web sites.
bshannona at 2007-7-21 21:00:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 38
So there is no way to automatically detect the requirement during the connection ?Frank
Ni_Mina at 2007-7-21 21:00:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 39
Other than by trial and error, no.
bshannona at 2007-7-21 21:00:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 40

Now I have 3 versions of code, which is the best ?

========================================= [ 1 ] =========================================

Protocol=ssl?"smtps":"smtp";

if (auth && username != null && password != null)

{

props.put("mail."+Protocol+".auth","true");

//session=Session.getDefaultInstance(props,new SMTPAuthenticator(username,password));

session=Session.getInstance(props,new SMTPAuthenticator(username,password));

}

//else session=Session.getDefaultInstance(props,null);

else session=Session.getInstance(props,null);

...

=== create message ===

...

SMTPTransport t=(SMTPTransport)session.getTransport(Protocol);

try

{

if (Auth) t.connect(host,username,password);

else t.connect();

t.sendMessage(message,message.getAllRecipients());

}

catch (Exception e)

{

...

}

========================================= [ 2 ] =========================================

Protocol=ssl?"smtps":"smtp";

if (auth && username != null && password != null)

{

props.put("mail."+Protocol+".auth","true");

//session=Session.getDefaultInstance(props,new SMTPAuthenticator(username,password));

session=Session.getInstance(props,new SMTPAuthenticator(username,password));

}

//else session=Session.getDefaultInstance(props,null);

else session=Session.getInstance(props,null);

...

=== create message ===

...

SMTPTransport t=(SMTPTransport)session.getTransport(Protocol);

try

{

t.connect();

t.sendMessage(message,message.getAllRecipients());

}

catch (Exception e)

{

...

}

========================================= [ 3 ] =========================================

Protocol=ssl?"smtps":"smtp";

if (auth) props.put("mail."+Protocol+".auth","true");

//session=Session.getDefaultInstance(props,null);

session=Session.getInstance(props,null);

...

=== create message ===

...

SMTPTransport t=(SMTPTransport)session.getTransport(Protocol);

try

{

if (Auth) t.connect(host,username,password);

else t.connect();

t.sendMessage(message,message.getAllRecipients());

}

catch (Exception e)

{

...

}

Also, when to use : Session.getDefaultInstance ?

And when to use : Session.getInstance ?

Frank

Ni_Mina at 2007-7-21 21:00:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 41
I would use #3, it's simpler. If you request authentication and don'tsupply a username or password, it will fail.Always use getInstance.(Knowing more about your application might cause me to choose adifferent answer.)
bshannona at 2007-7-21 21:00:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 42

Alright, it seems the best solution is :

Protocol=ssl?"smtps":"smtp";

if (auth) props.put("mail."+Protocol+".auth","true");

session=Session.getInstance(props,null);

...

=== create message ===

...

SMTPTransport t=(SMTPTransport)session.getTransport(Protocol);

try

{

if (Auth && username != null && password != null) t.connect(host,username,password);

else t.connect();

t.sendMessage(message,message.getAllRecipients());

}

catch (Exception e)

{

...

}

Ni_Mina at 2007-7-21 21:00:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 43
What is this line for ?props.put("mail.mime.address.strict","false");or props.put("mail.mime.address.strict","true");Frank
Ni_Mina at 2007-7-21 21:00:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 44
See the javadocs for the javax.mail.internet package, and for the MimeMessage class.
bshannona at 2007-7-21 21:00:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...