Skip to content

Commit

Permalink
Refactor code and set message header to send to expensify.
Browse files Browse the repository at this point in the history
  • Loading branch information
mengyiyuan committed Jun 1, 2017
1 parent 25aafee commit 430d991
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 164 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#### Run Quickstart by running `gradle -q run`
#### Run GrabReceiptsForwarder by running `gradle -q run`

[Tutorial guide](https://developers.google.com/gmail/api/quickstart/java)

Expand All @@ -10,7 +10,9 @@ TO-DOs:
* ~~parse message properly~~
* ~~send message with MIME body~~
* ~~set date to Monday - Friday of the passing week (or generalize in the future)~~
* take input from somewhere to generalize the date range of receipts
* complete tests
* refactor code
* ~~refactor code~~
* ~~use REST api not client api? -nope, client api works~~
* ~~test sending receipts to expensify~~
* ...
88 changes: 88 additions & 0 deletions src/main/java/GmailServiceConfigurer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.gmail.GmailScopes;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;

class GmailServiceConfigurer {
private String applicationName;
private HttpTransport httpTransport;
private JsonFactory jsonFactory;
private List<String> scopes;
private FileDataStoreFactory dataStoreFactory;

GmailServiceConfigurer() {
}

GmailServiceConfigurer(String applicationName, HttpTransport httpTransport, JsonFactory jsonFactory, List<String> scopes, FileDataStoreFactory dataStoreFactory) {
this.applicationName = applicationName;
this.httpTransport = httpTransport;
this.jsonFactory = jsonFactory;
this.scopes = scopes;
this.dataStoreFactory = dataStoreFactory;
}

GmailServiceConfigurer loadDefaultConfiguration() {
final java.io.File DATA_STORE_DIR = new java.io.File(
System.getProperty("user.home"), ".credentials/gmail-java-quickstart");
this.applicationName = "Gmail API Java GrabReceiptsForwarder";
try {
this.httpTransport = GoogleNetHttpTransport.newTrustedTransport();
this.dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
} catch (GeneralSecurityException | IOException e) {
throw new RuntimeException(e);
}
this.jsonFactory = JacksonFactory.getDefaultInstance();
this.scopes = Collections.singletonList(GmailScopes.GMAIL_MODIFY);

return this;
}

String getApplicationName() {
return applicationName;
}

HttpTransport getHttpTransport() {
return httpTransport;
}

JsonFactory getJsonFactory() {
return jsonFactory;
}

Credential authorize() throws IOException {
GoogleClientSecrets clientSecrets = getClientSecrets();

GoogleAuthorizationCodeFlow flow = buildAuthorizationCodeFlow(clientSecrets);

return new AuthorizationCodeInstalledApp(
flow, new LocalServerReceiver()).authorize("user");
}

private GoogleAuthorizationCodeFlow buildAuthorizationCodeFlow(GoogleClientSecrets clientSecrets) throws IOException {
return new GoogleAuthorizationCodeFlow.Builder(
httpTransport, jsonFactory, clientSecrets, scopes)
.setDataStoreFactory(dataStoreFactory)
.setAccessType("offline")
.build();
}

private GoogleClientSecrets getClientSecrets() throws IOException {
InputStream in =
GrabReceiptsForwarder.class.getResourceAsStream("/client_secret.json");
return GoogleClientSecrets.load(jsonFactory, new InputStreamReader(in));
}
}
25 changes: 25 additions & 0 deletions src/main/java/GmailServiceProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.services.gmail.Gmail;

import java.io.IOException;

class GmailServiceProvider {
private GmailServiceConfigurer configurer;

GmailServiceProvider(GmailServiceConfigurer configurer) {
this.configurer = configurer;
}

Gmail getGmailService() {
Credential credential = null;
try {
credential = configurer.authorize();
} catch (IOException e) {
e.printStackTrace();
}
return new Gmail.Builder(configurer.getHttpTransport(), configurer.getJsonFactory(), credential)
.setApplicationName(configurer.getApplicationName())
.build();
}

}
19 changes: 19 additions & 0 deletions src/main/java/GrabReceiptsForwarder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.model.ListMessagesResponse;

import javax.mail.MessagingException;
import java.io.IOException;
import java.security.GeneralSecurityException;

public class GrabReceiptsForwarder {

public static void main(String[] args) throws IOException, MessagingException, GeneralSecurityException {
Gmail service = new GmailServiceProvider(new GmailServiceConfigurer().loadDefaultConfiguration()).getGmailService();
String user = "me";

MessageHandler messageHandler = new MessageHandler(service, user);
ListMessagesResponse response = messageHandler.getListMessageResponseBySearchQuery(new DateHandler().formatSearchQuery());
messageHandler.sendListMessages(response, "[email protected]");
}

}
72 changes: 72 additions & 0 deletions src/main/java/MessageHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import com.google.api.client.util.Base64;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.model.ListMessagesResponse;
import com.google.api.services.gmail.model.Message;

import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Properties;

class MessageHandler {
private final Gmail service;
private final String user;

MessageHandler(Gmail service, String user) {
this.service = service;
this.user = user;
}

ListMessagesResponse getListMessageResponseBySearchQuery(String query) throws IOException {
return service.users()
.messages().list(user)
.setQ(query)
.execute();
}

void sendListMessages(ListMessagesResponse messagesResponse, String to) throws IOException, MessagingException {
List<Message> messages = messagesResponse.getMessages();
for (Message message: messages) {
message = service.users().messages().get(user, message.getId()).execute();
MimeMessage mimeMessage = getMimeMessage(message.getId());
mimeMessage.setHeader("To", to);
sendMessage(mimeMessage);
}
}


private MimeMessage getMimeMessage(String messageId)
throws IOException, MessagingException {
Message message = service.users().messages().get(user, messageId).setFormat("raw").execute();

byte[] emailBytes = Base64.decodeBase64(message.getRaw());

Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);

return new MimeMessage(session, new ByteArrayInputStream(emailBytes));
}

private void sendMessage(MimeMessage email)
throws MessagingException, IOException {
Message message = createMessageWithEmail(email);
message = service.users().messages().send(user, message).execute();

System.out.println("Message id: " + message.getId());
System.out.println(message.toPrettyString());
}

private static Message createMessageWithEmail(MimeMessage email)
throws MessagingException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
email.writeTo(baos);
String encodedEmail = Base64.encodeBase64URLSafeString(baos.toByteArray());
Message message = new Message();
message.setRaw(encodedEmail);
return message;
}
}
151 changes: 0 additions & 151 deletions src/main/java/Quickstart.java

This file was deleted.

11 changes: 0 additions & 11 deletions src/test/java/DateHandlerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,6 @@
import static org.junit.Assert.assertEquals;

public class DateHandlerTest {
@Test
public void testFindThisMonday() throws Exception {
LocalDateTime now = LocalDateTime.now();
assertEquals(LocalDate.of(2017, 5, 29).getDayOfYear(), now.minusDays(now.getDayOfWeek().getValue() - 1).getDayOfYear());
}

@Test
public void testDateTimeFormat() throws Exception {
assertEquals("2017-05-31", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE));
}

@Test
public void testFormatSearchQuery() throws Exception {
assertEquals("from:([email protected]) business receipt after:2017-05-28 before:2017-06-03", new DateHandler().formatSearchQuery());
Expand Down
Loading

0 comments on commit 430d991

Please sign in to comment.