Gmail API decoding messages in Javascript
For a prototype app I'm writing, the following code is working for me:
var base64 = require('js-base64').Base64;
// js-base64 is working fine for me.
var bodyData = message.payload.body.data;
// Simplified code: you'd need to check for multipart.
base64.decode(bodyData.replace(/-/g, '+').replace(/_/g, '/'));
// If you're going to use a different library other than js-base64,
// you may need to replace some characters before passing it to the decoder.
Caution: these points are not explicitly documented and could be wrong:
The
users.messages: get
API returns "parsed body content" by default. This data seems to be always encoded in UTF-8 and Base64, regardless of theContent-Type
andContent-Transfer-Encoding
header.For example, my code had no problem parsing an email with these headers:
Content-Type: text/plain; charset=ISO-2022-JP
,Content-Transfer-Encoding: 7bit
.The mapping table of the Base64 encoding varies among various implementations. Gmail API uses
-
and_
as the last two characters of the table, as defined by RFC 4648's "URL and Filename safe Alphabet"1.Check if your Base64 library is using a different mapping table. If so, replace those characters with the ones your library accepts before passing the body to the decoder.
1 There is one supportive line in the documentation: the "raw" format returns "body content as a base64url encoded string". (Thanks Eric!)
Use atob to decode the messages in JavaScript (see ref). 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);
If the above does not decode 100% properly, the comments by @cgenco on this answer below may apply to you. In that case, do
var html = atob(part.body.data.replace(/-/g, '+').replace(/_/g, '/'));