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.
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'
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.
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.
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.
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