19

I want to get full message body. So I try:

Message gmailMessage = service.users().messages().get("me", messageId).setFormat("full").execute();

That to get body, I try:

gmailMessage.getPayload().getBody().getData()

but result always null. How to get full message body?

somebody
  • 1,077
  • 5
  • 14
  • 32
  • remove the setFormat? – Hinotori Feb 17 '16 at 21:38
  • The reason this particular version does not work is that the raw field is null on purpose. If you look at the api docs here. https://developers.google.com/gmail/api/v1/reference/users/messages/get. The "full" format does not use the raw field. – zypherman Sep 21 '17 at 17:20

9 Answers9

8

To get the data from your gmailMessage, you can use gmailMessage.payload.parts[0].body.data. If you want to decode it into readable text, you can do the following:

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;

System.out.println(StringUtils.newStringUtf8(Base64.decodeBase64(gmailMessage.payload.parts[0].body.data)));
Tholle
  • 108,070
  • 19
  • 198
  • 189
  • 3
    @Yster No problem :) Might be worth reading [this answer](http://stackoverflow.com/questions/32655874/cannot-get-the-body-of-email-with-gmail-php-api/32660892#32660892) to understand that this problem can be trickier than it seems. – Tholle Sep 22 '16 at 15:54
  • 1
    Answer is here https://developers.google.com/gmail/api/v1/reference/users/messages/get ("format" field) – ror Mar 08 '20 at 08:18
  • `message['payload']['parts'][0]['body']` always returns `{'size': 0}` – endolith Jun 11 '22 at 14:05
  • yes, i have also main portion of email body in parts[1] – washiur17 Jul 14 '23 at 06:44
6

I tried this way, since message.getPayload().getBody().getParts() was always null

import com.google.api.client.repackaged.org.apache.commons.codec.binary.Base64;
import com.google.api.client.repackaged.org.apache.commons.codec.binary.StringUtils;

(...)

Message message = service.users().messages().get(user, m.getId()).execute();
MessagePart part = message.getPayload();
System.out.println(StringUtils.newStringUtf8(Base64.decodeBase64(part.getBody().getData())));

And the result is pure HTML String

Hinotori
  • 552
  • 6
  • 15
6

I found more interesting way how to resolve a full body message (and not only body):

System.out.println(StringUtils.newStringUtf8(   Base64.decodeBase64 (message.getRaw())));
Yury Staravoitau
  • 175
  • 5
  • 11
5

If you have the message (com.google.api.services.gmail.model.Message) you could use the following methods:

public String getContent(Message message) {
    StringBuilder stringBuilder = new StringBuilder();
    try {
        getPlainTextFromMessageParts(message.getPayload().getParts(), stringBuilder);
        byte[] bodyBytes = Base64.decodeBase64(stringBuilder.toString());
        String text = new String(bodyBytes, StandardCharsets.UTF_8);
        return text;
    } catch (UnsupportedEncodingException e) {
        logger.error("UnsupportedEncoding: " + e.toString());
        return message.getSnippet();
    }
}

private void getPlainTextFromMessageParts(List<MessagePart> messageParts, StringBuilder stringBuilder) {
    for (MessagePart messagePart : messageParts) {
        if (messagePart.getMimeType().equals("text/plain")) {
            stringBuilder.append(messagePart.getBody().getData());
        }

        if (messagePart.getParts() != null) {
            getPlainTextFromMessageParts(messagePart.getParts(), stringBuilder);
        }
    }
}

It combines all message parts with the mimeType "text/plain" and returns it as one string.

Community
  • 1
  • 1
Henk
  • 176
  • 1
  • 7
5

here is the solution in c# code gmail API v1 to read the email body content:

  var request = _gmailService.Users.Messages.Get("me", mail.Id);
                request.Format = UsersResource.MessagesResource.GetRequest.FormatEnum.Full;

and to solve the data error

 var res = message.Payload.Body.Data.Replace("-", "+").Replace("_", "/");
 byte[] bodyBytes = Convert.FromBase64String(res);


 string val = Encoding.UTF8.GetString(bodyBytes);
Tal Avissar
  • 10,088
  • 6
  • 45
  • 70
  • If I had a million friends, I'd bribe them all to join SO just to upvote this answer! I've wasted hours on this decoding stuff, and your `Replace` addition solved it all in one fell swoop. תודה רבה – Avrohom Yisroel Jun 06 '21 at 16:19
1

When we get full message. The message body is inside Parts.

This is an example in which message headers (Date, From, To and Subject) are displayed and Message Body as a plain text is displayed. Parts in Payload returns both type of messages (plain text and formatted text). I was interested in Plain text.

Message msg = service.users().messages().get(user, message.getId()).setFormat("full").execute();
// Displaying Message Header Information
for (MessagePartHeader header : msg.getPayload().getHeaders()) {
  if (header.getName().contains("Date") || header.getName().contains("From") || header.getName().contains("To")
      || header.getName().contains("Subject"))
    System.out.println(header.getName() + ":" + header.getValue());
}
// Displaying Message Body as a Plain Text
for (MessagePart msgPart : msg.getPayload().getParts()) {
  if (msgPart.getMimeType().contains("text/plain"))
    System.out.println(new String(Base64.decodeBase64(msgPart.getBody().getData())));
}
Zaheer
  • 374
  • 4
  • 20
0

Base on the @Tholle comment I've made something like that

Message message = service.users().messages()
        .get(user, messageHolder.getId()).execute();

System.out.println(StringUtils.newStringUtf8(Base64.decodeBase64(
        message.getPayload().getParts().get(0).getBody().getData())));
Socowi
  • 25,550
  • 3
  • 32
  • 54
Tomasz TJ
  • 1
  • 1
0

There is a method to decode the body:

final String body = new String(message.getPayload().getParts().get(0).getBody().decodeData());
0
Message message = service.users().messages().get(user, messageId).execute();
    
//Print email body
List<MessagePart> parts = message.getPayload().getParts();
String data = parts.get(0).getBody().getData();
String body = new String(BaseEncoding.base64Url().decode(data));