【问题标题】:How can I know which email is a reply to another email, in C#?在 C# 中,我如何知道哪封电子邮件是对另一封电子邮件的回复?
【发布时间】:2012-03-18 16:02:52
【问题描述】:

我开发了一个 Web 应用程序,其中有一个功能可以为特定的销售订单输入备注。

当客户或客户服务主管输入注释时,将向相关方发送电子邮件通知(电子邮件通知使用 C# 中的 SmtpClient 和 MailMessage 对象发送)。

using (MailMessage objEmail = new MailMessage())
{
    Guid objGuid = new Guid();
    objGuid = Guid.NewGuid();
    String MessageID = "<" + objGuid.ToString() + ">";
    objEmail.Body = messagebody.ToString();
    objEmail.From = new MailAddress(sFrmadd, sFrmname);
    objEmail.Headers.Add("Message-Id", MessageID);
    objEmail.IsBodyHtml = true;
    objEmail.ReplyTo = new MailAddress("replyto@email.com");                    
    objEmail.Subject = sSubject;                    
    objEmail.To.Add(new MailAddress(sToadd));

    SmtpClient objSmtp = new SmtpClient();
    objSmtp.Credentials = new NetworkCredential("mynetworkcredential", "mypassword");
    objSmtp.DeliveryMethod = SmtpDeliveryMethod.Network;
    objSmtp.EnableSsl = true;
    objSmtp.Host = "myhostname";
    objSmtp.Port = 25;
    objSmtp.Timeout = 3 * 3600;

    objSmtp.Send(objEmail);                    
}

我将Guid 设置为邮件标头中正在发送的邮件的Message-Id

这一切都很好。

现在我想开发一个功能,让各方从各自的收件箱回复电子邮件通知。

并且我想在备注中记录对同一销售订单(相关方收到通知)的回复。

我正在使用 OpenPop.dll 来阅读收件箱中的通知回复。

/// <summary>
/// Fetch all messages from a POP3 server
/// </summary>
/// <param name="hostname">Hostname of the server. For example: pop3.live.com</param>
/// <param name="port">Host port to connect to. Normally: 110 for plain POP3, 995 for SSL POP3</param>
/// <param name="useSsl">Whether or not to use SSL to connect to server</param>
/// <param name="username">Username of the user on the server</param>
/// <param name="password">Password of the user on the server</param>
/// <returns>All Messages on the POP3 server</returns>
public static List<Message> FetchAllMessages(string hostname, int port, bool useSsl, string username, string password)
{
    // The client disconnects from the server when being disposed
    using (Pop3Client client = new Pop3Client())
    {
        // Connect to the server
        client.Connect(hostname, port, useSsl);

        // Authenticate ourselves towards the server
        client.Authenticate(username, password);

        // Get the number of messages in the inbox
        int messageCount = client.GetMessageCount();

        // We want to download all messages
        List<Message> allMessages = new List<Message>(messageCount);

        // Messages are numbered in the interval: [1, messageCount]
        // Ergo: message numbers are 1-based.
        for (int i = 1; i <= messageCount; i++)
        {
            allMessages.Add(client.GetMessage(i));
        }

        // Now return the fetched messages
        return allMessages;
    }
}

通过上述功能,我可以阅读“replyto@email.com”帐户中的所有电子邮件。但我无法在电子邮件的In-reply-to 标头中找到Message-Id

我不知道我做错了什么。

【问题讨论】:

  • 据我所知,没有可靠的方法可以做到这一点,您受制于电子邮件客户端,每个电子邮件客户端都有自己的怪癖。我见过的大多数类似系统都使用 主题行 来放入唯一的 id,然后在回复消息时从头开始删除“RE:”。
  • 我们过去常常在电子邮件中添加一些自定义标题。
  • 我相信即使是 Outlook 的对话也是基于主题的。

标签: c# asp.net email openpop


【解决方案1】:

我能想到的最佳解决方案是将您的数据放在“发件人”和/或“回复”标题中,例如使用“+”号。

说你的回信地址是replies@yourdomain.com

您必须在您的邮件服务器中添加过滤规则,以便发送到replies+anyrelevantdatahere@yourdomain.com 的任何邮件都落入replies@yourdomain.com 邮箱

Facebook 通知将其用于直接电子邮件回复。

gmail 也使用它(如果你有 gmail 地址试试)

(见http://forums.smartertools.com/showthread.php/27790-Plus-Addressing-configure-symbol

希望这会有所帮助。如果是这样,祝你邮件服务器配置好运

【讨论】:

    【解决方案2】:

    正如@jbl 所回答的,我们使用了加号寻址概念。我们要求我们的电子邮件提供商在我们的SMTP 服务器上启用此概念。 Gmail 默认提供此功能。

    在发送任何电子邮件时,我们会对在如下订单中输入的每个注释的地址做出唯一回复。

    String sReplyToadd = "replyto@domain.com";
    String replyToAddress = sReplyToadd.Substring(0, sReplyToadd.IndexOf('@')) + "+on" + orderID + "un" + userID + sReplyToadd.Substring(sReplyToadd.IndexOf('@'), sReplyToadd.Length - sReplyToadd.IndexOf('@'));
    

    这将使replyToAddress = "replyto+on1234un5678@domain.com" 成为一个唯一地址,用于识别订单和发布注释的用户。

    现在,这个地址的唯一回复将被分配给发送出去的电子邮件,如下所示。

    using (MailMessage objEmail = new MailMessage())
    {
        objEmail.Body = eMailBody;
        objEmail.From = new MailAddress("from@domain.com", "Display Name");
        objEmail.IsBodyHtml = true;
        objEmail.Subject = "email subject goes here";
        objEmail.To.Add(new MailAddress("tosomeuser@gmail.com");
    
        //here we set the unique reply to address for the outgoing email
        objEmail.ReplyTo = new MailAddress(replyToAddress); //replyto+on1234un5678@domain.com
    
        SmtpClient objSmtp = new SmtpClient();
    
        objSmtp.EnableSsl = true;
        objSmtp.Credentials = new NetworkCredential("username", "password");
        objSmtp.Host = "127.0.0.1";//"smtp.gmail.com" for gmail
        objSmtp.Port = 25;
    
        objSmtp.Send(objEmail);
    }
    

    ReplyTo 地址将出现在收件人地址中,如果用户点击他们电子邮件客户端中的回复按钮,如下所示。

    如果用户不更改To 地址,它将在我们的replyto@domain.com 邮箱中收到。我们在每封发送的电子邮件底部都添加了注释:请不要更改收件人地址以将您的回复正确映射到系统。

    邮件到达邮箱后,我们只需要查看邮件回复的To地址,得到需要的订单id和用户id,如下

    String replyFor = objEmail.To[0].ToString();
    Int64 orderID = Convert.ToInt64(replyFor.Substring(replyFor.LastIndexOf("+on") + 3, replyFor.LastIndexOf("un")));
    Int64 userID = replyFor.Substring(replyFor.LastIndexOf("un") + 2, replyFor.IndexOf("@") - replyFor.LastIndexOf("un") - 2);
    

    然后我们从此过上了幸福的生活!!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-30
      • 1970-01-01
      • 2019-07-05
      相关资源
      最近更新 更多