Vipul Tiwari
3 min readJun 14, 2024

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:

  1. Gmail API have a default limit of 100 if no limit is provided but max 500 mails can be read at once.
  2. List message response returns a next page token to fetch next page emails. Check setPageToken() method to set the token.
  3. Save the mimeType of attachments which will help to fetch correct HTTP content streaming.
  4. Brief list of operation supported can be found at: https://developers.google.com/gmail/api/reference/rest

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Vipul Tiwari
Vipul Tiwari

No responses yet

Write a response