Gmail API - анализ содержимого сообщения (декодирование Base64?) с помощью Javascript

Я пытаюсь использовать API Gmail, чтобы получить электронную почту пользователя, захватить тему и тело сообщения, а затем отобразить его на веб-странице. Я буду делать с ним другие вещи, но это та часть, с которой у меня возникают трудности. Я использую Angular.js.

Вот мой вызов API:

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>";
      })
    });
  });
}

Итак, gapi.client.gmail.users.messages.list возвращает массив моих сообщений с их идентификационными номерами. Это работает.

Вызов gapi.client.gmail.users.messages.get({<specific message ID>}) выводит это - {"B":{"method":"gmail.users.messages.get","rpcParams":{},"transport":{"name":"googleapis"}}}.

Не уверен, что это такое, но попытка получить полезную нагрузку сообщения (email.payload.parts) приводит к undefined. Итак, как я могу получить содержимое сообщения?

Кроме того, я бы предположил, что если я смогу получить содержимое сообщения, мне придется декодировать его в Base64, чтобы получить из него немного английского. Любые предложения по этому поводу также будут очень полезны. Я нашел это: https://github.com/kvz/phpjs, но так как я не уверен, как идти о получении содержимого сообщения, чтобы я мог попытаться его расшифровать, поэтому не уверен, что php.js поможет в этом отношении.


person artis3n    schedule 14.07.2014    source источник
comment
Для тех, кто ищет пакет npm, попробуйте этот npmjs.com/package/ gmail-api-parse-message   -  person Salitha    schedule 15.07.2021


Ответы (4)


В зависимости от того, как выглядят ваши электронные письма (одна текстовая/простая часть? составная часть с текстом/html? вложения и т. д.?), вы можете иметь или не иметь какие-либо «части» в вашем email.payload, и вместо этого у вас будет то, что вы ищем в "email.payload.body.data" (для односоставных сообщений). Все это предполагает, что вы делаете message.get с форматом по умолчанию ("полный"). Если вместо этого вы хотите получить всю электронную почту в поле message.raw и обработать ее в почтовых библиотеках для вашего языка, вы можете вызвать message.get(format=raw).

Для получения дополнительной информации ознакомьтесь с документацией по полям «body» и «parts[]» для «Message» по адресу https://developers.google.com/gmail/api/v1/reference/users/messages

person Eric D    schedule 14.07.2014
comment
При попытке записать gapi.client.gmail.users.messages.get({<message id>}).payload.body.data выводится Uncaught TypeError: Cannot read property 'body' of undefined. Однако при тестировании вызова метода .get в документации по API Gmail (я знал об этой ссылке, которую вы разместили) на странице Try it! раздел части messages.get, я вижу содержимое в поле полезной нагрузки моего объекта сообщения, поэтому оно не должно быть неопределенным. Хотя для частей[] там написано For...text/plain, this field is empty. Обычное сообщение электронной почты будет содержать обычный текст, верно? Так что, может быть, это не то, куда я должен идти.. - person artis3n; 15.07.2014

Что касается декодирования Base64, вы можете использовать

atob(dataToDecode)

Для Gmail вы также захотите заменить некоторые символы:

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

Вышеупомянутая функция доступна для вас в JavaScript (см. ref). Я сам использую его для декодирования сообщений Gmail. Нет необходимости устанавливать дополнительные вещи. Интересно, что если вы хотите закодировать свое сообщение в Base64, используйте btoa.

Теперь для доступа к полезной нагрузке вашего сообщения вы можете написать функцию:

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");

ссылается на мой предыдущий SO Question и

var part = message.parts.filter(function(part) {
  return part.mimeType == 'text/html';
});
var html = atob(part.body.data.replace(/-/g, '+').replace(/_/g, '/'));
person FullStack    schedule 20.02.2015
comment
О, мой gOoOd, спасибо за этот совет по GMail. Я пытался понять, почему моя расшифровка raw сообщений выходила искаженной. - person Zach Bloomquist; 18.07.2018
comment
оооо, ваш совет по замене Gmail просто спас меня - person WtFudgE; 15.04.2020

Ах! Я понял. parts — это массив, поэтому я должен был называть его так: gapi.client.gmail.users.messages.get({'id': <message ID>}).payload.parts[0].body.data

Теперь моя проблема заключается в декодировании электронных писем, которое оказывается успешным в электронных письмах с обычным текстом, но не работает в электронных письмах из не личных мест (компаний, электронных писем с обновлениями в социальных сетях и т. д.). Но я задам новый вопрос, чтобы получить на него ответы.

person artis3n    schedule 15.07.2014
comment
Вы должны использовать библиотеку для кодирования и декодирования. - person LeonH; 08.08.2014
comment
Смотрите мой ответ выше для кодирования/декодирования - person FullStack; 01.07.2015

Вам нужно искать, где находится тело для данного типа пантомимы, я написал для этого рекурсивную функцию:

function searchBodyRec(payload, mimeType){
    if (payload.body && payload.body.size && payload.mimeType === mimeType) {
        return payload.body.data;
    } else if (payload.parts && payload.parts.length) {
        return payload.parts.flatMap(function(part){
            return searchBodyRec(part, mimeType);
        }).filter(function(body){
            return body;
        });
    }
}

Итак, теперь вы можете позвонить

var encodedBody = searchBodyRec(this.message.payload, 'text/plain');

Видите там метод flatMap? Классический метод FP отсутствует в js, вот как его добавить (или вы можете использовать lodash.js или underscore.js, если не хотите возиться с нативными объектами)

Array.prototype.flatMap = function(lambda) { 
    return Array.prototype.concat.apply([], this.map(lambda)); 
};
person standup75    schedule 19.11.2015