Sync your Gmail to local storage using java
In this article we will see how we can setup the Gmail account so that we can sync the mail to any other storage through a microservice with Oauth 2.0.
To start with we need to enable Gmail API at https://console.cloud.google.com/

Complete the Oauth consent screen with scope gmail.readonly.

You can get the complete list of valid scopes from below link: https://developers.google.com/gmail/api/auth/scopes
Now click credentials from left navigation and download credentials.json file.
Create Credentials -> Select Application type (Desktop App) -> Create
Import below dependencies to build.gradle or pom.xml:
apply plugin: 'java'
apply plugin: 'application'
mainClassName = 'GmailQuickstart'
sourceCompatibility = 11
targetCompatibility = 11
version = '1.0'
repositories {
mavenCentral()
}
dependencies {
implementation 'com.google.api-client:google-api-client:2.0.0'
implementation 'com.google.oauth-client:google-oauth-client-jetty:1.34.1'
implementation 'com.google.apis:google-api-services-gmail:v1-rev20220404-2.0.0'
}
Create credentials using google authorisation flow:
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT)
throws IOException {
// Load client secrets.
InputStream in = GmailQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
if (in == null) {
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
}
GoogleClientSecrets clientSecrets =
GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
Credential credential = new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
//returns an authorized Credential object.
return credential;
}
Create GmailService object using above credentials object:
Gmail service = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, createCredentials()).setApplicationName("GMAIL_API")
.build();
Fetch message id’s from gmail account:
ListMessagesResponse listMessagesResponse = service.users().messages().list(user)
.setMaxResults(noOfMessages > 500 ? 500 : noOfMessages.longValue())
.setPageToken(token).execute();
GET https://gmail.googleapis.com/gmail/v1/users/{userId}/messages
Iterate on all messageId and keep fetching message object as shown below:
Message message1 = service.users().messages().get("me", message.getId()).execute();
GET https://gmail.googleapis.com/gmail/v1/users/{userId}/messages/{id}
Fetch “To”, “From” and “Subject” from message object.
for (MessagePartHeader messagePartHeader : messagePartHeaders) {
if ("To".equals(messagePartHeader.getName())) {
//TODO:///
}
if ("From".equals(messagePartHeader.getName())) {
emailEntity.setFromEmail(messagePartHeader.getValue());
}
if ("Subject".equals(messagePartHeader.getName())) {
emailEntity.setSubject(messagePartHeader.getValue());
}
}
Fetch mail body content :
emailEntity.setContent(message1.getSnippet());
Fetch mail attachments:
if (messageParts != null) {
for (MessagePart messagePart : messageParts) {
if (StringUtils.isNoneEmpty(messagePart.getFilename())) {
emailEntity.setAttachment(messagePart.getFilename());
emailEntity.setMimeType(messagePart.getMimeType());
File file = new File(ATTACHMENT_LOCATION + messagePart.getFilename());
if (file.createNewFile()) {
try(FileWriter fileWriter = new FileWriter(file)) {
fileWriter.write(messagePart.getBody().getAttachmentId());
}
}
else {
logger.log(Level.WARNING, "Attachment is having issue.");
}
}
}
}
Things to remember:
- Gmail API have a default limit of 100 if no limit is provided but max 500 mails can be read at once.
- List message response returns a next page token to fetch next page emails. Check setPageToken() method to set the token.
- Save the mimeType of attachments which will help to fetch correct HTTP content streaming.
- Brief list of operation supported can be found at: https://developers.google.com/gmail/api/reference/rest