API на Gmail – Анализирайте съдържанието на съобщението (декодиране на 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 (знаех за тази връзка, която публикувахте) на Опитайте! раздел на частта 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 въпрос и

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

Трябва да потърсите къде е тялото за даден тип mime, аз съм написал рекурсивна функция за това:

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