2014-07-17 24 views
8

Sto riscontrando seri problemi nel decodificare il corpo del messaggio delle e-mail che utilizzo utilizzando l'API di Gmail. Voglio prendere il contenuto del messaggio e inserire il contenuto in un div. Sto usando un decodificatore base64, che so non decodificherà le e-mail codificate in modo diverso, ma non sono sicuro di come controllare una e-mail per decidere quale decodificatore usare - le e-mail che dicono che sono codificate utf-8 sono decodificate con successo dal decodificatore base64, ma non essere un decodificatore utf-8.Messaggi di decodifica dell'API Gmail in Javascript

Ho studiato la decodifica della posta elettronica per diversi giorni e ho imparato che sono un po 'fuori dal mio campionato qui. Non ho fatto molto lavoro con la codifica della posta elettronica prima. Ecco il codice che sto usando per ottenere i messaggi di posta elettronica:

gapi.client.load('gmail', 'v1', function() { 
var request = gapi.client.gmail.users.messages.list({ 
    labelIds: ['INBOX'] 
}); 
request.execute(function(resp) { 
    document.getElementById('email-announcement').innerHTML = '<i>Hello! I am reading your <b>inbox</b> emails.</i><br><br>------<br>'; 
    var content = document.getElementById("message-list"); 
    if (resp.messages == null) { 
    content.innerHTML = "<b>Your inbox is empty.</b>"; 
    } else { 
    var encodings = 0; 
    content.innerHTML = ""; 
    angular.forEach(resp.messages, function(message) { 
     var email = gapi.client.gmail.users.messages.get({ 
     'id': message.id 
     }); 
     email.execute(function(stuff) { 
     if (stuff.payload == null) { 
      console.log("Payload null: " + message.id); 
     } 
     var header = ""; 
     var sender = ""; 
     angular.forEach(stuff.payload.headers, function(item) { 
      if (item.name == "Subject") { 
      header = item.value; 
      } 
      if (item.name == "From") { 
      sender = item.value; 
      } 
     }) 
     try { 
      var contents = ""; 
      if (stuff.payload.parts == null) { 
      contents = base64.decode(stuff.payload.body.data); 
      } else { 
      contents = base64.decode(stuff.payload.parts[0].body.data); 
      } 
      content.innerHTML += '<b>Subject: ' + header + '</b><br>'; 
      content.innerHTML += '<b>From: ' + sender + '</b><br>'; 
      content.innerHTML += contents + "<br><br>"; 
     } catch (err) { 
      console.log("Encoding error: " + encodings++); 
     } 
     }) 
    }) 
    } 
}); 
}); 

stavo eseguendo alcuni controlli e il debug, quindi non c'è avanzi console.log 's e alcune altre cose che sono lì solo per il test. Tuttavia, puoi vedere qui quello che sto cercando di fare.

Qual è il modo migliore per decodificare le email che prelevo dall'API di Gmail? Dovrei provare a mettere le e-mail in <script> con gli attributi charset e type corrispondenti al contenuto della codifica dell'email? Credo di ricordare che charset funziona solo con un attributo src, che non avrei qui. Eventuali suggerimenti?

risposta

14

per un'applicazione prototipo che sto scrivendo, il seguente codice sta lavorando per 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. 

Attenzione: questi punti non sono esplicitamente documentate e potrebbe essere sbagliato:

  1. Il users.messages: get API restituisce "contenuto del corpo analizzato" per impostazione predefinita. Questi dati sembrano essere sempre codificati in UTF-8 e Base64, indipendentemente dall'intestazione Content-Type e Content-Transfer-Encoding.

    Ad esempio, il mio codice non ha riscontrato problemi durante l'analisi di un'e-mail con queste intestazioni: Content-Type: text/plain; charset=ISO-2022-JP, Content-Transfer-Encoding: 7bit.

  2. La tabella di mapping della codifica Base64 varies among various implementations. L'API di Gmail utilizza - e _ come gli ultimi due caratteri della tabella, come definito dall''URL e l'alfabeto sicuro "Nome file RFC 4648 .

    Verificare se la libreria Base64 utilizza una tabella di mapping diversa. In tal caso, sostituire quei caratteri con quelli accettati dalla libreria prima di passare il corpo al decodificatore.


C'è una linea di supporto nella documentazione: the "raw" format restituisce "il contenuto del corpo come una stringa codificata base64url". (Grazie Eric!)

+0

nel complesso molto buono e utile, grazie! nota che per quanto riguarda il punto n. 2 è menzionato nei documenti API users.messages.get: https://developers.google.com/gmail/api/v1/reference/users/messages/get (vedi il formato = documenti RAW) . Ma forse dovrebbe essere ulteriormente ampliato ... –

+0

Ho controllato tante opzioni prima di trovare la soluzione di lavoro, grazie! – walla

+0

Funziona anche con la libreria python base64. Grazie!! – maamaa

3

Utilizzare atob per decodificare i messaggi in JavaScript (vedere ref).Per accedere al proprio messaggio payload, è possibile scrivere una funzione:

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

riferimento dal mio precedente SO Question e

var part = message.parts.filter(function(part) { 
    return part.mimeType == 'text/html'; 
}); 
var html = atob(part.body.data); 

Se quanto sopra non decodificare correttamente al 100%, i commenti di @cgenco su questa risposta di seguito potrebbe applicarsi a voi. In tal caso, fare

var html = atob(part.body.data.replace(/-/g, '+').replace(/_/g, '/')); 
+0

Sembra che il comando .replace (/ -/g, '+'). Replace (/ _/g, '/') 'debba ancora essere fatto per poter decodificare correttamente. – cgenco

+0

@cgenco, grazie per la condivisione. Puoi spiegare perché non è sufficiente senza le funzioni 'replace'? Sarò felice di rivedere la mia risposta. – FullStack

+0

per la risposta di @ ento, codifica Base64 [varia attraverso le implementazioni] (https://en.wikipedia.org/wiki/Base64#Implementations_and_history), e Google capita di usare la codifica che usa '-' invece di' + 'e' _' invece di '/'. – cgenco

1

ecco la soluzione: Gmail API - "Users.messages: get" metodo è in risposta message.payload.body.data parted dati base64, è separato da simbolo "-" . Non è tutto il testo codificato in base64, è parte del testo base64. Devi provare a decodificare ogni singola parte di questo o fare una stringa mono da unire e sostituire il simbolo "-". Dopo questo puoi facilmente decodificarlo in testo umano. È possibile controllare manualmente ogni parte qui https://www.base64decode.org