Skip to content

Commit 8b54cc0

Browse files
committed
Added an ability of send email via Gmail "sendAs".| #80.
1 parent 9f30fae commit 8b54cc0

File tree

4 files changed

+101
-29
lines changed

4 files changed

+101
-29
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Business Source License 1.0 © 2017 FlowCrypt Limited ([email protected]).
3+
* Use limitations apply. See https://github.com/FlowCrypt/flowcrypt-android/blob/master/LICENSE
4+
* Contributors: DenBond7
5+
*/
6+
7+
package com.flowcrypt.email.api.email.gmail;
8+
9+
import android.accounts.Account;
10+
import android.content.Context;
11+
12+
import com.flowcrypt.email.R;
13+
import com.flowcrypt.email.api.email.JavaEmailConstants;
14+
import com.flowcrypt.email.database.dao.source.AccountDao;
15+
import com.google.api.client.extensions.android.http.AndroidHttp;
16+
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
17+
import com.google.api.client.http.HttpTransport;
18+
import com.google.api.client.json.JsonFactory;
19+
import com.google.api.client.json.jackson2.JacksonFactory;
20+
import com.google.api.services.gmail.Gmail;
21+
22+
/**
23+
* This class helps to work with Gmail API.
24+
*
25+
* @author Denis Bondarenko
26+
* Date: 30.10.2017
27+
* Time: 14:35
28+
29+
*/
30+
31+
public class GmailApiHelper {
32+
33+
/**
34+
* Generate {@link Gmail} using incoming {@link AccountDao}. The {@link} Gmail is the main point in using Gmail API.
35+
*
36+
* @param context Interface to global information about an application environment.
37+
* @param accountDao The {@link AccountDao} object which contains information about an email account.
38+
* @return Generated {@link Gmail}.
39+
*/
40+
public static Gmail generateGmailApiService(Context context, AccountDao accountDao) {
41+
if (accountDao == null || accountDao.getAccount() == null) {
42+
throw new IllegalArgumentException("AccountDao is not valid.");
43+
}
44+
45+
GoogleAccountCredential googleAccountCredential = generateGoogleAccountCredential(context,
46+
accountDao.getAccount());
47+
48+
HttpTransport httpTransport = AndroidHttp.newCompatibleTransport();
49+
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
50+
return new Gmail.Builder(httpTransport, jsonFactory, googleAccountCredential)
51+
.setApplicationName(context.getString(R.string.app_name)).build();
52+
}
53+
54+
/**
55+
* Generate {@link GoogleAccountCredential} which will be used with Gmail API.
56+
*
57+
* @param context Interface to global information about an application environment.
58+
* @param account The Gmail account.
59+
* @return Generated {@link GoogleAccountCredential}.
60+
*/
61+
private static GoogleAccountCredential generateGoogleAccountCredential(Context context, Account account) {
62+
GoogleAccountCredential googleAccountCredential = new GoogleAccountCredential(context,
63+
JavaEmailConstants.OAUTH2 + GmailConstants.SCOPE_MAIL_GOOGLE_COM);
64+
googleAccountCredential.setSelectedAccount(account);
65+
66+
return googleAccountCredential;
67+
}
68+
}

FlowCrypt/src/main/java/com/flowcrypt/email/api/email/sync/tasks/SendMessageSyncTask.java

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import com.flowcrypt.email.api.email.EmailUtil;
1717
import com.flowcrypt.email.api.email.FoldersManager;
18+
import com.flowcrypt.email.api.email.gmail.GmailApiHelper;
1819
import com.flowcrypt.email.api.email.model.AttachmentInfo;
1920
import com.flowcrypt.email.api.email.model.OutgoingMessageInfo;
2021
import com.flowcrypt.email.api.email.sync.SyncListener;
@@ -25,12 +26,15 @@
2526
import com.flowcrypt.email.js.PgpKey;
2627
import com.flowcrypt.email.js.PgpKeyInfo;
2728
import com.flowcrypt.email.security.SecurityStorageConnector;
29+
import com.google.api.client.util.Base64;
30+
import com.google.api.services.gmail.Gmail;
2831
import com.sun.mail.imap.IMAPFolder;
2932

3033
import org.apache.commons.io.FileUtils;
3134
import org.apache.commons.io.IOUtils;
3235

