2014-04-11 28 views
7

Ho letto alcune grandi risorse online come http://www.jwz.org/doc/threading.html e sembra che ogni e-mail sia inviata con un'intestazione Message-ID quindi qualsiasi risposta ad esso include In-Reply-To nominando quell'ID e Refences che può nominare un elenco di id di messaggio principale, e i client di posta elettronica usano queste informazioni per costruire discussioni durante la visualizzazione di un elenco di e-mail nella vista filettata.Come far sì che le e-mail inviate vengano visualizzate nella vista del destinatario di GMail con ID messaggio, In-Reply-To e Riferimenti

La mia domanda è: è possibile inviare una serie di e-mail a un destinatario con intestazioni contraffatte, per farle apparire in un thread senza che il destinatario risponda ad esse? In tal caso, perché il mio tentativo di seguito non funziona?

Abbiamo un sistema che invia diverse e-mail relative a un'entità specifica nel nostro sistema. Diciamo che vendiamo widget e utenti di posta elettronica diverse volte su ciascun widget. Desideriamo che tutte le e-mail per un ID widget specifico vengano visualizzate come thread di posta elettronica nei client di posta elettronica dei nostri utenti.

Il viaggio qui sembra essere che normalmente vengono inviate e-mail, quindi risposto a. Il nostro sistema vuole semplicemente inviare diverse e-mail e falsificare le intestazioni In-Reply-To e References per ingannare i client di posta elettronica per visualizzarli in un albero.

Il formato Message-ID che sto utilizzando è: 'foobar' + widgetId + sequenza

  • widgetId = un numero unico per ciascun widget per esempio 1234
  • sequenza = un numero sequenziale incrementato ogni volta che inviamo una mail

prima e-mail:

Seconda email:

Terzo e-mail:

(per inciso, compresa la quota @server.com di un ID messaggio sembra essere di vitale importanza. Senza quello, usando per es. foobar-123-0, il nostro server SMTP semplicemente ignorato e usò proprio ID messaggio generata automaticamente)

Messaggi di posta elettronica vengono visualizzati correttamente in Thunderbird, come un albero, ma non in Gmail, che appena arrivato elencati uno dopo l'altro nella Posta in arrivo, mentre altre conversazioni sono correttamente filettato proprio accanto a loro.Non sono sicuro se mi sto sbagliando e Thunderbird sta facendo il meglio che può con dati sbagliati, o se Gmail ha bisogno di uno zucchero extra non standard che non sto fornendo.

Ecco il mio script di test node.js:

/*jshint dojo:true */ 
/*global console:true */ 
'use strict'; 
var Q = require('q'), 
    nconf = require('nconf'), 
    optimist = require('optimist'), 
    nodemailer = require('nodemailer'); 

console.log('Started to run.'); 
var argv = optimist.argv, 
    config = nconf.argv().env().file('conf.json'), 
    smtpConfig = config.get('smtp'), 
     smtpTransport = nodemailer.createTransport('SMTP', { 
      service: smtpConfig.service, // 'Gmail', 
      auth: { 
       user: smtpConfig.user, //'[email protected]', 
       pass: smtpConfig.pass //'xyz' 
      } 
     }), 
    rand = Math.floor(Math.random() * 5000), // a random enough unique id 
    messageIdPrefix = 'foobar-' + rand + '-'; 

var promises = [], 
    references = ''; 

for (var i = 0 ; i < 3 ; i ++) { 
    // Prepare email content 
    var subject = 'This is test email ' + i, 
     htmlMessage = '<h1>Am I threaded? Email ' + i + '</h1><p>???</p>', 
     textMessage = 'Am I threaded? Email ' + i + '\n\n???'; 

    var recipients = '[email protected]'; 

    // Each email in this sequence has a common prefix 
    // In Reply To should be the single immediate parent message id 
    // References should list all parents, top most first 
    var messageId = messageIdPrefix + i + '@server.com', 
     inReplyTo = (i > 0) ? ('<' + (messageIdPrefix + (i-1)) + '@server.com>') : false; 

    // setup e-mail data with unicode symbols 
    var mailOptions = { 
     from: config.get('ourEmail'), 
     to: recipients, 
     subject: subject, 
     text: textMessage, 
     html: htmlMessage, 
     messageId: messageId, 
     inReplyTo: inReplyTo, 
     references: references, 
     headers: { 
      // 'in-Reply-To': inReplyTo 
     } 
    }; 

    // send mail with defined transport object 
    var q = Q.defer(); 
    promises.push(q.promise); 
    smtpTransport.sendMail(mailOptions, function (error, response) { 
     if (error) { 
      console.error(error); 
      q.reject('error'); 
     } else { 
      console.log('Message sent: ' + response.message); 
      q.resolve('yay!'); 
     } 
    }); 

    // next time round loop, if any, includes this id in the references list 
    references = (references ? (references + ' ') : '') + messageId; 
} 

Q.all(promises).then(function (results) { 
    console.log('All done, closing mail connection: ', results); 
    smtpTransport.close(); // shut down the connection pool, no more messages 
}); 

Richiede un file di configurazione come:

{ 
    "ourEmail": "[email protected]", 
    "smtp": { 
     "service": "Gmail", 
     "user": "[email protected]", 
     "pass": "ilikecheese" 
    } 
} 

per i punti bonus, si prega di suggerire perché il mio tentativo di utilizzare Q.all non sembra il fuoco e la sceneggiatura non esce in modo pulito, nonostante l'invio corretto di tutte le e-mail :)

risposta

5

La risposta al motivo per cui non sono thread in Gmail è perché il threading di Gmail è don e in base all'oggetto dei messaggi (non è basato sul campo "in-reply-to" o "references" nell'intestazione).

Vedi le risposte a questa domanda su StackExchange per maggiori dettagli su come Gmail non filettatura: https://webapps.stackexchange.com/questions/965/how-does-gmail-decide-to-thread-email-messages ..

I soggetti nel tuo caso sono "Questo è il test di e-mail 1", "Questa è la prova di e-mail 2" e "Questa è l'e-mail di prova 3" che non causerà il threading in base alle regole utilizzate da Gmail.

+0

Grazie. Abbiamo notato esattamente questo comportamento questa settimana, quando abbiamo convogliato tutte le email in uscita dalla nostra piattaforma di test a un unico account di posta elettronica. Molti di loro erano la stessa azione "X ha fatto Y", ma normalmente sarebbero andati a conti di molte persone diverse. Se visualizzati nella stessa casella di posta in arrivo di Gmail, erano tutti collegati. Quindi immagino che tutti i soggetti debbano essere sufficientemente simili, vale a dire "Re:" e "Fwd:" e altri cruft verrebbero ignorati, ma essenzialmente la corrispondenza della stringa Subject viene utilizzata in gmail? Ciò conferma il nostro piano, quindi :) – Neek

+2

La risposta accettata nell'altra domanda collegata indica anche l'intestazione "in-reply-to", che posso confermare osservando alcuni thread di mailing list che ho visto oggi. Una persona ha diviso il thread più volte omettendo l'intestazione "in-reply-to" nelle sue risposte. Tutti i messaggi hanno lo stesso oggetto ma non sono stati inseriti correttamente fino a quando non ha risolto il suo client in modo che includesse l'intestazione "in-reply-to". – TwoD