Gmail API - Parse message content (Base64 decoding?) with Javascript

19,819

Solution 1

Depending on what your emails look like (single text/plain part? multipart with text/html? attachments, etc?) you may or may not have any "parts" in your email.payload and instead you'll have what you're looking for in "email.payload.body.data" (for single-part messages). This is all assuming you're doing a message.get with the default format ("full"). If you instead want to get the entire email in the message.raw field and deal with it in email libraries for your language you can call message.get(format=raw).

For more info check out the "body" and "parts[]" field documentation for "Message" at https://developers.google.com/gmail/api/v1/reference/users/messages

Solution 2

Regarding the Base64 decoding, you can use

atob(dataToDecode)

For Gmail, you'll also want to replace some characters:

atob( dataToDecode.replace(/-/g, '+').replace(/_/g, '/') ); 

The above function is available to you in JavaScript (see ref). I use it myself to decode the Gmail messages. No need to install extra stuff. As an interesting tangent, if you want to encode your message to Base64, use btoa.

Now, for accessing your message payload, you can write a function:

var extractField = function(json, fieldName) {
  return json.payload.headers.filter(function(header) {
    return header.name === fieldName;
  })[0].value;
};
var date = extractField(response, "Date");
var subject = extractField(response, "Subject");

referenced from my previous SO Question and

var part = message.parts.filter(function(part) {
  return part.mimeType == 'text/html';
});
var html = atob(part.body.data.replace(/-/g, '+').replace(/_/g, '/'));

Solution 3

Ah! I figured it out. parts is an array, so I should have been calling it like: gapi.client.gmail.users.messages.get({'id': <message ID>}).payload.parts[0].body.data

Now my problem is decoding the emails, which is proving successful in plain text emails, but failing in emails from non-personal locations (businesses, social media update emails, etc.). But I'll make a new question to get answers for that.

Share:
19,819
artis3n
Author by

artis3n

Updated on June 12, 2022

Comments

  • artis3n
    artis3n about 2 years

    I'm trying to use the Gmail API to get a user's email, grab the message subject and body, and then display it on a webpage. I'll be doing other stuff with it, but this is the part that I am having difficulty with. I am using Angular.js.

    Here is my API call:

    function makeApiCall() {
      gapi.client.load('gmail', 'v1', function() {
        var request = gapi.client.gmail.users.messages.list({
          labelIds: ['INBOX']
        });
        request.execute(function(resp) {
          var content = document.getElementById("message-list");
          angular.forEach(resp, function(message) {
            var email = gapi.client.gmail.users.messages.get({'id': message.id});
            // var raw = email.payload.parts;
            // console.log(raw);
            content.innerHTML += JSON.stringify(email) + "<br>";
          })
        });
      });
    }
    

    So gapi.client.gmail.users.messages.list returns an array of my messages, with their ID numbers. That is working.

    The call to gapi.client.gmail.users.messages.get({<specific message ID>}) outputs this - {"B":{"method":"gmail.users.messages.get","rpcParams":{},"transport":{"name":"googleapis"}}}.

    Not sure what that is, but trying to get the message payload (email.payload.parts), results in undefined. So, how can I get the message content?

    Also, I would assume that if I can get the message contents, I would then have to Base64 decode the contents to get some English out of it. Any suggestions for that would be of great help also. I've found this: https://github.com/kvz/phpjs, but since I'm not sure how to go about getting the message contents so that I can try and decode them, so not sure if that php.js is of an help in that regard.

  • artis3n
    artis3n almost 10 years
    When trying to log gapi.client.gmail.users.messages.get({<message id>}).payload.body.data, it outputs Uncaught TypeError: Cannot read property 'body' of undefined. However when testing out the .get method call on the Gmail API documentation (I knew about that link you posted) at the Try it! section of the messages.get part, I can see content in the payload field of my message object, so it shouldn't be undefined. Although for parts[], it says For...text/plain, this field is empty. A basic email message would contain plain text, correct? So maybe that's not where I'm supposed to go..
  • LeonH
    LeonH almost 10 years
    You should use a library for encoding and decoding
  • FullStack
    FullStack almost 9 years
    See my answer above for encoding/decoding
  • Zach Bloomquist
    Zach Bloomquist almost 6 years
    Oh my gOoOd thank you for that GMail tip. I was trying to figure out why my decoding was coming out garbled on raw messages.
  • WtFudgE
    WtFudgE about 4 years
    ooooh my, your gmail replace tip just saved me