Gmail 发送电子邮件作为回复
Gmail Send Email As Reply
通过 gmail 发送电子邮件非常简单,如下所示:
Sending email in .NET through Gmail
但我似乎找不到发送电子邮件作为对另一封电子邮件的回复的方法。自动包括以前的消息。
乐趣代码:与发送电子邮件无关(阅读此处,使用 AE.Net.Mail imap 客户端库)
public GmailConnector()
{
StringBuilder sb1 = new StringBuilder();
using (var context = new SupportDataContext())
using (var client = new ImapClient("imap.gmail.com", "xxxx@gmail.com", "xxx", AuthMethods.Login, 993, true))
{
client.SelectMailbox("INBOX");
Console.WriteLine(client.GetMessageCount());
var mm = client.SearchMessages(SearchCondition.Seen(), false, true);
foreach (var m in mm)
{
if (m.Value == null)
continue;
var msg = m.Value;
var emailRef = msg.To.First().Address;
SupportThread supportThread = null;
if (emailRef.Contains("+"))
{
var supportThreadRef = emailRef.Substring(emailRef.IndexOf('+') + 1, emailRef.IndexOf('@') - emailRef.IndexOf('+') - 1);
var supportThreadId = long.Parse(supportThreadRef);
supportThread = context.SupportThreads.First(x => x.Id == supportThreadId);
}
else if (msg.Subject.Contains("RE:"))
{
var subjectRef = msg.Subject.Replace("RE:", "").Trim();
var tmpDate = msg.Date.AddDays(-7);
var tmpSupportThread = context.SupportThreads.FirstOrDefault(x => x.EntryDate < msg.Date && x.EntryDate > tmpDate && x.Title.Equals(subjectRef));
if (tmpSupportThread != null)
supportThread = tmpSupportThread;
}
if (supportThread == null)
{
supportThread = new SupportThread();
supportThread.Title = msg.Subject;
supportThread.Creator = msg.From.Address;
supportThread.CreatorName = msg.From.DisplayName;
supportThread.EntryDate = msg.Date;
}
var responseMessage = msg.AlternateViews.GetHtmlView().Body;
responseMessage.Substring(0, responseMessage.IndexOf(REPLY_SEPERATOR));
var tmpEmailMessage = new EmailMessage();
tmpEmailMessage.EntryDate = msg.Date;
tmpEmailMessage.InnerContent = responseMessage;
tmpEmailMessage.SenderEmail = msg.From.Address;
tmpEmailMessage.SenderDisplayName = msg.From.DisplayName;
tmpEmailMessage.Title = msg.Subject;
tmpEmailMessage.SupportThread = supportThread;
foreach (var attachment in m.Value.Attachments)
{
var tmpAttachment = new Attachment();
tmpAttachment.Data = attachment.GetData();
tmpAttachment.Name = attachment.Filename;
tmpAttachment.EmailMessage = tmpEmailMessage;
context.Attachments.InsertOnSubmit(tmpAttachment);
}
context.EmailMessages.InsertOnSubmit(tmpEmailMessage);
context.SubmitChanges();
}
}
var fromAddress = new MailAddress("from@gmail.com", "From Name");
var toAddress = new MailAddress("to@example.com", "To Name");
const string fromPassword = "fromPassword";
const string subject = "Subject";
const string body = "Body";
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
};
using (var message = new System.Net.Mail.MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
})
{
smtp.Send(message);
}
Console.Read();
}
只需接收收到的电子邮件,读出发件人、主题、文本等数据,并在创建回复时使用它们。回复的目的地应该是发件人的邮箱地址,subject = "RE:"+subject+incoming,至于正文你可以用任何你想要的方法。我不认为有任何用于回复电子邮件的内置功能。你必须手动做这些事情。
首先你得想办法把邮件客户端邮箱里的内容弄出来,比如outlook或者手动从SMTP服务器下载最近的X封邮件。
- 检索原始电子邮件(通过 OLE 从 Outlook-> COM 对象 -> outlook ole 对象就像您安装的 outlook 邮件客户端的用户代理)。Google 如何做到这一点。或从 SMTP 下载最新邮件。
- 获得邮件内容后,创建一封包含传入邮件内容的电子邮件。然后发送。如果您使用 Microsoft OLE,那么您也可以通过 outlook ole 对象发送电子邮件。
回复消息非常简单。大多数情况下,您只需像创建任何其他消息一样创建回复消息。只有一些细微的差别:
- 在回复邮件中,如果您要回复的邮件中不存在前缀,则您需要在
Subject
header 前加上 "Re: "
前缀(在换句话说,如果您回复的消息的 Subject
为 "Re: party tomorrow night!"
,您会 而不是 加上另一个 "Re: "
).
- 您需要将回复邮件的
In-Reply-To
header 设置为原始邮件中 Message-Id
header 的值。
- 您需要将原始消息的
References
header 复制到回复消息的 References
header 中,然后附加原始消息的 Message-Id
header.
- 您可能希望在回复中 "quote" 原始消息的文本。
如果用代码来表达这个逻辑,它可能看起来像这样(我在这个例子中使用 MailKit):
public static MimeMessage Reply (MimeMessage message, bool replyToAll)
{
var reply = new MimeMessage ();
// reply to the sender of the message
if (message.ReplyTo.Count > 0) {
reply.To.AddRange (message.ReplyTo);
} else if (message.From.Count > 0) {
reply.To.AddRange (message.From);
} else if (message.Sender != null) {
reply.To.Add (message.Sender);
}
if (replyToAll) {
// include all of the other original recipients - TODO: remove ourselves from these lists
reply.To.AddRange (message.To);
reply.Cc.AddRange (message.Cc);
}
// set the reply subject
if (!message.Subject.StartsWith ("Re:", StringComparison.OrdinalIgnoreCase))
reply.Subject = "Re: " + message.Subject;
else
reply.Subject = message.Subject;
// construct the In-Reply-To and References headers
if (!string.IsNullOrEmpty (message.MessageId)) {
reply.InReplyTo = message.MessageId;
foreach (var id in message.References)
reply.References.Add (id);
reply.References.Add (message.MessageId);
}
// quote the original message text
using (var quoted = new StringWriter ()) {
var sender = message.Sender ?? message.From.Mailboxes.FirstOrDefault ();
quoted.WriteLine ("On {0}, {1} wrote:", message.Date.ToString ("f"), !string.IsNullOrEmpty (sender.Name) ? sender.Name : sender.Address);
using (var reader = new StringReader (message.TextBody)) {
string line;
while ((line = reader.ReadLine ()) != null) {
quoted.Write ("> ");
quoted.WriteLine (line);
}
}
reply.Body = new TextPart ("plain") {
Text = quoted.ToString ()
};
}
return reply;
}
注意:此代码假定 message.TextBody
不为空。有可能,尽管不太可能发生这种情况(这意味着消息不包含 text/plain
body)。
通过 gmail 发送电子邮件非常简单,如下所示:
Sending email in .NET through Gmail
但我似乎找不到发送电子邮件作为对另一封电子邮件的回复的方法。自动包括以前的消息。
乐趣代码:与发送电子邮件无关(阅读此处,使用 AE.Net.Mail imap 客户端库)
public GmailConnector()
{
StringBuilder sb1 = new StringBuilder();
using (var context = new SupportDataContext())
using (var client = new ImapClient("imap.gmail.com", "xxxx@gmail.com", "xxx", AuthMethods.Login, 993, true))
{
client.SelectMailbox("INBOX");
Console.WriteLine(client.GetMessageCount());
var mm = client.SearchMessages(SearchCondition.Seen(), false, true);
foreach (var m in mm)
{
if (m.Value == null)
continue;
var msg = m.Value;
var emailRef = msg.To.First().Address;
SupportThread supportThread = null;
if (emailRef.Contains("+"))
{
var supportThreadRef = emailRef.Substring(emailRef.IndexOf('+') + 1, emailRef.IndexOf('@') - emailRef.IndexOf('+') - 1);
var supportThreadId = long.Parse(supportThreadRef);
supportThread = context.SupportThreads.First(x => x.Id == supportThreadId);
}
else if (msg.Subject.Contains("RE:"))
{
var subjectRef = msg.Subject.Replace("RE:", "").Trim();
var tmpDate = msg.Date.AddDays(-7);
var tmpSupportThread = context.SupportThreads.FirstOrDefault(x => x.EntryDate < msg.Date && x.EntryDate > tmpDate && x.Title.Equals(subjectRef));
if (tmpSupportThread != null)
supportThread = tmpSupportThread;
}
if (supportThread == null)
{
supportThread = new SupportThread();
supportThread.Title = msg.Subject;
supportThread.Creator = msg.From.Address;
supportThread.CreatorName = msg.From.DisplayName;
supportThread.EntryDate = msg.Date;
}
var responseMessage = msg.AlternateViews.GetHtmlView().Body;
responseMessage.Substring(0, responseMessage.IndexOf(REPLY_SEPERATOR));
var tmpEmailMessage = new EmailMessage();
tmpEmailMessage.EntryDate = msg.Date;
tmpEmailMessage.InnerContent = responseMessage;
tmpEmailMessage.SenderEmail = msg.From.Address;
tmpEmailMessage.SenderDisplayName = msg.From.DisplayName;
tmpEmailMessage.Title = msg.Subject;
tmpEmailMessage.SupportThread = supportThread;
foreach (var attachment in m.Value.Attachments)
{
var tmpAttachment = new Attachment();
tmpAttachment.Data = attachment.GetData();
tmpAttachment.Name = attachment.Filename;
tmpAttachment.EmailMessage = tmpEmailMessage;
context.Attachments.InsertOnSubmit(tmpAttachment);
}
context.EmailMessages.InsertOnSubmit(tmpEmailMessage);
context.SubmitChanges();
}
}
var fromAddress = new MailAddress("from@gmail.com", "From Name");
var toAddress = new MailAddress("to@example.com", "To Name");
const string fromPassword = "fromPassword";
const string subject = "Subject";
const string body = "Body";
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
};
using (var message = new System.Net.Mail.MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
})
{
smtp.Send(message);
}
Console.Read();
}
只需接收收到的电子邮件,读出发件人、主题、文本等数据,并在创建回复时使用它们。回复的目的地应该是发件人的邮箱地址,subject = "RE:"+subject+incoming,至于正文你可以用任何你想要的方法。我不认为有任何用于回复电子邮件的内置功能。你必须手动做这些事情。 首先你得想办法把邮件客户端邮箱里的内容弄出来,比如outlook或者手动从SMTP服务器下载最近的X封邮件。
- 检索原始电子邮件(通过 OLE 从 Outlook-> COM 对象 -> outlook ole 对象就像您安装的 outlook 邮件客户端的用户代理)。Google 如何做到这一点。或从 SMTP 下载最新邮件。
- 获得邮件内容后,创建一封包含传入邮件内容的电子邮件。然后发送。如果您使用 Microsoft OLE,那么您也可以通过 outlook ole 对象发送电子邮件。
回复消息非常简单。大多数情况下,您只需像创建任何其他消息一样创建回复消息。只有一些细微的差别:
- 在回复邮件中,如果您要回复的邮件中不存在前缀,则您需要在
Subject
header 前加上"Re: "
前缀(在换句话说,如果您回复的消息的Subject
为"Re: party tomorrow night!"
,您会 而不是 加上另一个"Re: "
). - 您需要将回复邮件的
In-Reply-To
header 设置为原始邮件中Message-Id
header 的值。 - 您需要将原始消息的
References
header 复制到回复消息的References
header 中,然后附加原始消息的Message-Id
header. - 您可能希望在回复中 "quote" 原始消息的文本。
如果用代码来表达这个逻辑,它可能看起来像这样(我在这个例子中使用 MailKit):
public static MimeMessage Reply (MimeMessage message, bool replyToAll)
{
var reply = new MimeMessage ();
// reply to the sender of the message
if (message.ReplyTo.Count > 0) {
reply.To.AddRange (message.ReplyTo);
} else if (message.From.Count > 0) {
reply.To.AddRange (message.From);
} else if (message.Sender != null) {
reply.To.Add (message.Sender);
}
if (replyToAll) {
// include all of the other original recipients - TODO: remove ourselves from these lists
reply.To.AddRange (message.To);
reply.Cc.AddRange (message.Cc);
}
// set the reply subject
if (!message.Subject.StartsWith ("Re:", StringComparison.OrdinalIgnoreCase))
reply.Subject = "Re: " + message.Subject;
else
reply.Subject = message.Subject;
// construct the In-Reply-To and References headers
if (!string.IsNullOrEmpty (message.MessageId)) {
reply.InReplyTo = message.MessageId;
foreach (var id in message.References)
reply.References.Add (id);
reply.References.Add (message.MessageId);
}
// quote the original message text
using (var quoted = new StringWriter ()) {
var sender = message.Sender ?? message.From.Mailboxes.FirstOrDefault ();
quoted.WriteLine ("On {0}, {1} wrote:", message.Date.ToString ("f"), !string.IsNullOrEmpty (sender.Name) ? sender.Name : sender.Address);
using (var reader = new StringReader (message.TextBody)) {
string line;
while ((line = reader.ReadLine ()) != null) {
quoted.Write ("> ");
quoted.WriteLine (line);
}
}
reply.Body = new TextPart ("plain") {
Text = quoted.ToString ()
};
}
return reply;
}
注意:此代码假定 message.TextBody
不为空。有可能,尽管不太可能发生这种情况(这意味着消息不包含 text/plain
body)。