Send email by gmail via OAuth2 - Gukie/building-recommend GitHub Wiki

At the very beginning, the refer is:

1. Send email by username and password

This is not recommended since:

  • Your email password will be written on the source code.
  • you should turn "Allow less secure apps: ON" via Chrome, which is not recommended by Google. Otherwise, following exception will happen:
534-5.7.14 <https://accounts.google.com/signin/continue?sarp=1&scc=1&plt=AKgnsbsl
534-5.7.14 3pXIYm9tw30fPF4rN_jJSf-p1FiHhwOXQkwWPPbPzS3b42Gqah8y-OEjNDswEEGMn35xAk
534-5.7.14 viNdoKg_EfKCwBhyklWL-Yz0wAY2vilmKqMhANNERua3AQBviXNyPYwX9a0nY05B9j2Et0
534-5.7.14 4uR2GV1yfsbRCzaxQdos0USi9CGPO-NZUTN17vSsVvmjxx6STu4OD5OIcmteP_KhphKpVC
534-5.7.14 z1s-axcY45_fynUAkkSP66lEWxfhA> Please log in via your web browser and
534-5.7.14 then try again.
534-5.7.14  Learn more at
534 5.7.14  https://support.google.com/mail/answer/78754 r8sm2156157oih.34 - gsmtp
javax.mail.AuthenticationFailedException
	at javax.mail.Service.connect(Service.java:306)
	at javax.mail.Service.connect(Service.java:156)
	at javax.mail.Service.connect(Service.java:105)
	at javax.mail.Transport.send0(Transport.java:168)
	at javax.mail.Transport.send(Transport.java:98)

refer:

2. Send by OAuth2

This will use an access token, which is recommended by Google.

First, generate access token.

  • Create a google clientID on Google APIs Console
  • Download oauth2.py file
  • Download python 2.x, and install locally(I use 2.7.14)
  • Execute following python command:
python oauth2.py --generate_oauth2_token --client_id={your_client_id} --client_secret={your_client_secret}

refer:

Second, share with you some stupid mistakes when coding

After configure the correct access token, Exception still happens:

Following issue happens:
530-5.5.1 Authentication Required. Learn more at
530 5.5.1  https://support.google.com/mail/?p=WantAuthError m40sm2728661otb.34 - gsmtp
DEBUG SMTP: got response code 530, with response: 530-5.5.1 Authentication Required. Learn more at
530 5.5.1  https://support.google.com/mail/?p=WantAuthError m40sm2728661otb.34 - gsmtp

After debugging and research on Google, finally find a stupid mistake made by myself.

  • NO.1. the OAuth2SaslClientFactory should changed to yours
public class MyOAuth2Authenticator {
	private final Logger logger = Logger.getLogger(MyOAuth2Authenticator.class.getName());

	public final class OAuth2Provider extends Provider {
		private static final long serialVersionUID = 1L;

		public OAuth2Provider() {
			super("Google OAuth2 Provider", 1.0, "Provides the XOAUTH2 SASL Mechanism");
			String yourFactoryClass= "xxxxx"; // this should be your OAuth2SaslClientFactory.
			put("SaslClientFactory.XOAUTH2",yourFactoryClass);
		}
	}
  • NO.2. keep the password to be empty string when connecting to SMTPTransport
	public SMTPTransport getSmtpTransport(Session session,String host, int port, String userEmail) throws Exception {
//		Session session = getSmtpSession(oauthToken, debug);

		final URLName unusedUrlName = null;
		SMTPTransport transport = new SMTPTransport(session, unusedUrlName);
		// If the password is non-null, SMTP tries to do AUTH LOGIN.
		final String emptyPassword = ""; // do not change this, keep it
		transport.connect(host, port, userEmail, emptyPassword);

		return transport;
	}