我已經閱讀了http://www.jwz.org/doc/threading.html等一些很棒的在線資源,並且似乎任何電子郵件都使用Message-ID
標頭髮送,那麼對它的任何回覆包括命名該ID的In-Reply-To
和可以命名父消息ID的列表的In-Reply-To
,並且當在線程視圖中查看電子郵件列表時,電子郵件客戶端使用該信息來構建線程。如何使發送的電子郵件在GMail收件人的視圖中顯示爲與Message-ID,In-Reply-To和引用
我的問題是:是否可以將一系列電子郵件發送給帶有僞造標題的收件人,以使它們顯示在線索中,而收件人不回覆它們?如果是這樣,爲什麼我的下面的嘗試不工作?
我們有一個系統發送與我們系統中特定實體有關的幾封電子郵件。假設我們多次銷售小工具和電子郵件用戶關於每個小工具。我們希望針對特定窗口小部件ID的所有電子郵件在我們用戶的電子郵件客戶端中顯示爲電子郵件線索。
這裏的旅行似乎是通常發送電子郵件,然後回覆。我們的系統只是想發送幾封電子郵件,並僞造In-Reply-To和References頭,以欺騙電子郵件客戶端在樹中顯示它們。
我使用的消息ID的格式是: 'foobar的' +爲widgetid +序列
- 爲widgetid =唯一的號碼每個插件例如1234
- 序列=每我們發送電子郵件時遞增的序列號
第一電子郵件:
- 郵件ID
<[email protected]>
- 在-回覆:不設置
- 參考:未提供
第二封電子郵件:
- 郵件ID
<[email protected]>
- 在-回覆:
<[email protected]>
- 參考文獻:
<[email protected]>
第三電子郵件:
- 郵件ID
<[email protected]>
- 在 - 回覆:
<[email protected]>
個 - 參考文獻:
<[email protected]> <[email protected]>
(順便說一下,包括消息ID的@server.com
部分似乎是至關重要的。沒有這個,使用例如foobar-123-0
,我們的SMTP服務器只是忽略了它,並用它自己的自動生成的消息ID)
電子郵件正確地顯示在Thunderbird中的一棵樹,而不是在Gmail中,他們只是前一後在收件箱中列出的一個,而其他的談話是正確地穿過他們旁邊。我不知道我是否搞錯了,Thunderbird的數據不好,或者Gmail需要一些額外的非標準糖,我不提供。
這裏是我的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
});
需要像conf文件:
{
"ourEmail": "[email protected]",
"smtp": {
"service": "Gmail",
"user": "[email protected]",
"pass": "ilikecheese"
}
}
獎勵積分,請提示,爲何我嘗試使用Q.all
似乎沒有不盡管所有電子郵件都正確發送,但火和腳本仍未完全退出:)
謝謝。本週我們已經注意到了這種行爲,當時我們將來自測試平臺的所有外發電子郵件發送到一個電子郵件帳戶。其中有幾個是同樣的行爲,「X做Y」,但通常會去許多不同的個人賬戶。在同一個Gmail收件箱中查看時,它們全部都是線程化的。因此,我想所有的主題都必須足夠相似,即「Re:」和「Fwd:」,其他的主題將被忽略,但基本上主題字符串匹配用於gmail?然後:)我們的計劃,然後:) – Neek
在其他問題鏈接的接受的答案確實表明「在回覆」標題也被考慮,我可以通過查看我今天看到的一些郵件列表線程來確認。一個人通過在他的回覆中忽略了「in-reply-to」標題多次拆分該線程。所有的消息都有相同的主題,但沒有正確的線程,直到他修復了他的客戶端,因此它包含了「回覆內容」標題。 – TwoD