问题
Sending an emai lthrough gmail is easy enough as seen below:
Sending email in .NET through Gmail
But I can't seem to find a method to send the email as a response to another email. Automatically including the previous messages.
Code for fun: Doesn't really relate to sending an email(reading here, using AE.Net.Mail library for imap client)
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();
}
回答1:
Replying to a message is fairly simple. For the most part, you'd just create the reply message the same way you'd create any other message. There are only a few slight differences:
- In the reply message, you'll want to prefix the
Subject
header with"Re: "
if the prefix doesn't already exist in the message you are replying to (in other words, if you are replying to a message with aSubject
of"Re: party tomorrow night!"
, you would not prefix it with another"Re: "
). - You will want to set the reply message's
In-Reply-To
header to the value of theMessage-Id
header in the original message. - You will want to copy the original message's
References
header into the reply message'sReferences
header and then append the original message'sMessage-Id
header. - You will probably want to "quote" the original message's text in the reply.
If this logic were to be expressed in code, it might look something like this (I'm using MailKit in this example):
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;
}
Note: This code assumes that message.TextBody
is not null. It's possible, although fairly unlikely, that this could happen (meaning that the message does not contain a text/plain
body).
回答2:
Just take the incoming email, read out its data such as sender, subject, text and make use of them when creating the reply. The destination of the reply should be the sender's email address, subject = "RE:"+subject+incoming, as for the text you can use whatever methodology you want. I don't think that there is any built-in function for replying to an email. You gotta do those things manually. First of all you have to find some way to get out the contents of the mailbox of the email client, such as outlook or download the last X messages from the SMTP server manually.
- retrieve the original email (either from Outlook-> COM Object through OLE -> an outlook ole object is like a useragent of your installed outlook mailing cloent).Google how to do that. OR download latest mails from SMTP.
- Once you have the contents of the mail, create an email which contains the contents of incoming mail. Then send it. If you go with Microsoft OLE then you might as well send the email through the outlook ole object.
来源:https://stackoverflow.com/questions/39276486/gmail-send-email-as-reply