Gmail Send Email As Reply

2019-06-04 06:55发布

问题:

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:

  1. 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 a Subject of "Re: party tomorrow night!", you would not prefix it with another "Re: ").
  2. You will want to set the reply message's In-Reply-To header to the value of the Message-Id header in the original message.
  3. You will want to copy the original message's References header into the reply message's References header and then append the original message's Message-Id header.
  4. 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.


标签: c# smtp