Como posso saber qual email é uma resposta a outro email, em C#?
Pergunta
Desenvolvi uma aplicação web, na qual existe uma funcionalidade para inserir nota para um determinado pedido de venda.
Quando uma nota é inserida por um cliente ou executivo de atendimento ao cliente, uma notificação por e-mail é enviada à parte relevante (a notificação por e-mail é enviada usando objetos SmtpClient e MailMessage em C#).
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);
}
Estou definindo um Guid
Enquanto o Message-Id
da mensagem que está sendo enviada nos cabeçalhos da mensagem.
Tudo isso funciona bem.
Agora quero desenvolver uma funcionalidade para que as partes respondam à notificação por e-mail de suas respectivas caixas de entrada.
E quero registrar as respostas nas notas do mesmo Pedido de Venda (para o qual a parte recebeu a notificação).
Estou usando OpenPop.dll para ler a caixa de entrada de respostas de notificação.
/// <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;
}
}
A partir da função acima, posso ler todos os e-mails da minha conta "replyto@email.com".Mas não estou conseguindo encontrar o Message-Id
no In-reply-to
cabeçalho dos e-mails.
Não sei o que estou fazendo de errado.
Solução
A melhor solução que consigo pensar é colocar seus dados no cabeçalho "De" e/ou "Responder para" usando, por exemplo, o sinal '+'.
Digamos que seu endereço de retorno seja respostas@seudominio.com
Você deve adicionar uma regra de filtro em seu servidor de e-mail, para que qualquer mensagem enviada para respostas+qualquerdadorelevanteaqui@seudomínio.com caia na caixa de correio respostas@seudomínio.com
As notificações do Facebook usam isso para respostas diretas por e-mail.
O Gmail também usa (tente se você tiver um endereço do Gmail)
( ver http://forums.smartertools.com/showthread.php/27790-Plus-Addressing-configure-symbol )
Espero que isso ajude.Se sim, boa sorte com a configuração do servidor de email
Outras dicas
Conforme respondido por @jbl, usamos o conceito de endereçamento positivo.Pedimos ao nosso provedor de e-mail para ativar esse conceito em nosso SMTP
servidor.O Gmail fornece isso por padrão.
Ao enviar qualquer e-mail, daríamos uma resposta exclusiva ao endereço para cada nota inserida em um pedido, como abaixo.
String sReplyToadd = "replyto@domain.com";
String replyToAddress = sReplyToadd.Substring(0, sReplyToadd.IndexOf('@')) + "+on" + orderID + "un" + userID + sReplyToadd.Substring(sReplyToadd.IndexOf('@'), sReplyToadd.Length - sReplyToadd.IndexOf('@'));
Isto faria com que replyToAddress = "replyto+on1234un5678@domain.com"
, um endereço exclusivo para identificar o pedido e o usuário que postou a nota.
Agora, esta resposta exclusiva ao endereço seria atribuída ao e-mail enviado conforme abaixo.
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
o endereço apareceria no endereço para, se o usuário clicar no botão responder em seu cliente de e-mail, conforme mostrado abaixo.
Se o usuário não alterar o To
endereço, ele seria recebido em nosso replyto@domain.com
caixa de correio.Colocamos uma nota na parte inferior de cada e-mail enviado: Não altere o endereço Para para mapear sua resposta corretamente para o sistema.
Assim que o e-mail chegar à caixa de correio, só precisamos verificar o To
endereço da resposta do e-mail e obtenha o ID do pedido e o ID do usuário necessários, conforme abaixo
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);
E então vivemos felizes para sempre!!!