Try sending an email with the Gmail API Client Library for Java

I'm supposed to use the API of G Suite at work, but I can't find much material, so I tried using it for the time being.

This time the application framework is Spring Boot. Trying to use OAuth with a desktop app can be a hassle.

Preparation

I will omit the registration in API Console, the acquisition of OAuth client ID, and the setting of redirect URI because there is a lot of prior information.

Enable Gmail on the Library screen of the API console. Then add the API client library to your project. Since the Google API library is separated for each service, specify the library for Gmail. Also, include spring-boot-starter-mail for formatting mail data.

build.gradle


    // https://mvnrepository.com/artifact/com.google.apis/google-api-services-gmail
    compile group: 'com.google.apis', name: 'google-api-services-gmail', version: 'v1-rev72-1.23.0'

    // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.8.RELEASE'
    // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-mail
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: '1.5.8.RELEASE'

Authentication started

To take advantage of Gmail's API, you must first direct the user to a Google login page and receive an authorization code from there. The source page itself can be separate from the redirect URI.

At this time, look at Scope List and set the one to get the required permissions. Also, you cannot get a refresh token unless you set it to setAccessType ("offline"). SetApprovalPrompt ("force") . In that case, the validity period will expire in one day.

    private static final Collection<String> SCOPES = Arrays
            .asList("https://mail.google.com/");

    @GetMapping("/")
    public void mail(@NonNull HttpServletResponse res)
            throws GeneralSecurityException, IOException {
        //Authentication started
        val jsonFactory = JacksonFactory.getDefaultInstance();
        val transport = GoogleNetHttpTransport.newTrustedTransport();
        val flow = new GoogleAuthorizationCodeFlow.Builder(transport,
                jsonFactory, CLIENT_ID, CLIENT_SECRET, SCOPES).build();
        val url = flow.newAuthorizationUrl().setAccessType("offline")
                .setApprovalPrompt("force").setRedirectUri(REDIRECT_URI)
                .build();
        res.sendRedirect(url);
    }

Note that val in the above is lombok.val, which is for omitting the type declaration.

Get token

After approval by the user, you will be redirected to the specified redirect URI with an authentication code, and you will get a token based on that.

    @GetMapping(PATH)
    public String doMail(@RequestParam @NonNull final String code)
            throws Exception {
        //Token setting
        val jsonFactory = JacksonFactory.getDefaultInstance();
        val transport = GoogleNetHttpTransport.newTrustedTransport();
        val token = new GoogleAuthorizationCodeTokenRequest(transport,
                jsonFactory, CLIENT_ID, CLIENT_SECRET, code, REDIRECT_URI)
                        .execute();
        val cred = new GoogleCredential.Builder().setJsonFactory(jsonFactory)
                .setTransport(transport)
                .setClientSecrets(CLIENT_ID, CLIENT_SECRET).build()
                .setFromTokenResponse(token);

Note that if you know the token in some way, you can skip the user authentication process by building the TokenResponse object directly.

Email data creation

The mail data itself is Base64URL-encoded text data according to RFC 2822. If you write this with StringBuilder etc., it may lead to vulnerabilities such as header injection, so this time I will use Spring's MimeMessageHelper.

        val email = new MimeMessageHelper(
                this.javaMailSender.createMimeMessage(), "UTF-8");
        email.setSubject("test");
        email.setTo("fuga@localhost");
        email.setText("Hogehoge");
        val baos = new ByteArrayOutputStream();
        email.getMimeMessage().writeTo(baos);
        val msg = new Message()
                .setRaw(Base64.encodeBase64URLSafeString(baos.toByteArray()));

The second half of the above is as described in Google's Guide.

API call

Build a Gmail object with a GoogleCredential object that contains an access token. All you have to do is select the API from there and execute execute ().

        val gmail = new Gmail.Builder(transport, jsonFactory, cred)
                .setApplicationName("thud").build();
        val res = gmail.users().messages().send(EMAIL, msg).execute();
        // val res = gmail.users().labels().list(EMAIL).execute();
        return res.toString();

Recommended Posts

Try sending an email with the Gmail API Client Library for Java
To automatically send an email with an attachment using the Gmail API in Python
Create an alias for Route53 to CloudFront with the AWS API
I tried sending an email from the Sakura server with flask-mail
I tried sending an email with python.
Try sending the aggregated results of two records by email with pykintone
I checked the library for using the Gracenote API
Get an access token for the Pocket API
I tried sending an email with SendGrid + Python
Try building an environment for MayaPython with VisualStudioCode
Notes on transactions in the Java client library in the datastore
[Boto3] Search for Cognito users with the List Users API
I tried hitting the API with echonest's python client
Try hitting the Twitter API quickly and easily with Python
[Python] Send an email from gmail with two-step verification set
I tried sending an email from Amazon SES with Python
Get data from analytics API with Google API Client for python
(For beginners) Try creating a simple web API with Django
For the time being, try using the docomo chat dialogue API
Create an API with Django
Try an autoencoder with Pytorch
Try using the Twitter API
Try using the Twitter API
Try using the PeeringDB 2.0 API
Call the API with python3.
Grant an access token with the curl command and POST the API