3336
import java.io.BufferedInputStream;
37+
import java.io.ByteArrayOutputStream;
3438
import java.io.File;
3539
import java.io.IOException;
3640
import java.io.InputStream;
@@ -90,7 +94,7 @@ public boolean isUseSMTP() {
9094
public void runSMTPAction(AccountDao accountDao, Session session, Store store, SyncListener syncListener)
9195
throws Exception {
9296
super.runSMTPAction(accountDao, session, store, syncListener);
93-
97+
boolean isMessageSent = false;
9498
if (syncListener != null) {
9599
Context context = syncListener.getContext();
96100

@@ -105,21 +109,36 @@ public void runSMTPAction(AccountDao accountDao, Session session, Store store, S
105109

106110
MimeMessage mimeMessage = createMimeMessage(session, context, accountDao, pgpCacheDirectory);
107111

108-
Transport transport = prepareTransportForSmtp(syncListener.getContext(), session, accountDao);
109-
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
110-
111112
switch (accountDao.getAccountType()) {
112113
case AccountDao.ACCOUNT_TYPE_GOOGLE:
114+
if (accountDao.getEmail().equalsIgnoreCase(outgoingMessageInfo.getFromPgpContact().getEmail())) {
115+
Transport transport = prepareTransportForSmtp(syncListener.getContext(), session, accountDao);
116+
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
117+
} else {
118+
Gmail gmailApiService = GmailApiHelper.generateGmailApiService(context, accountDao);
119+
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
120+
mimeMessage.writeTo(byteArrayOutputStream);
121+
122+
com.google.api.services.gmail.model.Message sentMessage
123+
= new com.google.api.services.gmail.model.Message();
124+
sentMessage.setRaw(Base64.encodeBase64URLSafeString(byteArrayOutputStream.toByteArray()));
125+
sentMessage = gmailApiService.users().messages().send("me", sentMessage).execute();
126+
isMessageSent = sentMessage.getId() != null;
127+
}
128+
113129
//Gmail automatically save a copy of the sent message.
114130
break;
115131

116132
default:
133+
Transport transport = prepareTransportForSmtp(syncListener.getContext(), session, accountDao);
134+
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
135+
117136
saveCopyOfSentMessage(accountDao, store, syncListener.getContext(), mimeMessage);
118137
}
119138

120139
FileUtils.cleanDirectory(pgpCacheDirectory);
121140

122-
syncListener.onMessageSent(accountDao, ownerKey, requestCode, true);
141+
syncListener.onMessageSent(accountDao, ownerKey, requestCode, isMessageSent);
123142
}
124143
}
125144

FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,9 @@ public void onMessageEncryptionTypeChange(MessageEncryptionType messageEncryptio
482482
*/
483483
public void notifyUserAboutErrorWhenSendMessage() {
484484
isMessageSendingNow = false;
485-
getActivity().invalidateOptionsMenu();
485+
if (getActivity() != null) {
486+
getActivity().invalidateOptionsMenu();
487+
}
486488
UIUtil.exchangeViewVisibility(getContext(), false, progressView, getContentView());
487489
showInfoSnackbar(getView(), getString(R.string.error_occurred_while_sending_message));
488490
}
@@ -524,7 +526,7 @@ private OutgoingMessageInfo getOutgoingMessageInfo() {
524526
}
525527

526528
outgoingMessageInfo.setToPgpContacts(pgpContacts.toArray(new PgpContact[0]));
527-
outgoingMessageInfo.setFromPgpContact(new PgpContact(activeAccountDao.getEmail(), null));
529+
outgoingMessageInfo.setFromPgpContact(new PgpContact(editTextFrom.getText().toString(), null));
528530

529531
return outgoingMessageInfo;
530532
}
@@ -691,12 +693,12 @@ private void updateViews() {
691693
}
692694

693695
private String prepareRecipients(List<String> recipients) {
694-
String result = "";
696+
StringBuilder stringBuilder = new StringBuilder();
695697
for (String s : recipients) {
696-
result += s + " ";
698+
stringBuilder.append(s).append(" ");
697699
}
698700

699-
return result;
701+
return stringBuilder.toString();
700702
}
701703

702704
/**

FlowCrypt/src/main/java/com/flowcrypt/email/ui/loader/LoadGmailAliasesLoader.java

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,10 @@
99
import android.content.Context;
1010
import android.support.v4.content.AsyncTaskLoader;
1111

12-
import com.flowcrypt.email.R;
13-
import com.flowcrypt.email.api.email.JavaEmailConstants;
14-
import com.flowcrypt.email.api.email.gmail.GmailConstants;
12+
import com.flowcrypt.email.api.email.gmail.GmailApiHelper;
1513
import com.flowcrypt.email.database.dao.source.AccountAliasesDao;
1614
import com.flowcrypt.email.database.dao.source.AccountDao;
1715
import com.flowcrypt.email.model.results.LoaderResult;
18-
import com.google.api.client.extensions.android.http.AndroidHttp;
19-
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
20-
import com.google.api.client.http.HttpTransport;
21-
import com.google.api.client.json.JsonFactory;
22-
import com.google.api.client.json.jackson2.JacksonFactory;
2316
import com.google.api.services.gmail.Gmail;
2417
import com.google.api.services.gmail.model.ListSendAsResponse;
2518
import com.google.api.services.gmail.model.SendAs;
@@ -59,17 +52,7 @@ public void onStartLoading() {
5952
@Override
6053
public LoaderResult loadInBackground() {
6154
try {
62-
GoogleAccountCredential googleAccountCredential = new GoogleAccountCredential(getContext(),
63-
JavaEmailConstants.OAUTH2 + GmailConstants.SCOPE_MAIL_GOOGLE_COM);
64-
googleAccountCredential.setSelectedAccount(accountDao.getAccount());
65-
66-
HttpTransport httpTransport = AndroidHttp.newCompatibleTransport();
67-
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
68-
Gmail mService = new Gmail.Builder(
69-
httpTransport, jsonFactory, googleAccountCredential)
70-
.setApplicationName(getContext().getString(R.string.app_name))
71-
.build();
72-
55+
Gmail mService = GmailApiHelper.generateGmailApiService(getContext(), accountDao);
7356
ListSendAsResponse aliases = mService.users().settings().sendAs().list("me").execute();
7457
List<AccountAliasesDao> accountAliasesDaoList = new ArrayList<>();
7558
for (SendAs alias : aliases.getSendAs()) {

0 commit comments

Comments
 (0)