I have to read some confirmation emails which are developed by tables in HTML.
I'm using GMail API and Java programming language for it.
I'm doing automatization of the registration process so I have to get the link to the confirmation email and click on that confirm button by Selenium test.
In response I'm getting emails with only text, for eg if I send to my mail some random text, I can get that text in response, however, for table kinds of emails I'm getting messages that the body is null.
This is the HTML code of that email.
Image of the email: Image of email
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<title>Test</title>
<meta content="light only" name="color-scheme" />
<meta name="”x-apple-disable-message-reformatting”" />
<style></style>
</head>
<body class="full-width" data-gr-ext-installed="" data-new-gr-c-s-check-loaded="14.997.0" style="max-width: 600px;width: 100%;background: #333333; margin: 0 auto;">
<div class="full-width" style="width: 100%;padding: 1em 0;"><!--[if mso | IE]>
</td></tr></table>
<![endif]--><!--[if mso | IE]>
<table class="full-width" border="0" cellpadding="0" cellspacing="0" width="600" align="center" style="width: 100%;">
<tr style=" width: 100%;">
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
<![endif]-->
<div class="full-width" style=" width: 100%;margin:0 auto;max-width:600px;background:#333333;">
<table align="center" border="0" cellpadding="0" cellspacing="0" class="full-width" style="font-size:0px;width:100%;background:#1b2940;">
<tbody class="full-width">
<tr class="full-width">
<td class="full-width" style="text-align:center;vertical-align:top;font-size:0px;padding:0px;"><!--[if mso | IE]>
<table class="full-width" border="0" cellpadding="0" cellspacing="0">
<tr class="full-width">
<td class="full-width" style="vertical-align:middle;width:600px;">
<![endif]-->
<div aria-labelledby="mj-column-per-100" class="full-width" style="vertical-align:middle;display:inline-block;font-size:13px;text-align:left;width:100%;">
<table border="0" cellpadding="0" cellspacing="0" class="full-width" style="vertical-align:middle;" width="100%">
<tbody class="full-width">
<tr>
<td align="center" style="word-break:break-word;font-size:0px;padding:0px;">
<table align="center" border="0" cellpadding="0" cellspacing="0" style="border-collapse:collapse;border-spacing:0px;">
<tbody><!--
<tr>--><!-- <td style="width:600px;">--><!-- <a href="https://www.24bettle.com/?utm_source=system-email&utm_medium=Image"--><!-- target="_blank" >--><!-- <img alt="24Bettle Logo"--><!-- src="http://24bettle.com/images/email_images/button-gradient-pic.png"--><!-- style="outline: none; text-decoration: none; clear: both; border: 0px; max-width: 640px; width: 600px; height: 122px; "--><!-- title=""/>--><!-- </a>--><!-- </td>--><!-- </tr>-->
<tr>
<td style="width:650px"><img class="first-banner" src="https://24bettle.com/images/banners/24header-image-2.png" style="outline: none; text-decoration: none; clear: both; border: 0px; max-width: 600px; width: 100%;" /></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td align="center" style="word-break:break-word;font-size:0px;padding:0px;"> </td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td></tr></table>
<![endif]--></td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td></tr></table>
<![endif]--><!--[if mso | IE]>
<table border="0" cellpadding="0" cellspacing="0" width="600" align="center" style="width:600px;">
<tr>
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
<![endif]-->
<div class="full-width" style=" width: 100%;margin:0 auto;max-width:600px;background:#fff;">
<table border="0" cellpadding="0" cellspacing="0" class="full-width" style="padding: 2em 2em;vertical-align:middle;" width="100%">
<tbody class="full-width">
<tr>
<td align="left" style="word-break:break-word;font-size:0px;padding:0px;">
<div style="cursor:auto;color:#000000;font-family:Verdana, sans-serif;font-size:20px;line-height:20px;">
<p style="font-size: 20px; margin: 0px 0px 15px; color: rgb(76, 76, 76); text-align: center;">Hello {username},</p>
</div>
</td>
</tr>
<tr class="full-width">
<td align="left" style="word-break:break-word;font-size:0px;padding:0px;">
<div style="cursor:auto;color:#000000;font-family:Verdana, sans-serif;font-size:14px;line-height:20px;">
<table border="0" cellpadding="0" cellspacing="0" style="font-size: 13px; background-color: rgb(255, 255, 255); vertical-align: middle;" width="100%">
<tbody>
<tr>
<td align="left" style="word-break: break-word; font-size: 0px; padding: 0px;">
<div style="cursor: auto; font-family: Verdana, sans-serif; font-size: 14px; line-height: 20px;">
<table border="0" cellpadding="0" cellspacing="0" style="font-family: Verdana, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); vertical-align: middle;" width="100%">
<tbody>
<tr>
<td align="left" style="word-break: break-word; font-size: 0px; padding: 0px;">
<div style="cursor: auto; font-size: 14px; line-height: 20px;">
<p><span style="font-family: verdana, geneva, sans-serif;"><span style="color:#333333;">Hit the link to confirm your shiny, new account and enter <strong>24Bettle </strong>- a new dimension of awesome!</span></span></p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
<tr>
<td align="center" style="word-break:break-word;font-size:0px;padding:10px 25px;">
<table align="center" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr><!-- style="border: 3px solid #4A8FFF;box-shadow: 0px 5px 10px 0px rgba(85,108,108,1);display:inline-block;text-decoration:none;color:white;font-family:Verdana, sans-serif;font-size:22px;text-shadow: 0px 2px 0px #000000;line-height: 20px;font-weight:900;margin:0px; padding:22px 23px; background: transparent linear-gradient(180deg, RGB(118, 191, 254) 44%, #1A3380 97%) 0% 0% no-repeat padding-box; no-repeat:padding-box;border-radius: 35px"-->
<td align="center" bgcolor="" style="border-radius:6px;color:white;cursor:auto;background: url(http://24bettle.com/images/email_images/button-gradient-pic.png);background-size: 100% 100%;" valign="middle"><a href="{register_confirmation_url}" id="button" style="background-color: #4587F1;background-size: 100% 100%;background-repeat: no-repeat; background-size: cover;box-shadow: 0px 5px 10px 0px rgba(85,108,108,0.4);display:inline-block;text-decoration:none;color:white;font-size:22px;line-height: 20px;font-weight:700;margin:0px; padding: 22px 35px;border-radius: 35px;font-family: 'Oswald', sans-serif; " target="_blank">CONFIRM!</a></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td align="center" style="word-break:break-word;font-size:0px;padding:0px;">
<div style="cursor:auto;color:#000000;font-family:Verdana, sans-serif;font-size:14px;line-height:14px;">
<div style="text-align: -webkit-center; background-color: rgb(255, 255, 255); cursor: auto; font-family: Verdana, sans-serif; font-size: 14px; line-height: 14px;"> </div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="full-width" style="margin:0 auto;max-width:600px;">
<table align="center" border="0" cellpadding="0" cellspacing="0" class="full-width" style="font-size:0px;width:100%;background:#333333;">
<tbody class="full-width">
<tr>
<td style="text-align:center;vertical-align:top;font-size:0px;padding:0px;">
<div aria-labelledby="mj-column-per-100" class="mj-column-per-100" style="background-color: #333333;vertical-align:middle;display:inline-block;font-size:13px;text-align:center;width:100%;">
<table border="0" cellpadding="0" cellspacing="0" style="vertical-align:middle;" width="100%">
<tbody style="background: #141E30; ">
<tr>
<td align="center" style="word-break:break-word;font-size:0px;padding: 10px 0 0 0;background-color: #333333">
<div style="cursor:auto;color:#CCCCCC;font-family:Verdana, sans-serif;line-height:22px;">
<p style="padding: 0 1em;font-family: 'Segoe UI',sans-serif;font-size: 14px; margin: 0; color: #CCCCCC;text-align: -webkit-center;"> </p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td></tr></table>
<![endif]--></td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td></tr></table>
<![endif]--><!--[if mso | IE]>
<table class="full-width" border="0" cellpadding="0" cellspacing="0" width="600" align="center" style="width:600px;">
<tr>
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
<![endif]-->
<div class="full-width" style="margin:0 auto;max-width:600px;background:#fff;">
<table align="center" border="0" cellpadding="0" cellspacing="0" class="full-width" style="font-size:0px;width:100%;background:#fff;">
<tbody>
<tr>
<td style="text-align:center;vertical-align:top;font-size:0px;padding:0px;"><!--[if mso | IE]>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td style="vertical-align:middle;width:300px;">
<![endif]--><!--[if mso | IE]>
</td>
<td style="vertical-align:middle;width:300px;">
<![endif]--><!--[if mso | IE]>
</td></tr></table>
<![endif]--></td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td></tr></table>
<![endif]--></div>
</body>
</html>
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.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.repackaged.org.apache.commons.codec.binary.Base64;
import com.google.api.client.repackaged.org.apache.commons.codec.binary.StringUtils;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.Gmail.Users;
import com.google.api.services.gmail.Gmail.Users.Messages;
import com.google.api.services.gmail.Gmail.Users.Messages.Get;
import com.google.api.services.gmail.GmailScopes;
import com.google.api.services.gmail.model.Label;
import com.google.api.services.gmail.model.ListLabelsResponse;
import com.google.api.services.gmail.model.ListMessagesResponse;
import com.google.api.services.gmail.model.Message;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;
public class GmailQuickstart {
private static final String APPLICATION_NAME = "Gmail API Java Quickstart";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";
/**
* Global instance of the scopes required by this quickstart.
* If modifying these scopes, delete your previously saved tokens/ folder.
*/
private static final List<String> SCOPES = Collections.singletonList(GmailScopes.GMAIL_LABELS);
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
/**
* Creates an authorized Credential object.
* @param HTTP_TRANSPORT The network HTTP Transport.
* @return An authorized Credential object.
* @throws IOException If the credentials.json file cannot be found.
*/
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();
return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}
public static void main(String... args) throws IOException,
// Build a new authorized API client service.
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Gmail service = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
// Print the labels in the user's account.
String user = "me";
ListLabelsResponse listResponse = service.users().labels().list(user).execute();
List<Label> labels = listResponse.getLabels();
if (labels.isEmpty()) {
System.out.println("No labels found.");
} else {
System.out.println("Labels:");
for (Label label: labels) {
System.out.printf("- %s\n", label.getName());
}
}
// Access Gmail inbox
Gmail.Users.Messages.List request = service.users().messages().list(user).setQ("from: " + "helpdesk@b-bets.com");
ListMessagesResponse messagesResponse = request.execute();
request.setPageToken(messagesResponse.getNextPageToken());
// Get ID of the email you are looking for
Gmail.Users.Messages.List request = service.users().messages().list(user).setQ("from: " + "support1@24bettle.com");
String messageId = messagesResponse.getMessages().get(0).getId();
Message message = service.users().messages().get(user, messageId).execute();
// Print email body
String emailBody = StringUtils
.newStringUtf8(Base64.decodeBase64(message.getPayload().getParts().get(0).getBody().getData()));
System.out.println("Email body : " + emailBody);
}
}
The HTML table you are looking for is in a subpart of the message's first part.
The response you are getting from Try this API
has this approximate shape (excluding irrelevant fields):
{
"payload": {
"body": { "size": 0 },
"parts": [
{
"partId": "0",
"body": { "size": 0 },
"parts": [
{
"partId": "0.0",
// Other fields
},
{
"partId": "0.1",
"mimeType": "text/html",
"body": {
"size": 14024,
"data": "BASE64_ENCODED_STRING" // HTML table
},
// Other fields
}
]
},
{
"partId": "1",
// Other fields
}
]
},
// Other fields
}
If you look at this, it's clear that the content you are looking for is in the first part, but this part itself contains several subparts. The second of these parts contains the desired content.
You should be able to retrieve the data from this part via:
message.getPayload().getParts().get(0).getParts().get(1).getBody().getData();
Therefore, replace this:
String emailBody = StringUtils
.newStringUtf8(Base64.decodeBase64(message.getPayload().getParts().get(0).getBody().getData()));
With this:
String emailBody = StringUtils
.newStringUtf8(Base64.decodeBase64(message.getPayload().getParts().get(0).getParts().get(1).getBody().getData()));