LoginSignup
12
16

More than 5 years have passed since last update.

AndroidからOAuthトークンを利用してGMailを送る

Posted at

SMTPはパスワード認証がデフォらしく,パスワードを利用するサンプルはたくさんあるが,GmailはOAuthのトークンによる認証も出来るので,実際にやってみたサンプル.StackOverflowを参考に実装したが元スレ見つけられなくなってしまったので,手元で動いたコードを下にメモしておく.javamail-androidライブラリを利用している.

前提として, https://mail.google.comに対するトークンはすでに取得できているものとする.

import android.os.AsyncTask;
import com.sun.mail.smtp.SMTPTransport;
import com.sun.mail.util.BASE64EncoderStream;

import javax.activation.DataHandler;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.util.ByteArrayDataSource;
import java.util.Properties;

public class GmailSendHelper {
    private static final int RESPONSE_CODE_AUTH_SUCCESS = 235;
    private static final int SUBMISSION_PORT = 587;
    private static final String GMAIL_SMTP_SERVER = "smtp.gmail.com";
    private final String userEmail;
    private final String authToken;
    private Session session;

    public GmailSendHelper(String userEmail, String authToken) {
        this.userEmail = userEmail;
        this.authToken = authToken;
    }

    private SMTPTransport connectToSmtp(String host, int port) 
            throws MessagingException {
        Properties props = new Properties();
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.starttls.required", "true");
        props.put("mail.smtp.sasl.enable", "false");
        session = Session.getInstance(props);

        SMTPTransport transport 
                = new SMTPTransport(session, /* URL Name */ null);
        transport.connect(
                host, port, userEmail, /* Password, OAuth認証なのでNull */ null);

        byte[] response = BASE64EncoderStream.encode(
                String.format("user=%s\1auth=Bearer %s\1\1", 
                        userEmail, authToken).getBytes()
        );

        transport.issueCommand(
                "AUTH XOAUTH2 " + new String(response), RESPONSE_CODE_AUTH_SUCCESS);
        return transport;
    }

    public synchronized void sendHtmlMail(
            String subject, String body, String recipients) 
            throws MessagingException {
        SMTPTransport smtpTransport 
                = connectToSmtp(GMAIL_SMTP_SERVER, SUBMISSION_PORT);

        MimeMessage message = new MimeMessage(session);
        DataHandler handler = new DataHandler(
                new ByteArrayDataSource(body.getBytes(), "text/html"));
        message.setSender(new InternetAddress(userEmail));
        message.setSubject(subject);
        message.setDataHandler(handler);
        if (recipients.indexOf(',') > 0) {
            message.setRecipients(
                    Message.RecipientType.TO, InternetAddress.parse(recipients));
        } else {
            message.setRecipient(
                    Message.RecipientType.TO, new InternetAddress(recipients));
        }
        smtpTransport.sendMessage(message, message.getAllRecipients());
    }

    public synchronized void sendHtmlMailAsync(
            final String subject, final String body, final String recipients) {
        AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
            @Override
            protected String doInBackground(Void... params) {
                try {
                    sendHtmlMail(subject, body, recipients);
                    return "";
                } catch (MessagingException e) {
                    // TODO: handle error
                    return e.getMessage();
                }
            }
        };
        task.execute();
    }
}
12
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
16